diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes	Mon Feb 10 10:39:32 2003
+++ b/Documentation/Changes	Mon Feb 10 10:39:32 2003
@@ -52,7 +52,7 @@
 o  Gnu make               3.78                    # make --version
 o  binutils               2.9.5.0.25              # ld -v
 o  util-linux             2.10o                   # fdformat --version
-o  module-init-tools      0.9.8                   # rmmod -V
+o  module-init-tools      0.9.9                   # depmod -V
 o  e2fsprogs              1.29                    # tune2fs
 o  jfsutils               1.0.14                  # fsck.jfs -V
 o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
diff -Nru a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl
--- a/Documentation/DocBook/journal-api.tmpl	Mon Feb 10 10:39:23 2003
+++ b/Documentation/DocBook/journal-api.tmpl	Mon Feb 10 10:39:23 2003
@@ -141,17 +141,14 @@
 Or if you've asked for access to a buffer you now know is now longer 
 required to be pushed back on the device you can call journal_forget()
 in much the same way as you might have used bforget() in the past.
-
 </para>
 
-
-
 <para>
 A journal_flush() may be called at any time to commit and checkpoint
 all your transactions.
 </para>
-<para>
 
+<para>
 Then at umount time , in your put_super() (2.4) or write_super() (2.5)
 you can then call journal_destroy() to clean up your in-core journal object.
 </para>
@@ -168,8 +165,8 @@
 across differing journals, and another filesystem other than
 yours (say ext3) may be modified in a later syscall.
 </para>
-<para>
 
+<para>
 The second case to bear in mind is that journal_start() can 
 block if there isn't enough space in the journal for your transaction 
 (based on the passed nblocks param) - when it blocks it merely(!) needs to
@@ -180,10 +177,14 @@
 deadlocks. Note that journal_extend() has similar blocking behaviour to
 journal_start() so you can deadlock here just as easily as on journal_start().
 </para>
-<para>
 
-Try to reserve the right number of blocks the first time. ;-).
+<para>
+Try to reserve the right number of blocks the first time. ;-). This will
+be the maximum number of blocks you are going to touch in this transaction.
+I advise having a look at at least ext3_jbd.h to see the basis on which 
+ext3 uses to make these decisions.
 </para>
+
 <para>
 Another wriggle to watch out for is your on-disk block allocation strategy.
 why? Because, if you undo a delete, you need to ensure you haven't reused any
@@ -211,6 +212,30 @@
 if you allow unprivileged userspace to trigger codepaths containing these
 calls.
 </para>
+
+<para>
+A new feature of jbd since 2.5.25 is commit callbacks with the new
+journal_callback_set() function you can now ask the journalling layer
+to call you back when the transaction is finally commited to disk, so that
+you can do some of your own management. The key to this is the journal_callback
+struct, this maintains the internal callback information but you can
+extend it like this:-
+</para>
+<programlisting>
+	struct  myfs_callback_s {
+		//Data structure element required by jbd..
+		struct journal_callback for_jbd;
+		// Stuff for myfs allocated together.
+		myfs_inode*    i_commited;
+	
+	}
+</programlisting>
+
+<para>
+this would be useful if you needed to know when data was commited to a 
+particular inode.
+</para>
+
 </sect1>
 
 <sect1>
diff -Nru a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
--- a/Documentation/SubmittingDrivers	Mon Feb 10 10:39:30 2003
+++ b/Documentation/SubmittingDrivers	Mon Feb 10 10:39:30 2003
@@ -62,7 +62,7 @@
 		in Documentation/CodingStyle. If you have sections of code
 		that need to be in other formats, for example because they
 		are shared with a windows driver kit and you want to
-		maintain them just once seperate them out nicely and note
+		maintain them just once separate them out nicely and note
 		this fact.
 
 Portability:	Pointers are not always 32bits, not all computers are little
diff -Nru a/Documentation/arm/SA1100/CERF b/Documentation/arm/SA1100/CERF
--- a/Documentation/arm/SA1100/CERF	Mon Feb 10 10:39:23 2003
+++ b/Documentation/arm/SA1100/CERF	Mon Feb 10 10:39:23 2003
@@ -1,23 +1,28 @@
-The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board that measures 
-approximately 2" square. It includes an Ethernet controller, an RS232-compatible serial port, a
-USB function port, and one CompactFlash+ slot on the back. Pictures can be found at the
+The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board
+that measures approximately 2" square. It includes an Ethernet
+controller, an RS232-compatible serial port, a USB function port, and
+one CompactFlash+ slot on the back. Pictures can be found at the
 Intrinsyc website, http://www.intrinsyc.com.
 
-This document describes the support in the Linux kernel for the Intrinsyc CerfBoard as of
-version 2.4.0-test4-np1.
+This document describes the support in the Linux kernel for the
+Intrinsyc CerfBoard as of version 2.4.0-test4-np1.
 
 Supported in this version:
-   - CompactFlash+ slot (select PCMCIA in General Setup and any options that may be required)
-   - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in Network Devices)
+   - CompactFlash+ slot (select PCMCIA in General Setup and any options
+     that may be required)
+   - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in
+     Network Devices)
    - Serial ports with a serial console (hardcoded to 38400 8N1)
 
 Not supported in this version (yet):
    - LCD driver/touchscreen interface
-   - UDC (a driver exists right now, but is unstable and slow and only works with the Linux USB)
+   - UDC (a driver exists right now, but is unstable and slow and only
+     works with the Linux USB)
 
-In order to get this kernel onto your Cerf, you need a server that runs both BOOTP and
-TFTP. Detailed instructions should have come with your evaluation kit on how to use the
-bootloader. This series of commands will suffice:
+In order to get this kernel onto your Cerf, you need a server that runs
+both BOOTP and TFTP. Detailed instructions should have come with your
+evaluation kit on how to use the bootloader. This series of commands
+will suffice:
 
    make cerf_config
    make xconfig
@@ -25,10 +30,9 @@
    make zImage
    cp arch/arm/boot/zImage <TFTP directory>
 
-The default config uses a 4MB RAM disk located at 0xc0500000 as root. Setting the board to
-mount root from a NFS partition works, too.
+The default config uses a 4MB RAM disk located at 0xc0500000 as root.
+Setting the board to mount root from a NFS partition works, too.
 
 
 I-Gene Leong, Intrinsyc Software Inc.
 ileong@intrinsyc.com
-
diff -Nru a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
--- a/Documentation/filesystems/ext3.txt	Mon Feb 10 10:39:25 2003
+++ b/Documentation/filesystems/ext3.txt	Mon Feb 10 10:39:25 2003
@@ -78,7 +78,7 @@
 filesystem code will inform the JBD of modifications it is performing
 (Call a transaction).  the journal support the transactions start and
 stop, and in case of crash, the journal can replayed the transactions
-to put the partition on a consistant state fastly.
+to put the partition on a consistent state fastly.
 
 handles represent a single atomic update to a filesystem.  JBD can
 handle external journal on a block device.
diff -Nru a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
--- a/Documentation/filesystems/jfs.txt	Mon Feb 10 10:39:29 2003
+++ b/Documentation/filesystems/jfs.txt	Mon Feb 10 10:39:29 2003
@@ -28,8 +28,6 @@
 Plans for our near term development items
 
    - enhance support for logfile on dedicated partition
-   - get access control list functionality operational
-   - get extended attributes functionality operational
 
 Longer term work items
 
@@ -37,7 +35,7 @@
    - add quota support
    - add support for block sizes (512,1024,2048)
 
-Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+Please send bugs, comments, cards and letters to shaggy@austin.ibm.com.
 
 The JFS mailing list can be subscribed to by using the link labeled
 "Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/.
diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
--- a/Documentation/filesystems/proc.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/filesystems/proc.txt	Mon Feb 10 10:39:24 2003
@@ -911,7 +911,7 @@
 The four values in printk denote
 * console_loglevel,
 * default_message_loglevel,
-* minimum_console_level and
+* minimum_console_loglevel and
 * default_console_loglevel
 respectively.
 
diff -Nru a/Documentation/ia64/README b/Documentation/ia64/README
--- a/Documentation/ia64/README	Mon Feb 10 10:39:32 2003
+++ b/Documentation/ia64/README	Mon Feb 10 10:39:32 2003
@@ -4,40 +4,40 @@
    platform.  This document provides information specific to IA-64
    ONLY, to get additional information about the Linux kernel also
    read the original Linux README provided with the kernel.
- 
+
 INSTALLING the kernel:
 
  - IA-64 kernel installation is the same as the other platforms, see
    original README for details.
-   
- 
+
+
 SOFTWARE REQUIREMENTS
 
    Compiling and running this kernel requires an IA-64 compliant GCC
    compiler.  And various software packages also compiled with an
    IA-64 compliant GCC compiler.
- 
+
 
 CONFIGURING the kernel:
 
    Configuration is the same, see original README for details.
-  
-   
+
+
 COMPILING the kernel:
 
  - Compiling this kernel doesn't differ from other platform so read
    the original README for details BUT make sure you have an IA-64
    compliant GCC compiler.
- 
+
 IA-64 SPECIFICS
 
  - General issues:
- 
+
     o Hardly any performance tuning has been done. Obvious targets
       include the library routines (IP checksum, etc.). Less
       obvious targets include making sure we don't flush the TLB
       needlessly, etc.
-	  
+
     o SMP locks cleanup/optimization
-	
+
     o IA32 support.  Currently experimental.  It mostly works.
diff -Nru a/Documentation/ia64/fsys.txt b/Documentation/ia64/fsys.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/ia64/fsys.txt	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,231 @@
+-*-Mode: outline-*-
+
+		Light-weight System Calls for IA-64
+		-----------------------------------
+
+		        Started: 13-Jan-2003
+		    Last update: 24-Jan-2003
+
+	              David Mosberger-Tang
+		      <davidm@hpl.hp.com>
+
+Using the "epc" instruction effectively introduces a new mode of
+execution to the ia64 linux kernel.  We call this mode the
+"fsys-mode".  To recap, the normal states of execution are:
+
+  - kernel mode:
+	Both the register stack and the memory stack have been
+	switched over to kernel memory.  The user-level state is saved
+	in a pt-regs structure at the top of the kernel memory stack.
+
+  - user mode:
+	Both the register stack and the kernel stack are in
+	user memory.  The user-level state is contained in the
+	CPU registers.
+
+  - bank 0 interruption-handling mode:
+	This is the non-interruptible state which all
+	interruption-handlers start execution in.  The user-level
+	state remains in the CPU registers and some kernel state may
+	be stored in bank 0 of registers r16-r31.
+
+In contrast, fsys-mode has the following special properties:
+
+  - execution is at privilege level 0 (most-privileged)
+
+  - CPU registers may contain a mixture of user-level and kernel-level
+    state (it is the responsibility of the kernel to ensure that no
+    security-sensitive kernel-level state is leaked back to
+    user-level)
+
+  - execution is interruptible and preemptible (an fsys-mode handler
+    can disable interrupts and avoid all other interruption-sources
+    to avoid preemption)
+
+  - neither the memory nor the register stack can be trusted while
+    in fsys-mode (they point to the user-level stacks, which may
+    be invalid)
+
+In summary, fsys-mode is much more similar to running in user-mode
+than it is to running in kernel-mode.  Of course, given that the
+privilege level is at level 0, this means that fsys-mode requires some
+care (see below).
+
+
+* How to tell fsys-mode
+
+Linux operates in fsys-mode when (a) the privilege level is 0 (most
+privileged) and (b) the stacks have NOT been switched to kernel memory
+yet.  For convenience, the header file <asm-ia64/ptrace.h> provides
+three macros:
+
+	user_mode(regs)
+	user_stack(task,regs)
+	fsys_mode(task,regs)
+
+The "regs" argument is a pointer to a pt_regs structure.  The "task"
+argument is a pointer to the task structure to which the "regs"
+pointer belongs to.  user_mode() returns TRUE if the CPU state pointed
+to by "regs" was executing in user mode (privilege level 3).
+user_stack() returns TRUE if the state pointed to by "regs" was
+executing on the user-level stack(s).  Finally, fsys_mode() returns
+TRUE if the CPU state pointed to by "regs" was executing in fsys-mode.
+The fsys_mode() macro is equivalent to the expression:
+
+	!user_mode(regs) && user_stack(task,regs)
+
+* How to write an fsyscall handler
+
+The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers
+(fsyscall_table).  This table contains one entry for each system call.
+By default, a system call is handled by fsys_fallback_syscall().  This
+routine takes care of entering (full) kernel mode and calling the
+normal Linux system call handler.  For performance-critical system
+calls, it is possible to write a hand-tuned fsyscall_handler.  For
+example, fsys.S contains fsys_getpid(), which is a hand-tuned version
+of the getpid() system call.
+
+The entry and exit-state of an fsyscall handler is as follows:
+
+** Machine state on entry to fsyscall handler:
+
+ - r10	  = 0
+ - r11	  = saved ar.pfs (a user-level value)
+ - r15	  = system call number
+ - r16	  = "current" task pointer (in normal kernel-mode, this is in r13)
+ - r32-r39 = system call arguments
+ - b6	  = return address (a user-level value)
+ - ar.pfs = previous frame-state (a user-level value)
+ - PSR.be = cleared to zero (i.e., little-endian byte order is in effect)
+ - all other registers may contain values passed in from user-mode
+
+** Required machine state on exit to fsyscall handler:
+
+ - r11	  = saved ar.pfs (as passed into the fsyscall handler)
+ - r15	  = system call number (as passed into the fsyscall handler)
+ - r32-r39 = system call arguments (as passed into the fsyscall handler)
+ - b6	  = return address (as passed into the fsyscall handler)
+ - ar.pfs = previous frame-state (as passed into the fsyscall handler)
+
+Fsyscall handlers can execute with very little overhead, but with that
+speed comes a set of restrictions:
+
+ o Fsyscall-handlers MUST check for any pending work in the flags
+   member of the thread-info structure and if any of the
+   TIF_ALLWORK_MASK flags are set, the handler needs to fall back on
+   doing a full system call (by calling fsys_fallback_syscall).
+
+ o Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11,
+   r15, b6, and ar.pfs) because they will be needed in case of a
+   system call restart.  Of course, all "preserved" registers also
+   must be preserved, in accordance to the normal calling conventions.
+
+ o Fsyscall-handlers MUST check argument registers for containing a
+   NaT value before using them in any way that could trigger a
+   NaT-consumption fault.  If a system call argument is found to
+   contain a NaT value, an fsyscall-handler may return immediately
+   with r8=EINVAL, r10=-1.
+
+ o Fsyscall-handlers MUST NOT use the "alloc" instruction or perform
+   any other operation that would trigger mandatory RSE
+   (register-stack engine) traffic.
+
+ o Fsyscall-handlers MUST NOT write to any stacked registers because
+   it is not safe to assume that user-level called a handler with the
+   proper number of arguments.
+
+ o Fsyscall-handlers need to be careful when accessing per-CPU variables:
+   unless proper safe-guards are taken (e.g., interruptions are avoided),
+   execution may be pre-empted and resumed on another CPU at any given
+   time.
+
+ o Fsyscall-handlers must be careful not to leak sensitive kernel'
+   information back to user-level.  In particular, before returning to
+   user-level, care needs to be taken to clear any scratch registers
+   that could contain sensitive information (note that the current
+   task pointer is not considered sensitive: it's already exposed
+   through ar.k6).
+
+The above restrictions may seem draconian, but remember that it's
+possible to trade off some of the restrictions by paying a slightly
+higher overhead.  For example, if an fsyscall-handler could benefit
+from the shadow register bank, it could temporarily disable PSR.i and
+PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as
+needed.  In other words, following the above rules yields extremely
+fast system call execution (while fully preserving system call
+semantics), but there is also a lot of flexibility in handling more
+complicated cases.
+
+* Signal handling
+
+The delivery of (asynchronous) signals must be delayed until fsys-mode
+is exited.  This is acomplished with the help of the lower-privilege
+transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user()
+checks whether the interrupted task was in fsys-mode and, if so, sets
+PSR.lp and returns immediately.  When fsys-mode is exited via the
+"br.ret" instruction that lowers the privilege level, a trap will
+occur.  The trap handler clears PSR.lp again and returns immediately.
+The kernel exit path then checks for and delivers any pending signals.
+
+* PSR Handling
+
+The "epc" instruction doesn't change the contents of PSR at all.  This
+is in contrast to a regular interruption, which clears almost all
+bits.  Because of that, some care needs to be taken to ensure things
+work as expected.  The following discussion describes how each PSR bit
+is handled.
+
+PSR.be	Cleared when entering fsys-mode.  A srlz.d instruction is used
+	to ensure the CPU is in little-endian mode before the first
+	load/store instruction is executed.  PSR.be is normally NOT
+	restored upon return from an fsys-mode handler.  In other
+	words, user-level code must not rely on PSR.be being preserved
+	across a system call.
+PSR.up	Unchanged.
+PSR.ac	Unchanged.
+PSR.mfl Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.mfh	Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.ic	Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
+PSR.i	Unchanged.  Note: fsys-mode handlers can clear the bit, if needed.
+PSR.pk	Unchanged.
+PSR.dt	Unchanged.
+PSR.dfl	Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.dfh	Unchanged.  Note: fsys-mode handlers must not write-registers!
+PSR.sp	Unchanged.
+PSR.pp	Unchanged.
+PSR.di	Unchanged.
+PSR.si	Unchanged.
+PSR.db	Unchanged.  The kernel prevents user-level from setting a hardware
+	breakpoint that triggers at any privilege level other than 3 (user-mode).
+PSR.lp	Unchanged.
+PSR.tb	Lazy redirect.  If a taken-branch trap occurs while in
+	fsys-mode, the trap-handler modifies the saved machine state
+	such that execution resumes in the gate page at
+	syscall_via_break(), with privilege level 3.  Note: the
+	taken branch would occur on the branch invoking the
+	fsyscall-handler, at which point, by definition, a syscall
+	restart is still safe.  If the system call number is invalid,
+	the fsys-mode handler will return directly to user-level.  This
+	return will trigger a taken-branch trap, but since the trap is
+	taken _after_ restoring the privilege level, the CPU has already
+	left fsys-mode, so no special treatment is needed.
+PSR.rt	Unchanged.
+PSR.cpl	Cleared to 0.
+PSR.is	Unchanged (guaranteed to be 0 on entry to the gate page).
+PSR.mc	Unchanged.
+PSR.it	Unchanged (guaranteed to be 1).
+PSR.id	Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.da	Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.dd	Unchanged.  Note: the ia64 linux kernel never sets this bit.
+PSR.ss	Lazy redirect.  If set, "epc" will cause a Single Step Trap to
+	be taken.  The trap handler then modifies the saved machine
+	state such that execution resumes in the gate page at
+	syscall_via_break(), with privilege level 3.
+PSR.ri	Unchanged.
+PSR.ed	Unchanged.  Note: This bit could only have an effect if an fsys-mode
+	handler performed a speculative load that gets NaTted.  If so, this
+	would be the normal & expected behavior, so no special treatment is
+	needed.
+PSR.bn	Unchanged.  Note: fsys-mode handlers may clear the bit, if needed.
+	Doing so requires clearing PSR.i and PSR.ic as well.
+PSR.ia	Unchanged.  Note: the ia64 linux kernel never sets this bit.
diff -Nru a/Documentation/isdn/HiSax.cert b/Documentation/isdn/HiSax.cert
--- a/Documentation/isdn/HiSax.cert	Mon Feb 10 10:39:24 2003
+++ b/Documentation/isdn/HiSax.cert	Mon Feb 10 10:39:24 2003
@@ -27,7 +27,7 @@
 the layer 1. Because all hardware based on these chips are complete ISDN
 solutions in one chip all cards and USB-TAs using these chips are to be
 regarded as approved for those tests. Some additional electrical tests
-of the layer 1 which are independant of the driver and related to a
+of the layer 1 which are independent of the driver and related to a
 special hardware used will be regarded as approved if at least one 
 solution has been tested including those electrical tests. So if cards 
 or tas have been completely approved for any other os, the approval
diff -Nru a/Documentation/kbuild/00-INDEX b/Documentation/kbuild/00-INDEX
--- a/Documentation/kbuild/00-INDEX	Mon Feb 10 10:39:24 2003
+++ b/Documentation/kbuild/00-INDEX	Mon Feb 10 10:39:24 2003
@@ -1,10 +1,10 @@
 00-INDEX
     	- this file: info on the kernel build process
-bug-list.txt
-	- known bugs in kbuild programs
 commands.txt
 	- overview of kbuild commands
 kconfig-language.txt
 	- specification of Config Language, the language in Kconfig files
+random.txt
+	- description of generic config targets
 makefiles.txt
 	- developer information for linux kernel makefiles
diff -Nru a/Documentation/kbuild/bug-list.txt b/Documentation/kbuild/bug-list.txt
--- a/Documentation/kbuild/bug-list.txt	Mon Feb 10 10:39:24 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,22 +0,0 @@
-Bug List
-21 January 1999
-Michael Elizabeth Chastain, <mailto:mec@shout.net>
-
-- If a variable has a value of "m" in the previous .config file,
-  and a type of bool in the Config script, then all the interpreters
-  get confused.  This happens frequently when someone changes a
-  tristate option to a bool option and people in the field have
-  .config files with a value of 'm'.  For example: CONFIG_PSMOUSE.
-
-- CONFIG_MODVERSIONS has incorrect dependencies.  If you have a
-  problem building the kernel, and you have CONFIG_MODVERSIONS turned
-  on, do a 'make dep' followed by 'make clean' before you try anything
-  else.
-
-- 'make dep' uses multistage dependencies, so the .hdepend file contains
-  'touch' commands.  As a result, building a kernel often touches files
-  in include/linux/*.h.  This messes up CVS and other systems which like
-  to rely on file dates.
-
-- 'make dep' fails for C files which include other C files, such as
-  drivers/cdrom/sbpcd2.c.
diff -Nru a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
--- a/Documentation/kbuild/makefiles.txt	Mon Feb 10 10:39:30 2003
+++ b/Documentation/kbuild/makefiles.txt	Mon Feb 10 10:39:30 2003
@@ -1,74 +1,76 @@
 Linux Kernel Makefiles
-2000-September-14
-Michael Elizabeth Chastain, <mec@shout.net>
-
-
-
-=== Table of Contents
 
 This document describes the Linux kernel Makefiles.
 
-  1  Overview
-  2  Who does what
-  3  Makefile language
-  4  Variables passed down from the top
-  5  The structure of an arch Makefile
-     5.1  Architecture-specific variables
-     5.2  Vmlinux build variables
-     5.3  Post-vmlinux goals
-     5.4  Mandatory arch-specific goals
-  6  The structure of a subdirectory Makefile
-     6.1  Comments
-     6.2  Goal definitions
-     6.3  Adapter section
-     6.4  Rules.make section
-     6.5  Special rules
-  7  Rules.make variables
-     7.1  Subdirectories
-     7.2  Object file goals
-     7.3  Library file goals
-     7.4  Loadable module goals
-     7.5  Multi-part modules
-     7.6  Compilation flags
-     7.7  Miscellaneous variables
-  8  New-style variables
-     8.1  New variables
-     8.2  Converting to old-style
-  9  Credits
+=== Table of Contents
 
+	=== 1 Overview
+	=== 2 Who does what
+	=== 3 The kbuild Makefiles
+	   --- 3.1 Goal definitions
+	   --- 3.2 Built-in object goals - obj-y
+	   --- 3.3 Loadable module goals - obj-m
+	   --- 3.4 Objects which export symbols - export-objs
+	   --- 3.5 Library file goals - L_TARGET
+	   --- 3.6 Descending down in directories
+	   --- 3.7 Compilation flags
+	   --- 3.8 Command line dependency
+	   --- 3.9 Dependency tracking
+	   --- 3.10 Special Rules
+
+	=== 4 Host Program support
+	   --- 4.1 Simple Host Program
+	   --- 4.2 Composite Host Programs
+	   --- 4.3 Defining shared libraries  
+	   --- 4.4 Using C++ for host programs
+	   --- 4.5 Controlling compiler options for host programs
+	   --- 4.6 When host programs are actually built
+
+	=== 5 Kbuild clean infrastructure
+
+	=== 6 Architecture Makefiles
+	   --- 6.1 Set variables to tweak the build to the architecture
+	   --- 6.2 Add prerequisites to prepare:
+	   --- 6.3 List directories to visit when descending
+	   --- 6.4 Architecture specific boot images
+	   --- 6.5 Building non-kbuild targets
+	   --- 6.6 Commands useful for building a boot image
+	   --- 6.7 Custom kbuild commands
+
+	=== 7 Kbuild Variables
+	=== 8 Makefile language
+	=== 9 Credits
+	=== 10 TODO
 
 === 1 Overview
 
 The Makefiles have five parts:
 
-    Makefile: the top Makefile.
-    .config: the kernel configuration file.
-    arch/*/Makefile: the arch Makefiles.
-    Subdirectory Makefiles: there are about 300 of these.
-    Rules.make: the common rules for all subdirectory Makefiles.
+	Makefile		the top Makefile.
+	.config			the kernel configuration file.
+	arch/$(ARCH)/Makefile	the arch Makefile.
+	scripts/Makefile.*	common rules etc. for all kbuild Makefiles.
+	kbuild Makefiles	there are about 500 of these.
 
-The top Makefile reads the .config file, which comes from the
-kernel configuration process.
+The top Makefile reads the .config file, which comes from the kernel
+configuration process.
 
 The top Makefile is responsible for building two major products: vmlinux
-(the resident kernel image) and modules (any module files).  It builds
-these goals by recursively descending into the subdirectories of the
-kernel source tree.  The list of subdirectories which are visited depends
-upon the kernel configuration.
-
-The top Makefile textually includes an arch Makefile with the name
-arch/$(ARCH)/Makefile.  The arch Makefile supplies architecture-specific
-information to the top Makefile.
-
-Each subdirectory has a Makefile which carries out the commands passed
-down from above.  The subdirectory Makefile uses information from the
-.config file to construct various file lists, and then it textually
-includes the common rules in Rules.make.
-
-Rules.make defines rules which are common to all the subdirectory
-Makefiles.  It has a public interface in the form of certain variable
-lists.  It then declares rules based on those lists.
+(the resident kernel image) and modules (any module files).
+It builds these goals by recursively descending into the subdirectories of
+the kernel source tree.
+The list of subdirectories which are visited depends upon the kernel
+configuration. The top Makefile textually includes an arch Makefile
+with the name arch/$(ARCH)/Makefile. The arch Makefile supplies
+architecture-specific information to the top Makefile.
+
+Each subdirectory has a kbuild Makefile which carries out the commands
+passed down from above. The kbuild Makefile uses information from the
+.config file to construct various file lists used by kbuild to build 
+any built-in or modular targets.
 
+scripts/Makefile.* contains all the definitions/rules etc. that
+are used to build the kernel based on the kbuild makefiles.
 
 
 === 2 Who does what
@@ -76,19 +78,19 @@
 People have four different relationships with the kernel Makefiles.
 
 *Users* are people who build kernels.  These people type commands such as
-"make menuconfig" or "make bzImage".  They usually do not read or edit
+"make menuconfig" or "make".  They usually do not read or edit
 any kernel Makefiles (or any other source files).
 
 *Normal developers* are people who work on features such as device
 drivers, file systems, and network protocols.  These people need to
-maintain the subdirectory Makefiles for the subsystem that they are
+maintain the kbuild Makefiles for the subsystem that they are
 working on.  In order to do this effectively, they need some overall
 knowledge about the kernel Makefiles, plus detailed knowledge about the
-public interface for Rules.make.
+public interface for kbuild.
 
 *Arch developers* are people who work on an entire architecture, such
-as sparc or ia64.  Arch developers need to know about the arch Makefiles
-as well as subdirectory Makefiles.
+as sparc or ia64.  Arch developers need to know about the arch Makefile
+as well as kbuild Makefiles.
 
 *Kbuild developers* are people who work on the kernel build system itself.
 These people need to know about all aspects of the kernel Makefiles.
@@ -96,883 +98,895 @@
 This document is aimed towards normal developers and arch developers.
 
 
+=== 3 The kbuild Makefiles
 
-=== 3 Makefile language
-
-The kernel Makefiles are designed to run with GNU Make.  The Makefiles
-use only the documented features of GNU Make, but they do use many
-GNU extensions.
-
-GNU Make supports elementary list-processing functions.  The kernel
-Makefiles use a novel style of list building and manipulation with few
-"if" statements.
-
-GNU Make has two assignment operators, ":=" and "=".  ":=" performs
-immediate evaluation of the right-hand side and stores an actual string
-into the left-hand side.  "=" is like a formula definition; it stores the
-right-hand side in an unevaluated form and then evaluates this form each
-time the left-hand side is used.
-
-There are some cases where "=" is appropriate.  Usually, though, ":="
-is the right choice.
-
-All of the examples in this document were drawn from actual kernel
-sources.  The examples have been reformatted (white space changed, lines
-split), but are otherwise exactly the same.
-
-
-
-=== 4 Variables passed down from the top
-
-The top Makefile exports the following variables:
-
-    VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
-
-	These variables define the current kernel version.  A few arch
-	Makefiles actually use these values directly; they should use
-	$(KERNELRELEASE) instead.
-
-	$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic
-	three-part version number, such as "2", "4", and "0".  These three
-	values are always numeric.
-
-	$(EXTRAVERSION) defines an even tinier sublevel for pre-patches
-	or additional patches.	It is usually some non-numeric string
-	such as "-pre4", and is often blank.
-
-    KERNELRELEASE
-
-	$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable
-	for constructing installation directory names or showing in
-	version strings.  Some arch Makefiles use it for this purpose.
-
-    ARCH
-
-	This variable defines the target architecture, such as "i386",
-	"arm", or "sparc".   Many subdirectory Makefiles test $(ARCH)
-	to determine which files to compile.
-
-	By default, the top Makefile sets $(ARCH) to be the same as the
-	host system system architecture.  For a cross build, a user may
-	override the value of $(ARCH) on the command line:
-
-	    make ARCH=m68k ...
-
-    TOPDIR, HPATH
-	
-	$(TOPDIR) is the path to the top of the kernel source tree.
-	Subdirectory Makefiles need this so that they can include
-	$(TOPDIR)/Rules.make.
-
-	$(HPATH) is equal to $(TOPDIR)/include.  A few arch Makefiles
-	need to use this to do special things using include files.
-
-    SUBDIRS
-
-	$(SUBDIRS) is a list of directories which the top Makefile
-	enters in order to build either vmlinux or modules.  The actual
-	directories in $(SUBDIRS) depend on the kernel configuration.
-	The top Makefile defines this variable, and the arch Makefile
-	extends it.
-
-    HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS
-    LINKFLAGS
-
-	$(HEAD), $(CORE_FILES), $(NETWORKS), $(DRIVERS), and $(LIBS)
-	specify lists of object files and libraries to be linked into
-	vmlinux.
-	
-	The files in $(HEAD) are linked first in vmlinux.
-
-	$(LINKFLAGS) specifies the flags to build vmlinux.
-
-	The top Makefile and the arch Makefile jointly define these
-	variables.  The top Makefile defines $(CORE_FILES), $(NETWORKS),
-	$(DRIVERS), and $(LIBS).  The arch Makefile defines $(HEAD)
-	and $(LINKFLAGS), and extends $(CORE_FILES) and $(LIBS).
-
-	Note: there are more variables here than necessary.  $(NETWORKS),
-	$(DRIVERS), and even $(LIBS) could be subsumed into $(CORE_FILES).
-
-    CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP
-    CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS
-    PERL
-    GENKSYMS
-
-	These variables specify the commands and flags that Rules.make
-	uses to build goal files from source files.
-
-	$(CFLAGS_KERNEL) contains extra C compiler flags used to compile
-	resident kernel code.
-
-	$(MODFLAGS) contains extra C compiler flags used to compile code
-	for loadable kernel modules.  In the future, this flag may be
-	renamed to the more regular name $(CFLAGS_MODULE).
-
-	$(AFLAGS) contains assembler flags.
-
-	$(GENKSYMS) contains the command used to generate kernel symbol
-	signatures when CONFIG_MODVERSIONS is enabled.	The genksyms
-	command comes from the module-init-tools package.
-
-    CROSS_COMPILE
-
-	This variable is a prefix path for other variables such as $(CC),
-	$(AS), and $(LD).  The arch Makefiles sometimes use and set this
-	variable explicitly.  Subdirectory Makefiles don't need to worry
-	about it.
-
-	The user may override $(CROSS_COMPILE) on the command line if
-	desired.
-
-    HOSTCC, HOSTCFLAGS
-
-	These variables define the C compiler and C compiler flags to
-	be used for compiling host side programs.  These are separate
-	variables because the target architecture can be different from
-	the host architecture.
-
-	If your Makefile compiles and runs a program that is executed
-	during the course of building the kernel, then it should use
-	$(HOSTCC) and $(HOSTCFLAGS).
+Most Makefiles within the kernel are kbuild Makefiles that use the
+kbuild infrastructure. This chapter introduce the syntax used in the
+kbuild makefiles.
 
-	For example, the subdirectory drivers/pci has a helper program
-	named gen-devlist.c.  This program reads a list of PCI ID's and
-	generates C code in the output files classlist.h and devlist.h.
+Section 3.1 "Goal definitions" is a quick intro, further chapters provide
+more details, with real examples.
 
-	Suppose that a user has an i386 computer and wants to build a
-	kernel for an ia64 machine.  Then the user would use an ia64
-	cross-compiler for most of the compilation, but would use a
-	native i386 host compiler to compile drivers/pci/gen-devlist.c.
+--- 3.1 Goal definitions
 
-	For another example, kbuild helper programs such as
-	scripts/mkdep.c and scripts/lxdialog/*.c are compiled with
-	$(HOSTCC) rather than $(CC).
+	Goal definitions are the main part (heart) of the kbuild Makefile.
+	These lines define the files to be built, any special compilation
+	options, and any subdirectories to be entered recursively.
 
-    ROOT_DEV, SVGA_MODE, RAMDISK
+	The most simple kbuild makefile contains one line:
 
-	End users edit these variables to specify certain information
-	about the configuration of their kernel.  These variables
-	are ancient!  They are also specific to the i386 architecture.
-	They really should be replaced with CONFIG_* options.
-
-    MAKEBOOT
-
-	This variable is defined and used only inside the main arch
-	Makefiles.  The top Makefile should not export it.
-
-    INSTALL_PATH
-
-	This variable defines a place for the arch Makefiles to install
-	the resident kernel image and System.map file.
+	Example:
+		obj-y += foo.o
 
-    INSTALL_MOD_PATH, MODLIB
+	This tell kbuild that there is one object in that directory named
+	foo.o. foo.o will be build from foo.c or foo.S.
 
-	$(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module
-	installation.  This variable is not defined in the Makefile but
-	may be passed in by the user if desired.
+	If foo.o shall be built as a module, the variable obj-m is used.
+	Therefore the following pattern is often used:
 
-	$(MODLIB) specifies the directory for module installation.
-	The top Makefile defines $(MODLIB) to
-	$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE).  The user may
-	override this value on the command line if desired.
+	Example:
+		obj-$(CONFIG_FOO) += foo.o
 
-    CONFIG_SHELL
+	$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module).
+	If CONFIG_FOO is neither y nor m, then the file will not be compiled
+	nor linked.
 
-	This variable is private between Makefile and Rules.make.
-	Arch makefiles and subdirectory Makefiles should never use this.
+--- 3.2 Built-in object goals - obj-y
 
-    MODVERFILE
+	The kbuild Makefile specifies object files for vmlinux
+	in the lists $(obj-y).  These lists depend on the kernel
+	configuration.
 
-	An internal variable.  This doesn't need to be exported, as it
-	is never used outside of the top Makefile.
+	Kbuild compiles all the $(obj-y) files.  It then calls
+	"$(LD) -r" to merge these files into one built-in.o file.
+	built-in.o is later linked into vmlinux by the parent Makefile.
 
-    MAKE, MAKEFILES
+	The order of files in $(obj-y) is significant.  Duplicates in
+	the lists are allowed: the first instance will be linked into
+	built-in.o and succeeding instances will be ignored.
 
-	Some variables internal to GNU Make.
+	Link order is significant, because certain functions
+	(module_init() / __initcall) will be called during boot in the
+	order they appear. So keep in mind that changing the link
+	order may e.g.  change the order in which your SCSI
+	controllers are detected, and thus you disks are renumbered.
 
-	$(MAKEFILES) in particular is used to force the arch Makefiles
-	and subdirectory Makefiles to read $(TOPDIR)/.config without
-	including it explicitly.  (This was an implementational hack
-	and could be fixed).
+	Example:
+		#drivers/isdn/i4l/Makefile
+		# Makefile for the kernel ISDN subsystem and device drivers.
+		# Each configuration option enables a list of files.
+		obj-$(CONFIG_ISDN)             += isdn.o
+		obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
 
+--- 3.3 Loadable module goals - obj-m
 
+	$(obj-m) specify object files which are built as loadable
+	kernel modules.
 
-=== 5 The structure of an arch Makefile
+	A module may be built from one source file or several source
+	files. In the case of one source file, the kbuild makefile
+	simply adds the file to $(obj-m).
 
+	Example:
+		#drivers/isdn/i4l/Makefile
+		obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
 
+	Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'
 
---- 5.1 Architecture-specific variables
+	If a kernel module is built from several source files, you specify
+	that you want to build a module in the same way as above.
 
-The top Makefile includes one arch Makefile file, arch/$(ARCH)/Makefile.
-This section describes the functions of the arch Makefile.
+	Kbuild needs to know which the parts that you want to build your
+	module from, so you have to tell it by setting an
+	$(<module_name>-objs) variable.
 
-An arch Makefile extends some of the top Makefile's variables with
-architecture-specific values.
+	Example:
+		#drivers/isdn/i4l/Makefile
+		obj-$(CONFIG_ISDN) += isdn.o
+		isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
 
-    SUBDIRS
+	In this example, the module name will be isdn.o. Kbuild will
+	compile the objects listed in $(isdn-objs) and then run
+	"$(LD) -r" on the list of these files to generate isdn.o.
 
-	The top Makefile defines $(SUBDIRS).  The arch Makefile extends
-	$(SUBDIRS) with a list of architecture-specific directories.
+	Kbuild recognises objects used for composite objects by the suffix
+	-objs, and the suffix -y. This allows the Makefiles to use
+	the value of a CONFIG_ symbol to determine if an object is part
+	of a composite object.
 
 	Example:
+		#fs/ext2/Makefile
+	        obj-$(CONFIG_EXT2_FS)        += ext2.o
+	 	ext2-y                       := balloc.o bitmap.o
+	        ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
+	
+	In this example xattr.o is only part of the composite object
+	ext2.o, if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
 
-		# arch/alpha/Makefile
-
-		SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm \
-		           arch/alpha/lib arch/alpha/math-emu
-
-	This list may depend on the configuration:
+	Note: Of course, when you are building objects into the kernel,
+	the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
+	kbuild will build an ext2.o file for you out of the individual
+	parts and then link this into built-in.o, as you would expect.
 
-		# arch/arm/Makefile
+--- 3.4 Objects which export symbols - export-objs
 
-		ifeq ($(CONFIG_ARCH_ACORN),y)
-		SUBDIRS         += drivers/acorn
-		...
-		endif
+	When using loadable modules, not every global symbol in the
+	kernel / other modules is automatically available, only those
+	explicitly exported are available for your module.
 
-    CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP
-    CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS
+	To make a symbol available for use in modules, to "export" it,
+	use the EXPORT_SYMBOL(<symbol>) directive in your source. In
+	addition, you need to list all object files which export symbols
+	(i.e. their source contains an EXPORT_SYMBOL() directive) in the
+	Makefile variable $(export-objs).
 
-	The top Makefile defines these variables, and the arch Makefile
-	extends them.
+	Example:
+		#drivers/isdn/i4l/Makefile
+		# Objects that export symbols.
+		export-objs     := isdn_common.o
 
-	Many arch Makefiles dynamically run the target C compiler to
-	probe supported options:
+	since isdn_common.c contains
 
-		# arch/i386/Makefile
+	    EXPORT_SYMBOL(register_isdn);
 
-		# prevent gcc from keeping the stack 16 byte aligned
-		CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 \
-			  -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
-			  then echo "-mpreferred-stack-boundary=2"; fi)
+	which makes the function register_isdn available to
+	low-level ISDN drivers.
+	There exist a EXPORT_SYMBOL_GPL() variant with similar functionality,
+	but more restrictive with what may use that symbol. The requirement
+	to list the .o file in export-objs is the same.
 
-	And, of course, $(CFLAGS) can depend on the configuration:
+--- 3.5 Library file goals - L_TARGET
 
-		# arch/i386/Makefile
+	Instead of building a built-in.o file, you may also
+	build an archive which again contains objects listed in $(obj-y).
+	This is normally not necessary and only used in lib/ and 
+	arch/$(ARCH)/lib directories.
+	Only the name lib.a is allowed.
 
-		ifdef CONFIG_M386
-		CFLAGS += -march=i386
-		endif
+	Example:
+		#arch/i386/lib/Makefile
+		L_TARGET := lib.a
+		obj-y    := checksum.o delay.o
 
-		ifdef CONFIG_M486
-		CFLAGS += -march=i486
-		endif
+	This will create a library lib.a based on checksum.o and delay.o.
 
-		ifdef CONFIG_M586
-		CFLAGS += -march=i586
-		endif
+--- 3.6 Descending down in directories
 
-	Some arch Makefiles redefine the compilation commands in order
-	to add architecture-specific flags:
+	A Makefile is only responsible for building objects in its own
+	directory. Files in subdirectories should be taken care of by
+	Makefiles in these subdirs. The build system will automatically
+	invoke make recursively in subdirectories, provided you let it know of
+	them.
 
-		# arch/s390/Makefile
+	To do so obj-y and obj-m are used.
+	ext2 lives in a separate directory, and the Makefile present in fs/
+	tells kbuild to descend down using the following assignment.
 
-		LD=$(CROSS_COMPILE)ld -m elf_s390
-		OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
+	Example:
+		#fs/Makefile
+		obj-$(CONfIG_EXT2_FS) += ext2/
 
+	If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular)
+	the corresponding obj- variable will be set, and kbuild will descend
+	down in the ext2 directory.
+	Kbuild only uses this information to decide that it needs to visit
+	the directory, it is the Makefile in the subdirectory that
+	specifies what is modules and what is built-in.
 
+	It is good practice to use a CONFIG_ variable when assigning directory
+	names. This allows kbuild to totally skip the directory if the
+	corresponding CONFIG_ option is neither 'y' nor 'm'.
 
---- 5.2 Vmlinux build variables
+--- 3.7 Compilation flags
 
-An arch Makefile cooperates with the top Makefile to define variables
-which specify how to build the vmlinux file.  Note that there is no
-corresponding arch-specific section for modules; the module-building
-machinery is all architecture-independent.
+    EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
 
-    HEAD, CORE_FILES, LIBS
-    LINKFLAGS
+	All the EXTRA_ variables apply only to the kbuild makefile
+	where they are assigned. The EXTRA_ variables apply to all
+	commands executed in the kbuild makefile.
 
-	The top Makefile defines the architecture-independent core of
-	thse variables, and the arch Makefile extends them.  Note that the
-	arch Makefile defines (not just extends) $(HEAD) and $(LINKFLAGS).
+	$(EXTRA_CFLAGS) specifies options for compiling C files with
+	$(CC).
 
 	Example:
-
-		# arch/m68k/Makefile
-
-		ifndef CONFIG_SUN3
-		LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux.lds
-		else
-		LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux-sun3.lds -N
-		endif
-
-		...
-
-		ifndef CONFIG_SUN3
-		HEAD := arch/m68k/kernel/head.o
-		else
-		HEAD := arch/m68k/kernel/sun3-head.o
+		# drivers/sound/emu10k1/Makefile
+		EXTRA_CFLAGS += -I$(obj)
+		ifdef DEBUG
+		    EXTRA_CFLAGS += -DEMU10K1_DEBUG
 		endif
 
-		SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
-		CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES)
-		LIBS += arch/m68k/lib/lib.a
 
+	This variable is necessary because the top Makefile owns the
+	variable $(CFLAGS) and uses it for compilation flags for the
+	entire tree.
 
+	$(EXTRA_AFLAGS) is a similar string for per-directory options
+	when compiling assembly language source.
 
---- 5.3 Post-vmlinux goals
+	Example:
+		#arch/x86_64/kernel/Makefile
+		EXTRA_AFLAGS := -traditional
 
-An arch Makefile specifies goals that take the vmlinux file, compress
-it, wrap it in bootstrapping code, and copy the resulting files somewhere.
-This includes various kinds of installation commands.
 
-These post-vmlinux goals are not standardized across different
-architectures.  Here is a list of these goals and the architectures
-that support each of them (as of kernel version 2.4.0-test6-pre5):
+	$(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for
+	per-directory options to $(LD) and $(AR).
 
-    balo		mips
-    bootimage		alpha
-    bootpfile		alpha, ia64
-    bzImage		i386, m68k
-    bzdisk		i386
-    bzlilo		i386
-    compressed		i386, m68k, mips, mips64, sh
-    dasdfmt		s390
-    Image		arm
-    image		s390
-    install		arm, i386
-    lilo		m68k
-    msb			alpha, ia64
-    my-special-boot	alpha, ia64
-    orionboot		mips
-    rawboot		alpha
-    silo		s390
-    srmboot		alpha
-    tftpboot.img	sparc, sparc64
-    vmlinux.64		mips64
-    vmlinux.aout	sparc64
-    zImage		arm, i386, m68k, mips, mips64, ppc, sh
-    zImage.initrd	ppc
-    zdisk		i386, mips, mips64, sh
-    zinstall		arm
-    zlilo		i386
-    znetboot.initrd	ppc
+	Example:
+		#arch/m68k/fpsp040/Makefile
+		EXTRA_LDFLAGS := -x
 
+    CFLAGS_$@, AFLAGS_$@
 
+	CFLAGS_$@ and AFLAGS_$@ only apply to commands in current
+	kbuild makefile.
 
---- 5.4 Mandatory arch-specific goals
+	$(CFLAGS_$@) specifies per-file options for $(CC).  The $@
+	part has a literal value which specifies the file that it is for.
 
-An arch Makefile must define the following arch-specific goals.
-These goals provide arch-specific actions for the corresponding goals
-in the top Makefile:
+	Example:
+		# drivers/scsi/Makefile
+		CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
+		CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
+				     -DGDTH_STATISTICS
+		CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
-    archclean		clean
-    archdep		dep
-    archmrproper	mrproper
+	These three lines specify compilation flags for aha152x.o,
+	gdth.o, and seagate.o
 
+	$(AFLAGS_$@) is a similar feature for source files in assembly
+	languages.
 
+	Example:
+		# arch/arm/kernel/Makefile
+		AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
+		AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
 
-=== 6 The structure of a subdirectory Makefile
+--- 3.9 Dependency tracking
 
-A subdirectory Makefile has four sections.
+	Kbuild track dependencies on the following:
+	1) All prerequisite files (both *.c and *.h)
+	2) CONFIG_ options used in all prerequisite files
+	3) Command-line used to compile target
 
+	Thus, if you change an option to $(CC) all affected files will
+	be re-compiled.
 
+--- 3.10 Special Rules
 
---- 6.1 Comments
+	Special rules are used when the kbuild infrastructure does
+	not provide the required support. A typical example is
+	header files generated during the build process.
+	Another example is the architecture specific Makefiles which
+	needs special rules to prepare boot images etc.
 
-The first section is a comment header. Historically, many anonymous
-people have edited kernel Makefiles without leaving any change
-histories in the header; comments from them would have been valuable.
+	Special rules are written as normal Make rules.
+	Kbuild is not executing in the directory where the Makefile is
+	located, so all special rules shall provide a relative
+	path to prerequisite files and target files.
 
+	Two variables are used when defining special rules:
 
+    $(src)
+	$(src) is a relative path which points to the directory
+	where the Makefile is located. Always use $(src) when
+	referring to files located in the src tree.
 
---- 6.2 Goal definitions
+    $(obj)
+	$(obj) is a relative path which points to the directory
+	where the target is saved. Always use $(obj) when
+	referring to generated files.
 
-The second section is a bunch of definitions that are the heart of the
-subdirectory Makefile.  These lines define the files to be built, any
-special compilation options, and any subdirectories to be recursively
-entered.  The declarations in these lines depend heavily on the kernel
-configuration variables (CONFIG_* symbols).
+	Example:
+		#drivers/scsi/Makefile
+		$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
+			$(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl
 
-The second section looks like this:
+	This is a special rule, following the normal syntax
+	required by make.
+	The target file depends on two prerequisite files. References
+	to the target file are prefixed with $(obj), references
+	to prerequisites are referenced with $(src) (because they are not
+	generated files).
 
-	# drivers/block/Makefile
-	obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
-	obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
-	obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
-	obj-$(CONFIG_ATARI_FLOPPY)	+= ataflop.o
 
+=== 4 Host Program support
 
---- 6.4 Rules.make section
+Kbuild supports building executables on the host for use during the
+compilation stage.
+Two steps are required in order to use a host executable.
 
-The third section is the single line:
+The first step is to tell kbuild that a host program exists. This is
+done utilising the variable host-prog.
 
-	include $(TOPDIR)/Rules.make
+The second step is to add an explicit dependency to the executable.
+This can be done in two ways. Either add the dependency in a rule, 
+or utilise the variable build-targets.
+Both possibilities are described in the following.
 
+--- 4.1 Simple Host Program
 
+	In some cases there is a need to compile and run a program on the
+	computer where the build is running.
+	The following line tells kbuild that the program bin2hex shall be
+	built on the build host.
 
---- 6.5 Special rules
+	Example:
+		host-progs := bin2hex
 
-The fourth section contains any special Makefile rules needed that are
-not available through the common rules in Rules.make.
+	Kbuild assumes in the above example that bin2hex is made from a single
+	c-source file named bin2hex.c located in the same directory as
+	the Makefile.
+  
+--- 4.2 Composite Host Programs
 
+	Host programs can be made up based on composite objects.
+	The syntax used to define composite objetcs for host programs is
+	similar to the syntax used for kernel objects.
+	$(<executeable>-objs) list all objects used to link the final
+	executable.
 
+	Example:
+		#scripts/lxdialog/Makefile
+		host-progs    := lxdialog  
+		lxdialog-objs := checklist.o lxdialog.o
 
-=== 7 Rules.make variables
+	Objects with extension .o are compiled from the corresponding .c
+	files. In the above example checklist.c is compiled to checklist.o
+	and lxdialog.c is compiled to lxdialog.o.
+	Finally the two .o files are linked to the executable, lxdialog.
+	Note: The syntax <executable>-y is not permitted for host-programs.
 
-The public interface of Rules.make consists of the following variables:
+--- 4.3 Defining shared libraries  
+  
+	Objects with extension .so are considered shared libraries, and
+	will be compiled as position independent objects.
+	Kbuild provides support for shared libraries, but the usage
+	shall be restricted.
+	In the following example the libkconfig.so shared library is used
+	to link the executable conf.
 
+	Example:
+		#scripts/kconfig/Makefile
+		host-progs      := conf
+		conf-objs       := conf.o libkconfig.so
+		libkconfig-objs := expr.o type.o
+  
+	Shared libraries always require a corresponding -objs line, and
+	in the example above the shared library libkconfig is composed by
+	the two objects expr.o and type.o.
+	expr.o and type.o will be built as position independent code and
+	linked as a shared library libkconfig.so. C++ is not supported for
+	shared libraries.
 
+--- 4.4 Using C++ for host programs
 
---- 7.1 Subdirectories
+	kbuild offers support for host programs written in C++. This was
+	introduced solely to support kconfig, and is not recommended
+	for general use.
 
-A Makefile is only responsible for building objects in its own
-directory. Files in subdirectories should be taken care of by
-Makefiles in the these subdirs. The build system will automatically
-invoke make recursively in subdirectories, provided you let it know of
-them.
+	Example:
+		#scripts/kconfig/Makefile
+		host-progs    := qconf
+		qconf-cxxobjs := qconf.o
 
-To do so, use the subdir-{y,m,n,} variables:
+	In the example above the executable is composed of the C++ file
+	qconf.cc - identified by $(qconf-cxxobjs).
+	
+	If qconf is composed by a mixture of .c and .cc files, then an
+	additional line can be used to identify this.
 
-	subdir-$(CONFIG_ISDN)                   += i4l
-	subdir-$(CONFIG_ISDN_CAPI)              += capi
+	Example:
+		#scripts/kconfig/Makefile
+		host-progs    := qconf
+		qconf-cxxobjs := qconf.o
+		qconf-objs    := check.o
+	
+--- 4.5 Controlling compiler options for host programs
 
-When building the actual kernel, i.e. vmlinux ("make
-{vmlinux,bzImage,...}"), make will recursively descend into
-directories listed in $(subdir-y).
+	When compiling host programs, it is possible to set specific flags.
+	The programs will always be compiled utilising $(HOSTCC) passed
+	the options specified in $(HOSTCFLAGS).
+	To set flags that will take effect for all host programs created
+	in that Makefile use the variable HOST_EXTRACFLAGS.
 
-When building modules ("make modules"), make will recursively descend
-into directories listed in $(subdir-m).
+	Example:
+		#scripts/lxdialog/Makefile
+		HOST_EXTRACFLAGS += -I/usr/include/ncurses
+  
+	To set specific flags for a single file the following construction
+	is used:
 
-When building the dependencies ("make dep") make needs to visit every
-subdir, so it'll descend into every directory listed in 
-$(subdir-y), $(subdir-m), $(subdir-n), $(subdir-).
+	Example:
+		#arch/ppc64/boot/Makefile
+		HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
+  
+	It is also possible to specify additional options to the linker.
+  
+	Example:
+		#scripts/kconfig/Makefile
+		HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
 
-You may encounter the case where a config option may be set to "y", but
-you still want to possibly build modules in that subdirectory.
+	When linking qconf it will be passed the extra option "-L$(QTDIR)/lib".
+ 
+--- 4.6 When host programs are actually built
 
-For example, drivers/isdn/capi/Makefile has
+	Kbuild will only build host-programs when they are referenced
+	as a prerequisite.
+	This is possible in two ways:
 
-	obj-$(CONFIG_ISDN_CAPI)                 += kernelcapi.o capiutil.o
-	obj-$(CONFIG_ISDN_CAPI_CAPI20)          += capi.o
+	(1) List the prerequisite explicitly in a special rule.
 
-where it's possible that CONFIG_ISDN_CAPI=y, but
-CONFIG_ISDN_CAPI_CAPI20=m.
+	Example:
+		#drivers/pci/Makefile
+		host-progs := gen-devlist
+		$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
+			( cd $(obj); ./gen-devlist ) < $<
 
-This is expressed by the following construct in the parent Makefile
-drivers/isdn/Makefile:
+	The target $(obj)/devlist.h will not be built before 
+	$(obj)/gen-devlist is updated. Note that references to
+	the host programs in special rules must be prefixed with $(obj).
 
-	mod-subdirs                             := i4l hisax capi eicon
-	subdir-$(CONFIG_ISDN_CAPI)              += capi
+	(2) Use $(build-targets)
+	When there is no suitable special rule, and the host program
+	shall be built when a makefile is entered, the $(build-targets)
+	variable shall be used.
 
-Having a subdir ("capi") listed in the variable $(mod-subdirs) will
-make the build system enter the specified subdirectory during "make
-modules" also, even though the subdir ("capi") is listed only in
-$(subdir-y), not $(subdir-m).
+	Example:
+		#scripts/lxdialog/Makefile
+		host-progs    := lxdialog
+		build-targets := $(host-progs)
 
+	This will tell kbuild to build lxdialog even if not referenced in
+	any rule.
 
---- 7.2 Object file goals
+=== 5 Kbuild clean infrastructure
 
-    O_TARGET, obj-y
+"make clean" deletes most generated files in the src tree where the kernel
+is compiled. This includes generated files such as host programs.
+Kbuild knows targets listed in $(host-progs) and $(EXTRA_TARGETS) and
+they are all deleted during "make clean".
+Files matching the patterns "*.[oas]", "*.ko", plus some additional files
+generated by kbuild are deleted all over the kernel src tree when
+"make clean" is executed.
 
-	The subdirectory Makefile specifies object files for vmlinux
-	in the lists $(obj-y).  These lists depend on the kernel
-	configuration.
+Additional files can be specified by means of $(clean-files).
 
-	Rules.make compiles all the $(obj-y) files.  It then calls
-	"$(LD) -r" to merge these files into one .o file with the name
-	$(O_TARGET).  This $(O_TARGET) is later linked into vmlinux by 
-	a parent Makefile.
+	Example:
+		#drivers/pci/Makefile
+		clean-files := devlist.h classlist.h
 
-	The order of files in $(obj-y) is significant.  Duplicates in
-	the lists are allowed: the first instance will be linked into
-	$(O_TARGET) and succeeding instances will be ignored.
+When executing "make clean", the two files "devlist.h classlist.h" will
+be deleted. Kbuild knows that files specified by $(clean-files) are
+located in the same directory as the makefile.
 
-	Link order is significant, because certain functions
-	(module_init() / __initcall) will be called during boot in the
-	order they appear. So keep in mind that changing the link
-	order may e.g.  change the order in which your SCSI
-	controllers are detected, and thus you disks are renumbered.
+Usually kbuild descends down in subdirectories due to "obj-* := dir/",
+but in the architecture makefiles where the kbuild infrastructure
+is not sufficent this sometimes needs to be explicit.
 
 	Example:
+		#arch/i386/boot/Makefile
+		subdir- := compressed/
 
-	    # Makefile for the kernel ISDN subsystem and device drivers.
-
-	    # The target object and module list name.
-
-	    O_TARGET        := vmlinux-obj.o
+The above assignment instructs kbuild to descend down in the
+directory compressed/ when "make clean" is executed.
 
-	    # Each configuration option enables a list of files.
+To support the clean infrastructure in the Makefiles that builds the
+final bootimage there is an optional target named archclean:
 
-	    obj-$(CONFIG_ISDN)                      += isdn.o
-	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
+	Example:
+		#arch/i386/Makefile
+		archclean:
+			$(Q)$(MAKE) $(clean)=arch/i386/boot
 
-	    # The global Rules.make.
+When "make clean" is executed, make will descend down in arch/i386/boot,
+and clean as usual. The Makefile located in arch/i386/boot/ may use
+the subdir- trick to descend further down.
 
-	    include $(TOPDIR)/Rules.make
+Note 1: arch/$(ARCH)/Makefile cannot use "subdir-", because that file is
+included in the top level makefile, and the kbuild infrastructure
+is not operational at that point.
 
---- 7.3 Library file goals
+Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will
+be visited during "make clean".
 
-    L_TARGET
+=== 6 Architecture Makefiles
 
-        Instead of building an O_TARGET object file, you may also
-	build an archive which again contains objects listed in
-	$(obj-y). This is normally not necessary and only used in
-	the lib, arch/$(ARCH)/lib directories.
+The top level Makefile sets up the environment and does the preparation,
+before starting to descend down in the individual directories.
+The top level makefile contains the generic part, whereas the
+arch/$(ARCH)/Makefile contains what is required to set-up kbuild
+to the said architecture.
+To do so arch/$(ARCH)/Makefile sets a number of variables, and defines
+a few targets.
 
+When kbuild executes the following steps are followed (roughly):
+1) Configuration of the kernel => produced .config
+2) Store kernel version in include/linux/version.h
+3) Symlink include/asm to include/asm-$(ARCH)
+4) Updating all other prerequisites to the target prepare:
+   - Additional prerequisites are specified in arch/$(ARCH)/Makefile
+5) Recursively descend down in all directories listed in
+   init-* core* drivers-* net-* libs-* and build all targets.
+   - The value of the above variables are extended in arch/$(ARCH)/Makefile.
+6) All object files are then linked and the resulting file vmlinux is 
+   located at the root of the src tree.
+   The very first objects linked are listed in head-y, assigned by
+   arch/$(ARCH)/Makefile.
+7) Finally the architecture specific part does any required post processing
+   and builds the final bootimage.
+   - This includes building boot records
+   - Preparing initrd images and the like
 
---- 7.4 Loadable module goals
 
-    obj-m
+--- 6.1 Set variables to tweak the build to the architecture
 
-	$(obj-m) specify object files which are built as loadable
-	kernel modules.
+    LDFLAGS		Generic $(LD) options
 
-	A module may be built from one source file or several source
-	files. In the case of one source file, the subdirectory
-	Makefile simply adds the file to $(obj-m)
+	Flags used for all invocations of the linker.
+	Often specifying the emulation is sufficient.
 
 	Example:
+		#arch/s390/Makefile
+		LDFLAGS         := -m elf_s390
+	Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise
+	the flags used. See chapter 7.
+	
+    LDFLAGS_MODULE	Options for $(LD) when linking modules
 
-	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
+	LDFLAGS_MODULE is used to set specific flags for $(LD) when
+	linking the .ko files used for modules.
+	Default is "-r", for relocatable output.
 
-	If a kernel module is built from several source files, you specify
-	that you want to build a module in the same way as above.
+    LDFLAGS_vmlinux	Options for $(LD) when linking vmlinux
 
-	However, the build system of course needs to know which the parts
-	are that you want to build your module of, so you have to tell it
-	by setting an $(<module_name>-objs) variable.
+	LDFLAGS_vmlinux is used to specify additional flags to pass to
+	the linker when linking the final vmlinux.
+	LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
 
 	Example:
+		#arch/i386/Makefile
+		LDFLAGS_vmlinux := -e stext
 
-	    obj-$(CONFIG_ISDN)                      += isdn.o
-
-	    isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o
-
-	In this example, the module name will be isdn.o. Rules.make
-	will compile the objects listed in $(isdn-objs) and then run
-	"$(LD) -r" on the list of these files to generate isdn.o
-
-	Note: Of course, when you are building objects into the kernel,
-	the syntax above will also work. So, if you have CONFIG_ISDN=y,
-	the build system will build an isdn.o for you out of the individual
-	parts and then link this into the $(O_TARGET), as you'd expect.
-
+    LDFLAGS_BLOB	Options for $(LD) when linking the initramfs blob
 
---- 7.5 Objects which export symbols
-
-    export-objs
+	The image used for initramfs is made during the build process.
+	LDFLAGS_BLOB is used to specify additional flags to be used when
+	creating the initramfs_data.o file.
+	Example:
+		#arch/i386/Makefile
+		LDFLAGS_BLOB := --format binary --oformat elf32-i386
 
-	When using loadable modules, not every global symbol in the
-	kernel / other modules is automatically available, only those
-	explicitly exported are available for your module.
+    OBJCOPYFLAGS	objcopy flags
 
-	To make a symbol available for use in modules, to "export" it,
-	use the EXPORT_SYMBOL(<symbol>) directive in your source. In
-	addition, you need to list all object files which export symbols
-	(i.e. their source contains an EXPORT_SYMBOL() directive) in the
-	Makefile variable $(export-objs).
+	When $(call if_changed,objcopy) is used to translate a .o file,
+	then the flags specified in OBJCOPYFLAGS will be used.
+	$(call if_changed,objcopy) is often used to generate raw binaries on
+	vmlinux.
 
 	Example:
+		#arch/s390/Makefile
+		OBJCOPYFLAGS := -O binary
 
-	    # Objects that export symbols.
+		#arch/s390/boot/Makefile
+		$(obj)/image: vmlinux FORCE
+			$(call if_changed,objcopy)
 
-	    export-objs     := isdn_common.o
+	In this example the binary $(obj)/image is a binary version of
+	vmlinux. The usage of $(call if_changed,xxx) will be described later.
 
-        since isdn_common.c contains
+    AFLAGS		$(AS) assembler flags
 
-	    EXPORT_SYMBOL(register_isdn);
+	Default value - see top level Makefile
+	Append or modify as required per architecture.
 
-	which makes the function register_isdn available to
-	low-level ISDN drivers.
-	    
+	Example:
+		#arch/sparc64/Makefile
+		AFLAGS += -m64 -mcpu=ultrasparc
 
---- 7.6 Compilation flags
+    CFLAGS		$(CC) compiler flags
 
-    EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
+	Default value - see top level Makefile
+	Append or modify as required per architecture.
 
-	$(EXTRA_CFLAGS) specifies options for compiling C files with
-	$(CC).	The options in this variable apply to all $(CC) commands
-	for files in the current directory.
+	Often the CFLAGS variable depends on the configuration.
 
 	Example:
+		#arch/i386/Makefile
+		cflags-$(CONFIG_M386) += -march=i386
+		CFLAGS += $(cflags-y)
 
-		# drivers/sound/emu10k1/Makefile
-		EXTRA_CFLAGS += -I.
-		ifdef DEBUG
-		    EXTRA_CFLAGS += -DEMU10K1_DEBUG
-		endif
+	Many arch Makefiles dynamically run the target C compiler to
+	probe supported options:
 
-	$(EXTRA_CFLAGS) does not apply to subdirectories of the current
-	directory.  Also, it does not apply to files compiled with
-	$(HOSTCC).
+		#arch/i386/Makefile
+		check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc \
+		            /dev/null\ > /dev/null 2>&1; then echo "$(1)"; \
+		            else echo "$(2)"; fi)
+		cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,\
+		                                     -march=c3,-march=i486)
 
-	This variable is necessary because the top Makefile owns the
-	variable $(CFLAGS) and uses it for compilation flags for the
-	entire tree.
+		CFLAGS += $(cflags-y)
 
-	$(EXTRA_AFLAGS) is a similar string for per-directory options
-	when compiling assembly language source.
+	The above examples both utilise the trick that a config option expands
+	to 'y' when selected.
 
-	Example: at the time of writing, there were no examples of
-	$(EXTRA_AFLAGS) in the kernel corpus.
+    CFLAGS_KERNEL	$(CC) options specific for built-in
 
-	$(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for
-	per-directory options to $(LD) and $(AR).
+	$(CFLAGS_KERNEL) contains extra C compiler flags used to compile
+	resident kernel code.
 
-	Example: at the time of writing, there were no examples of
-	$(EXTRA_LDFLAGS) or $(EXTRA_ARFLAGS) in the kernel corpus.
+    CFLAGS_MODULE	$(CC) options specific for modules
 
-    CFLAGS_$@, AFLAGS_$@
+	$(CFLAGS_MODULE) contains extra C compiler flags used to compile code
+	for loadable kernel modules.
 
-	$(CFLAGS_$@) specifies per-file options for $(CC).  The $@
-	part has a literal value which specifies the file that it's for.
+ 
+--- 6.2 Add prerequisites to prepare:
 
-	Example:
+	The prepare: rule is used to list prerequisites that needs to be
+	built before starting to descend down in the subdirectories.
+	This is usual header files containing assembler constants.
 
-		# drivers/scsi/Makefile
-		CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
-		CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
-				     -DGDTH_STATISTICS
-		CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
+		Example:
+		#arch/s390/Makefile
+		prepare: include/asm-$(ARCH)/offsets.h
 
-	These three lines specify compilation flags for aha152x.o,
-	gdth.o, and seagate.o
+	In this example the file include/asm-$(ARCH)/offsets.h will
+	be built before descending down in the subdirectories.
+	See also chapter XXX-TODO that describe how kbuild supports
+	generating offset header files.
 
-	$(AFLAGS_$@) is a similar feature for source files in assembly
-	languages.
 
-	Example:
+--- 6.3 List directories to visit when descending
 
-		# arch/arm/kernel/Makefile
-		AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
-		AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
+	An arch Makefile cooperates with the top Makefile to define variables
+	which specify how to build the vmlinux file.  Note that there is no
+	corresponding arch-specific section for modules; the module-building
+	machinery is all architecture-independent.
 
-	Rules.make has a feature where an object file depends on the
-	value of $(CFLAGS_$@) that was used to compile it.  (It also
-	depends on the values of $(CFLAGS) and $(EXTRA_CFLAGS)).  Thus,
-	if you change the value of $(CFLAGS_$@) for a file, either by
-	editing the Makefile or overriding the value some other way,
-	Rules.make will do the right thing and re-compile your source
-	file with the new options.
+	
+    head-y, init-y, core-y, libs-y, drivers-y, net-y
 
-	Note: because of a deficiency in Rules.make, assembly language
-	files do not have flag dependencies.  If you edit $(AFLAGS_$@)
-	for such a file, you will have to remove the object file in order
-	to re-build from source.
+	$(head-y) list objects to be linked first in vmlinux.
+	$(libs-y) list directories where a libs.a archive can be located.
+	The rest list directories where a built-in.o object file can be located.
 
-    LD_RFLAG
+	$(init-y) objects will be located after $(head-y).
+	Then the rest follows in this order:
+	$(core-y), $(libs-y), $(drivers-y) and $(net-y).
 
-	This variable is used, but never defined.  It appears to be a
-	vestige of some abandoned experiment.
+	The top level Makefile define values for all generic directories,
+	and arch/$(ARCH)/Makefile only adds architecture specific directories.
 
+	Example:
+		#arch/sparc64/Makefile
+		core-y += arch/sparc64/kernel/
+		libs-y += arch/sparc64/prom/ arch/sparc64/lib/
+		drivers-$(CONFIG_OPROFILE)  += arch/sparc64/oprofile/
 
 
---- 7.7 Miscellaneous variables
+--- 6.4 Architecture specific boot images
 
-    IGNORE_FLAGS_OBJS
+	An arch Makefile specifies goals that take the vmlinux file, compress
+	it, wrap it in bootstrapping code, and copy the resulting files
+	somewhere. This includes various kinds of installation commands.
+	The actual goals are not standardized across architectures.
 
-	$(IGNORE_FLAGS_OBJS) is a list of object files which will not have
-	their flag dependencies automatically tracked.	This is a hackish
-	feature, used to kludge around a problem in the implementation
-	of flag dependencies.  (The problem is that flag dependencies
-	assume that a %.o file is built from a matching %.S or %.c file.
-	This is sometimes not true).
+	It is common to locate any additional processing in a boot/
+	directory below arch/$(ARCH)/.
 
-    USE_STANDARD_AS_RULE
+	Kbuild does not provide any smart way to support building a
+	target specified in boot/. Therefore arch/$(ARCH)/Makefile shall
+	call make manually to build a target in boot/.
 
-	This is a transition variable.	If $(USE_STANDARD_AS_RULE)
-	is defined, then Rules.make will provide standard rules for
-	assembling %.S files into %.o files or %.s files (%.s files
-	are useful only to developers).
+	The recommended approach is to include shortcuts in
+	arch/$(ARCH)/Makefile, and use the full path when calling down
+	into the arch/$(ARCH)/boot/Makefile.
 
-	If $(USE_STANDARD_AS_RULE) is not defined, then Rules.make
-	will not provide these standard rules.	In this case, the
-	subdirectory Makefile must provide its own private rules for
-	assembling %.S files.
+	Example:
+		#arch/i386/Makefile
+		boot := arch/i386/boot
+		bzImage: vmlinux
+			$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
-	In the past, all Makefiles provided private %.S rules.	Newer
-	Makefiles should define USE_STANDARD_AS_RULE and use the standard
-	Rules.make rules.  As soon as all the Makefiles across all
-	architectures have been converted to USE_STANDARD_AS_RULE, then
-	Rules.make can drop the conditional test on USE_STANDARD_AS_RULE.
-	After that, all the other Makefiles can drop the definition of
-	USE_STANDARD_AS_RULE.
+	"$(Q)$(MAKE) $(build)=<dir>" is the recommended way to invoke
+	make in a subdirectory.
 
+	There are no rules for naming of the architecture specific targets,
+	but executing "make help" will list all relevant targets.
+	To support this $(archhelp) must be defined.
 
+	Example:
+		#arch/i386/Makefile
+		define archhelp
+		  echo  '* bzImage      - Image (arch/$(ARCH)/boot/bzImage)'
+		endef
 
-=== 8 New-style variables
+	When make is executed without arguments, the first goal encountered
+	will be built. In the top level Makefile the first goal present
+	is all:.
+	An architecture shall always per default build a bootable image.
+	In "make help" the default goal is highlighted with a '*'.
+	Add a new prerequisite to all: to select a default goal different
+	from vmlinux.
 
-[ This sections dates back from a time where the way to write Makefiles
-  described above was "new-style". I'm leaving it in as it describes the
-  same thing in other words, so it may be of some use ]
+	Example:
+		#arch/i386/Makefile
+		all: bzImage 
 
-The "new-style variables" are simpler and more powerful than the
-"old-style variables".  As a result, many subdirectory Makefiles shrank
-more than 60%.  This author hopes that, in time, all arch Makefiles and
-subdirectory Makefiles will convert to the new style.
+	When "make" is executed without arguments, bzImage will be built.
 
-Rules.make does not understand new-style variables.  Thus, each new-style
-Makefile has a section of boilerplate code that converts the new-style
-variables into old-style variables.  There is also some mixing, where
-people define most variables using "new style" but then fall back to
-"old style" for a few lines.
+--- 6.5 Building non-kbuild targets
 
---- 8.1 New variables
+    EXTRA_TARGETS
 
-    obj-y obj-m obj-n obj-
+	EXTRA_TARGETS specify additional targets created in current
+	directory, in addition to any targets specified by obj-*.
 
-	These variables replace $(O_OBJS), $(OX_OBJS), $(M_OBJS),
-	and $(MX_OBJS).
+	Listing all targets in EXTRA_TARGETS is required for three purposes:
+	1) Avoid that the target is linked in as part of built-in.o
+	2) Enable kbuild to check changes in command lines
+	   - When $(call if_changed,xxx) is used
+	3) kbuild knows what file to delete during "make clean"
 
 	Example:
+		#arch/i386/kernel/Makefile
+		EXTRA_TARGETS := head.o init_task.o
 
-		# drivers/block/Makefile
-		obj-$(CONFIG_MAC_FLOPPY)        += swim3.o
-		obj-$(CONFIG_BLK_DEV_FD)        += floppy.o
-		obj-$(CONFIG_AMIGA_FLOPPY)      += amiflop.o
-		obj-$(CONFIG_ATARI_FLOPPY)      += ataflop.o
+	In this example EXTRA_TARGETS is used to list object files that
+	shall be built, but shall not be linked as part of built-in.o.
 
-	Notice the use of $(CONFIG_...) substitutions on the left hand
-	side of an assignment operator.  This gives GNU Make the power
-	of associative indexing!  Each of these assignments replaces
-	eight lines of code in an old-style Makefile.
-
-	After executing all of the assignments, the subdirectory
-	Makefile has built up four lists: $(obj-y), $(obj-m), $(obj-n),
-	and $(obj-).
+	Example:
+		#arch/i386/boot/Makefile
+		EXTRA_TARGETS := vmlinux.bin bootsect bootsect.o
 
-	$(obj-y) is a list of files to include in vmlinux.
-	$(obj-m) is a list of files to build as single-file modules.
-	$(obj-n) and $(obj-) are ignored.
+	In this example EXTRA_TARGETS is used to list all intermediate
+	targets, and all final targets.
+	The targets are added to EXTRA_TARGETS to enable 2) and 3) above.
+	
+--- 6.6 Commands useful for building a boot image
 
-	Each list may contain duplicates items; duplicates are
-	automatically removed later.  Duplicates in both $(obj-y) and
-	$(obj-m) will automatically be removed from the $(obj-m) list.
+	Kbuild provide a few macros that are useful when building a
+	boot image.
 
-	Example:
+    if_changed
 
-		# drivers/net/Makefile
+	if_changed is the infrastructure used for the following commands.
 
-		...
-		obj-$(CONFIG_OAKNET) += oaknet.o 8390.o
-		...
-		obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
-		...
-		obj-$(CONFIG_STNIC) += stnic.o 8390.o
-		...
-		obj-$(CONFIG_MAC8390) += daynaport.o 8390.o
-		...
+	Usage:
+		target: source(s) FORCE
+			$(call if_changed,ld/objcopy/gzip)
+
+	When the rule is evaluated it is checked to see if any files
+	needs an update, or the commandline has changed since last
+	invocation. The latter will force a rebuild if any options
+	to the executable have changed.
+	Any target that utilises if_changed must be listed in EXTRA_TARGETS,
+	otherwise the command line check will fail, and the target will
+	always be built.
+	if_changed may be used in conjunction with custom commands as
+	defined in 6.7 "Custom kbuild commands".
+	Note: It is a typical mistake to forget the FORCE prerequisite.
 
-	In this example, four different drivers require the code in
-	8390.o.  If one or more of these four drivers are built into
-	vmlinux, then 8390.o will also be built into vmlinux, and will
-	*not* be built as a module -- even if another driver which needs
-	8390.o is built as a module.  (The modular driver is able to
-	use services of the 8390.o code in the resident vmlinux image).
+    ld
+	Link target. Often LDFLAGS_$@ is used to set specific options to ld.
+	
+    objcopy
+	Copy binary. Uses OBJCOPYFLAGS usually specified in
+	arch/$(ARCH)/Makefile.
 
-    export-objs
+    gzip
+	Compress target. Use maximum compression to compress target.
 
-	$(export-objs) is a list of all the files in the subdirectory
-	which potentially export symbols.  The canonical way to construct
-	this list is:
 
-	    grep -l EXPORT_SYMBOL *.c
+--- 6.7 Custom kbuild commands
 
-	(but watch out for sneaky files that call EXPORT_SYMBOL from an
-	included header file!)
+	When kbuild is executing with KBUILD_VERBOSE=0 then only a shorthand
+	of a command is normally displayed.
+	To enable this behaviour for custom commands kbuild requires
+	two variables to be set:
+	quiet_cmd_<command>	- what shall be echoed
+	      cmd_<command>	- the command to execute
 
-	This is a potential list, independent of the kernel configuration.
-	All files that export symbols go into $(export-objs).  The
-	boilerplate code then uses the $(export-objs) list to separate
-	the real file lists into $(*_OBJS) and $(*X_OBJS).
+	Example:
+		#
+		quiet_cmd_image = BUILD   $@
+		      cmd_image = $(obj)/tools/build $(BUILDFLAGS) \
+		                                     $(obj)/vmlinux.bin > $@
 
-	Experience has shown that maintaining the proper X's in an
-	old-style Makefile is difficult and error-prone.  Maintaining the
-	$(export-objs) list in a new-style Makefile is simpler and easier
-	to audit.
+		$(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+			$(call if_changed,image)
+			@echo 'Kernel: $@ is ready'
 
-    $(foo)-objs
+	When updating the $(obj)/bzImage target the line:
 
-	Some kernel modules are composed of multiple object files linked
-	together.
+	BUILD    arch/i386/boot/bzImage
 
-	For each multi-part kernel modul there is a list of all the
-	object files which make up that module.  For a kernel module
-	named foo.o, its object file list is foo-objs.
+	will be displayed with "make KBUILD_VERBOSE=0".
+	
 
-	Example:
+=== 7 Kbuild Variables
 
-		# drivers/scsi/Makefile
-		list-multi	:= scsi_mod.o sr_mod.o initio.o a100u2w.o
+The top Makefile exports the following variables:
 
-		...
+    VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
 
-		scsi_mod-objs	:= hosts.o scsi.o scsi_ioctl.o constants.o \
-				   scsicam.o scsi_proc.o scsi_error.o \
-				   scsi_obsolete.o scsi_queue.o scsi_lib.o \
-				   scsi_merge.o scsi_dma.o scsi_scan.o \
-				   scsi_syms.o
-		sr_mod-objs	:= sr.o sr_ioctl.o sr_vendor.o
-		initio-objs	:= ini9100u.o i91uscsi.o
-		a100u2w-objs	:= inia100.o i60uscsi.o
+	These variables define the current kernel version.  A few arch
+	Makefiles actually use these values directly; they should use
+	$(KERNELRELEASE) instead.
 
-	The subdirectory Makefile puts the modules onto obj-* lists in
-	the usual configuration-dependent way:
+	$(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic
+	three-part version number, such as "2", "4", and "0".  These three
+	values are always numeric.
 
-		obj-$(CONFIG_SCSI)		+= scsi_mod.o
-		obj-$(CONFIG_BLK_DEV_SR)	+= sr_mod.o
-		obj-$(CONFIG_SCSI_INITIO)	+= initio.o
-		obj-$(CONFIG_SCSI_INIA100)	+= a100u2w.o
+	$(EXTRAVERSION) defines an even tinier sublevel for pre-patches
+	or additional patches.	It is usually some non-numeric string
+	such as "-pre4", and is often blank.
 
-	Suppose that CONFIG_SCSI=y.  Then vmlinux needs to link in all
-	14 components of scsi_mod.o.
+    KERNELRELEASE
 
-	Suppose that CONFIG_BLK_DEV_SR=m.  Then the 3 components
-	of sr_mod.o will be linked together with "$(LD) -r" to make the
-	kernel module sr_mod.o.
+	$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable
+	for constructing installation directory names or showing in
+	version strings.  Some arch Makefiles use it for this purpose.
 
-	Also suppose CONFIG_SCSI_INITIO=n.  Then initio.o goes onto
-	the $(obj-n) list and that's the end of it.  Its component
-	files are not compiled, and the composite file is not created.
+    ARCH
 
+	This variable defines the target architecture, such as "i386",
+	"arm", or "sparc". Some kbuild Makefiles test $(ARCH) to
+	determine which files to compile.
 
-    subdir-y subdir-m subdir-n subdir-
+	By default, the top Makefile sets $(ARCH) to be the same as the
+	host system architecture.  For a cross build, a user may
+	override the value of $(ARCH) on the command line:
 
-	These variables replace $(ALL_SUB_DIRS), $(SUB_DIRS) and
-	$(MOD_SUB_DIRS).
+	    make ARCH=m68k ...
 
-	Example:
 
-		# drivers/Makefile
-		subdir-$(CONFIG_PCI)		+= pci
-		subdir-$(CONFIG_PCMCIA)		+= pcmcia
-		subdir-$(CONFIG_MTD)		+= mtd
-		subdir-$(CONFIG_SBUS)		+= sbus
+    INSTALL_PATH
 
-	These variables work similar to obj-*, but are used for
-	subdirectories instead of object files.
+	This variable defines a place for the arch Makefiles to install
+	the resident kernel image and System.map file.
+	Use this for architecture specific install targets.
 
-	After executing all assignments, the subdirectory Makefile has
-	built up four lists: $(subdir-y), $(subdir-m), $(subdir-n),
-	and $(subdir-).
+    INSTALL_MOD_PATH, MODLIB
 
-	$(subdir-y) is a list of directories that should be entered
-		for making vmlinux.
-	$(subdir-m) is a list of directories that should be entered
-		for making modules.
-	$(subdir-n) and $(subdir-) are only used for collecting a list
-		of all subdirectories of this directory.
+	$(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module
+	installation.  This variable is not defined in the Makefile but
+	may be passed in by the user if desired.
 
-	Each list besides subdir-y may contain duplicates items; duplicates
-	are automatically removed later.
+	$(MODLIB) specifies the directory for module installation.
+	The top Makefile defines $(MODLIB) to
+	$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE).  The user may
+	override this value on the command line if desired.
 
-    mod-subdirs
+=== 8 Makefile language
 
-	$(mod-subdirs) is a list of all the subdirectories that should
-	be added to $(subdir-m), too if they appear in $(subdir-y)
+The kernel Makefiles are designed to run with GNU Make.  The Makefiles
+use only the documented features of GNU Make, but they do use many
+GNU extensions.
 
-	Example:
+GNU Make supports elementary list-processing functions.  The kernel
+Makefiles use a novel style of list building and manipulation with few
+"if" statements.
 
-		# fs/Makefile
-		mod-subdirs :=	nls
+GNU Make has two assignment operators, ":=" and "=".  ":=" performs
+immediate evaluation of the right-hand side and stores an actual string
+into the left-hand side.  "=" is like a formula definition; it stores the
+right-hand side in an unevaluated form and then evaluates this form each
+time the left-hand side is used.
 
-	This means nls should be added to (subdir-y) and $(subdir-m) if
-	CONFIG_NFS = y.
+There are some cases where "=" is appropriate.  Usually, though, ":="
+is the right choice.
 
 === 9 Credits
 
-Thanks to the members of the linux-kbuild mailing list for reviewing
-drafts of this document, with particular thanks to Peter Samuelson
-and Thomas Molina.
+Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
+Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
+Updates by Sam Ravnborg <sam@ravnborg.org>
+
+=== 10 TODO
+
+- Describe how kbuild support shipped files with _shipped.
+- Generating offset header files.
+- Add more variables to section 7?
+
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Mon Feb 10 10:39:33 2003
+++ b/Documentation/kernel-parameters.txt	Mon Feb 10 10:39:33 2003
@@ -1,4 +1,4 @@
-November 2002             Kernel Parameters                     v2.5.49
+February 2003             Kernel Parameters                     v2.5.59
                           ~~~~~~~~~~~~~~~~~
 
 The following is a consolidated list of the kernel parameters as implemented
@@ -60,6 +60,7 @@
 	V4L	Video For Linux support is enabled.
 	VGA	The VGA console has been enabled.
 	VT	Virtual terminal support is enabled.
+	WDT	Watchdog support is enabled.
 	XT	IBM PC/XT MFM hard disk support is enabled.
 
 In addition, the following text indicates that the option:
@@ -98,6 +99,9 @@
 	advansys=	[HW,SCSI]
 			See header of drivers/scsi/advansys.c.
 
+	advwdt=		[HW,WDT] Advantech WDT
+			Format: <iostart>,<iostop>
+
 	aedsp16=	[HW,OSS] Audio Excel DSP 16
 			Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
 			See also header of sound/oss/aedsp16.c.
@@ -111,6 +115,9 @@
 	aic7xxx=	[HW,SCSI]
 			See Documentation/scsi/aic7xxx.txt.
 
+	aic79xx=	[HW,SCSI]
+			See Documentation/scsi/aic79xx.txt.
+
 	allowdma0	[ISAPNP]
 
 	AM53C974=	[HW,SCSI]
@@ -230,20 +237,12 @@
 
 	cs89x0_media=	[HW,NET]
 			Format: { rj45 | aui | bnc }
-
-	ctc=		[HW,NET]
-			See drivers/s390/net/ctcmain.c, comment before function
-			ctc_setup().
  
 	cyclades=	[HW,SERIAL] Cyclades multi-serial port adapter.
  
 	dasd=		[HW,NET]    
 			See header of drivers/s390/block/dasd_devmap.c.
 
-	dasd_discipline=
-			[HW,NET]
-			See header of drivers/s390/block/dasd.c.
-
 	db9=		[HW,JOY]
 	db9_2=
 	db9_3=
@@ -254,9 +253,6 @@
 			Format: <area>[,<node>]
 			See also Documentation/networking/decnet.txt.
 
-	decr_overclock= [PPC]
-	decr_overclock_proc0=
-
 	devfs=		[DEVFS]
 			See Documentation/filesystems/devfs/boot-options.
  
@@ -305,6 +301,9 @@
 			This option is obsoleted by the "netdev=" option, which
 			has equivalent usage. See its documentation for details.
 
+	eurwdt=		[HW,WDT] Eurotech CPU-1220/1410 onboard watchdog.
+			Format: <io>[,<irq>]
+
 	fd_mcs=		[HW,SCSI]
 			See header of drivers/scsi/fd_mcs.c.
 
@@ -350,7 +349,9 @@
 	hisax=		[HW,ISDN]
 			See Documentation/isdn/README.HiSax.
 
-	hugepages=	[HW,IA-32] Maximal number of HugeTLB pages
+	hugepages=	[HW,IA-32,IA-64] Maximal number of HugeTLB pages.
+
+	noirqbalance	[IA-32,SMP,KNL] Disable kernel irq balancing
 
 	i8042_direct	[HW] Non-translated mode
 	i8042_dumbkbd
@@ -394,6 +395,10 @@
 
 	inttest=	[IA64]
 
+	io7=		[HW] IO7 for Marvel based alpha systems
+			See comment before marvel_specify_io7 in
+			arch/alpha/kernel/core_marvel.c.
+
 	ip=		[IP_PNP]
 			See Documentation/nfsroot.txt.
 
@@ -495,6 +500,7 @@
  
 	mdacon=		[MDA]
 			Format: <first>,<last>
+			Specifies range of consoles to be captured by the MDA.
  
 	mem=exactmap	[KNL,BOOT,IA-32] Enable setting of an exact
 			E820 memory map, as specified by the user.
@@ -576,6 +582,8 @@
  
 	nodisconnect	[HW,SCSI,M68K] Disables SCSI disconnects.
 
+	noexec		[IA-64]
+
 	nofxsr		[BUGS=IA-32]
 
 	nohighio	[BUGS=IA-32] Disable highmem block I/O.
@@ -599,7 +607,9 @@
 
 	noresume	[SWSUSP] Disables resume and restore original swap space.
  
-	no-scroll	[VGA]
+	no-scroll	[VGA] Disables scrollback.
+			This is required for the Braillex ib80-piezo Braille
+			reader made by F.H. Papenmeier (Germany).
 
 	nosbagart	[IA-64]
 
@@ -809,6 +819,9 @@
 			See a comment before function sbpcd_setup() in
 			drivers/cdrom/sbpcd.c.
 
+	sc1200wdt=	[HW,WDT] SC1200 WDT (watchdog) driver
+			Format: <io>[,<timeout>[,<isapnp>]]
+
 	scsi_debug_*=	[SCSI]
 			See drivers/scsi/scsi_debug.c.
 
@@ -997,9 +1010,6 @@
 	spia_pedr=
 	spia_peddr=
 
-	spread_lpevents=
-			[PPC]
-
 	sscape=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
  
@@ -1009,6 +1019,19 @@
 	st0x=		[HW,SCSI]
 			See header of drivers/scsi/seagate.c.
 
+	sti=		[HW]
+			Format: <num>
+			Set the STI (builtin display/keyboard on the HP-PARISC
+			machines) console (graphic card) which should be used
+			as the initial boot-console.
+			See also comment in drivers/video/console/sticore.c.
+
+	sti_font=	[HW]
+			See comment in drivers/video/console/sticore.c.
+
+	stifb=		[HW]
+			Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
+
 	stram_swap=	[HW,M68k]
 
 	swiotlb=	[IA-64] Number of I/O TLB slabs
@@ -1079,7 +1102,7 @@
 	wd7000=		[HW,SCSI]
 			See header of drivers/scsi/wd7000.c.
 
-	wdt=		[HW] Watchdog
+	wdt=		[WDT] Watchdog
 			See Documentation/watchdog.txt.
 
 	xd=		[HW,XT] Original XT pre-IDE (RLL encoded) disks.
diff -Nru a/Documentation/md.txt b/Documentation/md.txt
--- a/Documentation/md.txt	Mon Feb 10 10:39:29 2003
+++ b/Documentation/md.txt	Mon Feb 10 10:39:29 2003
@@ -9,7 +9,7 @@
 for old raid arrays without persistent superblocks:
   md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
 
-for raid arrays with persistant superblocks
+for raid arrays with persistent superblocks
   md=<md device no.>,dev0,dev1,...,devn
   
 md device no. = the number of the md device ... 
@@ -21,7 +21,7 @@
 
 raid level = -1 linear mode
               0 striped mode
-	      other modes are only supported with persistant super blocks
+	      other modes are only supported with persistent super blocks
 
 chunk size factor = (raid-0 and raid-1 only)
               Set  the chunk size as 4k << n.
diff -Nru a/Documentation/modules.txt b/Documentation/modules.txt
--- a/Documentation/modules.txt	Mon Feb 10 10:39:23 2003
+++ b/Documentation/modules.txt	Mon Feb 10 10:39:23 2003
@@ -9,20 +9,13 @@
 that the kernel now supports.  The current required version is listed
 in the file linux/Documentation/Changes.
 
-* * * NOTE * * *
-The kernel has been changed to remove kerneld support and use
-the new kmod support.  Keep this in mind when reading this file.  Kmod
-does the exact same thing as kerneld, but doesn't require an external
-program (see Documentation/kmod.txt)
-
 In the beginning...
 -------------------
 
 Anyway, your first step is to compile the kernel, as explained in the
 file linux/README.  It generally goes like:
 
-	make config
-	make dep
+	make *config <= usually menuconfig or xconfig
 	make clean
 	make zImage or make zlilo
 
@@ -39,15 +32,16 @@
 	plus those things that you just can't live without...
 
 The set of modules is constantly increasing, and you will be able to select
-the option "m" in "make config" for those features that the current kernel
+the option "m" in "make menuconfig" for those features that the current kernel
 can offer as loadable modules.
 
 You also have a possibility to create modules that are less dependent on
-the kernel version.  This option can be selected during "make config", by
+the kernel version.  This option can be selected during "make *config", by
 enabling CONFIG_MODVERSIONS, and is most useful on "stable" kernel versions,
-such as the kernels from the 1.2 and 2.0 series.
+such as the kernels from the 2.<even number> series.
 If you have modules that are based on sources that are not included in
 the official kernel sources, you will certainly like this option...
+See below how to compile modules outside the official kernel.
 
 Here is a sample of the available modules included in the kernel sources:
 
@@ -83,22 +77,45 @@
 
 	make modules
 
-This will compile all modules and update the linux/modules directory.
-In this directory you will then find a bunch of symbolic links,
-pointing to the various object files in the kernel tree.
+This will compile all modules. A module is identified by the
+extension .ko, for kernel object.
 Now, after you have created all your modules, you should also do:
 
 	make modules_install
 
 This will copy all newly made modules into subdirectories under
 "/lib/modules/kernel_release/", where "kernel_release" is something
-like 2.0.1, or whatever the current kernel version is...
+like 2.5.54, or whatever the current kernel version is.
+Note: Installing modules may require root privileges.
 
 As soon as you have rebooted the newly made kernel, you can install
 and remove modules at will with the utilities: "insmod" and "rmmod".
 After reading the man-page for insmod, you will also know how easy
 it is to configure a module when you do "insmod" (hint: symbol=value).
 
+Installing modules in a non-standard location
+---------------------------------------------
+When the modules needs to be installed under another directory
+the INSTALL_MOD_PATH can be used to prefix "/lib/modules" as seen
+in the following example:
+
+make INSTALL_MOD_PATH=/frodo modules_install
+
+This will install the modules in the directory /frodo/lib/modules.
+/frodo can be a NFS mounted filesystem on another machine, allowing
+out-of-the-box support for installation on remote machines.
+
+
+Compiling modules outside the official kernel
+---------------------------------------------
+Often modules are developed outside the official kernel.
+To keep up with changes in the build system the most portable way
+to compile a module outside the kernel is to use the following command-line:
+
+make -C path/to/kernel/src SUBDIRS=$PWD modules
+
+This requires that a makefile exits made in accordance to
+Documentation/kbuild/makefiles.txt.
 
 Nifty features:
 ---------------
diff -Nru a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
--- a/Documentation/networking/bonding.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/networking/bonding.txt	Mon Feb 10 10:39:24 2003
@@ -258,7 +258,7 @@
         Specifies the ip addresses to use when arp_interval is > 0. These are
         the targets of the ARP request sent to determine the health of the link
         to the targets. Specify these values in ddd.ddd.ddd.ddd format.
-        Multiple ip adresses must be seperated by a comma. At least one ip
+        Multiple ip adresses must be separated by a comma. At least one ip
         address needs to be given for ARP monitoring to work. The maximum number
         of targets that can be specified is set at 16.
 
@@ -309,7 +309,7 @@
 case of just one target,  the target itself may go down or have a problem
 making it unresponsive to ARP requests. Having an additional target (or
 several) would increase the reliability of the ARP monitoring.
-Multiple ARP targets must be seperated by commas as follows:
+Multiple ARP targets must be separated by commas as follows:
 
 # example options for ARP monitoring with three targets
 alias bond0 bonding
diff -Nru a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
--- a/Documentation/networking/ip-sysctl.txt	Mon Feb 10 10:39:26 2003
+++ b/Documentation/networking/ip-sysctl.txt	Mon Feb 10 10:39:26 2003
@@ -281,6 +281,14 @@
 	assassination.   
 	Default: 0
 
+tcp_low_latency - BOOLEAN
+	If set, the TCP stack makes decisions that prefer lower
+	latency as opposed to higher throughput.  By default, this
+	option is not set meaning that higher throughput is preferred.
+	An example of an application where this default should be
+	changed would be a Beowulf compute cluster.
+	Default: 0
+
 ip_local_port_range - 2 INTEGERS
 	Defines the local port range that is used by TCP and UDP to
 	choose the local port. The first number is the first, the 
diff -Nru a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
--- a/Documentation/s390/s390dbf.txt	Mon Feb 10 10:39:29 2003
+++ b/Documentation/s390/s390dbf.txt	Mon Feb 10 10:39:29 2003
@@ -8,7 +8,7 @@
 ------------
 The goal of this feature is to provide a kernel debug logging API 
 where log records can be stored efficiently in memory, where each component 
-(e.g. device drivers) can have one seperate debug log.
+(e.g. device drivers) can have one separate debug log.
 One purpose of this is to inspect the debug logs after a production system crash
 in order to analyze the reason for the crash.
 If the system still runs but only a subcomponent which uses dbf failes,
diff -Nru a/Documentation/scsi/ChangeLog.sym53c8xx b/Documentation/scsi/ChangeLog.sym53c8xx
--- a/Documentation/scsi/ChangeLog.sym53c8xx	Mon Feb 10 10:39:30 2003
+++ b/Documentation/scsi/ChangeLog.sym53c8xx	Mon Feb 10 10:39:30 2003
@@ -529,7 +529,7 @@
 	* version pre-sym53c8xx-0.13
 	- Some rewrite of the device detection code. This code had been 
 	  patched too much and needed to be face-lifted a bit.
-	  Remove all platform dependant fix-ups that was not needed or
+	  Remove all platform dependent fix-ups that was not needed or
 	  conflicted with some other driver code as work-arounds.
 	  Reread the NVRAM before the calling of ncr_attach(). This spares 
 	  stack space and so allows to handle more boards.
diff -Nru a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt
--- a/Documentation/scsi/aic79xx.txt	Mon Feb 10 10:39:30 2003
+++ b/Documentation/scsi/aic79xx.txt	Mon Feb 10 10:39:30 2003
@@ -1,5 +1,5 @@
 ====================================================================
-=             Adaptec Ultra320 Family Manager Set v1.1.1           =
+=             Adaptec Ultra320 Family Manager Set v1.3.0           =
 =                                                                  =
 =                            README for                            =
 =                    The Linux Operating System                    =
@@ -27,6 +27,10 @@
    Adaptec SCSI Card 39320D  Dual Channel 64-bit PCI-X 133MHz to
                              Ultra320 SCSI Card (two external VHDC
                              and one internal 68-pin)
+   Adaptec SCSI Card 39320D  Dual Channel 64-bit PCI-X 133MHz to
+                             Ultra320 SCSI Card (two external VHDC
+                             and one internal 68-pin) based on the
+                             AIC-7902B ASIC
    Adaptec SCSI Card 29320   Single Channel 64-bit PCI-X 133MHz to
                              Ultra320 SCSI Card (one external 
                              68-pin, two internal 68-pin, one
@@ -39,12 +43,28 @@
                              Ultra320 SCSI ASIC
    AIC-7902A4                Dual Channel 64-bit PCI-X 133MHz to 
                              Ultra320 SCSI ASIC
-
+   AIC-7902B                 Dual Channel 64-bit PCI-X 133MHz to
+                             Ultra320 SCSI ASIC
 
 2. Version History
 
+   (V1.3.0, January 2003) Full regression testing for all U320 products
+   completed.
+
+   (V1.3.0 ALPHA, November 2002) Initial Alpha release.
+   Added abort and target/lun reset error recovery handler and
+   interrupt coalessing.
+
+   (V1.2.0, November 2002) Added support for Domain Validation and
+   Hewlett-Packard version of the 39320D and AIC-7902 adapters.
+   Support for previous adapters has not been fully tested and should
+   only be used at the customer's own risk.
+
    (V1.1.1, September 2002) Added support for the Linux 2.5.X kernel series
 
+   (V1.1.0, August 2002) Added support for four additional SCSI
+   products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
+
    (V1.1, August 2002) Added support for four additional SCSI
    products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
 
@@ -56,20 +76,21 @@
           - 320MB/s transfer rates
           - Packetized SCSI Protocol at 160MB/s and 320MB/s
           - Quick Arbitration Selection (QAS)
-          - Initiator Mode (target mode not currently 
-            supported)
-          - Support for the PCI-x standard up to 133MHz
-          - Support for the PCI v2.2 standard
+          - Retained Training Information (Rev B. ASIC only)
+        - Interrupt Coalessing
+        - Initiator Mode (target mode not currently 
+          supported)
+        - Support for the PCI-X standard up to 133MHz
+        - Support for the PCI v2.2 standard
 
    2.2. Operating System Support:
-        - Redhat Linux 7.2, 7.3, Advanced Server 2.1
-	- SuSE Linux 7.3, 8.0, Enterprise Server 7
+        - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1
+        - SuSE Linux 7.3, 8.0, 8.1, Enterprise Server 7
         - only Intel and AMD x86 supported at this time
-	- >4GB memory configurations supported.
+        - >4GB memory configurations supported.
 
      Refer to the User's Guide for more details on this.
 
-
 3. Command Line Options
 
         WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS
@@ -77,7 +98,7 @@
                  USE THEM WITH CAUTION. 
 
    Edit the file "modules.conf" in the directory /etc and add/edit a
-   line containing 'options aic79xx=[command[,command...]]' where
+   line containing 'options aic79xx aic79xx=[command[,command...]]' where
    'command' is one or more of the following:
    -----------------------------------------------------------------
               Option: verbose
@@ -88,6 +109,9 @@
    -----------------------------------------------------------------
               Option: debug:[value]
           Definition: Enables various levels of debugging information
+                      The bit definitions for the debugging mask can
+                      be found in drivers/scsi/aic7xxx/aic79xx.h under
+                      the "Debug" heading.
      Possible Values: 0x0000 = no debugging, 0xffff = full debugging
        Default Value: 0x0000
    -----------------------------------------------------------------
@@ -114,120 +138,140 @@
      Possible Values: This option is a flag
        Default Value: disabled
    -----------------------------------------------------------------
-	      Option: global_tag_depth
+              Option: global_tag_depth
           Definition: Global tag depth for all targets on all busses.
-		      This option sets the default tag depth which
-		      may be selectively overridden vi the tag_info
-		      option.
+                      This option sets the default tag depth which
+                      may be selectively overridden vi the tag_info
+                      option.
      Possible Values: 1 - 253
        Default Value: 32
    -----------------------------------------------------------------
               Option: tag_info:{{value[,value...]}[,{value[,value...]}...]}
           Definition: Set the per-target tagged queue depth on a
-		      per controller basis.  Both controllers and targets
-		      may be ommitted indicating that they should retain
-		      the default tag depth.
+                      per controller basis.  Both controllers and targets
+                      may be ommitted indicating that they should retain
+                      the default tag depth.
             Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}
-			On Controller 0
-			  specifies a tag depth of 16 for target 0
-			  specifies a tag depth of 64 for target 3
-			  specifies a tag depth of 8 for targets 4 and 5
-			  leaves target 6 at the default
-		          specifies a tag depth of 32 for targets 1,2,7-15
-			All other targets retain the default depth.
-
-		      tag_info:{{},{32,,32}}
-			On Controller 1
-			  specifies a tag depth of 32 for targets 0 and 2
-			All other targets retain the default depth.
-			
+                        On Controller 0
+                          specifies a tag depth of 16 for target 0
+                          specifies a tag depth of 64 for target 3
+                          specifies a tag depth of 8 for targets 4 and 5
+                          leaves target 6 at the default
+                          specifies a tag depth of 32 for targets 1,2,7-15
+                        All other targets retain the default depth.
+
+                      tag_info:{{},{32,,32}}
+                        On Controller 1
+                          specifies a tag depth of 32 for targets 0 and 2
+                        All other targets retain the default depth.
+                        
      Possible Values: 1 - 253
        Default Value: 32
    -----------------------------------------------------------------
               Option: rd_strm: {rd_strm_bitmask[,rd_strm_bitmask...]}
           Definition: Enable read streaming on a per target basis.
                       The rd_strm_bitmask is a 16 bit hex value in which
-		      each bit represents a target.  Setting the target's
+                      each bit represents a target.  Setting the target's
                       bit to '1' enables read streaming for that
                       target.  Controllers may be ommitted indicating that
-		      they should retain the default read streaming setting.
-	     Example: rd_strm:{0x0041}
-			On Controller 0
-			  enables read streaming for targets 0 and 6.
-			  disables read streaming for targets 1-5,7-15.
-			All other targets retain the default read
-			streaming setting.
-	     Example: rd_strm:{0x0023,,0xFFFF}
-			On Controller 0
-			  enables read streaming for targets 1,2, and 5.
-			  disables read streaming for targets 3,4,6-15.
-			On Controller 2
-			  enables read streaming for all targets.
-			All other targets retain the default read
-			streaming setting.
-		      
+                      they should retain the default read streaming setting.
+             Example: rd_strm:{0x0041}
+                        On Controller 0
+                          enables read streaming for targets 0 and 6.
+                          disables read streaming for targets 1-5,7-15.
+                        All other targets retain the default read
+                        streaming setting.
+             Example: rd_strm:{0x0023,,0xFFFF}
+                        On Controller 0
+                          enables read streaming for targets 1,2, and 5.
+                          disables read streaming for targets 3,4,6-15.
+                        On Controller 2
+                          enables read streaming for all targets.
+                        All other targets retain the default read
+                        streaming setting.
+                      
      Possible Values: 0x0000 - 0xffff
        Default Value: 0x0000
    -----------------------------------------------------------------
+              Option: dv: {value[,value...]}
+          Definition: Set Domain Validation Policy on a per-controller basis.
+                      Controllers may be ommitted indicating that
+                      they should retain the default read streaming setting.
+             Example: dv:{-1,0,,1,1,0}
+                        On Controller 0 leave DV at its default setting.
+                        On Controller 1 disable DV.
+                        Skip configuration on Controller 2.
+                        On Controllers 3 and 4 enable DV.
+                        On Controller 5 disable DV.
+
+     Possible Values: < 0 Use setting from serial EEPROM.
+                      0 Disable DV
+                      > 0 Enable DV
+       Default Value: DV Serial EEPROM configuration setting.
+   -----------------------------------------------------------------
+              Option: seltime:[value]
+          Definition: Specifies the selection timeout value
+     Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms
+       Default Value: 0
+   -----------------------------------------------------------------
+
+   *** The following three options should only be changed at ***
+   *** the direction of a technical support representative.  ***
+
+   -----------------------------------------------------------------
               Option: precomp: {value[,value...]}
           Definition: Set IO Cell precompensation value on a per-controller
-		      basis.
+                      basis.
                       Controllers may be ommitted indicating that
-		      they should retain the default precompensation setting.
-	     Example: precomp:{0x1}
-			On Controller 0 set precompensation to 1.
-	     Example: precomp:{1,,7}
-			On Controller 0 set precompensation to 1.
-			On Controller 2 set precompensation to 8.
-		      
+                      they should retain the default precompensation setting.
+             Example: precomp:{0x1}
+                        On Controller 0 set precompensation to 1.
+             Example: precomp:{1,,7}
+                        On Controller 0 set precompensation to 1.
+                        On Controller 2 set precompensation to 8.
+                      
      Possible Values: 0 - 7
        Default Value: Varies based on chip revision
    -----------------------------------------------------------------
               Option: slewrate: {value[,value...]}
           Definition: Set IO Cell slew rate on a per-controller basis.
                       Controllers may be ommitted indicating that
-		      they should retain the default slew rate setting.
-	     Example: slewrate:{0x1}
-			On Controller 0 set slew rate to 1.
-	     Example: slewrate :{1,,8}
-			On Controller 0 set slew rate to 1.
-			On Controller 2 set slew rate to 8.
-		      
+                      they should retain the default slew rate setting.
+             Example: slewrate:{0x1}
+                        On Controller 0 set slew rate to 1.
+             Example: slewrate :{1,,8}
+                        On Controller 0 set slew rate to 1.
+                        On Controller 2 set slew rate to 8.
+                      
      Possible Values: 0 - 15
        Default Value: Varies based on chip revision
    -----------------------------------------------------------------
               Option: amplitude: {value[,value...]}
           Definition: Set IO Cell signal amplitude on a per-controller basis.
                       Controllers may be ommitted indicating that
-		      they should retain the default read streaming setting.
-	     Example: amplitude:{0x1}
-			On Controller 0 set amplitude to 1.
-	     Example: amplitude :{1,,7}
-			On Controller 0 set amplitude to 1.
-			On Controller 2 set amplitude to 7.
-		      
+                      they should retain the default read streaming setting.
+             Example: amplitude:{0x1}
+                        On Controller 0 set amplitude to 1.
+             Example: amplitude :{1,,7}
+                        On Controller 0 set amplitude to 1.
+                        On Controller 2 set amplitude to 7.
+                      
      Possible Values: 1 - 7
        Default Value: Varies based on chip revision
    -----------------------------------------------------------------
-              Option: seltime:[value]
-          Definition: Specifies the selection timeout value
-     Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms
-       Default Value: 0
-   -----------------------------------------------------------------
 
-   Example: 'options aic79xx=verbose,rd_strm:{{0x0041}}'
-	enables verbose output in the driver and turns read streaming on
-	for targets 0 and 6 of Controller 0.
+   Example: 'options aic79xx aic79xx=verbose,rd_strm:{{0x0041}}'
+        enables verbose output in the driver and turns read streaming on
+        for targets 0 and 6 of Controller 0.
 
 4. Additional Notes
 
    4.1. Known/Unresolved or FYI Issues
 
-	* Domain Validation is not implemented.
-	* Under SuSE Linux Enterprise 7, the driver may fail to operate
-	  correctly due to a problem with PCI interrupt routing in the
-	  Linux kernel.  Please contact SuSE for an updated Linux
-	  kernel.
+        * Under SuSE Linux Enterprise 7, the driver may fail to operate
+          correctly due to a problem with PCI interrupt routing in the
+          Linux kernel.  Please contact SuSE for an updated Linux
+          kernel.
 
    4.2. Third-Party Compatibility Issues
 
@@ -240,6 +284,18 @@
         
         * PCI Hot Plug is untested and may cause the operating system 
           to stop responding.
+        * Luns that are not numbered contiguously starting with 0 might not
+          be automatically probed during system startup.  This is a limitation
+          of the OS.  Please contact your Linux vendor for instructions on
+          manually probing non-contiguous luns.
+        * Using the Driver Update Disk version of this package during OS
+          installation under RedHat might result in two versions of this
+          driver being installed into the system module directory.  This
+          might cause problems with the /sbin/mkinitrd program and/or
+          other RPM packages that try to install system modules.  The best
+          way to correct this once the system is running is to install
+          the latest RPM package version of this driver, available from
+          http://www.adaptec.com.
 
 
 5. Contacting Adaptec
@@ -316,7 +372,7 @@
 
 -------------------------------------------------------------------
 
-(c) 2002 Adaptec, Inc. All Rights Reserved. No part of this 
+(c) 2003 Adaptec, Inc. All Rights Reserved. No part of this 
 publication may be reproduced, stored in a retrieval system, or 
 transmitted in any form or by any means, electronic, mechanical, 
 photocopying, recording or otherwise, without prior written consent 
diff -Nru a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
--- a/Documentation/scsi/aic7xxx.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/scsi/aic7xxx.txt	Mon Feb 10 10:39:24 2003
@@ -1,5 +1,5 @@
 ====================================================================
-=    Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.10   =
+=    Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28   =
 =                            README for                            =
 =                     The Linux Operating System                   =
 ====================================================================
@@ -7,8 +7,9 @@
 The following information is available in this file:
 
   1. Supported Hardware
-  2. Command Line Options
-  3. Contacting Adaptec
+  2. Version History
+  3. Command Line Options
+  4. Contacting Adaptec
 
 1. Supported Hardware
 
@@ -44,52 +45,52 @@
    5.   Block Move Instruction Support - Doubles the speed of certain
         sequencer operations.
    6.   `Bayonet' style Scatter Gather Engine - Improves S/G prefetch
-	performance.
+        performance.
    7.   Queuing Registers - Allows queuing of new transactions without
-	pausing the sequencer.
+        pausing the sequencer.
    8.   Multiple Target IDs - Allows the controller to respond to selection
         as a target on multiple SCSI IDs.
 
    Controller      Chip   Host-Bus    Int-Connectors  Ext-Connectors  Notes
    --------------------------------------------------------------------------
-   AHA-274X[A]    aic7770   EISA        SE-50M          SE-HD50F
-   AHA-274X[A]W   aic7770   EISA        SE-HD68F	SE-HD68F
-				 	SE-50M
-   AHA-274X[A]T   aic7770   EISA       2 X SE-50M	SE-HD50F
-   AHA-2842       aic7770    VL          SE-50M		SE-HD50F
-   AHA-2940AU     aic7860   PCI/32       SE-50M		SE-HD50F
+   AHA-274X[A]    aic7770   EISA         SE-50M         SE-HD50F
+   AHA-274X[A]W   aic7770   EISA         SE-HD68F       SE-HD68F
+                                         SE-50M
+   AHA-274X[A]T   aic7770   EISA       2 X SE-50M       SE-HD50F
+   AHA-2842       aic7770    VL          SE-50M         SE-HD50F
+   AHA-2940AU     aic7860   PCI/32       SE-50M         SE-HD50F
    AVA-2902I      aic7860   PCI/32       SE-50M
    AVA-2902E      aic7860   PCI/32       SE-50M
-   AVA-2906       aic7856   PCI/32       SE-50M		SE-DB25F
-   APC-7850       aic7850   PCI/32       SE-50M			      1
+   AVA-2906       aic7856   PCI/32       SE-50M         SE-DB25F
+   APC-7850       aic7850   PCI/32       SE-50M                       1
    AVA-2940       aic7860   PCI/32       SE-50M
    AHA-2920B      aic7860   PCI/32       SE-50M
    AHA-2930B      aic7860   PCI/32       SE-50M
-   AHA-2920C      aic7856   PCI/32       SE-50M		SE-HD50F
+   AHA-2920C      aic7856   PCI/32       SE-50M         SE-HD50F
    AHA-2930C      aic7860   PCI/32       SE-50M
    AHA-2930C      aic7860   PCI/32       SE-50M
    AHA-2910C      aic7860   PCI/32       SE-50M
    AHA-2915C      aic7860   PCI/32       SE-50M
-   AHA-2940AU/CN  aic7860   PCI/32       SE-50M		SE-HD50F
-   AHA-2944W      aic7870   PCI/32     HVD-HD68F	HVD-HD68F
-				        HVD-50M
-   AHA-3940W      aic7870   PCI/32     2 X SE-HD68F	SE-HD68F        2
+   AHA-2940AU/CN  aic7860   PCI/32       SE-50M         SE-HD50F
+   AHA-2944W      aic7870   PCI/32     HVD-HD68F        HVD-HD68F
+                                        HVD-50M
+   AHA-3940W      aic7870   PCI/32     2 X SE-HD68F     SE-HD68F        2
    AHA-2940UW     aic7880   PCI/32       SE-HD68F
-					 SE-50M		SE-HD68F
-   AHA-2940U      aic7880   PCI/32       SE-50M		SE-HD50F
+                                         SE-50M         SE-HD68F
+   AHA-2940U      aic7880   PCI/32       SE-50M         SE-HD50F
    AHA-2940D      aic7880   PCI/32
-   AHA-2940 A/T   aic7880   PCI/32
+   aHA-2940 A/T   aic7880   PCI/32
    AHA-2940D A/T  aic7880   PCI/32
-   AHA-3940UW     aic7880   PCI/32     2 X SE-HD68F	SE-HD68F          3
+   AHA-3940UW     aic7880   PCI/32     2 X SE-HD68F     SE-HD68F          3
    AHA-3940UWD    aic7880   PCI/32     2 X SE-HD68F   2 X SE-VHD68F       3
-   AHA-3940U      aic7880   PCI/32     2 X SE-50M	SE-HD50F          3
-   AHA-2944UW     aic7880   PCI/32      HVD-HD68F	HVD-HD68F
-					 HVD-50M
+   AHA-3940U      aic7880   PCI/32     2 X SE-50M       SE-HD50F          3
+   AHA-2944UW     aic7880   PCI/32      HVD-HD68F       HVD-HD68F
+                                         HVD-50M
    AHA-3944UWD    aic7880   PCI/32     2 X HVD-HD68F  2 X HVD-VHD68F      3
    AHA-4944UW     aic7880   PCI/32
    AHA-2930UW     aic7880   PCI/32
-   AHA-2940UW Pro aic7880   PCI/32      SE-HD68F	SE-HD68F            4
-					 SE-50M
+   AHA-2940UW Pro aic7880   PCI/32      SE-HD68F        SE-HD68F            4
+                                         SE-50M
    AHA-2940UW/CN  aic7880   PCI/32
    AHA-2940UDual  aic7895   PCI/32
    AHA-2940UWDual aic7895   PCI/32
@@ -98,30 +99,30 @@
    AHA-3940AUWD   aic7895   PCI/32
    AHA-3940AU     aic7895   PCI/32
    AHA-3944AUWD   aic7895   PCI/32     2 X HVD-HD68F  2 X HVD-VHD68F
-   AHA-2940U2B    aic7890   PCI/32      LVD-HD68F	LVD-HD68F
+   AHA-2940U2B    aic7890   PCI/32      LVD-HD68F       LVD-HD68F
    AHA-2940U2 OEM aic7891   PCI/64
-   AHA-2940U2W    aic7890   PCI/32      LVD-HD68F	LVD-HD68F
-				        SE-HD68F 
-					 SE-50M
-   AHA-2950U2B    aic7891   PCI/64      LVD-HD68F	LVD-HD68F
-   AHA-2930U2     aic7890   PCI/32      LVD-HD68F	SE-HD50F
-					 SE-50M 
+   AHA-2940U2W    aic7890   PCI/32      LVD-HD68F       LVD-HD68F
+                                        SE-HD68F 
+                                         SE-50M
+   AHA-2950U2B    aic7891   PCI/64      LVD-HD68F       LVD-HD68F
+   AHA-2930U2     aic7890   PCI/32      LVD-HD68F       SE-HD50F
+                                         SE-50M 
    AHA-3950U2B    aic7897   PCI/64
    AHA-3950U2D    aic7897   PCI/64
    AHA-29160      aic7892   PCI/64-66
    AHA-29160 CPQ  aic7892   PCI/64-66
-   AHA-29160N     aic7892   PCI/32      LVD-HD68F	SE-HD50F
-					 SE-50M
+   AHA-29160N     aic7892   PCI/32      LVD-HD68F       SE-HD50F
+                                         SE-50M
    AHA-29160LP    aic7892   PCI/64-66
    AHA-19160      aic7892   PCI/64-66
    AHA-29150LP    aic7892   PCI/64-66
    AHA-29130LP    aic7892   PCI/64-66
    AHA-3960D      aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
-					 LVD-50M
+                                         LVD-50M
    AHA-3960D CPQ  aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
-					 LVD-50M
+                                         LVD-50M
    AHA-39160      aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
-					 LVD-50M
+                                         LVD-50M
 
    1. No BIOS support
    2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus
@@ -129,14 +130,22 @@
    4. All three SCSI connectors may be used simultaneously without
       SCSI "stub" effects.
 
-2. Command Line Options
+2. Version History
+
+        6.2.28 - Domain Validation Fixes
+                 PCI parity error disable
+                 Enhanced Memory Mapped I/O probe
+
+        6.2.20 - Added Domain Validation
+
+3. Command Line Options
 
         WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS
                  INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE.
                  USE THEM WITH CAUTION. 
 
    Edit the file "modules.conf" in the directory /etc and add/edit a
-   line containing 'options aic7xxx=[command[,command...]]' where
+   line containing 'options aic7xxx aic7xxx=[command[,command...]]' where
    'command' is one or more of the following:
    -----------------------------------------------------------------
               Option: verbose
@@ -150,6 +159,30 @@
      Possible Values: 0x0000 = no debugging, 0xffff = full debugging
        Default Value: 0x0000
    -----------------------------------------------------------------
+              Option: no_probe
+          Definition: Do not probe for EISA/VLB controllers.
+                      This is a toggle.  If the driver is compiled
+                      to not probe EISA/VLB controllers by default,
+                      specifying "no_probe" will enable this probing.
+                      If the driver is compiled to probe EISA/VLB
+                      controllers by default, specifying "no_probe"
+                      will disable this probing.
+     Possible Values: This option is a toggle
+       Default Value: EISA/VLB probing is disabled by default.
+   -----------------------------------------------------------------
+              Option: pci_parity
+          Definition: Toggles the detection of PCI parity errors.
+                      On many motherboards with VIA chipsets,
+                      PCI parity is not generated correctly on the
+                      PCI bus.  It is impossible for the hardware to
+                      differentiate between these "spurious" parity
+                      errors and real parity errors.  The symptom of
+                      this problem is a stream of the message:
+    "scsi0: Data Parity Error Detected during address or write data phase"
+                      output by the driver.
+     Possible Values: This option is a toggle
+       Default Value: PCI Parity Error reporting is disabled
+   -----------------------------------------------------------------
               Option: no_reset
           Definition: Do not reset the bus during the initial probe
                       phase
@@ -173,33 +206,33 @@
      Possible Values: This option is a flag
        Default Value: disabled
    -----------------------------------------------------------------
-	      Option: global_tag_depth
+              Option: global_tag_depth:[value]
           Definition: Global tag depth for all targets on all busses.
-		      This option sets the default tag depth which
-		      may be selectively overridden vi the tag_info
-		      option.
+                      This option sets the default tag depth which
+                      may be selectively overridden vi the tag_info
+                      option.
      Possible Values: 1 - 253
        Default Value: 32
    -----------------------------------------------------------------
               Option: tag_info:{{value[,value...]}[,{value[,value...]}...]}
           Definition: Set the per-target tagged queue depth on a
-		      per controller basis.  Both controllers and targets
-		      may be ommitted indicating that they should retain
-		      the default tag depth.
+                      per controller basis.  Both controllers and targets
+                      may be ommitted indicating that they should retain
+                      the default tag depth.
             Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}
-			On Controller 0
-			  specifies a tag depth of 16 for target 0
-			  specifies a tag depth of 64 for target 3
-			  specifies a tag depth of 8 for targets 4 and 5
-			  leaves target 6 at the default
-		          specifies a tag depth of 32 for targets 1,2,7-15
-			All other targets retain the default depth.
-
-		      tag_info:{{},{32,,32}}
-			On Controller 1
-			  specifies a tag depth of 32 for targets 0 and 2
-			All other targets retain the default depth.
-			
+                        On Controller 0
+                          specifies a tag depth of 16 for target 0
+                          specifies a tag depth of 64 for target 3
+                          specifies a tag depth of 8 for targets 4 and 5
+                          leaves target 6 at the default
+                          specifies a tag depth of 32 for targets 1,2,7-15
+                        All other targets retain the default depth.
+
+                      tag_info:{{},{32,,32}}
+                        On Controller 1
+                          specifies a tag depth of 32 for targets 0 and 2
+                        All other targets retain the default depth.
+                        
      Possible Values: 1 - 253
        Default Value: 32
    -----------------------------------------------------------------
@@ -208,10 +241,30 @@
      Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms
        Default Value: 0
    -----------------------------------------------------------------
+              Option: dv: {value[,value...]} 
+          Definition: Set Domain Validation Policy on a per-controller basis.
+                      Controllers may be ommitted indicating that
+                      they should retain the default read streaming setting.
+             Example: dv:{-1,0,,1,1,0}
+                        On Controller 0 leave DV at its default setting.
+                        On Controller 1 disable DV.
+                        Skip configuration on Controller 2.
+                        On Controllers 3 and 4 enable DV.
+                        On Controller 5 disable DV.
+
+     Possible Values: < 0 Use setting from serial EEPROM.
+                      0 Disable DV
+                      > 0 Enable DV
+
+       Default Value: SCSI-Select setting on controllers with a SCSI Select
+                      option for DV.  Otherwise, on for controllers supporting
+                      U160 speeds and off for all other controller types.
+   -----------------------------------------------------------------
 
-   Example: 'options aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1"
-	enables verbose logging, Disable EISA/VLB probing,
-	and set tag depth on Controller 1/Target 2 to 10 tags.
+   Example:
+   'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1"
+        enables verbose logging, Disable EISA/VLB probing,
+        and set tag depth on Controller 1/Target 2 to 10 tags.
 
 3. Contacting Adaptec
 
diff -Nru a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
--- a/Documentation/scsi/ibmmca.txt	Mon Feb 10 10:39:29 2003
+++ b/Documentation/scsi/ibmmca.txt	Mon Feb 10 10:39:29 2003
@@ -346,7 +346,7 @@
    This table is quite informative for interested users. It shows the load
    of commands on the subsystem and wether you are running the bypassed 
    (software) or integrated (hardware) SCSI-command set (see below). The
-   amount of accesses is shown. Read, write, modeselect is shown seperately
+   amount of accesses is shown. Read, write, modeselect is shown separately
    in order to help debugging problems with CD-ROMs or tapedrives.
    
    The following table shows the list of 15 logical device numbers, that are
@@ -906,7 +906,7 @@
       to does not offer more space, invalid memory accesses destabilized the
       kernel.
    3) version 4.0 is only valid for kernel 2.4.0 or later. This is necessary
-      to remove old kernel version dependant waste from the driver. 3.2d is
+      to remove old kernel version dependent waste from the driver. 3.2d is
       only distributed with older kernels but keeps compatibility with older
       kernel versions. 4.0 and higher versions cannot be used with older 
       kernels anymore!! You must have at least kernel 2.4.0!!
@@ -943,7 +943,7 @@
 
    4 To do
    -------
-        - IBM SCSI-2 F/W external SCSI bus support in seperate mode!
+        - IBM SCSI-2 F/W external SCSI bus support in separate mode!
 	- It seems that the handling of bad disks is really bad -
 	  non-existent, in fact. However, a low-level driver cannot help
 	  much, if such things happen.
@@ -1382,7 +1382,7 @@
    
    9 Disclaimer
    ------------
-   Beside the GNU General Public License and the dependant disclaimers and disclaimers
+   Beside the GNU General Public License and the dependent disclaimers and disclaimers
    concerning the Linux-kernel in special, this SCSI-driver comes without any
    warranty. Its functionality is tested as good as possible on certain 
    machines and combinations of computer hardware, which does not exclude,
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	Mon Feb 10 10:39:23 2003
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	Mon Feb 10 10:39:23 2003
@@ -213,6 +213,8 @@
 
     mpu_port	- 0x300 (default),0x310,0x320,0x330, -1 (diable)
     fm_port     - 0x388 (default), -1 (disable)
+    soft_ac3    - Sofware-conversion of raw SPDIF packets (model 033 only)
+                  (default = 1)
 
     Module supports autoprobe and multiple chips (max 8).
     
@@ -748,7 +750,8 @@
   Module snd-rme32
   ----------------
 
-    Module for RME Digi32, Digi32/8 and Digi32 PRO soundcards.
+    Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, 
+    Prodif96 and Prodif Gold) soundcards.
 
     Module supports up to 8 cards.
 
diff -Nru a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
--- a/Documentation/sound/alsa/CMIPCI.txt	Mon Feb 10 10:39:23 2003
+++ b/Documentation/sound/alsa/CMIPCI.txt	Mon Feb 10 10:39:23 2003
@@ -20,7 +20,7 @@
 
 - The first DAC supports U8 and S16LE formats, while the second DAC
   supports only S16LE.
-- The second DAC supports only two channel stereo.
+- The seconde DAC supports only two channel stereo.
 
 Please note that the CM8x38 DAC doesn't support continuous playback
 rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000,
@@ -65,15 +65,20 @@
 "-MC" such like "CMI8738-MC6".  You can check this name from
 /proc/asound/cards.
 
-When the 4/6-ch output is enabled, the front DAC accepts up to 6 (or
-4) channels.  This is different from the dual DACs described in the
-previous section.  While the dual DAC supports two different rates or
+When the 4/6-ch output is enabled, the second DAC accepts up to 6 (or
+4) channels.  While the dual DAC supports two different rates or
 formats, the 4/6-ch playback supports only the same condition for all
-channels.
+channels.  Since the multi-channel playback mode uses both DACs, you
+cannot operate with full-duplex.
 
-For using 4/6 channel playback, you need to specify the PCM channels
-as you like and set the format S16LE.  For example, for playback with
-4 channels,
+The 4.0 and 5.1 modes are defined as the pcm "surround40" and "surround51"
+in alsa-lib.  For example, you can play a WAV file with 6 channels like
+
+	% aplay -Dsurround51 sixchannels.wav
+
+For programmin the 4/6 channel playback, you need to specify the PCM
+channels as you like and set the format S16LE.  For example, for playback
+with 4 channels,
 
 	snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
 	    // or mmap if you like
@@ -82,9 +87,15 @@
 
 and use the interleaved 4 channel data.
 
-There is a control switch, "Line-In As Bass".  As you can imagine from
-its name, the line-in jack is used for the bass (5th and 6th channels)
-output.
+There are some control switchs affecting to the speaker connections:
+
+"Line-In As Rear"	- As mentioned above, the line-in jack is used
+	for the rear (3th and 4th channels) output.
+"Line-In As Bass"	- The line-in jack is used for the bass (5th
+	and 6th channels) output.
+"Mic As Center/LFE"	- The mic jack is used for the bass output.
+	If this switch is on, you cannot use a microphone as a capture
+	source, of course.
 
 
 Digital I/O
@@ -134,8 +145,7 @@
 	(see the next section).
 
 "IEC958 In Select"  - Select SPDIF input, the internal CD-in (false)
-	and the external input (true).  This switch appears only on
-	the chip models 039 or later.
+	and the external input (true).
 
 "IEC958 Loop"       - SPDIF input data is loop back into SPDIF
 	output (aka bypass)
@@ -169,6 +179,11 @@
 Similarly the following switches are off: "IEC958 Mix Analog" and
 "IEC958 Loop".  The switches are resumed after closing the SPDIF PCM
 device automatically to the previous state.
+
+On the model 033, AC3 is implemented by the software conversion in
+the driver.  This prevents the mmap support.  If you need mmap
+support, pass the "soft_ac3=0" module option.  This doesn't matter
+on the newer models.
 
 
 ANALOG MIXER INTERFACE
diff -Nru a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,102 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<book>
+<?dbhtml filename="index.html">
+
+<!-- ****************************************************** -->
+<!-- Header  -->
+<!-- ****************************************************** -->
+  <bookinfo>
+    <title>The ALSA Driver API</title>
+
+    <legalnotice>
+    <para>
+    This document is free; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version. 
+    </para>
+
+    <para>
+    This document is distributed in the hope that it will be useful,
+    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
+    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
+    PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
+    for more details.
+    </para>
+
+    <para>
+    You should have received a copy of the GNU General Public
+    License along with this program; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+    MA 02111-1307 USA
+    </para>
+    </legalnotice>
+
+  </bookinfo>
+
+  <chapter><title>Management of Cards and Devices</title>
+     <sect1><title>Card Managment</title>
+!Esound/core/init.c
+     </sect1>
+     <sect1><title>Device Components</title>
+!Esound/core/device.c
+     </sect1>
+     <sect1><title>KMOD and Device File Entries</title>
+!Esound/core/sound.c
+     </sect1>
+     <sect1><title>Memory Management Helpers</title>
+!Esound/core/memory.c
+!Iinclude/sound/sndmagic.h
+     </sect1>
+  </chapter>
+  <chapter><title>PCM API</title>
+     <sect1><title>PCM Core</title>
+!Esound/core/pcm.c
+!Esound/core/pcm_lib.c
+!Esound/core/pcm_native.c
+     </sect1>
+     <sect1><title>PCM Format Helpers</title>
+!Esound/core/pcm_misc.c
+     </sect1>
+     <sect1><title>PCM Memory Managment</title>
+!Esound/core/pcm_memory.c
+     </sect1>
+     <sect1><title>SG-Buffer Helpers</title>
+!Esound/core/pcm_sgbuf.c
+     </sect1>
+  </chapter>
+  <chapter><title>Control/Mixer API</title>
+     <sect1><title>General Control Interface</title>
+!Esound/core/control.c
+     </sect1>
+     <sect1><title>AC97 Codec API</title>
+!Esound/pci/ac97/ac97_codec.c
+     </sect1>
+  </chapter>
+  <chapter><title>MIDI API</title>
+     <sect1><title>Raw MIDI API</title>
+!Esound/core/rawmidi.c
+     </sect1>
+     <sect1><title>MPU401-UART API</title>
+!Esound/drivers/mpu401/mpu401_uart.c
+     </sect1>
+  </chapter>
+  <chapter><title>Proc Info API</title>
+     <sect1><title>Proc Info Interface</title>
+!Esound/core/info.c
+     </sect1>
+  </chapter>
+  <chapter><title>Miscellaneous Functions</title>
+     <sect1><title>Hardware-Dependent Devices API</title>
+!Esound/core/hwdep.c
+     </sect1>
+     <sect1><title>ISA DMA Helpers</title>
+!Esound/core/isadma.c
+     </sect1>
+     <sect1><title>Other Helper Macros</title>
+!Iinclude/sound/core.h
+     </sect1>
+  </chapter>
+
+</book>
diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,5222 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<book>
+<?dbhtml filename="index.html">
+
+<!-- ****************************************************** -->
+<!-- Header  -->
+<!-- ****************************************************** -->
+  <bookinfo>
+    <title>Writing an ALSA Driver</title>
+    <author>
+      <firstname>Takashi</firstname>
+      <surname>Iwai</surname>
+      <affiliation>
+        <address>
+          <email>tiwai@suse.de</email>
+        </address>
+      </affiliation>
+     </author>
+
+     <date>Dec. 27, 2002</date>
+     <edition>0.2 (reborn at Christmas)</edition>
+
+    <abstract>
+      <para>
+        This document describes how to write an ALSA (Advanced Linux
+        Sound Architecture) driver.
+      </para>
+    </abstract>
+
+    <legalnotice>
+    <para>
+    Copyright (c) 2002  Takashi Iwai <email>tiwai@suse.de</email>
+    </para>
+
+    <para>
+    This document is free; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version. 
+    </para>
+
+    <para>
+    This document is distributed in the hope that it will be useful,
+    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
+    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
+    PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
+    for more details.
+    </para>
+
+    <para>
+    You should have received a copy of the GNU General Public
+    License along with this program; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+    MA 02111-1307 USA
+    </para>
+    </legalnotice>
+
+  </bookinfo>
+
+<!-- ****************************************************** -->
+<!-- Preface  -->
+<!-- ****************************************************** -->
+  <preface id="preface">
+    <title>Preface</title>
+    <para>
+      This document describes how to write an
+      <ulink url="http://www.alsa-project.org/"><citetitle>
+      ALSA (Advanced Linux Sound Architecture)</citetitle></ulink>
+      driver. The document focuses mainly on the PCI soundcard.
+      In the case of other device types, the API might
+      be different, too. However, at least the ALSA kernel API is
+      consistent, and therefore it would be still a bit help for
+      writing them.
+    </para>
+
+    <para>
+    The target of this document is ones who already have enough
+    skill of C language and have the basic knowledge of linux
+    kernel programming.  This document doesn't explain the general
+    topics of linux kernel codes and doesn't cover the detail of
+    implementation of each low-level driver.  It describes only how is
+    the standard way to write a PCI sound driver on ALSA.
+    </para>
+
+    <para>
+      If you are already familiar with the older ALSA ver.0.5.x, you
+    can check the drivers such as <filename>es1938.c</filename> or
+    <filename>maestro3.c</filename> which have also almost the same
+    code-base in the ALSA 0.5.x tree, so you can compare the differences.
+    </para>
+
+    <para>
+      This document is still a draft version. Any feedbacks and
+    corrections, please!!
+    </para>
+  </preface>
+
+
+<!-- ****************************************************** -->
+<!-- File Tree Structure  -->
+<!-- ****************************************************** -->
+  <chapter id="file-tree">
+    <title>File Tree Structure</title>
+
+    <section id="file-tree-general">
+      <title>General</title>
+      <para>
+        The ALSA drivers are provided in the two ways.
+      </para>
+
+      <para>
+        One is the the trees provided as a tarball or via cvs from the
+      ALSA's ftp site, and another is the 2.5 (or later) Linux kernel
+      tree. To synchronize both, the ALSA driver tree is split to
+      two different trees: alsa-kernel and alsa-driver. The former
+      contains purely the source codes for the Linux 2.5 (or later)
+      tree. This tree is designed only for compilation on 2.5 or
+      later environment. The latter, alsa-driver, contains many subtle
+      files for compiling the ALSA driver on the outside of Linux
+      kernel like configure script, the wrapper functions for older,
+      2.2 and 2.4 kernels, to adapt the latest kernel API,
+      and additional drivers which are still in development or in
+      tests.  The drivers in alsa-driver tree will be moved to
+      alsa-kernel (eventually 2.5 kernel tree) once when they are
+      finished and confirmed to work fine.
+      </para>
+
+      <para>
+        The file tree structure of ALSA driver is depicted below. Both
+        alsa-kernel and alsa-driver have almost the same file
+        structure, except for <quote>core</quote> directory. It's
+        named as <quote>acore</quote> in alsa-driver tree. 
+
+        <example>
+          <title>ALSA File Tree Structure</title>
+          <literallayout>
+        sound
+                /core
+                        /oss
+                        /seq
+                                /oss
+                                /instr
+                /ioctl32
+                /include
+                /drivers
+                        /mpu401
+                        /opl3
+                /i2c
+                        /l3
+                /synth
+                        /emux
+                /pci
+                        /(cards)
+                /isa
+                        /(cards)
+                /arm
+                /ppc
+                /sparc
+                /usb
+                /pcmcia /(cards)
+                /oss
+          </literallayout>
+        </example>
+      </para>
+    </section>
+
+    <section id="file-tree-core-directory">
+      <title>core directory</title>
+      <para>
+        This directory contains the middle layer, that is, the heart
+      of ALSA drivers. In this directory, the native ALSA modules are
+      stored. The sub-directories contain different modules and are
+      dependent upon the kernel config. 
+      </para>
+
+      <section id="file-tree-core-directory-oss">
+        <title>core/oss</title>
+
+        <para>
+          The codes for PCM and mixer OSS emulation modules are stored
+        in this directory. The rawmidi OSS emulation is included in
+        the ALSA rawmidi code since it's quite small. The sequencer
+        code is stored in core/seq/oss directory (see
+        <link linkend="file-tree-core-directory-seq-oss"><citetitle>
+        below</citetitle></link>).
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-ioctl32">
+        <title>core/ioctl32</title>
+
+        <para>
+          This directory contains the 32bit-ioctl wrappers for 64bit
+        architectures such like x86-64, ppc64 and sparc64. For 32bit
+        and alpha architectures, these are not compiled. 
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-seq">
+        <title>core/seq</title>
+        <para>
+          This and its sub-directories are for the ALSA
+        sequencer. This directory contains the sequencer core and
+        primary sequencer modules such like snd-seq-midi,
+        snd-seq-virmidi, etc. They are compiled only when
+        <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel
+        config. 
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-seq-oss">
+        <title>core/seq/oss</title>
+        <para>
+          This contains the OSS sequencer emulation codes.
+        </para>
+      </section>
+
+      <section id="file-tree-core-directory-deq-instr">
+        <title>core/seq/instr</title>
+        <para>
+          This directory contains the modules for the sequencer
+        instrument layer. 
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-include-directory">
+      <title>include directory</title>
+      <para>
+        This is the place for the public header files of ALSA drivers,
+      which are to be exported to the user-space, or included by
+      several files at different directories. Basically, the private
+      header files should not be placed in this directory, but you may
+      still find files there, due to historical reason :) 
+      </para>
+    </section>
+
+    <section id="file-tree-drivers-directory">
+      <title>drivers directory</title>
+      <para>
+        This directory contains the non-architecture-specific
+      codes. For example, the dummy pcm driver and the serial MIDI
+      driver are found in this directory. In the sub-directories,
+      there are the codes for components which are independent from
+      bus and cpu architectures. 
+      </para>
+
+      <section id="file-tree-drivers-directory-mpu401">
+        <title>drivers/mpu401</title>
+        <para>
+          The MPU401 and MPU401-UART modules are stored here.
+        </para>
+      </section>
+
+      <section id="file-tree-drivers-directory-opl3">
+        <title>drivers/opl3</title>
+        <para>
+          The OPL3 FM-synth stuff is found here.
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-i2c-directory">
+      <title>i2c directory</title>
+      <para>
+        This contains the ALSA i2c components.
+      </para>
+
+      <para>
+        Although there is a standard i2c layer on Linux, ALSA uses its
+      own i2c codes for some cards, because the soundcard needs only a
+      simple operation and the standard API is too complicated for
+      such a purpose. 
+      </para>
+
+      <section id="file-tree-i2c-directory-l3">
+        <title>i2c/l3</title>
+        <para>
+          This is a sub-directory for ARM L3 i2c.
+        </para>
+      </section>
+    </section>
+
+    <section id="file-tree-synth-directory">
+        <title>synth directory</title>
+        <para>
+          This contains the synth middle-level modules.
+        </para>
+
+        <para>
+          So far, there is only Emu8000/Emu10k1 synth driver under
+        synth/emux sub-directory. 
+        </para>
+    </section>
+
+    <section id="file-tree-pci-directory">
+      <title>pci directory</title>
+      <para>
+        This and its sub-directories hold the top-level card modules
+      for PCI soundcards. 
+      </para>
+
+      <para>
+        The drivers compiled from a single file is stored directly on
+      pci directory, while the drivers with several source files are
+      stored on its own sub-directory (e.g. emu10k1, ice1712). 
+      </para>
+    </section>
+
+    <section id="file-tree-isa-directory">
+      <title>isa directory</title>
+      <para>
+        This and its sub-directories hold the top-level card modules
+      for ISA soundcards. 
+      </para>
+    </section>
+
+    <section id="file-tree-arm-ppc-sparc-directories">
+      <title>arm, ppc, and sparc directories</title>
+      <para>
+        These are for the top-level card modules which are
+      architecture specific. 
+      </para>
+    </section>
+
+    <section id="file-tree-usb-directory">
+      <title>usb directory</title>
+      <para>
+        This contains the USB-audio driver. On the latest version, the
+      USB MIDI driver is integrated together with usb-audio driver. 
+      </para>
+    </section>
+
+    <section id="file-tree-pcmcia-directory">
+      <title>pcmcia directory</title>
+      <para>
+        The PCMCIA, especially PCCard drivers will go here. CardBus
+      drivers will be on pci directory, because its API is identical
+      with the standard PCI cards. 
+      </para>
+
+      <para>
+        At this moment, only VX-pocket driver exists.
+      </para>
+    </section>
+
+    <section id="file-tree-oss-directory">
+      <title>oss directory</title>
+      <para>
+        The OSS/Lite source files are stored here on Linux 2.5 (or
+      later) tree. (In the ALSA driver tarball, it's empty, of course :) 
+      </para>
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Basic Flow for PCI Drivers  -->
+<!-- ****************************************************** -->
+  <chapter id="basic-flow">
+    <title>Basic Flow for PCI Drivers</title>
+
+    <section id="basic-flow-outline">
+      <title>Outline</title>
+      <para>
+        The minimum flow of PCI soundcard is like the following:
+
+        <itemizedlist>
+          <listitem><para>define the PCI ID table (see the section
+          <link linkend="pci-resource-entries"><citetitle>PCI Entries
+          </citetitle></link>).</para></listitem> 
+          <listitem><para>create <function>probe()</function> callback.</para></listitem>
+          <listitem><para>create <function>remove()</function> callback.</para></listitem>
+          <listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
+          <listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem>
+          <listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
+        </itemizedlist>
+      </para>
+    </section>
+
+    <section id="basic-flow-example">
+      <title>Full Code Example</title>
+      <para>
+        The code example is shown below. Some parts are kept
+      unimplemented at this moment but will be filled in the
+      succeeding sections. The numbers in comment lines of
+      <function>snd_mychip_probe()</function> function are the
+      markers. 
+
+        <example>
+          <title>Basic Flow for PCI Drivers Example</title>
+          <programlisting>
+<![CDATA[
+  #include <sound/driver.h>
+  #include <linux/init.h>
+  #include <linux/pci.h>
+  #include <linux/slab.h>
+  #include <sound/core.h>
+  #define SNDRV_GET_ID
+  #include <sound/initval.h>
+
+  // module parameters (see "Module Parameters")
+  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;
+
+  // definition of the chip-specific record
+  typedef struct snd_mychip mychip_t;
+  struct snd_mychip {
+          snd_card_t *card;
+          // rest of implementation will be in the section
+          // "PCI Resource Managements"
+  };
+
+  // this should be go into <sound/sndmagic.h>
+  // (see "Management of Cards and Components")
+  #define mychip_t_magic        0xa15a4501
+
+  // chip-specific destructor
+  // (see "PCI Resource Managements")
+  static int snd_mychip_free(mychip_t *chip)
+  {
+          // will be implemented later...
+  }
+
+  // component-destructor
+  // (see "Management of Cards and Components")
+  static int snd_mychip_dev_free(snd_device_t *device)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                  device->device_data, return -ENXIO);
+          return snd_mychip_free(chip);
+  }
+
+  // chip-specific constructor
+  // (see "Management of Cards and Components")
+  static int __devinit snd_mychip_create(snd_card_t *card,
+                                         struct pci_device *pci,
+                                         mychip_t *rchip)
+  {
+          mychip_t *chip;
+          int err;
+          static snd_device_ops_t ops = {
+                 .dev_free = snd_mychip_dev_free,
+          };
+
+          *rchip = NULL;
+
+          // check PCI availability here
+          // (see "PCI Resource Managements")
+
+          // allocate a chip-specific data with magic-alloc
+          chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+          if (chip == NULL)
+                  return -ENOMEM;
+
+          chip->card = card;
+
+          // rest of initialization here; will be implemented
+          // later, see "PCI Resource Managements"
+
+          if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+                                    chip, &ops)) < 0) {
+                  snd_mychip_free(chip);
+                  return err;
+          }
+          *rchip = chip;
+          return 0;
+  }
+
+  // constructor -- see "Constructor" sub-section
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          static int dev;
+          snd_card_t *card;
+          mychip_t *chip;
+          int err;
+
+          // (1)
+          if (dev >= SNDRV_CARDS)
+                  return -ENODEV;
+          if (!enable[dev]) {
+                  dev++;
+                  return -ENOENT;
+          }
+
+          // (2)
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+          if (card == NULL)
+                  return -ENOMEM;
+
+          // (3)
+          if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
+                  snd_card_free(card);
+                  return err;
+          }
+
+          // (4)
+          // implemented later
+
+          // (5)
+          strcpy(card->driver, "My Chip");
+          strcpy(card->shortname, "My Own Chip 123");
+          sprintf(card->longname, "%s at 0x%lx irq %i",
+                  card->shortname, chip->ioport, chip->irq);
+
+          // (6)
+          if ((err = snd_card_register(card)) < 0) {
+                  snd_card_free(card);
+                  return err;
+          }
+
+          // (7)
+          pci_set_drvdata(pci, chip);
+          dev++;
+          return 0;
+  }
+
+  // destructor -- see "Destructor" sub-section
+  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                     pci_get_drvdata(pci), return);
+          if (chip)
+                  snd_card_free(chip->card);
+          pci_set_drvdata(pci, NULL);
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="basic-flow-constructor">
+      <title>Constructor</title>
+      <para>
+        The real constructor of PCI drivers is probe callback. The
+      probe callback and other component-constructors which are called
+      from probe callback should be defined with
+      <parameter>__devinit</parameter> prefix. You 
+      cannot use <parameter>__init</parameter> prefix for them,
+      because any PCI device could be a hotplug device. 
+      </para>
+
+      <para>
+        In the probe callback, the following scheme is often used.
+      </para>
+
+      <section id="basic-flow-constructor-device-index">
+        <title>1) Check and increment the device index.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int dev;
+  ....
+  if (dev >= SNDRV_CARDS)
+          return -ENODEV;
+  if (!enable[dev]) {
+          dev++;
+          return -ENOENT;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+        where enable[dev] is the module option.
+        </para>
+
+        <para>
+          At each time probe callback is called, check the
+        availability of the device. If not available, simply increment
+        the device index and returns. dev will be incremented also
+        later (<link
+        linkend="basic-flow-constructor-set-pci"><citetitle>step
+        7</citetitle></link>). 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-card">
+        <title>2) Create a card instance</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_card_t *card;
+  ....
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The detail will be explained in the section
+          <link linkend="card-management-card-instance"><citetitle>
+          Management of Cards and Components</citetitle></link>.
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-main">
+        <title>3) Create a main component</title>
+        <para>
+          In this part, the PCI resources are allocated.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  mychip_t *chip;
+  ....
+  if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
+          snd_card_free(card);
+          return err;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          The detail will be explained in the section <link
+        linkend="pci-resource"><citetitle>PCI Resource
+        Managements</citetitle></link>.
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-create-other">
+        <title>4) Create other components, such as mixer, MIDI, etc.</title>
+        <para>
+          Here you define the basic components such as
+          <link linkend="pcm-interface"><citetitle>PCM</citetitle></link>,
+          mixer (e.g. <link linkend="api-ac97"><citetitle>AC97</citetitle></link>),
+          MIDI (e.g. <link linkend="midi-interface"><citetitle>MPU-401</citetitle></link>),
+          and other interfaces.
+          Also, if you want a <link linkend="proc-interface"><citetitle>proc
+        file</citetitle></link>, define it here, too.
+        </para>
+      </section>
+        
+      <section id="basic-flow-constructor-main-component">
+        <title>5) Set the driver ID and name strings.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  strcpy(card->driver, "My Chip");
+  strcpy(card->shortname, "My Own Chip 123");
+  sprintf(card->longname, "%s at 0x%lx irq %i",
+          card->shortname, chip->ioport, chip->irq);
+]]>
+            </programlisting>
+          </informalexample>
+
+          The driver field holds the minimal ID string of the
+        chip. This is referred by alsa-lib's configurator, so keep it
+        simple but unique. 
+          Even the same driver can have different driver IDs to
+        distinguish the functionality of each chip type. 
+        </para>
+
+        <para>
+          The shortname field is a string shown as more verbose
+        name. The longname field contains the information which is
+        shown in <filename>/proc/asound/cards</filename>. 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-register-card">
+        <title>6) Register the card instance.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  if ((err = snd_card_register(card)) < 0) {
+          snd_card_free(card);
+          return err;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Will be explained in the section <link
+        linkend="card-management-registration"><citetitle>Management
+        of Cards and Components</citetitle></link>, too. 
+        </para>
+      </section>
+
+      <section id="basic-flow-constructor-set-pci">
+        <title>7) Set the PCI driver data and return zero.</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+        pci_set_drvdata(pci, chip);
+        dev++;
+        return 0;
+]]>
+            </programlisting>
+          </informalexample>
+
+          In the above, the chip record is stored. This pointer is
+        referred in the remove callback and power-management
+        callbacks, too. 
+	If the card doesn't support the suspend/resume, you can store
+        the card pointer instead of the chip pointer, so that
+        <function>snd_card_free</function> can be called directly
+        without cast in the remove callback.  But anyway, be sure
+        which pointer is used.
+        </para>
+      </section>
+    </section>
+
+    <section id="basic-flow-destructor">
+      <title>Destructor</title>
+      <para>
+        The destructor, remove callback, simply releases the card
+      instance. Then the ALSA middle layer will release all the
+      attached components automatically. 
+      </para>
+
+      <para>
+        It would be typically like the following:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                    pci_get_drvdata(pci), return);
+          if (chip)
+                  snd_card_free(chip->card);
+          pci_set_drvdata(pci, NULL);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+        The above code assumes that the chip is allocated
+	with snd_magic stuff and
+      has the field to hold the card pointer (see <link
+      linkend="card-management"><citetitle>the next
+      section</citetitle></link>). 
+      </para>
+    </section>
+
+    <section id="basic-flow-header-files">
+      <title>Header Files</title>
+      <para>
+        For the above example, at least the following include files
+      are necessary. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  #include <sound/driver.h>
+  #include <linux/init.h>
+  #include <linux/pci.h>
+  #include <linux/slab.h>
+  #include <sound/core.h>
+  #define SNDRV_GET_ID
+  #include <sound/initval.h>
+]]>
+          </programlisting>
+        </informalexample>
+
+	where the last twos are necessary only when module options are
+      defined in the source file.  If the codes are split to several
+      files, the file without module options don't need them.
+      </para>
+
+      <para>
+        In addition to them, you'll need
+      <filename>&lt;linux/interrupt.h&gt;</filename> for the interrupt
+      handling, and <filename>&lt;asm/io.h&gt;</filename> for the i/o
+      access. If you use <function>mdelay()</function> or
+      <function>udelay()</function> functions, you'll need to include
+      <filename>&lt;linux/delay.h&gt;</filename>, too. 
+      </para>
+
+      <para>
+      The ALSA interfaces like PCM or control API are define in other
+      header files as <filename>&lt;sound/xxx.h&gt;</filename>.
+      They have to be included after
+      <filename>&lt;sound/core.h&gt;</filename>.
+      </para>
+
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Management of Cards and Components  -->
+<!-- ****************************************************** -->
+  <chapter id="card-management">
+    <title>Management of Cards and Components</title>
+
+    <section id="card-management-card-instance">
+      <title>Card Instance</title>
+      <para>
+      For each soundcard, a <quote>card</quote> record must be allocated.
+      </para>
+
+      <para>
+      A card record is the headquarters of the soundcard.  It manages
+      the list of whole devices (components) on the soundcard, such as
+      PCM, mixers, MIDI, synthesizer, and so on.  Also, the card
+      record holds the ID and the name strings of the card, manages
+      the root of proc files, and controls the power-management states
+      and hotplug disconnections.  The component list on the card
+      record is used to manage the proper releases of resources at
+      destruction. 
+      </para>
+
+      <para>
+        As mentioned above, to create a card instance, call
+      <function>snd_card_new()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_card_t *card;
+  card = snd_card_new(index, id, module, extra_size);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The function takes four arguments, the card-index number, the
+        id string, the module pointer (usually
+        <constant>THIS_MODULE</constant>),
+        and the size of extra-data space.  The last argument is used to
+        allocate card-&gt;private_data for the
+        chip-specific data.  Note that this data
+        <emphasis>is</emphasis> allocated by
+        <function>snd_card_new()</function>.
+      </para>
+    </section>
+
+    <section id="card-management-component">
+      <title>Components</title>
+      <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.
+      A component can be a PCM instance, a control interface, a raw
+      MIDI interface, etc.  Each of such instances has one component
+      entry.
+      </para>
+
+      <para>
+        A component can be created via
+        <function>snd_device_new()</function> function. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        This takes the card pointer, the device-level
+      (<constant>SNDRV_DEV_XXX</constant>), the data pointer, and the
+      callback pointers (<parameter>&amp;ops</parameter>). The
+      device-level defines the type of components and the order of
+      registration and de-registration.  For most of components, the
+      device-level is already defined.  For a user-defined component,
+      you can use <constant>SNDRV_DEV_LOWLEVEL</constant>.
+      </para>
+
+      <para>
+      This function itself doesn't allocate the data space. The data
+      must be allocated manually beforehand, and its pointer is passed
+      as the argument. This pointer is used as the identifier
+      (<parameter>chip</parameter> in the above example) for the
+      instance. 
+      </para>
+
+      <para>
+        Each ALSA pre-defined component such as ac97 or pcm calls
+      <function>snd_device_new()</function> inside its
+      constructor. The destructor for each component is defined in the
+      callback pointers.  Hence, you don't need to take care of
+      calling a destructor for such a component.
+      </para>
+
+      <para>
+        If you would like to create your own component, you need to
+      set the destructor function to dev_free callback in
+      <parameter>ops</parameter>, so that it can be released
+      automatically via <function>snd_card_free()</function>. The
+      example will be shown later as an implementation of a
+      chip-specific data. 
+      </para>
+    </section>
+
+    <section id="card-management-chip-specific">
+      <title>Chip-Specific Data</title>
+      <para>
+      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 {
+          ....
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        You might have objections against such a typedef, but this
+      typedef is necessary if you use a <quote>magic-cast</quote>
+      (explained <link
+      linkend="card-management-chip-what-advantage"><citetitle>later</citetitle></link>). 
+      </para>
+
+      <para>
+        In general, there are two ways to allocate the chip record.
+      </para>
+
+      <section id="card-management-chip-specific-snd-card-new">
+        <title>1. Allocating via <function>snd_card_new()</function>.</title>
+        <para>
+          As mentioned above, you can pass the extra-data-length to the 4th argument of <function>snd_card_new()</function>, i.e.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(mychip_t));
+]]>
+            </programlisting>
+          </informalexample>
+
+          whether <type>mychip_t</type> is the type of the chip record.
+        </para>
+
+        <para>
+          In return, the allocated record can be accessed as
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  mychip_t *chip = (mychip_t *)card->private_data;
+]]>
+            </programlisting>
+          </informalexample>
+
+          With this method, you don't have to allocate twice. But you
+        cannot use <quote>magic-cast</quote> for this record pointer,
+        instead. 
+        </para>
+      </section>
+
+      <section id="card-management-chip-specific-allocate-extra">
+        <title>2. Allocating an extra device.</title>
+
+        <para>
+          After allocating a card instance via
+          <function>snd_card_new()</function> (with
+          <constant>NULL</constant> on the 4th arg), call
+          <function>snd_magic_kcalloc()</function>. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_card_t *card;
+  mychip_t *chip;
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+  .....
+  chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+]]>
+            </programlisting>
+          </informalexample>
+
+          Once when the record is allocated via snd_magic stuff, you
+        can use <quote>magic-cast</quote> for the void pointer. 
+        </para>
+
+        <para>
+          The chip record should have the field to hold the card
+          pointer at least, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  struct snd_mychip {
+          snd_card_t *card;
+          ....
+  };
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Then, set the card pointer in the returned chip instance.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  chip->card = card;
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Also, you need to define a magic-value for <type>mychip_t</type>.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  #define mychip_t_magic        0xa15a4501
+]]>
+            </programlisting>
+          </informalexample>
+	(the detail will be described in the
+	<link linkend="card-management-chip-what-advantage"><citetitle>
+	next</citetitle></link> subsection).
+	</para>
+
+        <para>
+          Next, initialize the fields, and register this chip
+          record as a low-level device with a specified
+          <parameter>ops</parameter>, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static snd_device_ops_t ops = {
+          .dev_free =        snd_mychip_dev_free,
+  };
+  ....
+  snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+]]>
+            </programlisting>
+          </informalexample>
+
+          <function>snd_mychip_dev_free()</function> is the
+        device-destructor function, which will call the real
+        destructor. 
+        </para>
+
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_mychip_dev_free(snd_device_t *device)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t, device->device_data,
+                                          return -ENXIO);
+          return snd_mychip_free(chip);
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          where <function>snd_mychip_free()</function> is the real destructor.
+        </para>
+      </section>
+
+      <section id="card-management-chip-what-advantage">
+        <title>Not a magic but a logic</title>
+
+        <para>Now, you might have a question: What is the advantage of the
+        second method?  Obviously, it looks far more complicated.</para> 
+        <para>
+          As I wrote many times, the second method allows a
+        <quote>magic-cast</quote> for <type>mychip_t</type>. If you
+        have a void pointer (such as
+        pcm-&gt;private_data), the pointer type
+        is unknown at the compile time, and you cannot know even if a
+        wrong pointer type is passed. The compiler would accept
+        it. The magic-cast checks the pointer type at the runtime (and
+        whether it's a null pointer, too). Hence, the cast will be
+        much safer and good for debugging. 
+        </para>
+
+	<para>
+	As you have already seen, allocation with a magic-header can
+	be done via <function>snd_magic_kmalloc()</function> or
+	<function>snd_magic_kcalloc()</function>.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  mychip_t *chip;
+  chip = snd_magic_kmalloc(mychip_t, 0, GFP_KERNEL);
+  chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+]]>
+            </programlisting>
+          </informalexample>
+
+        The difference of these two functions is whether the area is
+	zero-cleared (<function>kcalloc</function>) or not
+	(<function>kmalloc</function>).
+	</para>
+
+	<para>
+	The first argument of the allocator is the type of the
+	record.  The magic-constant has to be defined for this type
+	beforehand.  In this case, we'll need to define
+	<constant>mychip_t_magic</constant>, for example, as already
+	seen,
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  #define mychip_t_magic        0xa15a4501
+]]>
+            </programlisting>
+          </informalexample>
+
+        The value is arbitrary but should be unique.
+        This is usually defined in
+        <filename>&lt;include/sndmagic.h&gt;</filename> or
+        <filename>&lt;include/amagic.h&gt;</filename> for alsa-driver tree,
+        but you may define it locally in the code at the early
+        development stage, since changing
+        <filename>sndmagic.h</filename> will lead to the recompilation
+        of the whole driver codes.
+        </para>
+
+	<para>
+	The second argument is the extra-data length.  It is usually
+        zero.  The third argument is the flags to be passed to kernel
+        memory allocator, <constant>GFP_XXX</constant>.  Normally,
+        <constant>GFP_KERNEL</constant> is passed.
+	</para>
+
+        <para>
+          For casting a pointer, use
+          <function>snd_magic_cast()</function> macro:
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  mychip_t *chip = snd_magic_cast(mychip_t, source_pointer, action);
+]]>
+            </programlisting>
+          </informalexample>
+
+        where <parameter>source_pointer</parameter> is the pointer to
+        be casted (e.g. pcm-&gt;private_data), and
+        <parameter>action</parameter> is the action to do if the cast
+        fails (e.g. return <constant>-EINVAL</constant>). 
+        </para>
+
+	<para>
+	For releasing the magic-allocated data, you need to call
+        <function>snd_magic_kfree()</function> function instead of
+        <function>kfree()</function>.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_magic_kfree(chip);
+]]>
+            </programlisting>
+          </informalexample>
+	</para>
+
+	<para>
+	If you call <function>kfree()</function> for the
+	magic-allocated value, it will lead to memory leaks.
+	When the ALSA drivers are compiled with
+	<constant>CONFIG_SND_DEBUG_MEMORY</constant> kernel config (or
+	configured with <option>--with-debug=full</option>), the
+	non-matching free will be checked and you'll see warning
+	messages.
+	</para>
+
+        <para>
+          If you are 100% sure that your code is bug-free, you can
+          compile the driver without
+          <constant>CONFIG_SND_DEBUG_MEMORY</constant> kernel config,
+          so that the magic-allocator and the magic-cast will be
+          replaced to the normal kmalloc and cast.
+        </para>
+      </section>
+    </section>
+
+    <section id="card-management-registration">
+      <title>Registration and Release</title>
+      <para>
+        After all components are assigned, register the card instance
+      by calling <function>snd_card_register()</function>. The access
+      to the device files are enabled at this point. That is, before
+      <function>snd_card_register()</function> is called, the
+      components are safely inaccessible from external side. If this
+      call fails, exit the probe function after releasing the card via
+      <function>snd_card_free()</function>. 
+      </para>
+
+      <para>
+        For releasing the card instance, you can call simply
+      <function>snd_card_free()</function>. As already mentioned, all
+      components are released automatically by this call. 
+      </para>
+
+      <para>
+        As further notes, the destructors (both
+      <function>snd_mychip_dev_free</function> and
+      <function>snd_mychip_free</function>) cannot be defined with
+      <parameter>__devexit</parameter> prefix, because they may be
+      called from the constructor, too, at the false path. 
+      </para>
+
+      <para>
+      For a device which allows hotplugging, you can use
+      <function>snd_card_free_in_thread</function>.  This one will
+      postpone the destruction and wait in a kernel-thread until all
+      devices are closed.
+      </para>
+
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- PCI Resource Managements  -->
+<!-- ****************************************************** -->
+  <chapter id="pci-resource">
+    <title>PCI Resource Managements</title>
+
+    <section id="pci-resource-example">
+      <title>Full Code Example</title>
+      <para>
+        In this section, we'll finish the chip-specific constructor,
+      destructor and PCI entries. The example code is shown first,
+      below. 
+
+        <example>
+          <title>PCI Resource Managements Example</title>
+          <programlisting>
+<![CDATA[
+  struct snd_mychip {
+          snd_card_t *card;
+          struct pci_dev *pci;
+
+          unsigned long port;
+          struct resource *res_port;
+
+          int irq;
+  };
+
+  static int snd_mychip_free(mychip_t *chip)
+  {
+          // disable hardware here if any
+          // (not implemented in this document)
+
+          // release the i/o port
+          if (chip->res_port) {
+                  release_resource(chip->res_port);
+                  kfree_nocheck(chip->res_port);
+          }
+          // release the irq
+          if (chip->irq >= 0)
+                  free_irq(chip->irq, (void *)chip);
+          // release the data
+          snd_magic_kfree(chip);
+          return 0;
+  }
+
+  // chip-specific constructor
+  static int __devinit snd_mychip_create(snd_card_t *card,
+                                         struct pci_dev *pci,
+                                         mychip_t **rchip)
+  {
+          mychip_t *chip;
+          int err;
+          static snd_device_ops_t ops = {
+                 .dev_free = snd_mychip_dev_free,
+          };
+
+          *rchip = NULL;
+
+          // check PCI availability (28bit DMA)
+          if ((err = pci_enable_device(pci)) < 0)
+                  return err;
+          if (!pci_dma_supported(pci, 0x0fffffff)) {
+                  printk(KERN_ERR "error to set 28bit mask DMA\n");
+                  return -ENXIO;
+          }
+          pci_set_dma_mask(pci, 0x0fffffff);
+
+          chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL);
+          if (chip == NULL)
+                  return -ENOMEM;
+
+          // initialize the stuff
+          chip->card = card;
+          chip->pci = pci;
+          chip->irq = -1;
+
+          // (1) PCI resource allocation
+          chip->port = pci_resource_start(pci, 0);
+          if ((chip->res_port = request_region(chip->port, 8,
+                                                 "My Chip")) == NULL) { 
+                  snd_mychip_free(chip);
+                  printk(KERN_ERR "cannot allocate the port\n");
+                  return -EBUSY;
+          }
+          if (request_irq(pci->irq, snd_mychip_interrupt,
+                          SA_INTERRUPT|SA_SHIRQ, "My Chip",
+                          (void *)chip)) {
+                  snd_mychip_free(chip);
+                  printk(KERN_ERR "cannot grab irq\n");
+                  return -EBUSY;
+          }
+          chip->irq = pci->irq;
+
+          // (2) initialization of the chip hardware
+          //     (not implemented in this document)
+
+          if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+                                    chip, &ops)) < 0) {
+                  snd_mychip_free(chip);
+                  return err;
+          }
+          *rchip = chip;
+          return 0;
+  }        
+
+  // PCI IDs
+  static struct pci_device_id snd_mychip_ids[] __devinitdata = {
+          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+          ....
+          { 0, }
+  };
+  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
+
+  // pci_driver definition
+  static struct pci_driver driver = {
+          .name = "My Own Chip",
+          .id_table = snd_mychip_ids,
+          .probe = snd_mychip_probe,
+          .remove = __devexit_p(snd_mychip_remove),
+  };
+
+  // initialization of the module
+  static int __init alsa_card_mychip_init(void)
+  {
+          int err;
+
+          if ((err = pci_module_init(&driver)) < 0) {
+  #ifdef MODULE
+                  printk(KERN_ERR "My chip soundcard not found "
+                                  "or device busy\n");
+  #endif
+                  return err;
+          }
+          return 0;
+  }
+
+  // clean up the module
+  static void __exit alsa_card_mychip_exit(void)
+  {
+          pci_unregister_driver(&driver);
+  }
+
+  module_init(alsa_card_mychip_init)
+  module_exit(alsa_card_mychip_exit)
+
+  EXPORT_NO_SYMBOLS; /* for old kernels only */
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pci-resource-some-haftas">
+      <title>Some Hafta's</title>
+      <para>
+        The allocation of PCI resources is done in the
+      <function>probe()</function> function, and usually an extra
+      <function>xxx_create()</function> function is written for this
+      purpose. 
+      </para>
+
+      <para>
+        In the case of PCI devices, you have to call at first
+      <function>pci_enable_device()</function> function before
+      allocating resources. Also, you need to set the proper PCI DMA
+      mask to limit the accessed i/o range. In some cases, you might
+      need to call <function>pci_set_master()</function> function,
+      too. 
+      </para>
+
+      <para>
+        Suppose the 28bit mask, and the code to be added would be like:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if ((err = pci_enable_device(pci)) < 0)
+          return err;
+  if (!pci_dma_supported(pci, 0x0fffffff)) {
+          printk(KERN_ERR "error to set 28bit mask DMA\n");
+          return -ENXIO;
+  }
+  pci_set_dma_mask(pci, 0x0fffffff);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="pci-resource-resource-allocation">
+      <title>Resource Allocation</title>
+      <para>
+        The allocation of ports and irqs are done via standard kernel
+      functions. Unlike ALSA ver.0.5.x., there are no helpers for
+      that. And these resources must be released in the destructor
+      function (see below). Also, on ALSA 0.9.x, you don't need
+      allocate (pseudo-)DMA for PCI like 0.5.x. 
+      </para>
+
+      <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
+        following fields: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_mychip {
+          snd_card_t *card;
+
+          unsigned long port;
+          struct resource *res_port;
+
+          int irq;
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        For an i/o port (and also a memory region), you need to have
+      the resource pointer for the standard resource management. For
+      an irq, you have to keep only the irq number (integer). But you
+      need to initialize this number as -1 before actual allocation,
+      since irq 0 is valid. The port address and its resource pointer
+      can be initialized as null by
+      <function>snd_magic_kcalloc()</function> automatically, so you
+      don't have to take care of it. 
+      </para>
+
+      <para>
+        The allocation of an i/o port is done like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  chip->port = pci_resource_start(pci, 0);
+  if ((chip->res_port = request_region(chip->port, 8,
+                                       "My Chip")) == NULL) { 
+          printk(KERN_ERR "cannot allocate the port 0x%lx\n",
+                 chip->port);
+          snd_mychip_free(chip);
+          return -EBUSY;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        It will reserve the i/o port region of 8 bytes of the given
+      PCI device. The returned value, chip-&gt;res_port, is allocated
+      via <function>kmalloc()</function> by
+      <function>request_region()</function>. The pointer must be
+      released via <function>kfree()</function>, but there is some
+      problem regarding this. This issue will be explained more below.
+      </para>
+
+      <para>
+        The allocation of an interrupt source is done like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (request_irq(pci->irq, snd_mychip_interrupt,
+                  SA_INTERRUPT|SA_SHIRQ, "My Chip",
+                  (void *)chip)) {
+          snd_mychip_free(chip);
+          printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+          return -EBUSY;
+  }
+  chip->irq = pci->irq;
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <function>snd_mychip_interrupt()</function> is the
+      interrupt handler defined <link
+      linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>.
+      Note that chip-&gt;irq should be defined
+      only when <function>request_irq()</function> succeeded.
+      </para>
+
+      <para>
+      On the PCI bus, the interrupts can be shared. Thus,
+      <constant>SA_SHIRQ</constant> is given as the interrupt flag of
+      <function>request_irq()</function>. 
+      </para>
+
+      <para>
+        The last argument of <function>request_irq()</function> is the
+      data pointer passed to the interrupt handler. Usually, the
+      chip-specific record is used for that, but you can use what you
+      like, too. 
+      </para>
+
+      <para>
+        I won't define the detail of the interrupt handler at this
+        point, but at least its appearance can be explained now. The
+        interrupt handler looks usually like the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_mychip_interrupt(int irq, void *dev_id,
+                                   struct pt_regs *regs)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          ....
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+        Again the magic-cast is used here to get the correct pointer
+      from the second argument. 
+      </para>
+
+      <para>
+        Now let's write the corresponding destructor for the resources
+      above. The role of destructor is simple: disable the hardware
+      (if already activated) and release the resources. So far, we
+      have no hardware part, so the disabling is not written here. 
+      </para>
+
+      <para>
+        For releasing the resources, <quote>check-and-release</quote>
+        method is a safer way. For the i/o port, do like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (chip->res_port) {
+          release_resource(chip->res_port);
+          kfree_nocheck(chip->res_port);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        As you can see, the i/o resource pointer is also to be freed
+      via <function>kfree_nocheck()</function> after
+      <function>release_resource()</function> is called. You
+      cannot use <function>kfree()</function> here, because on ALSA,
+      <function>kfree()</function> may be a wrapper to its own
+      allocator with the memory debugging. Since the resource pointer
+      is allocated externally outside the ALSA, it must be released
+      via the native
+      <function>kfree()</function>.
+      <function>kfree_nocheck()</function> is used for that; it calls
+      the native <function>kfree()</function> without wrapper. 
+      </para>
+
+      <para>
+        For releasing the interrupt, do like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (chip->irq >= 0)
+          free_irq(chip->irq, (void *)chip);
+]]>
+          </programlisting>
+        </informalexample>
+
+        And finally, release the chip-specific record.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_magic_kfree(chip);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The chip instance is freed via
+      <function>snd_magic_kfree()</function>. Please use this function
+      for the object allocated by
+      <function>snd_magic_kmalloc()</function>. If you free it with
+      <function>kfree()</function>, it won't work properly and will
+      result in the memory leak. Also, again, remember that you cannot
+      set <parameter>__devexit</parameter> prefix for this destructor. 
+      </para>
+
+      <para>
+      We didn't implement the hardware-disabling part in the above.
+      If you need to do this, please note that the destructor may be
+      called even before the initialization of the chip is completed.
+      It would be better to have a flag to skip the hardware-disabling
+      if the hardware was not initialized yet.
+      </para>
+
+      <para>
+      When the chip-data is assigned to the card using
+      <function>snd_device_new()</function> with
+      <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is 
+      called at the last.  that is, it is assured that all other
+      components like PCMs and controls have been already released.
+      You don't have to call stopping PCMs, etc. explicitly, but just
+      stop the hardware in the low-level.
+      </para>
+
+      <para>
+        The management of a memory-mapped region is almost as same as
+        the management of an i/o port. You'll need three fields like
+        the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_mychip {
+          ....
+          unsigned long iobase_phys;
+          unsigned long iobase_virt;
+          struct resource *res_iobase;
+  };
+]]>
+          </programlisting>
+        </informalexample>
+
+        and the allocation would be (assuming its size is 512 bytes):
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  chip->iobase_phys = pci_resource_start(pci, 0);
+  chip->iobase_virt = (unsigned long)
+                      ioremap_nocache(chip->iobase_phys, 512);
+  if ((chip->res_port = request_mem_region(chip->port, 512,
+                                           "My Chip")) == NULL) {
+          printk(KERN_ERR "cannot allocate the memory region\n");
+          snd_mychip_free(chip);
+          return -EBUSY;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+        
+        and the corresponding destructor would be:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int snd_mychip_free(mychip_t *chip)
+  {
+          ....
+          if (chip->iobase_virt)
+                  iounmap((void *)chip->iobase_virt);
+          if (chip->res_iobase) {
+                  release_resource(chip->res_iobase);
+                  kfree_nocheck(chip->res_iobase);
+          }
+          ....
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+    </section>
+
+    <section id="pci-resource-entries">
+      <title>PCI Entries</title>
+      <para>
+        So far, so good. Let's finish the rest of missing PCI
+      stuffs. At first, we need a
+      <structname>pci_device_id</structname> table for this
+      chipset. It's a table of PCI vendor/device ID number, and some
+      masks. 
+      </para>
+
+      <para>
+        For example,
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct pci_device_id snd_mychip_ids[] __devinitdata = {
+          { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+          ....
+          { 0, }
+  };
+  MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first and second fields of
+      <structname>pci_device_id</structname> struct are the vendor and
+      device IDs. If you have nothing special to filter the matching
+      devices, you can use the rest of fields like above. The last
+      field of <structname>pci_device_id</structname> struct is a
+      private data for this entry. You can specify any value here, for
+      example, to tell the type of different operations per each
+      device IDs. Such an example is found in intel8x0 driver. 
+      </para>
+
+      <para>
+        The last entry of this list is the terminator. You must
+      specify this all-zero entry. 
+      </para>
+
+      <para>
+        Then, prepare the <structname>pci_driver</structname> record:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static struct pci_driver driver = {
+          .name = "My Own Chip",
+          .id_table = snd_mychip_ids,
+          .probe = snd_mychip_probe,
+          .remove = __devexit_p(snd_mychip_remove),
+  };
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The <structfield>probe</structfield> and
+      <structfield>remove</structfield> functions are what we already
+      defined in 
+      the previous sections. The <structfield>remove</structfield> should
+      be defined with 
+      <function>__devexit_p()</function> macro, so that it's not
+      defined for built-in (and non-hot-pluggable) case. The
+      <structfield>name</structfield> 
+      field is the name string of this device. Note that you must not
+      use a slash <quote>/</quote> in this string. 
+      </para>
+
+      <para>
+        And at last, the module entries:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int __init alsa_card_mychip_init(void)
+  {
+          int err;
+
+          if ((err = pci_module_init(&driver)) < 0) {
+  #ifdef MODULE
+                  printk(KERN_ERR "My chip soundcard not found"
+                                  " or device busy\n");
+  #endif
+                  return err;
+          }
+          return 0;
+  }
+
+  static void __exit alsa_card_mychip_exit(void)
+  {
+          pci_unregister_driver(&driver);
+  }
+
+  module_init(alsa_card_mychip_init)
+  module_exit(alsa_card_mychip_exit)
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Note that these module entries are tagged with
+      <parameter>__init</parameter> and 
+      <parameter>__exit</parameter> prefixes, not
+      <parameter>__devinit</parameter> nor
+      <parameter>__devexit</parameter>.
+      </para>
+
+      <para>
+        Oh, one thing was forgotten. If you have no exported symbols,
+        you need to declare it on 2.2 or 2.4 kernels (on 2.5 kernels
+        it's not necessary, though).
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  EXPORT_NO_SYMBOLS;
+]]>
+          </programlisting>
+        </informalexample>
+
+        That's all!
+      </para>
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- PCM Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="pcm-interface">
+    <title>PCM Interface</title>
+
+    <section id="pcm-interface-general">
+      <title>General</title>
+      <para>
+        The PCM middle layer of ALSA is quite powerful and it is only
+      necessary for each driver to implement the low-level functions
+      to access its hardware.
+      </para>
+
+      <para>
+        For accessing to the PCM layer, you need to include
+      <filename>&lt;sound/pcm.h&gt;</filename> above all. In addition,
+      <filename>&lt;sound/pcm_params.h&gt;</filename> might be needed
+      if you access to some functions related with hw_param. 
+      </para>
+
+      <para>
+        Each card device can have up to four pcm instances. A pcm
+      instance corresponds to a pcm device file. The limitation of
+      number of instances comes only from the available bit size of
+      the linux's device number. Once when 64bit device number is
+      used, we'll have more available pcm instances. 
+      </para>
+
+      <para>
+        A pcm instance consists of pcm playback and capture streams,
+      and each pcm stream consists of one or more pcm substreams. Some
+      soundcard supports the multiple-playback function. For example,
+      emu10k1 has a PCM playback of 32 stereo substreams. In this case, at
+      each open, a free substream is (usually) automatically chosen
+      and opened. Meanwhile, when only one substream exists and it was
+      already opened, the succeeding open will result in the blocking
+      or the error with <constant>EAGAIN</constant> according to the
+      file open mode. But you don't have to know the detail in your
+      driver. The PCM middle layer will take all such jobs. 
+      </para>
+    </section>
+
+    <section id="pcm-interface-example">
+      <title>Full Code Example</title>
+      <para>
+      The example code below does not include any hardware access
+      routines but shows only the skeleton, how to build up the PCM
+      interfaces.
+
+        <example>
+          <title>PCM Example Code</title>
+          <programlisting>
+<![CDATA[
+  #include <sound/pcm.h>
+  ....
+
+  #define chip_t mychip_t
+  ....
+
+  /* hardware definition */
+  static snd_pcm_hardware_t snd_mychip_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,
+          .rates =            SNDRV_PCM_RATE_8000_48000,
+          .rate_min =         8000,
+          .rate_max =         48000,
+          .channels_min =     2,
+          .channels_max =     2,
+          .buffer_bytes_max = 32768,
+          .period_bytes_min = 4096,
+          .period_bytes_max = 32768,
+          .periods_min =      1,
+          .periods_max =      1024,
+  };
+
+  /* open callback */
+  static int snd_mychip_pcm_open(snd_pcm_substream_t *subs)
+  {
+          mychip_t *chip = snd_pcm_substream_chip(substream);
+          snd_pcm_runtime_t *runtime = substream->runtime;
+
+          runtime->hw = snd_mychip_playback_hw;
+          // more hardware-initialization will be done here
+          return 0;
+  }
+
+  /* close callback */
+  static int snd_mychip_pcm_close(snd_pcm_substream_t *substream)
+  {
+          mychip_t *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)
+  {
+          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)
+  {
+          return snd_pcm_lib_free_pages(substream);
+  }
+
+  /* prepare callback */
+  static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream)
+  {
+          mychip_t *chip = snd_pcm_substream_chip(substream);
+          snd_pcm_runtime_t *runtime = substream->runtime;
+
+          // set up the hardware with the current configuration
+          // for example...
+          mychip_set_sample_format(chip, runtime->format);
+          mychip_set_sample_rate(chip, runtime->rate);
+          mychip_set_channels(chip, runtime->channels);
+          mychip_set_dma_setup(chip, runtime->dma_area,
+                               chip->buffer_size,
+                               chip->period_size);
+          return 0;
+  }
+
+  /* trigger callback */
+  static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream,
+                                    int cmd)
+  {
+          switch (cmd) {
+          case SNDRV_PCM_TRIGGER_START:
+                  // do something to start the PCM engine
+                  break;
+          case SNDRV_PCM_TRIGGER_STOP:
+                  // do something to stop the PCM engine
+                  break;
+          default:
+                  return -EINVAL;
+          }
+  }
+
+  /* pointer callback */
+  static snd_pcm_uframes_t
+  snd_mychip_pcm_pointer(snd_pcm_substream_t *substream)
+  {
+          mychip_t *chip = snd_pcm_substream_chip(substream);
+          unsigned int current_ptr;
+
+          // get the current hardware pointer
+          current_ptr = mychip_get_hw_pointer(chip);
+          return current_ptr;
+  }
+
+  /* operators */
+  static snd_pcm_ops_t snd_mychip_playback_ops = {
+          .open =        snd_mychip_playback_open,
+          .close =       snd_mychip_playback_close,
+          .ioctl =       snd_pcm_lib_ioctl,
+          .hw_params =   snd_mychip_pcm_hw_params,
+          .hw_free =     snd_mychip_pcm_hw_free,
+          .prepare =     snd_mychip_pcm_prepare,
+          .trigger =     snd_mychip_pcm_trigger,
+          .pointer =     snd_mychip_pcm_pointer,
+  };
+
+  /*
+   *  definitions of capture are omitted here...
+   */
+
+  /* create a pcm device */
+  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  {
+          snd_pcm_t *pcm;
+          int err;
+
+          if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
+                                 &pcm)) < 0) 
+                  return err;
+          pcm->private_data = chip;
+          strcpy(pcm->name, "My Chip");
+          chip->pcm = pcm;
+          /* set operators */
+          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                          &snd_mychip_playback_ops);
+          snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                          &snd_mychip_capture_ops);
+          /* pre-allocation of buffers */
+          snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm,
+                                                    64*1024, 64*1024);
+          return 0;
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pcm-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        A pcm instance is allocated <function>snd_pcm_new()</function>
+      function. It would be better to create a constructor for pcm,
+      namely, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  {
+          snd_pcm_t *pcm;
+          int err;
+
+          if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
+                                 &pcm)) < 0) 
+                  return err;
+          pcm->private_data = chip;
+          strcpy(pcm->name, "My Chip");
+          chip->pcm = pcm;
+	  ....
+          return 0;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The <function>snd_pcm_new()</function> function takes the four
+      arguments. The first argument is the card pointer to which this
+      pcm is assigned, and the second is the ID string. 
+      </para>
+
+      <para>
+        The third argument (<parameter>index</parameter>, 0 in the
+      above) is the index of this new pcm. It begins from zero. When
+      you will create more than one pcm instances, specify the
+      different numbers in this argument. For example,
+      <parameter>index</parameter> = 1 for the second PCM device.  
+      </para>
+
+      <para>
+        The fourth and fifth arguments are the number of substreams
+      for playback and capture, respectively. Here both 1 are given in
+      the above example.  When no playback or no capture is available,
+      pass 0 to the corresponding argument.
+      </para>
+
+      <para>
+        If a chip supports multiple playbacks or captures, you can
+      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
+      as follows: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_substream_t *substream;
+  int index = substream->number;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        After the pcm is created, you need to set operators for each
+        pcm stream. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                  &snd_mychip_playback_ops);
+  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                  &snd_mychip_capture_ops);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The operators are defined typically like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static snd_pcm_ops_t snd_mychip_playback_ops = {
+          .open =        snd_mychip_pcm_open,
+          .close =       snd_mychip_pcm_close,
+          .ioctl =       snd_pcm_lib_ioctl,
+          .hw_params =   snd_mychip_pcm_hw_params,
+          .hw_free =     snd_mychip_pcm_hw_free,
+          .prepare =     snd_mychip_pcm_prepare,
+          .trigger =     snd_mychip_pcm_trigger,
+          .pointer =     snd_mychip_pcm_pointer,
+  };
+]]>
+          </programlisting>
+        </informalexample>
+
+        Each of callbacks is explained in the subsection 
+        <link linkend="pcm-interface-operators"><citetitle>
+        Operators</citetitle></link>.
+      </para>
+
+      <para>
+        After setting the operators, most likely you'd like to
+        pre-allocate the buffer. For the pre-allocation, simply call
+        the following: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm,
+                                          64*1024, 64*1024);
+]]>
+          </programlisting>
+        </informalexample>
+
+        It will allocate up to 64kB buffer as default. The details of
+      buffer management will be described in the later section <link
+      linkend="buffer-and-memory"><citetitle>Buffer and Memory
+      Management</citetitle></link>. 
+      </para>
+
+      <para>
+        Additionally, you can set some extra information for this pcm
+        in pcm-&gt;info_flags.
+        The available values are defined as
+        <constant>SNDRV_PCM_INFO_XXX</constant> in
+        <filename>&lt;sound/asound.h&gt;</filename>, which is used for
+        the hardware definition (described later). When your soundchip
+        supports only half-duplex, specify like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+    <section id="pcm-interface-destructor">
+      <title>... And the Destructor?</title>
+      <para>
+        The destructor for a pcm instance is not always
+      necessary. Since the pcm device will be released by the middle
+      layer code automatically, you don't have to call destructor
+      explicitly.
+      </para>
+
+      <para>
+        The destructor would be necessary when you created some
+        special records internally and need to release them. In such a
+        case, set the destructor function to
+        pcm-&gt;private_free: 
+
+        <example>
+          <title>PCM Instance with a Destructor</title>
+          <programlisting>
+<![CDATA[
+  static void mychip_pcm_free(snd_pcm_t *pcm)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                    pcm->private_data, return);
+          // 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)
+  {
+          snd_pcm_t *pcm;
+          ....
+          // allocate your own data
+          chip->my_private_pcm_data = kmalloc(...);
+          // set the destructor
+          pcm->private_data = chip;
+          pcm->private_free = mychip_pcm_free;
+          ....
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="pcm-interface-operators">
+      <title>Operators</title>
+      <para>
+        OK, now let me explain the detail of each pcm callback
+      (<parameter>ops</parameter>). In general, every callback must
+      return 0 if successful, or a negative number with the error
+      number such as <constant>-EINVAL</constant> at any
+      error. 
+      </para>
+
+      <para>
+        The callback function takes at least the argument with
+        <type>snd_pcm_substream_t</type> pointer. For retrieving the
+        chip record from the given substream instance, you can use the
+        following macro. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  #define chip_t mychip_t
+
+  int xxx() {
+          mychip_t *chip = snd_pcm_substream_chip(substream);
+          ....
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        It's expanded with a magic-cast, so the cast-error is
+      automatically checked. You should define <type>chip_t</type> at
+      the beginning of the code, since this will be referred in many
+      places of pcm and control interfaces. 
+      </para>
+
+      <section id="pcm-interface-operators-open-callback">
+        <title>open callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(snd_pcm_substream_t *subs);
+]]>
+            </programlisting>
+          </informalexample>
+
+          This is called when a pcm substream is opened.
+        </para>
+
+        <para>
+          At least, here you have to initialize the runtime hardware
+          record. Typically, this is done by like this: 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  {
+          mychip_t *chip = snd_pcm_substream_chip(substream);
+          snd_pcm_runtime_t *runtime = substream->runtime;
+
+          runtime->hw = snd_mychip_playback_hw;
+          return 0;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          where <parameter>snd_mychip_playback_hw</parameter> is the
+          pre-defined hardware record.
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static snd_pcm_hardware_t snd_mychip_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,
+          .rates =            SNDRV_PCM_RATE_8000_48000,
+          .rate_min =         8000,
+          .rate_max =         48000,
+          .channels_min =     2,
+          .channels_max =     2,
+          .buffer_bytes_max = 32768,
+          .period_bytes_min = 4096,
+          .period_bytes_max = 32768,
+          .periods_min =      1,
+          .periods_max =      1024,
+  };
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The similar struct exists on ALSA 0.5.x driver, so you can
+        guess the values if you already wrote a driver. 
+        </para>
+
+        <para>
+          The <structfield>info</structfield> field contains the type and
+        capabilities of this pcm. The bit flags are defined in
+        <filename>&lt;sound/asound.h&gt;</filename> as
+        <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you
+        have to specify whether the mmap is supported and which
+        interleaved format is supported.
+        When the mmap is supported, add
+        <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the
+        hardware supports the interleaved or the non-interleaved
+        format, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or
+        <constant>SNDRV_PCM_INFO_NONINTERLEAVED</constant> flag must
+        be set, respectively. If both are supported, you can set both,
+        too. 
+        </para>
+
+        <para>
+          In the above example, <constant>MMAP_VALID</constant> and
+        <constant>BLOCK_TRANSFER</constant> are specified for OSS mmap
+        mode. Usually both are set. Of course,
+        <constant>MMAP_VALID</constant> is set only if the mmap is
+        really supported. 
+        </para>
+
+        <para>
+          The other possible flags are
+        <constant>SNDRV_PCM_INFO_PAUSE</constant> and
+        <constant>SNDRV_PCM_INFO_RESUME</constant>. The
+        <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. 
+        </para>
+
+        <para>
+          <structfield>formats</structfield> field contains the bit-flags
+        of supported formats (<constant>SNDRV_PCM_FMTBIT_XXX</constant>).
+        If the hardware supports more than one format, give all or'ed
+        bits.  In the example above, the signed 16bit little-endian
+        format is specified.
+        </para>
+
+        <para>
+        <structfield>rates</structfield> field contains the bit-flags of
+        supported rates (<constant>SNDRV_PCM_RATE_XXX</constant>).
+        When the chip supports continuous rates, pass
+        <constant>CONTINUOUS</constant> bit additionally.
+        The pre-defined rate bits are only for typical rates. If your
+        chip supports unconventional rates, you need to add
+        <constant>KNOT</constant> bit and set up the
+        constraint manually (explained later).
+        </para>
+
+        <para>
+        There have been many changes of terminology between
+        ALSA 0.5.x and 0.9.x.
+        On the ALSA 0.9.x world, <quote>period</quote> means what is
+        known as <quote>fragment</quote> in the OSS.  It's the least
+        size of (a part of) the buffer to generate an interrupt.
+        </para>
+
+        <para>
+        Now, taking the new terminology into account, the other fields
+        are self-explanatory (I hope). Please note that here, both 
+        min/max buffer and period sizes are specified in bytes. 
+        </para>
+
+        <para>
+          Some drivers allocate the private instance for each pcm
+          substream. It can be stored in
+          <constant>substream->runtime-&gt;private_data</constant>.
+          Since it's a void pointer, you 
+          should use magic-kmalloc and magic-cast for such an object. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  {
+          my_pcm_data_t *data;
+          ....
+          data = snd_magic_kmalloc(my_pcm_data_t, 0, GFP_KERNEL);
+          substream->runtime->private_data = data;
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          The allocated object must be released in the close callback below.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-close-callback">
+        <title>close callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_close(snd_pcm_substream_t *subs);
+]]>
+            </programlisting>
+          </informalexample>
+
+          Obviously, this is called when a pcm substream is closed.
+        </para>
+
+        <para>
+          Any private instance for a pcm substream allocated in the
+          open callback will be released here. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_close(snd_pcm_substream_t *substream)
+  {
+          ....
+          snd_magic_kfree(substream->runtime->private_data);
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-ioctl-callback">
+        <title>ioctl callback</title>
+        <para>
+          This is used for any special action to pcm ioctls. But
+        usually you can pass a generic ioctl callback, 
+        <function>snd_pcm_lib_ioctl</function>.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-hw-params-callback">
+        <title>hw_params callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_hw_params(snd_pcm_substream_t * substream,
+                               snd_pcm_hw_params_t * hw_params);
+]]>
+            </programlisting>
+          </informalexample>
+
+          This and <structfield>hw_free</structfield> callbacks exist
+        only on ALSA 0.9.x. 
+        </para>
+
+        <para>
+          This is called when the hardware parameter
+        (<structfield>hw_params</structfield>) is set
+        up by the application, 
+        that is, once when the buffer size, the period size, the
+        format, etc. are defined for the pcm substream. 
+        </para>
+
+        <para>
+          Many hardware set-up should be done in this callback,
+        including the allocation of buffers. 
+        </para>
+
+        <para>
+          Parameters to be initialized are retrieved by
+          <function>params_xxx()</function> macros. For allocating a
+          buffer, you can call a helper function, 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+]]>
+            </programlisting>
+          </informalexample>
+
+          <function>snd_pcm_lib_malloc_pages()</function> is available
+	  only when the DMA buffers have been pre-allocated.
+	  See the section <link
+	  linkend="buffer-and-memory-buffer-types"><citetitle>
+	  Buffer Types</citetitle></link> for more details.
+        </para>
+
+        <para>
+          Note that this and <structfield>prepare</structfield> callbacks
+        may be called multiple times per initialization.
+        For example, the OSS emulation may
+        call these callbacks at each change via its ioctl. 
+        </para>
+
+        <para>
+          Thus, you need to take care not to allocate the same buffers
+        many times, which will lead to memory leak!  Calling the
+        helper function above many times is OK. It will release the
+        previous buffer automatically when it was already allocated. 
+        </para>
+
+        <para>
+          Another note is that this callback is non-atomic
+        (schedulable). This is important, because the
+        <structfield>prepare</structfield> callback 
+        is atomic (non-schedulable). That is, mutex or any
+        schedule-related functions are available only in
+        <structfield>hw_params</structfield> callback. 
+	Please see the subsection
+	<link linkend="pcm-interface-atomicity"><citetitle>
+	Atomicity</citetitle></link> for details.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-hw-free-callback">
+        <title>hw_free callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_hw_free(snd_pcm_substream_t * substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This is called to release the resources allocated via
+          <structfield>hw_params</structfield>. For example, releasing the
+          buffer via 
+          <function>snd_pcm_lib_malloc_pages()</function> is done by
+          calling the following: 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  snd_pcm_lib_free_pages(substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This callback may be called multiple times, too.
+          Keep track whether the resource was already released. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-prepare-callback">
+       <title>prepare callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_prepare(snd_pcm_substream_t * substream);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          This callback is called when the pcm is
+        <quote>prepared</quote>. You can set the format type, sample
+        rate, etc. here. The difference from
+        <structfield>hw_params</structfield> is that the 
+        <structfield>prepare</structfield> callback will be called at each
+        time 
+        <function>snd_pcm_prepare()</function> is called, i.e. when
+        recovered after underruns, etc. 
+        </para>
+
+        <para>
+          As mentioned above, this callback is atomic.
+        </para>
+
+        <para>
+          In this and the following callbacks, you can refer to the
+        values via the runtime record,
+        substream-&gt;runtime.
+        For example, to get the current
+        rate, format or channels, access to
+        runtime-&gt;rate,
+        runtime-&gt;format or
+        runtime-&gt;channels, respectively. 
+        The physical address of the allocated buffer is set to
+	runtime-&gt;dma_area.  The buffer and period sizes are
+	in runtime-&gt;buffer_size and runtime-&gt;period_size,
+	respectively.
+        </para>
+
+        <para>
+          Note that the period and the buffer sizes are stored in
+          <quote>frames</quote>. In the ALSA world, 1 frame = channels
+          * samples-size. For conversion between frames and bytes, you
+          can use the helper functions,
+          <function>frames_to_bytes()</function> and
+          <function>bytes_to_frames()</function>. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  period_bytes = frames_to_bytes(runtime, runtime->period_size);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          Be careful that this callback will be called many times at
+        each set up, too. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-trigger-callback">
+        <title>trigger callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd);
+]]>
+            </programlisting>
+          </informalexample>
+
+          This is called when the pcm is started, stopped or paused.
+        </para>
+
+        <para>
+          Which action is specified in the second argument,
+          <constant>SNDRV_PCM_TRIGGER_XXX</constant> in
+          <filename>&lt;sound/pcm.h&gt;</filename>. At least,
+          <constant>START</constant> and <constant>STOP</constant>
+          commands must be defined in this callback. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  switch (cmd) {
+  case SNDRV_PCM_TRIGGER_START:
+          // do something to start the PCM engine
+          break;
+  case SNDRV_PCM_TRIGGER_STOP:
+          // do something to stop the PCM engine
+          break;
+  default:
+          return -EINVAL;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+
+        <para>
+          When the pcm supports the pause operation (given in info
+        field of the hardware table), <constant>PAUSE_PUSE</constant>
+        and <constant>PAUSE_RELEASE</constant> commands must be
+        handled here, too. The former is the command to pause the pcm,
+        and the latter to restart the pcm again. 
+        </para>
+
+        <para>
+          When the pcm supports the suspend/resume operation,
+        <constant>SUSPEND</constant> and <constant>RESUME</constant>
+        commands must be handled, too. Obviously it does suspend and
+        resume of the pcm substream. Usually, the
+        <constant>SUSPEND</constant> is identical with
+        <constant>STOP</constant> command and the
+        <constant>RESUME</constant> is identical with
+        <constant>START</constant> command.
+        </para>
+
+        <para>
+          This callback is also atomic.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-pointer-callback">
+        <title>pointer callback</title>
+        <para>
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream)
+]]>
+            </programlisting>
+          </informalexample>
+
+          This callback is called when the PCM middle layer inquires
+        the current hardware position on the buffer. The position must
+        be returned in frames (which was in bytes on ALSA 0.5.x),
+        ranged from 0 to buffer_size - 1.
+        </para>
+
+        <para>
+          This is called usually from the buffer-update routine in the
+        pcm middle layer, which is invoked when
+        <function>snd_pcm_period_elapsed()</function> is called in the
+        interrupt routine. Then the pcm middle layer updates the
+        position and calculates the available space, and wakes up the
+        sleeping poll threads, etc. 
+        </para>
+
+        <para>
+          This callback is also atomic.
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-copy-silence">
+        <title>copy and silence callbacks</title>
+        <para>
+          These callbacks are not mandatory, and can be omitted in
+        most cases. These callbacks are used when the hardware buffer
+        cannot be on the normal memory space. Some chips have their
+        own buffer on the hardware which is not mappable. In such a
+        case, you have to transfer the data manually from the memory
+        buffer to the hardware buffer. Or, if the buffer is
+        non-contiguous on both physical and virtual memory spaces,
+        these callbacks must be defined, too. 
+        </para>
+
+        <para>
+          If these two callbacks are defined, copy and set-silence
+        operations are done by them. The detailed will be described in
+        the later section <link
+        linkend="buffer-and-memory"><citetitle>Buffer and Memory
+        Management</citetitle></link>. 
+        </para>
+      </section>
+
+      <section id="pcm-interface-operators-page-callback">
+        <title>page callback</title>
+
+        <para>
+          This callback is also not mandatory. This callback is used
+        mainly for the non-contiguous buffer. The mmap calls this
+        callback to get the page address. Some examples will be
+        explained in the later section <link
+        linkend="buffer-and-memory"><citetitle>Buffer and Memory
+        Management</citetitle></link>, too. 
+        </para>
+      </section>
+    </section>
+
+    <section id="pcm-interface-interrupt-handler">
+      <title>Interrupt Handler</title>
+      <para>
+        The rest of pcm stuff is the PCM interrupt handler. The
+      role of PCM interrupt handler in the sound driver is to update
+      the buffer position and to tell the PCM middle layer when the
+      buffer position goes across the prescribed period size. To
+      inform this, call <function>snd_pcm_period_elapsed()</function>
+      function. 
+      </para>
+
+      <para>
+        There are several types of sound chips to generate the interrupts.
+      </para>
+
+      <section id="pcm-interface-interrupt-handler-boundary">
+        <title>Interrupts at the period (fragment) boundary</title>
+        <para>
+          This is the most frequently found type:  the hardware
+        generates an interrupt at each period boundary.
+	In this case, you can call
+        <function>snd_pcm_period_elapsed()</function> at each 
+        interrupt. 
+        </para>
+
+        <para>
+          <function>snd_pcm_period_elapsed()</function> takes the
+        substream pointer as its argument. Thus, you need to keep the
+        substream pointer accessible from the chip instance. For
+        example, define substream field in the chip record to hold the
+        current running substream pointer, and set the pointer value
+        at open callback (and reset at close callback). 
+        </para>
+
+        <para>
+          If you aquire a spinlock in the interrupt handler, and the
+        lock is used in other pcm callbacks, too, then you have to
+        release the lock before calling
+        <function>snd_pcm_period_elapsed()</function>, because
+        <function>snd_pcm_period_elapsed()</function> calls other pcm
+        callbacks inside. 
+        </para>
+
+        <para>
+          A typical coding would be like:
+
+          <example>
+	    <title>Interrupt Handler Case #1</title>
+            <programlisting>
+<![CDATA[
+  static void snd_mychip_interrupt(int irq, void *dev_id,
+                                   struct pt_regs *regs)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          spin_lock(&chip->lock);
+          ....
+          if (pcm_irq_invoked(chip)) {
+                  // call updater, unlock before it
+                  spin_unlock(&chip->lock);
+                  snd_pcm_period_elapsed(chip->substream);
+                  spin_lock(&chip->lock);
+          }
+          ....
+          spin_unlock(&chip->lock);
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+      </section>
+
+      <section id="pcm-interface-interrupt-handler-timer">
+        <title>High-frequent timer interrupts</title>
+        <para>
+	This is the case when the hardware doesn't generate interrupts
+        at the period boundary but do timer-interrupts at the fixed
+        timer rate (e.g. es1968 or ymfpci drivers). 
+        In this case, you need to check the current hardware
+        position and accumulates the processed sample length at each
+        interrupt.  When the accumulated size overcomes the period
+        size, call 
+        <function>snd_pcm_period_elapsed()</function> and reset the
+        accumulator. 
+        </para>
+
+        <para>
+          A typical coding would be like the following.
+
+          <example>
+	    <title>Interrupt Handler Case #2</title>
+            <programlisting>
+<![CDATA[
+  static void snd_mychip_interrupt(int irq, void *dev_id,
+                                   struct pt_regs *regs)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
+          spin_lock(&chip->lock);
+          ....
+          if (pcm_irq_invoked(chip)) {
+                  unsigned int last_ptr, size;
+                  // get the current hardware pointer (in frames)
+                  last_ptr = get_hw_ptr(chip);
+                  // calculate the processed frames since the
+                  // last update
+                  if (last_ptr < chip->last_ptr)
+                          size = runtime->buffer_size + last_ptr 
+                                   - chip->last_ptr; 
+                  else
+                          size = last_ptr - chip->last_ptr;
+                  // remember the last updated point
+                  chip->last_ptr = last_ptr;
+                  // accumulate the size
+                  chip->size += size;
+                  // over the period boundary?
+                  if (chip->size >= runtime->period_size) {
+                          // reset the accumulator
+                          chip->size %= runtime->period_size;
+                          // call updater
+                          spin_unlock(&chip->lock);
+                          snd_pcm_period_elapsed(substream);
+                          spin_lock(&chip->lock);
+                  }
+          }
+          ....
+          spin_unlock(&chip->lock);
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+      </section>
+
+      <section id="pcm-interface-interrupt-handler-both">
+        <title>On calling <function>snd_pcm_period_elapsed()</function></title>
+        <para>
+          In both cases, even if more than one period are elapsed, you
+        don't have to call
+        <function>snd_pcm_period_elapsed()</function> many times. Call
+        only once. And the pcm layer will check the current hardware
+        pointer and update to the latest status. 
+        </para>
+      </section>
+    </section>
+
+    <section id="pcm-interface-atomicity">
+      <title>Atomicity</title>
+      <para>
+      One of the most important (and thus difficult to debug) problem
+      on the kernel programming is the race condition.
+      On linux kernel, usually it's solved via spin-locks or
+      semaphores.  In general, if the race condition may
+      happen in the interrupt handler, it's handled as atomic, and you
+      have to use spinlock for protecting the critical session.  If it
+      never happens in the interrupt and it may take relatively long
+      time, you should use semaphore.
+      </para>
+
+      <para>
+      As already seen, some pcm callbacks are atomic and some are
+      not.  For example, <parameter>hw_params</parameter> callback is
+      non-atomic, while <parameter>prepare</parameter> callback is
+      atomic.  This means, the latter is called already in a spinlock
+      held by the PCM middle layer. Please take this atomicity into
+      account when you use a spinlock or a semaphore in the callbacks.
+      </para>
+
+      <para>
+      In the atomic callbacks, you cannot use functions which may call
+      <function>schedule</function> or go to
+      <function>sleep</function>.  The semaphore and mutex do sleep,
+      and hence they cannot be used inside the atomic callbacks
+      (e.g. <parameter>prepare</parameter> callback).
+      For taking a certain delay in such a callback, please use
+      <function>udelay()</function> or <function>mdelay()</function>.
+      </para>
+
+      <para>
+      This atomicity problem appears also in the initialization of the
+      hardware when the power-management is supported.  The functions
+      for suspending and resuming the chip must be atomic, i.e. no
+      mutex nor sleep can be used in them.
+      </para>
+
+    </section>
+    <section id="pcm-interface-constraints">
+      <title>Constraints</title>
+      <para>
+        If your chip supports unconventional sample rates, or only the
+      limited samples, you need to set a constraint for the
+      condition. 
+      </para>
+
+      <para>
+        For example, in order to restrict the sample rates in the some
+        supported values, use
+	<function>snd_pcm_hw_constraint_list()</function>.
+	You need to call this function in the open callback.
+
+        <example>
+	  <title>Example of Hardware Constraints</title>
+          <programlisting>
+<![CDATA[
+  static unsigned int rates[] =
+          {4000, 10000, 22050, 44100};
+  static snd_pcm_hw_constraint_list_t constraints_rates = {
+          .count = sizeof(rates) / sizeof(rates[0]),
+          .list = rates,
+          .mask = 0,
+  };
+
+  static int snd_mychip_pcm_open(snd_pcm_substream_t *substream)
+  {
+          int err;
+          ....
+          err = snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                           SNDRV_PCM_HW_PARAM_RATE,
+                                           &constraints_rates);
+          if (err < 0)
+                  return err;
+          ....
+  }
+]]>
+          </programlisting>
+        </example>
+      </para>
+
+      <para>
+        There are many different constraints. You can even define your
+      own constraint rules. I won't explain the details here, rather I
+      would like to say, <quote>Luke, use the source.</quote>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Control Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="control-interface">
+    <title>Control Interface</title>
+
+    <section id="control-interface-general">
+      <title>General</title>
+      <para>
+        The control interface is used widely for many switches,
+      sliders, etc. which are accessed from the user-space. Its most
+      important use is the mixer interface. In other words, on ALSA
+      0.9.x, all the mixer stuff is implemented on the control kernel
+      API (while there was an independent mixer kernel API on 0.5.x). 
+      </para>
+
+      <para>
+        ALSA has a well-defined AC97 control module. If your chip
+      supports only the AC97 and nothing else, you can skip this
+      section. 
+      </para>
+
+      <para>
+        The control API is defined in
+      <filename>&lt;sound/control.h&gt;</filename>.
+      Include this file if you add your own controls.
+      </para>
+    </section>
+
+    <section id="control-interface-definition">
+      <title>Definition of Controls</title>
+      <para>
+        For creating a new control, you need to define the three
+      callbacks: <structfield>info</structfield>,
+      <structfield>get</structfield> and
+      <structfield>put</structfield>. Then, define a
+      <type>snd_kcontrol_new_t</type> record, such as: 
+
+        <example>
+	  <title>Definition of a Control</title>
+          <programlisting>
+<![CDATA[
+  static snd_kcontrol_new_t my_control __devinitdata = {
+          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+          .name = "PCM Playback Switch",
+          .index = 0,
+          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+          .private_values = 0xffff,
+          .info = my_control_info,
+          .get = my_control_get,
+          .put = my_control_put
+  };
+]]>
+          </programlisting>
+        </example>
+      </para>
+
+      <para>
+        Most likely the control is created via
+      <function>snd_ctl_new1()</function>, and in such a case, you can
+      add <parameter>__devinitdata</parameter> prefix to the
+      definition like above. 
+      </para>
+
+      <para>
+        The <structfield>iface</structfield> field specifies the type of
+      the control,
+      <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are
+      <constant>MIXER</constant>, <constant>PCM</constant>,
+      <constant>CARD</constant>, etc.
+      </para>
+
+      <para>
+        The <structfield>name</structfield> is the name identifier
+      string. On ALSA 0.9.x, the control name is very important,
+      because its role is classified from its name. There are
+      pre-defined standard control names. The details are described in
+      the subsection
+      <link linkend="control-interface-control-names"><citetitle>
+      Control Names</citetitle></link>.
+      </para>
+
+      <para>
+        The <structfield>index</structfield> field holds the index number
+      of this control. If there are several different controls with
+      the same name, they can be distinguished by the index
+      number. This is the case when 
+      several codecs exist on the card. If the index is zero, you can
+      omit the definition above. 
+      </para>
+
+      <para>
+        The <structfield>access</structfield> field contains the access
+      type of this control. Give the combination of bit masks,
+      <constant>SNDRV_CTL_ELEM_ACCESS_XXX</constant>, there.
+      The detailed will be explained in the subsection
+      <link linkend="control-interface-access-flags"><citetitle>
+      Access Flags</citetitle></link>.
+      </para>
+
+      <para>
+        The <structfield>private_values</structfield> field contains
+      an arbitrary long integer value for this record. When using
+      generic <structfield>info</structfield>,
+      <structfield>get</structfield> and
+      <structfield>put</structfield> callbacks, you can pass a value 
+      through this field. If several small numbers are necessary, you can
+      combine them in bitwise. Or, it's possible to give a pointer
+      (casted to unsigned long) of some record to this field, too. 
+      </para>
+
+      <para>
+        The other three are
+	<link linkend="control-interface-callbacks"><citetitle>
+	callback functions</citetitle></link>.
+      </para>
+    </section>
+
+    <section id="control-interface-control-names">
+      <title>Control Names</title>
+      <para>
+        There are some standards for defining the control names. A
+      control is usually defined from the three parts as
+      <quote>SOURCE DIRECTION FUNCTION</quote>. 
+      </para>
+
+      <para>
+        The first, <constant>SOURCE</constant>, specifies the source
+      of the control, and is a string such as <quote>Master</quote>,
+      <quote>PCM</quote>, <quote>CD</quote> or
+      <quote>Line</quote>. There are many pre-defined sources. 
+      </para>
+
+      <para>
+        The second, <constant>DIRECTION</constant>, is one of the
+      following strings according to the direction of the control:
+      <quote>Playback</quote>, <quote>Capture</quote>, <quote>Bypass
+      Playback</quote> and <quote>Bypass Capture</quote>. Or, it can
+      be omitted, meaning both playback and capture directions. 
+      </para>
+
+      <para>
+        The third, <constant>FUNCTION</constant>, is one of the
+      following strings according to the function of the control:
+      <quote>Switch</quote>, <quote>Volume</quote> and
+      <quote>Route</quote>. 
+      </para>
+
+      <para>
+        The example of control names are, thus, <quote>Master Capture
+      Switch</quote> or <quote>PCM Playback Volume</quote>. 
+      </para>
+
+      <para>
+        There are some exceptions:
+      </para>
+
+      <section id="control-interface-control-names-global">
+        <title>Global capture and playback</title>
+        <para>
+          <quote>Capture Source</quote>, <quote>Capture Switch</quote>
+        and <quote>Capture Volume</quote> are used for the global
+        capture (input) source, switch and volume. Similarly,
+        <quote>Playback Switch</quote> and <quote>Playback
+        Volume</quote> are used for the global output gain switch and
+        volume. 
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-tone">
+        <title>Tone-controls</title>
+        <para>
+          tone-control switch and volumes are specified like
+        <quote>Tone Control - XXX</quote>, e.g. <quote>Tone Control -
+        Switch</quote>, <quote>Tone Control - Bass</quote>,
+        <quote>Tone Control - Center</quote>.  
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-3d">
+        <title>3D controls</title>
+        <para>
+          3D-control switches and volumes are specified like <quote>3D
+        Control - XXX</quote>, e.g. <quote>3D Control -
+        Switch</quote>, <quote>3D Control - Center</quote>, <quote>3D
+        Control - Space</quote>. 
+        </para>
+      </section>
+
+      <section id="control-interface-control-names-mic">
+        <title>Mic boost</title>
+        <para>
+          Mic-boost switch is set as <quote>Mic Boost</quote> or
+        <quote>Mic Boost (6dB)</quote>. 
+        </para>
+
+        <para>
+          More precise information can be found in
+        <filename>alsa-kernel/Documentation/ControlNames.txt</filename>.
+        </para>
+      </section>
+    </section>
+
+    <section id="control-interface-access-flags">
+      <title>Access Flags</title>
+
+      <para>
+      The access flag is the bit-flags which specifies the access type
+      of the given control.  The default access type is
+      <constant>SNDRV_CTL_ELEM_ACCESS_READWRITE</constant>, 
+      which means both read and write are allowed to this control.
+      When the access flag is omitted (i.e. = 0), it is
+      regarded as <constant>READWRITE</constant> access as default. 
+      </para>
+
+      <para>
+      When the control is read-only, pass
+      <constant>SNDRV_CTL_ELEM_ACCESS_READ</constant> instead.
+      In this case, you don't have to define
+      <structfield>put</structfield> callback.
+      Similarly, when the control is write-only (although it's a rare
+      case), you can use <constant>WRITE</constant> flag instead, and
+      you don't need <structfield>get</structfield> callback.
+      </para>
+
+      <para>
+      If the control value changes frequently (e.g. the VU meter),
+      <constant>VOLATILE</constant> flag should be given.  This means
+      that the control may be changed without
+      <link linkend="control-interface-change-notification"><citetitle>
+      notification</citetitle></link>.  Applications should poll such
+      a control constantly.
+      </para>
+
+      <para>
+      When the control is inactive, set
+      <constant>INACTIVE</constant> flag, too.
+      There are <constant>LOCK</constant> and
+      <constant>OWNER</constant> flags for changing the write
+      permissions.
+      </para>
+
+    </section>
+
+    <section id="control-interface-callbacks">
+      <title>Callbacks</title>
+
+      <section id="control-interface-callbacks-info">
+        <title>info callback</title>
+        <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>
+        object. For example, for a boolean control with a single
+        element will be: 
+
+          <example>
+	    <title>Example of info callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
+                          snd_ctl_elem_info_t *uinfo)
+  {
+          uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+          uinfo->count = 1;
+          uinfo->value.integer.min = 0;
+          uinfo->value.integer.max = 1;
+          return 0;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+
+        <para>
+          The <structfield>type</structfield> field specifies the type
+        of the control. There are <constant>BOOLEAN</constant>,
+        <constant>INTEGER</constant>, <constant>ENUMERATED</constant>,
+        <constant>BYTES</constant>, <constant>IEC958</constant> and
+        <constant>INTEGER64</constant>. The
+        <structfield>count</structfield> field specifies the 
+        number of elements in this control. For example, a stereo
+        volume would have count = 2. The
+        <structfield>value</structfield> field is a union, and 
+        the values stored are depending on the type. The boolean and
+        integer are identical. 
+        </para>
+
+        <para>
+          The enumerated type is a bit different from others.  You'll
+          need to set the string for the currently given item index. 
+
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
+  static char *texts[4] = {
+          "First", "Second", "Third", "Fourth"
+  };
+  uinfo->value.enumerated.items = 4;
+  if (uinfo->value.enumerated.item > 3)
+          uinfo->value.enumerated.item = 3;
+  strcpy(uinfo->value.enumerated.name,
+         texts[uinfo->value.enumerated.item]);
+]]>
+            </programlisting>
+          </informalexample>
+        </para>
+      </section>
+
+      <section id="control-interface-callbacks-get">
+        <title>get callback</title>
+
+        <para>
+          This callback is used to read the current value of the
+        control and to return to the user-space. 
+        </para>
+
+        <para>
+          For example,
+
+          <example>
+	    <title>Example of get callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_get(snd_kcontrol_t *kcontrol,
+                           snd_ctl_elem_value_t *ucontrol)
+  {
+          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          ucontrol->value.integer.value[0] = get_some_value(chip);
+          return 0;
+  }
+]]>
+            </programlisting>
+          </example>
+        </para>
+
+        <para>
+          Here, the chip instance is retrieved via
+        <function>snd_kcontrol_chip()</function> macro.  This macro
+        converts from kcontrol-&gt;private_data to the type defined by
+        <type>chip_t</type>. The
+        kcontrol-&gt;private_data field is 
+        given as the argument of <function>snd_ctl_new()</function>
+        (see the later subsection
+        <link linkend="control-interface-constructor"><citetitle>Constructor</citetitle></link>).
+        </para>
+
+        <para>
+	The <structfield>value</structfield> field is depending on
+        the type of control as well as on info callback.  For example,
+	the sb driver uses this field to store the register offset,
+        the bit-shift and the bit-mask.  The
+        <structfield>private_value</structfield> is set like
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  .private_value = reg | (shift << 16) | (mask << 24)
+]]>
+            </programlisting>
+          </informalexample>
+	and is retrieved in callbacks like
+          <informalexample>
+            <programlisting>
+<![CDATA[
+  static int snd_sbmixer_get_single(snd_kcontrol_t *kcontrol,
+                                    snd_ctl_elem_value_t *ucontrol)
+  {
+          int reg = kcontrol->private_value & 0xff;
+          int shift = (kcontrol->private_value >> 16) & 0xff;
+          int mask = (kcontrol->private_value >> 24) & 0xff;
+          ....
+  }
+]]>
+            </programlisting>
+          </informalexample>
+	</para>
+
+	<para>
+	In <structfield>get</structfield> callback, you have to fill all the elements if the
+        control has more than one elements,
+        i.e. <structfield>count</structfield> &gt; 1.
+	In the example above, we filled only one element
+        (<structfield>value.integer.value[0]</structfield>) since it's
+        assumed as <structfield>count</structfield> = 1.
+        </para>
+      </section>
+
+      <section id="control-interface-callbacks-put">
+        <title>put callback</title>
+
+        <para>
+          This callback is used to write a value from the user-space.
+        </para>
+
+        <para>
+          For example,
+
+          <example>
+	    <title>Example of put callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_put(snd_kcontrol_t *kcontrol,
+                           snd_ctl_elem_value_t *ucontrol)
+  {
+          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          int changed = 0;
+          if (chip->current_value !=
+               ucontrol->value.integer.value[0]) {
+                  change_current_value(chip,
+                              ucontrol->value.integer.value[0]);
+                  changed = 1;
+          }
+          return changed;
+  }
+]]>
+            </programlisting>
+          </example>
+
+          As seen above, you have to return 1 if the value is
+        changed. If the value is not changed, return 0 instead. 
+	If any fatal error happens, return a negative error code as
+        usual.
+        </para>
+
+        <para>
+	Like <structfield>get</structfield> callback,
+	when the control has more than one elements,
+	all elemehts must be evaluated in this callback, too.
+        </para>
+      </section>
+
+      <section id="control-interface-callbacks-all">
+        <title>Callbacks are not atomic</title>
+        <para>
+          All these three callbacks are basically not atomic.
+        </para>
+      </section>
+    </section>
+
+    <section id="control-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        When everything is ready, finally we can create a new
+      control. For creating a control, there are two functions to be
+      called, <function>snd_ctl_new1()</function> and
+      <function>snd_ctl_add()</function>. 
+      </para>
+
+      <para>
+        In the simplest way, you can do like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if ((err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip))) < 0)
+          return err;
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <parameter>my_control</parameter> is the
+      <type>snd_kcontrol_new_t</type> object defined above, and chip
+      is the object pointer to be passed to
+      kcontrol-&gt;private_data 
+      which can be referred in callbacks. 
+      </para>
+
+      <para>
+        <function>snd_ctl_new1()</function> allocates a new
+      <type>snd_kcontrol_t</type> 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
+      control component to the card. 
+      </para>
+    </section>
+
+    <section id="control-interface-change-notification">
+      <title>Change Notification</title>
+      <para>
+        If you need to change and update a control in the interrupt
+      routine, you can call <function>snd_ctl_notify()</function>. For
+      example, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
+]]>
+          </programlisting>
+        </informalexample>
+
+        This function takes the card pointer, the event-mask, and the
+      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>
+      to be notified.
+      You can find some examples in <filename>es1938.c</filename> or
+      <filename>es1968.c</filename> for hardware volume interrupts. 
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- API for AC97 Codec  -->
+<!-- ****************************************************** -->
+  <chapter id="api-ac97">
+    <title>API for AC97 Codec</title>
+
+    <section>
+      <title>General</title>
+      <para>
+        The ALSA AC97 codec layer is a well-defined one, and you don't
+      have to write many codes to control it. Only low-level control
+      routines are necessary. The AC97 codec API is defined in
+      <filename>&lt;sound/ac97_codec.h&gt;</filename>. 
+      </para>
+    </section>
+
+    <section id="api-ac97-example">
+      <title>Full Code Example</title>
+      <para>
+          <example>
+	    <title>Example of AC97 Interface</title>
+            <programlisting>
+<![CDATA[
+  struct snd_mychip {
+          ....
+          ac97_t *ac97;
+          ....
+  };
+
+  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+                                             unsigned short reg)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                   ac97->private_data, return 0);
+          ....
+          // read a register value here from the codec
+          return the_register_value;
+  }
+
+  static void snd_mychip_ac97_write(ac97_t *ac97,
+                                   unsigned short reg, unsigned short val)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                   ac97->private_data, return 0);
+          ....
+          // write the given register value to the codec
+  }
+
+  static int snd_mychip_ac97(mychip_t *chip)
+  {
+          ac97_t ac97;
+
+          memset(&ac97, 0, sizeof(ac97));
+          ac97.write = snd_mychip_ac97_write;
+          ac97.read = snd_mychip_ac97_read;
+          ac97.private_data = chip;
+          return snd_ac97_mixer(card, &ac97, &chip->ac97);
+  }
+
+]]>
+          </programlisting>
+        </example>
+      </para>
+    </section>
+
+    <section id="api-ac97-constructor">
+      <title>Constructor</title>
+      <para>
+        For creating an ac97 instance, call
+      <function>snd_ac97_mixer()</function> with an <type>ac97_t</type>
+      record, in which the callbacks and the private_data is set.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  ac97_t ac97;
+  int err;
+
+  memset(&ac97, 0, sizeof(ac97));
+  ac97.write = snd_mychip_ac97_write;
+  ac97.read = snd_mychip_ac97_read;
+  ac97.private_data = chip;
+  snd_ac97_mixer(card, &ac97, &chip->ac97);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where chip-&gt;ac97 is the pointer of a newly created
+        <type>ac97_t</type> instance.
+        This instance is not necessarily stored in the chip
+	record.  When you need to change the register values from the
+        driver, or need the suspend/resume of ac97 codecs, keep this
+        pointer to pass to the corresponding functions.
+      </para>
+    </section>
+
+    <section id="api-ac97-callbacks">
+      <title>Callbacks</title>
+      <para>
+        The standard callbacks are <structfield>read</structfield> and
+      <structfield>write</structfield>. Obviously they 
+      correspond to the functions for read and write accesses to the
+      hardware low-level codes. 
+      </para>
+
+      <para>
+        The <structfield>read</structfield> callback returns the
+        register value specified in the argument. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+                                             unsigned short reg)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                                   ac97->private_data, return 0);
+          ....
+          return the_register_value;
+  }
+]]>
+          </programlisting>
+        </informalexample>
+
+        Here, the chip can be cast from ac97-&gt;private_data.
+      </para>
+
+      <para>
+        Meanwhile, the <structfield>write</structfield> callback is
+        used to set the register value. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void snd_mychip_ac97_write(ac97_t *ac97,
+                       unsigned short reg, unsigned short val)
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      These callbacks are non-atomic like the callbacks of control API
+      unless they are called during suspend/resume phase.
+      </para>
+
+      <para>
+        There are also other callbacks:
+      <structfield>reset</structfield>,
+      <structfield>wait</structfield> and
+      <structfield>init</structfield>. 
+      </para>
+
+      <para>
+        The <structfield>reset</structfield> callback is used to reset
+      the codec. If the chip requires a special way of reset, you can
+      define this callback. 
+      This callback must be atomic when it's called in the suspend
+      mode.
+      </para>
+
+      <para>
+        The <structfield>wait</structfield> callback is used for a
+      certain wait at the standard initialization of the codec. If the
+      chip requires the extra wait-time, define this callback. 
+      This callback is always non-atomic, because it's never called
+      in the resume mode.
+      </para>
+
+      <para>
+        The <structfield>init</structfield> callback is used for
+      additional initialization of the codec.  This callback is called
+      after the reset, and should be atomic in the resume mode.
+      </para>
+    </section>
+
+    <section id="api-ac97-updating-registers">
+      <title>Updating Registers in The Driver</title>
+      <para>
+        If you need to access to the codec from the driver, you can
+      call the following functions:
+      <function>snd_ac97_write()</function>,
+      <function>snd_ac97_read()</function>,
+      <function>snd_ac97_update()</function> and
+      <function>snd_ac97_update_bits()</function>. 
+      </para>
+
+      <para>
+        Both <function>snd_ac97_write()</function> and
+        <function>snd_ac97_update()</function> functions are used to
+        set a value to the given register
+        (<constant>AC97_XXX</constant>). The different between them is
+        that <function>snd_ac97_update()</function> doesn't write a
+        value if the given value has been already set, while
+        <function>snd_ac97_write()</function> always rewrites the
+        value. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_write(ac97, AC97_MASTER, 0x8080);
+  snd_ac97_update(ac97, AC97_MASTER, 0x8080);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        <function>snd_ac97_read()</function> is used to read the value
+        of the given register. For example, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  value = snd_ac97_read(ac97, AC97_MASTER);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        <function>snd_ac97_update_bits()</function> is used to update
+        some bits of the given register.  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_update_bits(ac97, reg, mask, value);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Also, there is a function to change the sample rate (of a
+        certain register such as
+        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA is
+        supported by the codec:
+        <function>snd_ac97_set_rate()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The following registers are available for setting the rate:
+      <constant>AC97_PCM_MIC_ADC_RATE</constant>,
+      <constant>AC97_PCM_FRONT_DAC_RATE</constant>,
+      <constant>AC97_PCM_LR_ADC_RATE</constant>,
+      <constant>AC97_SPDIF</constant>. When the
+      <constant>AC97_SPDIF</constant> is specified, the register is
+      not really changed but the corresponding IEC958 status bits will
+      be updated. 
+      </para>
+    </section>
+
+    <section id="api-ac97-clock-adjustment">
+      <title>Clock Adjustment</title>
+      <para>
+        On some chip, the clock of the codec isn't 48000 but using a
+      PCI clock (to save a quartz!). In this case, change the field
+      ac97-&gt;clock to the corresponding
+      value. For example, intel8x0 
+      and es1968 drivers have the auto-measurement function of the
+      clock. 
+      </para>
+    </section>
+
+    <section id="api-ac97-proc-files">
+      <title>Proc Files</title>
+      <para>
+        The ALSA AC97 interface will create a proc file such as
+      <filename>/proc/asound/card0/ac97#0</filename> and
+      <filename>ac97#0regs</filename>. You can refer to these files to
+      see the current status and registers of the codec. 
+      </para>
+    </section>
+
+    <section id="api-ac97-multiple-codecs">
+      <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
+      ac97.num=1 or greater. The <structfield>num</structfield> field
+      specifies the codec 
+      number. 
+      </para>
+
+      <para>
+        If you have set up multiple codecs, you need to either write
+      different callbacks for each codec or check
+      ac97-&gt;num in the 
+      callback routines. 
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- MIDI (MPU401-UART) Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="midi-interface">
+    <title>MIDI (MPU401-UART) Interface</title>
+
+    <section id="midi-interface-general">
+      <title>General</title>
+      <para>
+        Many soundcards have built-in MIDI (MPU401-UART)
+      interfaces. When the soundcard supports the standard MPU401-UART
+      interface, most likely you can use the ALSA MPU401-UART API. The
+      MPU401-UART API is defined in
+      <filename>&lt;sound/mpu401.h&gt;</filename>. 
+      </para>
+
+      <para>
+        Some soundchips have similar but a little bit different
+      implementation of mpu401 stuff. For example, emu10k1 has its own
+      mpu401 routines. 
+      </para>
+
+      <para>
+        In this document, I won't explain the rawmidi interface API,
+      which is the basis of MPU401-UART implementation. 
+      </para>
+
+      <para>
+        For details, please check the source,
+      <filename>core/rawmidi.c</filename>, and examples such as
+      <filename>drivers/mpu401/mpu401_uart.c</filename> or
+      <filename>usb/usbmidi.c</filename>. 
+      </para>
+    </section>
+
+    <section id="midi-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        For creating a rawmidi object, call
+      <function>snd_mpu401_uart_new()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_rawmidi_t *rmidi;
+  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
+                      irq, irq_flags, &rmidi);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the card pointer, and the second is the
+      index of this component. You can create up to 8 rawmidi
+      devices. 
+      </para>
+
+      <para>
+        The third argument is the type of the hardware,
+      <constant>MPU401_HW_XXX</constant>. If it's not a special one,
+      you can use <constant>MPU401_HW_MPU401</constant>. 
+      </para>
+
+      <para>
+        The 4th argument is the i/o port address. Many
+      backward-compatible MPU401 has an i/o port such as 0x330. Or, it
+      might be a part of its own PCI i/o region. It depends on the
+      chip design. 
+      </para>
+
+      <para>
+        When the i/o port address above is a part of the PCI i/o
+      region, the MPU401 i/o port might have been already allocated
+      (reserved) by the driver itself. In such a case, pass non-zero
+      to the 5th argument
+      (<parameter>integrated</parameter>). Otherwise, pass 0 to it,
+      and 
+      the mpu401-uart layer will allocate the i/o ports by itself. 
+      </para>
+
+      <para>
+        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
+        returned explicitly by
+        <function>snd_mpu401_uart_new()</function>. You need to cast
+        rmidi-&gt;private_data to
+        <type>mpu401_t</type> explicitly, 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  mpu401_t *mpu;
+  mpu = snd_magic_cast(mpu401_t, rmidi->private_data, );
+]]>
+          </programlisting>
+        </informalexample>
+
+        and reset the cport as you like:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  mpu->cport = my_own_control_port;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The 6th argument specifies the irq number for UART. If the irq
+      is already allocated, pass 0 to the 7th argument
+      (<parameter>irq_flags</parameter>). Otherwise, pass the flags
+      for irq allocation 
+      (<constant>SA_XXX</constant> bits) to it, and the irq will be
+      reserved by the mpu401-uart layer. If the card doesn't generates
+      UART interrupts, pass -1 as the irq number. Then a timer
+      interrupt will be invoked for polling. 
+      </para>
+    </section>
+
+    <section id="midi-interface-interrupt-handler">
+      <title>Interrupt Handler</title>
+      <para>
+        When the interrupt is allocated in
+      <function>snd_mpu401_uart_new()</function>, the private
+      interrupt handler is used, hence you don't have to do nothing
+      else than creating the mpu401 stuff. Otherwise, you have to call
+      <function>snd_mpu401_uart_interrupt()</function> explicitly when
+      a UART interrupt is invoked and checked in your own interrupt
+      handler.  
+      </para>
+
+      <para>
+        In this case, you need to pass the private_data of the
+        returned rawmidi object from
+        <function>snd_mpu401_uart_new()</function> as the second
+        argument of <function>snd_mpu401_uart_interrupt()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Miscellaneous Devices  -->
+<!-- ****************************************************** -->
+  <chapter id="misc-devices">
+    <title>Miscellaneous Devices</title>
+
+    <section id="misc-devices-opl3">
+      <title>FM OPL3</title>
+      <para>
+        The FM OPL3 is still used on many chips (mainly for backward
+      compatibility). ALSA has a nice OPL3 FM control layer, too. The
+      OPL3 API is defined in
+      <filename>&lt;sound/opl3.h&gt;</filename>. 
+      </para>
+
+      <para>
+        FM registers can be directly accessed through direct-FM API,
+      defined in <filename>&lt;sound/asound_fm.h&gt;</filename>. In
+      ALSA native mode, FM registers are accessed through
+      Hardware-Dependant Device direct-FM extension API, whereas in
+      OSS compatible mode, FM registers can be accessed with OSS
+      direct-FM compatible API on <filename>/dev/dmfmX</filename> device. 
+      </para>
+
+      <para>
+        For creating the OPL3 component, you have two functions to
+        call. The first one is a constructor for <type>opl3_t</type>
+        instance. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  opl3_t *opl3;
+  snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
+                  integrated, &opl3);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the card pointer, the second one is the
+      left port address, and the third is the right port address. In
+      most cases, the right port is placed at the left port + 2. 
+      </para>
+
+      <para>
+        The fourth argument is the hardware type.
+      </para>
+
+      <para>
+        When the left and right ports have been already allocated by
+      the card driver, pass non-zero to the fifth argument
+      (<parameter>integrated</parameter>). Otherwise, opl3 module will
+      allocate the specified ports by itself. 
+      </para>
+
+      <para>
+        If this function returns successfully with 0, then create a
+        hwdep device for this opl3. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_hwdep_t *opl3hwdep;
+  snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the <type>opl3_t</type> instance you
+      created, and the second is the index number, usually 0. 
+      </para>
+
+      <para>
+        The third argument is the index-offset for the sequencer
+      client assigned to the OPL3 port. When there is an MPU401-UART,
+      give 1 for here (UART always takes 0). 
+      </para>
+    </section>
+
+    <section id="misc-devices-hardware-dependent">
+      <title>Hardware-Dependent Devices</title>
+      <para>
+        Some chips need the access from the user-space for special
+      controls or for loading the micro code. In such a case, you can
+      create a hwdep (hardware-dependent) device. The hwdep API is
+      defined in <filename>&lt;sound/hwdep.h&gt;</filename>. You can
+      find examples in opl3 driver or
+      <filename>isa/sb/sb16_csp.c</filename>. 
+      </para>
+
+      <para>
+        Creation of the <type>hwdep</type> instance is done via
+        <function>snd_hwdep_new()</function>. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_hwdep_t *hw;
+  snd_hwdep_new(card, "My HWDEP", 0, &hw);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where the third argument is the index number.
+      </para>
+
+      <para>
+        You can then pass any pointer value to the
+        <parameter>private_data</parameter>. Again, it should be a
+        magic-allocated record, so that the cast can be checked more
+        safely. If you assign a private data, you should define the
+        destructor, too. The destructor function is set to
+        <structfield>private_free</structfield> field.  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  mydata_t *p = snd_magic_kmalloc(mydata_t, 0, GFP_KERNEL);
+  hw->private_data = p;
+  hw->private_free = mydata_free;
+]]>
+          </programlisting>
+        </informalexample>
+
+        and the implementation of destructor would be:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static void mydata_free(snd_hwdep_t *hw)
+  {
+          mydata_t *p = snd_magic_cast(mydata_csp_t,
+                                       hw->private_data, return);
+          snd_magic_kfree(p);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The arbitrary file operations can be defined for this
+        instance. The file operators are defined in
+        <parameter>ops</parameter> table. For example, assume that
+        this chip needs an ioctl. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  hw->ops.open = mydata_open;
+  hw->ops.ioctl = mydata_ioctl;
+  hw->ops.release = mydata_release;
+]]>
+          </programlisting>
+        </informalexample>
+
+        And implement the callback functions as you like.
+      </para>
+    </section>
+
+    <section id="misc-devices-IEC958">
+      <title>IEC958 (S/PDIF)</title>
+      <para>
+        Usually the controls for IEC958 devices are implemented via
+      control interface. There is a macro to compose a name string for
+      IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function>
+      defined in <filename>&lt;include/asound.h&gt;</filename>.  
+      </para>
+
+      <para>
+        There are some standard controls for IEC958 status bits. These
+      controls use the type <type>SNDRV_CTL_ELEM_TYPE_IEC958</type>,
+      and the size of element is fixed as 4 bytes array
+      (value.iec958.status[x]). For <structfield>info</structfield>
+      callback, you don't specify 
+      the value field for this type (the count field must be set,
+      though). 
+      </para>
+
+      <para>
+        <quote>IEC958 Playback Con Mask</quote> is used to return the
+      bit-mask for the IEC958 status bits of consumer mode. Similarly,
+      <quote>IEC958 Playback Pro Mask</quote> returns the bitmask for
+      professional mode. They are read-only controls, and are defined
+      as MIXER controls (iface =
+      <constant>SNDRV_CTL_ELEM_IFACE_MIXER</constant>).  
+      </para>
+
+      <para>
+        Meanwhile, <quote>IEC958 Playback Default</quote> control is
+      defined for getting and setting the current default IEC958
+      bits. Note that this one is usually defined as a PCM control
+      (iface = <constant>SNDRV_CTL_ELEM_IFACE_PCM</constant>),
+      although in some places it's defined as a MIXER control. 
+      </para>
+
+      <para>
+        In addition, you can define the control switches to
+      enable/disable or to set the raw bit mode. The implementation
+      will depend on the chip, but the control should be named as
+      <quote>IEC958 xxx</quote>, preferably using
+      <function>SNDRV_CTL_NAME_IEC958()</function> macro. 
+      </para>
+
+      <para>
+        You can find several cases, for example,
+      <filename>pci/emu10k1</filename>,
+      <filename>pci/ice1712</filename>, or
+      <filename>pci/cmipci.c</filename>.  
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Buffer and Memory Management  -->
+<!-- ****************************************************** -->
+  <chapter id="buffer-and-memory">
+    <title>Buffer and Memory Management</title>
+
+    <section id="buffer-and-memory-buffer-types">
+      <title>Buffer Types</title>
+      <para>
+        ALSA provides several different buffer allocation functions
+      depending on the bus and the architecture. All these have a
+      consistent API. The allocation of physically-contiguous pages is
+      done via 
+      <function>snd_malloc_xxx_pages()</function> function, where xxx
+      is the bus type. 
+      </para>
+
+      <para>
+        The allocation of pages with fallback is
+      <function>snd_malloc_xxx_pages_fallback()</function>. This
+      function tries to allocate the specified pages but if the pages
+      are not available, it tries to reduce the page sizes until the
+      enough space is found.
+      </para>
+
+      <para>
+      For releasing the space, call
+      <function>snd_free_xxx_pages()</function> function. 
+      </para>
+
+      <para>
+      Usually, ALSA drivers try to allocate and reserve
+       a large contiguous physical space
+       at the time the module is loaded for the later use.
+       This is called <quote>pre-allocation</quote>.
+       As already written, you can call the following function at the
+       construction of pcm instance (in the case of PCI bus). 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_preallocate_pci_pages_for_all(pci, pcm, size, max);
+]]>
+          </programlisting>
+        </informalexample>
+
+        where <parameter>size</parameter> is the byte size to be
+      pre-allocated and the <parameter>max</parameter> is the maximal
+      size to be changed via <filename>prealloc</filename> proc file.
+      The allocator will try to get as the large area as possible
+      within the given size. 
+      There are different versions of pre-allocator for different
+      buses.
+      </para>
+
+      <para>
+        Once when the buffer is pre-allocated, you can use the
+        allocator in the <structfield>hw_params</structfield> callback 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_lib_malloc_pages(substream, size);
+]]>
+          </programlisting>
+        </informalexample>
+
+        Note that you have to pre-allocate to use this function
+        (i.e. you cannot use this function for
+        <link linkend="buffer-and-memory-non-contiguous"><citetitle>
+        a scatter-gather buffer</citetitle></link>).
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-external-hardware">
+      <title>External Hardware Buffers</title>
+      <para>
+        Some chips have their own hardware buffers and the DMA
+      transfer from the host memory is not available. In such a case,
+      you need to either 1) copy/set the audio data directly to the
+      external hardware buffer, or 2) make an intermediate buffer and
+      copy/set the data from it to the external hardware buffer in
+      interrupts (or in tasklets, preferably).
+      </para>
+
+      <para>
+        The first case works fine if the external hardware buffer is enough
+      large.  This method doesn't need any extra buffers and thus is
+      more effective. You need to define the
+      <structfield>copy</structfield> and
+      <structfield>silence</structfield> callbacks for 
+      the data transfer. However, there is a drawback: it cannot
+      be mmapped. The examples are GUS's GF1 PCM or emu8000's
+      wavetable PCM. 
+      </para>
+
+      <para>
+        The second case allows the mmap of the buffer, although you have
+      to handle an interrupt or a tasklet for transferring the data
+      from the intermediate buffer to the hardware buffer. You can find an
+      example in vxpocket driver. 
+      </para>
+
+      <para>
+        Another case is that the chip uses a PCI memory-map
+      region for the buffer instead of the host memory. In this case,
+      mmap is available only on certain architectures like intel. In
+      non-mmap mode, the data cannot be transferred as the normal
+      way. Thus you need to define <structfield>copy</structfield> and
+      <structfield>silence</structfield> callbacks as well 
+      as in the cases above. The examples are found in
+      <filename>rme32.c</filename> and <filename>rme96.c</filename>. 
+      </para>
+
+      <para>
+        The implementation of <structfield>copy</structfield> and
+        <structfield>silence</structfield> callbacks depends upon 
+        whether the hardware supports interleaved or non-interleaved
+        samples. The <structfield>copy</structfield> callback is
+        defined like below, a bit 
+        differently depending whether the direction is playback or
+        capture: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int playback_copy(snd_pcm_substream_t *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,
+               snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        In the case of interleaved samples, the second argument
+      (<parameter>channel</parameter>) is not used. The third argument
+      (<parameter>pos</parameter>) points the 
+      current position offset in frames. 
+      </para>
+
+      <para>
+        The meaning of the fourth argument is different between
+      playback and capture. For playback, it holds the source data
+      pointer, and for capture, it's the destination data pointer. 
+      </para>
+
+      <para>
+        The last argument is the number of frames to be copied.
+      </para>
+
+      <para>
+        What you have to do in this callback is again different
+        between playback and capture directions. In the case of
+        playback, you do: copy the given amount of data
+        (<parameter>count</parameter>) at the specified pointer
+        (<parameter>src</parameter>) to the specified offset
+        (<parameter>pos</parameter>) on the hardware buffer. When
+        coded like memcpy-like way, the copy would be like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src,
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        For the capture direction, you do: copy the given amount of
+        data (<parameter>count</parameter>) at the specified offset
+        (<parameter>pos</parameter>) on the hardware buffer to the
+        specified pointer (<parameter>dst</parameter>). 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos),
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+
+        Note that both of the position and the data amount are given
+      in frames. 
+      </para>
+
+      <para>
+        In the case of non-interleaved samples, the implementation
+      will be a bit more complicated. 
+      </para>
+
+      <para>
+        You need to check the channel argument, and if it's -1, copy
+      the whole channels. Otherwise, you have to copy only the
+      specified channel. Please check
+      <filename>isa/gus/gus_pcm.c</filename> as an example. 
+      </para>
+
+      <para>
+        The <structfield>silence</structfield> callback is also
+        implemented in a similar way. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  static int silence(snd_pcm_substream_t *substream, int channel,
+                     snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The meanings of arguments are identical with the
+      <structfield>copy</structfield> 
+      callback, although there is no <parameter>src/dst</parameter>
+      argument. In the case of interleaved samples, the channel
+      argument has no meaning, as well as on
+      <structfield>copy</structfield> callback.  
+      </para>
+
+      <para>
+        The role of <structfield>silence</structfield> callback is to
+        set the given amount 
+        (<parameter>count</parameter>) of silence data at the
+        specified offset (<parameter>pos</parameter>) on the hardware
+        buffer. Suppose that the data format is signed (that is, the
+        silent-data is 0), and the implementation using a memset-like
+        function would be like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0,
+            frames_to_bytes(runtime, count));
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        In the case of non-interleaved samples, again, the
+      implementation becomes a bit more complicated. See, for example,
+      <filename>isa/gus/gus_pcm.c</filename>. 
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-non-contiguous">
+      <title>Non-Contiguous Buffers</title>
+      <para>
+        If your hardware supports the page table like emu10k1 or the
+      buffer descriptors like via82xx, you can use the scatter-gather
+      (SG) DMA. ALSA provides an interface for handling SG-buffers.
+      The API is provided in <filename>&lt;sound/pcm_sgbuf.h&gt;</filename>. 
+      </para>
+
+      <para>
+        For creating the SG-buffer handler, call
+        <function>snd_pcm_lib_preallocate_sg_pages()</function> or
+        <function>snd_pcm_lib_preallocate_sg_pages_for_all()</function>
+	in the PCM constructor like other PCI pre-allocator.
+        You need to pass the
+        <structname>pci_dev</structname> struct pointer of the chip.
+        The <type>snd_sg_buf_t</type> instance is created as
+        substream-&gt;dma_private. You can cast
+        the pointer like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_pcm_sgbuf_t *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t,
+                              substream->dma_private, return -EINVAL);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Then call <function>snd_pcm_lib_malloc_pages()</function>
+      in <structfield>hw_params</structfield> callback
+      as well as in the case of normal PCI buffer.
+      The SG-buffer handler will allocate the non-contiguous kernel
+      pages of the given size and map them onto the virtually contiguous
+      memory.  The virtual pointer is addressed in runtime-&gt;dma_area.
+      The physical address (runtime-&gt;dma_addr) is set to zero,
+      because the buffer is physically non-contigous.
+      The physical address table is set up in sgbuf-&gt;table.
+      You can get the physical address at a certain offset via
+      <function>snd_pcm_sgbuf_get_addr()</function>. 
+      </para>
+
+      <para>
+        When a SG-handler is used, you need to set
+      <function>snd_pcm_sgbuf_ops_page</function> as
+      the <structfield>page</structfield> callback.
+      </para>
+
+      <para>
+        For releasing the data, call
+      <function>snd_pcm_lib_free_pages()</function> in the
+      <structfield>hw_free</structfield> callback as usual.
+      </para>
+    </section>
+
+    <section id="buffer-and-memory-vmalloced">
+      <title>Vmalloc'ed Buffers</title>
+      <para>
+        It's possible to use a buffer allocated via
+      <function>vmalloc</function>, for example, for an intermediate
+      buffer. Since the allocated pages are not contiguous, you need
+      to set the <structfield>page</structfield> callback to obtain
+      the physical address at every offset. 
+      </para>
+
+      <para>
+        The implementation of <structfield>page</structfield> callback
+        would be like this: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  #include <linux/vmalloc.h>
+
+  /* get the physical page pointer on the given offset */
+  static struct page *mychip_page(snd_pcm_substream_t *substream,
+                                  unsigned long offset)
+  {
+          void *pageptr = substream->runtime->dma_area + offset;
+          return vmalloc_to_page(pageptr);
+  }
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Proc Interface  -->
+<!-- ****************************************************** -->
+  <chapter id="proc-interface">
+    <title>Proc Interface</title>
+    <para>
+      ALSA provides an easy interface for procfs. The proc files are
+      very useful for debugging. I recommend you set up proc files if
+      you write a driver and want to get a running status or register
+      dumps. The API is found in
+      <filename>&lt;sound/info.h&gt;</filename>. 
+    </para>
+
+    <para>
+      For creating a proc file, call
+      <function>snd_card_proc_new()</function>. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  snd_info_entry_t *entry;
+  int err = snd_card_proc_new(card, "my-file", &entry);
+]]>
+        </programlisting>
+      </informalexample>
+
+      where the second argument specifies the proc-file name to be
+    created. The above example will create a file
+    <filename>my-file</filename> under the card directory,
+    e.g. <filename>/proc/asound/card0/my-file</filename>. 
+    </para>
+
+    <para>
+    Like other components, the proc entry created via
+    <function>snd_card_proc_new()</function> will be registered and
+    released automatically in the card registration and release
+    functions.
+    </para>
+
+    <para>
+      When the creation is successful, the function stores a new
+    instance at the pointer given in the third argument.
+    It is initialized as a text proc file for read only.  For using
+    this proc file as a read-only text file as it is, set the read
+    callback with a private data via 
+     <function>snd_info_set_text_ops()</function>.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  snd_info_set_text_ops(entry, chip, my_proc_read);
+]]>
+        </programlisting>
+      </informalexample>
+    
+    where the second argument (<parameter>chip</parameter>) is the
+    private data to be used in the callbacks and the third
+    (<parameter>my_proc_read</parameter>) is the callback function, which
+    is defined like
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void my_proc_read(snd_info_entry_t *entry,
+                           snd_info_buffer_t *buffer);
+]]>
+        </programlisting>
+      </informalexample>
+    
+    </para>
+
+    <para>
+    In the read callback, use <function>snd_iprintf()</function> for
+    output strings, which works just like normal
+    <function>printf()</function>.  For example,
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void my_proc_read(snd_info_entry_t *entry,
+                           snd_info_buffer_t *buffer)
+  {
+          chip_t *cm = snd_magic_cast(mychip_t,
+                                  entry->private_data, return);
+
+          snd_iprintf(buffer, "This is my chip!\n");
+          snd_iprintf(buffer, "Port = %ld\n", chip->port);
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+    The file permission can be changed afterwards.  As default, it's
+    set as read only for all users.  If you want to add the write
+    permission to the user (root as default), set like below:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+ entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+]]>
+        </programlisting>
+      </informalexample>
+
+    and set the write buffer size and the callback
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  entry->c.text.write_size = 256;
+  entry->c.text.write = my_proc_write;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+    The buffer size for read is set to 1024 implicitly by
+    <function>snd_info_set_text_ops()</function>.  It should suffice
+    in most cases (the size will be aligned to
+    <constant>PAGE_SIZE</constant> anyway), but if you need to handle
+    very large text files, you can set it explicitly, too.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  entry->c.text.read_size = 65536;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      For the write callback, you can use
+    <function>snd_info_get_line()</function> to get a text line, and
+    <function>snd_info_get_str()</function> to retrieve a string from
+    the line. Some examples are found in
+    <filename>core/oss/mixer_oss.c</filename>, core/oss/and
+    <filename>pcm_oss.c</filename>. 
+    </para>
+
+    <para>
+      For a raw-data proc-file, set the attributes like the following:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static struct snd_info_entry_ops my_file_io_ops = {
+          .read = my_file_io_read,
+  };
+
+  entry->content = SNDRV_INFO_CONTENT_DATA;
+  entry->private_data = chip;
+  entry->c.ops = &my_file_io_ops;
+  entry->size = 4096;
+  entry->mode = S_IFREG | S_IRUGO;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      The callback is much more complicated than the text-file
+      version. You need to use a low-level i/o functions such as
+      <function>copy_from/to_user()</function> to transfer the
+      data. Also, you have to keep tracking the file position, too. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static long my_file_io_read(snd_info_entry_t *entry,
+                              void *file_private_data,
+                              struct file *file,
+                              char *buf, long count)
+  {
+          long size = count;
+          if (file->f_pos + size > local_max_size)
+                  size = local_max_size - file->f_pos;
+          if (copy_to_user(buf, local_data + file->f_pos, size))
+                  return -EFAULT;
+          file->f_pos += size;
+          return size;
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Power Management  -->
+<!-- ****************************************************** -->
+  <chapter id="power-management">
+    <title>Power Management</title>
+    <para>
+      If the chip is supposed to work with with suspend/resume
+      functions, you need to add the power-management codes to the
+      driver. The additional codes for the power-management should be
+      <function>ifdef</function>'ed with
+      <constant>CONFIG_PM</constant>. 
+    </para>
+
+    <para>
+      Basic jobs of suspend/resume are done in
+      <structfield>suspend</structfield> and
+      <structfield>resume</structfield> callbacks of
+      <structname>pci_driver</structname> struct. Unfortunately, the
+      API of these callbacks was changed at the middle time of Linux
+      2.4.x, if you want to keep the support for older kernels, you
+      have to write two different callbacks. The example below is the
+      skeleton callbacks which just call the real suspend and resume
+      functions. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  #ifndef PCI_OLD_SUSPEND
+  static int snd_my_suspend(struct pci_dev *dev, u32 state)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                             pci_get_drvdata(dev), return -ENXIO);
+          mychip_suspend(chip);
+          return 0;
+  }
+  static int snd_my_resume(struct pci_dev *dev)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                             pci_get_drvdata(dev), return -ENXIO);
+          mychip_resume(chip);
+          return 0;
+  }
+  #else
+  static void snd_my_suspend(struct pci_dev *dev)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                             pci_get_drvdata(dev), return);
+          mychip_suspend(chip);
+  }
+  static void snd_mychip_resume(struct pci_dev *dev)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                             pci_get_drvdata(dev), return);
+          mychip_resume(chip);
+  }
+  #endif
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      The scheme of the real suspend job is as following.
+
+      <orderedlist>
+        <listitem><para>Check whether the power-state is already D3hot. If yes, skip the job.</para></listitem>
+        <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
+        <listitem><para>Save the register values if necessary.</para></listitem>
+        <listitem><para>Stop the hardware if necessary.</para></listitem>
+        <listitem><para>Set the power-state as D3hot by calling <function>snd_power_change_state()</function>.</para></listitem>
+      </orderedlist>
+    </para>
+
+    <para>
+      A typical code would be like:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void mychip_suspend(mychip_t *chip)
+  {
+          snd_card_t *card = chip->card;
+          // (1)
+          if (card->power_state == SNDRV_CTL_POWER_D3hot)
+                  return;
+          // (2)
+          snd_pcm_suspend_all(chip->pcm);
+          // (3)
+          snd_mychip_save_registers(chip);
+          // (4)
+          snd_mychip_stop_hardware(chip);
+          // (5)
+          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+    The scheme of the real resume job is as following.
+
+    <orderedlist>
+    <listitem><para>Check whether the power-state is already D0.
+    If yes, skip the job.</para></listitem>
+    <listitem><para>Enable the pci device again by calling
+    <function>pci_enable_device()</function>.</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>Set the power-state as D0 by calling
+    <function>snd_power_change_state()</function>.</para></listitem>
+    </orderedlist>
+    </para>
+
+    <para>
+    A typical code would be like:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static void mychip_resume(mychip_t *chip)
+  {
+          snd_card_t *card = chip->card;
+          // (1)
+          if (card->power_state == SNDRV_CTL_POWER_D0)
+                  return;
+          // (2)
+          pci_enable_device(chip->pci);
+          // (3)
+          snd_mychip_reinit_chip(chip);
+          // (4)
+          snd_mychip_restore_registers(chip);
+          // (5)
+          snd_ac97_resume(chip->ac97);
+          // (6)
+          snd_mychip_restart_chip(chip);
+          // (7)
+          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      In addition to the callbacks above, you should define a callback
+      for the changes via the ALSA control interface. It's defined
+      like below: 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int snd_mychip_set_power_state(snd_card_t *card,
+                                        unsigned int power_state)
+  {
+          mychip_t *chip = snd_magic_cast(mychip_t,
+                   card->power_state_private_data, return -ENXIO);
+          switch (power_state) {
+          case SNDRV_CTL_POWER_D0:
+          case SNDRV_CTL_POWER_D1:
+          case SNDRV_CTL_POWER_D2:
+                  mychip_resume(chip);
+                  break;
+          case SNDRV_CTL_POWER_D3hot:
+          case SNDRV_CTL_POWER_D3cold:
+                  mychip_suspend(chip);
+                  break;
+          default:
+                  return -EINVAL;
+          }
+          return 0;
+  }
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      OK, we have all callbacks now. Let's set up them now. In the
+      initialization of the card, add the following: 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          ....
+          snd_card_t *card;
+          ....
+  #ifdef CONFIG_PM
+          card->set_power_state = snd_mychip_set_power_state;
+          card->power_state_private_data = chip;
+  #endif
+          ....
+  }
+]]>
+        </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 you cannot call
+    <function>kmalloc()</function> with
+    <constant>GFP_KERNEL</constant> flag or
+    <function>vmalloc()</function> in the suspend callback.
+    The allocated buffer should be released in the corresponding
+    destructor.
+    </para>
+
+    <para>
+      And next, set suspend/resume callbacks to the pci_driver,
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static struct pci_driver driver = {
+          .name = "My Chip",
+          ....
+  #ifdef CONFIG_PM
+          .suspend = snd_mychip_suspend,
+          .resume = snd_mychip_resume,
+  #endif
+  };
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      Last but not least: Please keep in mind that you cannot call
+    <function>schedule()</function> during the suspend and the resume
+    callbacks. If any delay is necessary, you have to use
+    <function>mdelay()</function> or <function>udelay()</function>
+    instead of <function>schedule_timeout()</function>! 
+    Of course, semaphores cannot be used, too, which will invoke sleep
+    inside.
+    </para>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Module Parameters  -->
+<!-- ****************************************************** -->
+  <chapter id="module-parameters">
+    <title>Module Parameters</title>
+    <para>
+      There are standard module options for ALSA. At least, each
+      module should have <parameter>index</parameter>,
+      <parameter>id</parameter> and <parameter>enable</parameter>
+      options. 
+    </para>
+
+    <para>
+      If the module supports multiple cards (usually up to
+      8 = <constant>SNDRV_CARDS</constant> cards), they should be
+      arrays.  The default initial values are defined already as
+      constants for ease of programming:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  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;
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      If the module supports only a single card, they could be single
+    variables, instead.  <parameter>enable</parameter> option is not
+    always necessary in this case, but it wouldn't be so bad to have a
+    dummy option for compatibility.
+    </para>
+
+    <para>
+      The module parameters must be declared with the standard
+    <function>MODULE_PARM()</function> and
+    <function>MODULE_PARM_DESC()</function> macros. The ALSA provides
+    an additional macro, <function>MODULE_PARM_SYNTAX()</function>,
+    for describing its syntax. The strings will be written to
+    <filename>/lib/modules/XXX/modules.generic_string</filename>
+    file. 
+    </para>
+
+    <para>
+      For convenience, the typical string arguments given to
+    <function>MODULE_PARM_SYNTAX()</function> are defined in
+    <filename>&lt;sound/initval.h&gt;</filename>, such as
+    <constant>SNDRV_ID_DESC</constant> or
+    <constant>SNDRV_ENABLED</constant>.
+    </para>
+
+    <para>
+      The typical coding would be like below:
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  #define CARD_NAME "My Chip"
+
+  MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+  MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
+  MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
+  MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+  MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
+  MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
+  MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+  MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
+  MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      Also, don't forget to define the module description, classes,
+      license and devices. Especially, the recent modprobe requires to
+      define the module license as GPL, etc., otherwise the system is
+      shown as <quote>tainted</quote>. 
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  MODULE_DESCRIPTION("My Chip");
+  MODULE_CLASSES("{sound}");
+  MODULE_LICENSE("GPL");
+  MODULE_DEVICES("{{Vendor,My Chip Name}}");
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      For building the driver into kernel, you should define the
+      <function>setup()</function> function in addition, too. 
+      ALSA provides <function>get_id()</function> function to retrieve
+      a string argument from the kernel boot parameters.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  #ifndef MODULE
+
+  /* format is: snd-mychip=enable,index,id */
+
+  static int __init alsa_card_mychip_setup(char *str)
+  {
+          static unsigned __initdata nr_dev = 0;
+
+          if (nr_dev >= SNDRV_CARDS)
+                  return 0;
+          (void)(get_option(&str,&enable[nr_dev]) == 2 &&
+                 get_option(&str,&index[nr_dev]) == 2 &&
+                 get_id(&str,&id[nr_dev]) == 2);
+          nr_dev++;
+          return 1;
+  }
+
+  __setup("snd-mychip=", alsa_card_mychip_setup);
+
+  #endif /* ifndef MODULE */
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Useful Functions  -->
+<!-- ****************************************************** -->
+  <chapter id="useful-functions">
+    <title>Useful Functions</title>
+
+    <section id="useful-functions-snd-printk">
+      <title><function>snd_printk()</function> and friends</title>
+      <para>
+        ALSA provides a verbose version of
+      <function>printk()</function> function. If a kernel config
+      <constant>CONFIG_SND_VERBOSE_PRINTK</constant> is set, this
+      function prints the given message together with the file name
+      and the line of the caller. The <constant>KERN_XXX</constant>
+      prefix is processed as 
+      well as the original <function>printk()</function> does, so it's
+      recommended to add this prefix, e.g. 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_printk(KERN_ERR "Oh my, sorry, it's extremely bad!\n");
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        There are also <function>printk()</function>'s for
+      debugging. <function>snd_printd()</function> can be used for
+      general debugging purposes. If
+      <constant>CONFIG_SND_DEBUG</constant> is set, this function is
+      compiled, and works just like
+      <function>snd_printk()</function>. If the ALSA is compiled
+      without the debugging flag, it's ignored. 
+      </para>
+
+      <para>
+        <function>snd_printdd()</function> is compiled in only when
+      <constant>CONFIG_SND_DEBUG_DETECT</constant> is set. Please note
+      that <constant>DEBUG_DETECT</constant> is not set as default
+      even if you configure the alsa-driver with
+      <option>--with-debug=full</option> option. You need to give
+      explicitly <option>--with-debug=detect</option> option instead. 
+      </para>
+    </section>
+
+    <section id="useful-functions-snd-assert">
+      <title><function>snd_assert()</function></title>
+      <para>
+        <function>snd_assert()</function> macro is similar with the
+      normal <function>assert()</function> macro. For example,  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_assert(pointer != NULL, return -EINVAL);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        The first argument is the expression to evaluate, and the
+      second argument is the action if it fails. When
+      <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
+      error message such as <computeroutput>BUG? (xxx) (called from
+      yyy)</computeroutput>. When no debug flag is set, this is
+      ignored. 
+      </para>
+    </section>
+
+    <section id="useful-functions-snd-runtime-check">
+      <title><function>snd_runtime_check()</function></title>
+      <para>
+        This macro is quite similar with
+      <function>snd_assert()</function>. Unlike
+      <function>snd_assert()</function>, the expression is always
+      evaluated regardless of
+      <constant>CONFIG_SND_DEBUG</constant>. When
+      <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
+      show a message like <computeroutput>ERROR (xx) (called from
+      yyy)</computeroutput>. 
+      </para>
+    </section>
+
+    <section id="useful-functions-snd-bug">
+      <title><function>snd_BUG()</function></title>
+      <para>
+        It calls <function>snd_assert(0,)</function> -- that is, just
+      prints the error message at the point. It's useful to show that
+      a fatal error happens there. 
+      </para>
+    </section>
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Acknowledgments  -->
+<!-- ****************************************************** -->
+  <chapter id="acknowledments">
+    <title>Acknowledgments</title>
+    <para>
+      I would like to thank Phil Kerr for his help for improvement and
+      corrections of this document. 
+    </para>
+    <para>
+    Kevin Conder reformatted the original plain-text to the
+    DocBook format.
+    </para>
+  </chapter>
+
+
+</book>
diff -Nru a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/sound/alsa/OSS-Emulation.txt	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,302 @@
+		NOTES ON KERNEL OSS-EMULATION
+		=============================
+
+		Jan. 9, 2003  Takashi Iwai <tiwai@suse.de>
+
+
+Modules
+=======
+
+ALSA provides a powerful OSS emulation on the kernel.
+The OSS emulation for PCM, mixer and sequencer devices is implemented
+as add-on kernel modules, snd-pcm-oss, snd-mixer-oss and snd-seq-oss.
+When you need to access the OSS PCM, mixer or sequencer devices, the
+corresponding module has to be loaded.
+
+For loading these modules automatically, define the aliases in
+/etc/modules.conf like below:
+
+	alias sound-service-0-0 snd-mixer-oss
+	alias sound-service-0-1 snd-seq-oss
+	alias sound-service-0-3 snd-pcm-oss
+	alias sound-service-0-8 snd-seq-oss
+	alias sound-service-0-12 snd-pcm-oss
+
+Then the access to an OSS device file such as /dev/dsp0 triggers to
+load the necessary module via KMOD.
+
+For auto-loading the secondary card device like /dev/dsp1, the
+following aliases are necessary in addition:
+
+	alias sound-service-1-0 snd-mixer-oss
+	alias sound-service-1-3 snd-pcm-oss
+	alias sound-service-1-12 snd-pcm-oss
+
+Here you don't need to define service-1-1 and service-1-8 because
+there is only one sequencer device.
+Similarly, you can add definitions for the third or later cards as
+sound-service-X-Y.
+
+The OSS-MIDI is emulated directly in the ALSA rawmidi module,
+therefore no extra module exists for that purpose.
+
+The currently available OSS configuration is shown in
+/proc/asound/oss/sndstat.  This shows in the same syntax of
+/dev/sndstat, which is available on the commercial OSS driver.
+On ALSA, you can symlink /dev/sndstat to this proc file.
+
+Please note that the devices listed in this proc file appear only
+after the corresponding OSS-emulation module is loaded.  Don't worry
+even if "NOT ENABLED IN CONFIG" is shown in it.
+
+
+Device Mapping
+==============
+
+ALSA supports the following OSS device files:
+
+	PCM:
+		/dev/dspX
+		/dev/adspX
+
+	Mixer:
+		/dev/mixerX
+
+	MIDI:
+		/dev/midi0X
+		/dev/amidi0X
+
+	Sequencer:
+		/dev/sequencer
+		/dev/sequencer2 (aka /dev/music)
+
+where X is the card number from 0 to 7.
+
+(NOTE: Some distributions have the device files like /dev/midi0 and
+       /dev/midi1.  They are NOT for OSS but for tclmidi, which is
+       a totally different thing.)
+
+Unlike the real OSS, ALSA cannot use the device files more than the
+assigned ones.  For example, the first card cannot use /dev/dsp1 or
+/dev/dsp2, but only /dev/dsp0 and /dev/adsp0.
+
+As seen above, PCM and MIDI may have two devices.  Usually, the first
+PCM device (hw:0,0 in ALSA) is mapped to /dev/dsp and the secondary
+device (hw:0,1) to /dev/adsp (if available).  For MIDI, /dev/midi and
+/dev/amidi, respectively.
+
+You can change this device mapping via the module options of
+snd-pcm-oss and snd-rawmidi.  In the case of PCM, the following
+options are available for snd-pcm-oss:
+
+	dsp_map		PCM device number assigned to /dev/dspX
+			(default = 0)
+	adsp_map	PCM device number assigned to /dev/adspX
+			(default = 1)
+
+For example, to map the third PCM device (hw:0,2) to /dev/adsp0,
+define like this:
+
+	options snd-pcm-oss adsp_map=2
+
+The options take arrays.  For configuring the second card, specify
+two entries separated by comma.  For example, to map the third PCM
+device on the second card to /dev/adsp1, define like below:
+
+	options snd-pcm-oss adsp_map=0,2
+
+To change the mapping of MIDI devices, the following options are
+available for snd-rawmidi:
+
+	midi_map	MIDI device number assigned to /dev/midi0X
+			(default = 0)
+	amidi_map	MIDI device number assigned to /dev/amidi0X
+			(default = 1)
+
+For example, to assign the third MIDI device on the first card to
+/dev/midi00, define as follows:
+
+	options snd-rawmidi midi_map=2
+
+
+PCM Mode
+========
+
+As default, ALSA emulates the OSS PCM with so-called plugin layer,
+i.e. tries to convert the sample format, rate or channels
+automatically when the card doesn't support it natively.
+This will lead to some problems for some applications like quake or
+wine, especially if they use the card only in the MMAP mode.
+
+In such a case, you can change the behavior of PCM per application by
+writing a command to the proc file.  There is a proc file for each PCM
+stream, /proc/asound/cardX/pcmY[cp]/oss, where X is the card number
+(zero-based), Y the PCM device number (zero-based), and 'p' is for
+playback and 'c' for capture, respectively.  Note that this proc file
+exists only after snd-pcm-oss module is loaded.
+
+The command sequence has the following syntax:
+
+	app_name fragments fragment_size [options]
+
+app_name is the name of application with (higher priority) or without
+path.
+fragments specifies the number of fragments or zero if no specific
+number is given.
+fragment_size is the size of fragment in bytes or zero if not given.
+options is the optional parameters.  The following options are
+available:
+
+	disable		the application tries to open a pcm device for
+			this channel but does not want to use it.
+	direct		don't use plugins
+	block		force block open mode
+	non-block	force non-block open mode
+
+The disable option is useful when one stream direction (playback or
+capture) is not handled correctly by the application although the
+hardware itself does support both directions.
+The direct option is used, as mentioned above, to bypass the automatic
+conversion and useful for MMAP-applications.
+For example, to playback the first PCM device without plugins for
+quake, send a command via echo like the following:
+
+	% echo "quake 0 0 direct" > /proc/asound/card0/pcm0p/oss
+
+While quake wants only playback, you may append the second command
+to notify driver that only this direction is about to be allocated:
+
+	% echo "quake 0 0 disable" > /proc/asound/card0/pcm0c/oss
+
+The permission of proc files depend on the module options of snd.
+As default it's set as root, so you'll likely need to be superuser for
+sending the command above.
+
+The block and non-block options are used to change the behavior of
+opening the device file.
+As default, ALSA behaves as defined in POSIX, i.e. blocks the file
+when it's busy until the device becomes free (unless O_NONBLOCK is
+specified).  Some applications assume the non-block open behavior,
+which are actually implemented in some real OSS drivers.
+
+This blocking behavior can be changed globally via nonblock_open
+module option of snd-pcm-oss.  For using the non-block mode as default
+for OSS devices, define like the following:
+
+	options snd-pcm-oss nonblock_open=1
+
+You can check the currently defined configuration by reading the proc
+file.  The read image can be sent to the proc file again, hence you
+can save the current configuration
+
+	% cat /proc/asound/card0/pcm0p/oss > /somewhere/oss-cfg
+
+and restore it like
+
+	% cat /somewhere/oss-cfg > /proc/asound/card0/pcm0p/oss
+
+Also, for clearing all the current configuration, send "erase" command
+as below:
+
+	% echo "erase" > /proc/asound/card0/pcm0p/oss
+
+
+Mixer Elements
+==============
+
+Since ALSA has completely different mixer interface, the emulation of
+OSS mixer is relatively complicated.  ALSA builds up a mixer element
+from several different ALSA (mixer) controls based on the name
+string.  For example, the volume element SOUND_MIXER_PCM is composed
+from "PCM Playback Volume" and "PCM Playback Switch" controls for the
+playback direction and from "PCM Capture Volume" and "PCM Capture
+Switch" for the capture directory (if exists).  When the PCM volume of
+OSS is changed, all the volume and switch controls above are adjusted
+automatically.
+
+As default, ALSA uses the following control for OSS volumes:
+
+	OSS volume		ALSA control		Index
+	-----------------------------------------------------
+	SOUND_MIXER_VOLUME 	Master			0
+	SOUND_MIXER_BASS	Tone Control - Bass	0
+	SOUND_MIXER_TREBLE	Tone Control - Treble	0
+	SOUND_MIXER_SYNTH	Synth			0
+	SOUND_MIXER_PCM		PCM			0
+	SOUND_MIXER_SPEAKER	PC Speaker 		0
+	SOUND_MIXER_LINE	Line			0
+	SOUND_MIXER_MIC		Mic 			0
+	SOUND_MIXER_CD		CD 			0
+	SOUND_MIXER_IMIX	Monitor Mix 		0
+	SOUND_MIXER_ALTPCM	PCM			1
+	SOUND_MIXER_RECLEV	(not assigned)
+	SOUND_MIXER_IGAIN	Capture			0
+	SOUND_MIXER_OGAIN	Playback		0
+	SOUND_MIXER_LINE1	Aux			0
+	SOUND_MIXER_LINE2	Aux			1
+	SOUND_MIXER_LINE3	Aux			2
+	SOUND_MIXER_DIGITAL1	Digital			0
+	SOUND_MIXER_DIGITAL2	Digital			1
+	SOUND_MIXER_DIGITAL3	Digital			2
+	SOUND_MIXER_PHONEIN	Phone			0
+	SOUND_MIXER_PHONEOUT	Phone			1
+	SOUND_MIXER_VIDEO	Video			0
+	SOUND_MIXER_RADIO	Radio			0
+	SOUND_MIXER_MONITOR	Monitor			0
+
+The second column is the base-string of the corresponding ALSA
+control.  In fact, the controls with "XXX [Playback|Capture]
+[Volume|Switch]" will be checked in addition.
+
+The current assignment of these mixer elements is listed in the proc
+file, /proc/asound/cardX/mixer_oss, which will be like the following
+
+	VOLUME "Master" 0
+	BASS "" 0
+	TREBLE "" 0
+	SYNTH "" 0
+	PCM "PCM" 0
+	...
+
+where the first column is the OSS volume element, the second column
+the base-string of the corresponding ALSA control, and the third the
+control index.  When the string is empty, it means that the
+corresponding OSS control is not available.
+
+For changing the assignment, you can write the configuration to this
+proc file.  For example, to map "Wave Playback" to the PCM volume,
+send the command like the following:
+
+	% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/mixer_oss
+
+The command is exactly as same as listed in the proc file.  You can
+change one or more elements, one volume per line.  In the last
+example, both "Wave Playback Volume" and "Wave Playback Switch" will
+be affected when PCM volume is changed.
+
+Like the case of PCM proc file, the permission of proc files depend on
+the module options of snd.  you'll likely need to be superuser for
+sending the command above.
+
+As well as in the case of PCM proc file, you can save and restore the
+current mixer configuration by reading and writing the whole file
+image.
+
+
+Unsupported Features
+====================
+
+MMAP on ICE1712 driver
+----------------------
+ICE1712 supports only the unconventional format, interleaved
+10-channels 24bit (packed in 32bit) format.  Therefore you cannot mmap
+the buffer as the conventional (mono or 2-channels, 8 or 16bit) format
+on OSS.
+
+USB devices
+-----------
+Some USB devices support only 24bit format packed in 3bytes.  This
+format is not supported by OSS and no conversion is provided by kernel
+OSS emulation.  You can use the user-space OSS emulation via libaoss
+instead.
+
diff -Nru a/Documentation/sparc/sbus_drivers.txt b/Documentation/sparc/sbus_drivers.txt
--- a/Documentation/sparc/sbus_drivers.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/sparc/sbus_drivers.txt	Mon Feb 10 10:39:24 2003
@@ -208,7 +208,7 @@
 	char *mem;		/* Address in the CPU space */
 	u32 busa;		/* Address in the SBus space */
 
-	mem = (char *) sbus_alloc_consistant(sdev, MYMEMSIZE, &busa);
+	mem = (char *) sbus_alloc_consistent(sdev, MYMEMSIZE, &busa);
 
 	Then mem is used when CPU accesses this memory and u32
 is fed to the device so that it can do DVMA. This is typically
@@ -216,7 +216,7 @@
 
 	Do not forget to free the DVMA resources once you are done:
 
-	sbus_free_consistant(sdev, MYMEMSIZE, mem, busa);
+	sbus_free_consistent(sdev, MYMEMSIZE, mem, busa);
 
 	Streaming DVMA is more interesting. First you allocate some
 memory suitable for it or pin down some user pages. Then it all works
diff -Nru a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
--- a/Documentation/sysctl/kernel.txt	Mon Feb 10 10:39:27 2003
+++ b/Documentation/sysctl/kernel.txt	Mon Feb 10 10:39:27 2003
@@ -222,7 +222,7 @@
 printk:
 
 The four values in printk denote: console_loglevel,
-default_message_loglevel, minimum_console_level and
+default_message_loglevel, minimum_console_loglevel and
 default_console_loglevel respectively.
 
 These values influence printk() behavior when printing or
diff -Nru a/Documentation/tipar.txt b/Documentation/tipar.txt
--- a/Documentation/tipar.txt	Mon Feb 10 10:39:23 2003
+++ b/Documentation/tipar.txt	Mon Feb 10 10:39:23 2003
@@ -12,7 +12,7 @@
 This is a driver for the very common home-made parallel link cable, a cable 
 designed for connecting TI8x/9x graphing calculators (handhelds) to a computer
 or workstation (Alpha, Sparc). Given that driver is built on parport, the 
-parallel port abstraction layer, this driver is independant of the platform.
+parallel port abstraction layer, this driver is independent of the platform.
 
 It can also be used with another device plugged on the same port (such as a
 ZIP drive). I have a 100MB ZIP and both of them work fine !
@@ -90,4 +90,4 @@
 CREDITS:
 
 The code is based on tidev.c & parport.c.
-The driver has been developed independantly of Texas Instruments.
+The driver has been developed independently of Texas Instruments.
diff -Nru a/Documentation/usb/hiddev.txt b/Documentation/usb/hiddev.txt
--- a/Documentation/usb/hiddev.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/usb/hiddev.txt	Mon Feb 10 10:39:24 2003
@@ -9,7 +9,7 @@
 supplies) and monitor control on higher end monitors.
 
 To support these disparite requirements, the Linux USB system provides
-HID events to two seperate interfaces:
+HID events to two separate interfaces:
 * the input subsystem, which converts HID events into normal input
 device interfaces (such as keyboard, mouse and joystick) and a
 normalised event interface - see Documentation/input/input.txt
diff -Nru a/Documentation/usb/silverlink.txt b/Documentation/usb/silverlink.txt
--- a/Documentation/usb/silverlink.txt	Mon Feb 10 10:39:24 2003
+++ b/Documentation/usb/silverlink.txt	Mon Feb 10 10:39:24 2003
@@ -73,4 +73,4 @@
 CREDITS:
 
 The code is based on dabusb.c, printer.c and scanner.c !
-The driver has been developed independantly of Texas Instruments.
+The driver has been developed independently of Texas Instruments.
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Mon Feb 10 10:39:29 2003
+++ b/MAINTAINERS	Mon Feb 10 10:39:29 2003
@@ -614,11 +614,9 @@
 S:	Maintained
 
 ETHERNET BRIDGE
-P:	Lennert Buytenhek
-M:	buytenh@gnu.org
 L:	bridge@math.leidenuniv.nl
 W:	http://bridge.sourceforge.net/
-S:	Maintained
+S:	Unmaintained
 
 ETHERTEAM 16I DRIVER
 P:	Mika Kuoppala
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Feb 10 10:39:23 2003
+++ b/Makefile	Mon Feb 10 10:39:23 2003
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 59
+SUBLEVEL = 60
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -53,6 +53,8 @@
 CROSS_COMPILE 	=
 
 # 	That's our default target when none is given on the command line
+#	Note that 'modules' will be added as a prerequisite as well, 
+#	in the CONFIG_MODULES part below
 
 all:	vmlinux
 
@@ -183,6 +185,8 @@
 export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE 
 export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 
+export MODVERDIR := .tmp_versions
+
 # The temporary file to save gcc -MD generated dependencies must not
 # contain a comma
 depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
@@ -190,7 +194,7 @@
 noconfig_targets := xconfig menuconfig config oldconfig randconfig \
 		    defconfig allyesconfig allnoconfig allmodconfig \
 		    clean mrproper distclean \
-		    help tags TAGS sgmldocs psdocs pdfdocs htmldocs \
+		    help tags TAGS cscope sgmldocs psdocs pdfdocs htmldocs \
 		    checkconfig checkhelp checkincludes
 
 RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o
@@ -256,14 +260,22 @@
 
 -include .config.cmd
 
-ifdef CONFIG_MODULES
-export EXPORT_FLAGS := -DEXPORT_SYMTAB
-endif
-
 ifndef CONFIG_FRAME_POINTER
 CFLAGS		+= -fomit-frame-pointer
 endif
 
+#	When we're building modules with modversions, we need to consider
+#	the built-in objects during the descend as well, in order to
+#	make sure the checksums are uptodate before we record them.
+
+ifdef CONFIG_MODVERSIONS
+ifeq ($(KBUILD_MODULES),1)
+ifneq ($(KBUILD_BUILTIN),1)
+  KBUILD_BUILTIN := 1
+endif
+endif
+endif
+
 #
 # INSTALL_PATH specifies where to place the updated kernel and system map
 # images.  Uncomment if you want to place them anywhere other than root.
@@ -289,12 +301,12 @@
 #       normal descending-into-subdirs phase, since at that time
 #       we cannot yet know if we will need to relink vmlinux.
 #	So we descend into init/ inside the rule for vmlinux again.
-
-vmlinux-objs := $(HEAD) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)
+head-y += $(HEAD)
+vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)
 
 quiet_cmd_vmlinux__ = LD      $@
 define cmd_vmlinux__
-	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(HEAD) $(init-y) \
+	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(head-y) $(init-y) \
 	--start-group \
 	$(core-y) \
 	$(libs-y) \
@@ -384,7 +396,7 @@
 # 	Handle descending into subdirectories listed in $(SUBDIRS)
 
 .PHONY: $(SUBDIRS)
-$(SUBDIRS): .hdepend prepare
+$(SUBDIRS): prepare
 	$(Q)$(MAKE) $(build)=$@
 
 #	Things we need done before we descend to build or make
@@ -392,6 +404,17 @@
 
 .PHONY: prepare
 prepare: include/linux/version.h include/asm include/config/MARKER
+ifdef CONFIG_MODVERSIONS
+ifdef KBUILD_MODULES
+ifeq ($(origin SUBDIRS),file)
+	$(Q)rm -rf $(MODVERDIR)
+	$(Q)mkdir $(MODVERDIR)
+else
+	@echo '*** Warning: Overriding SUBDIRS on the command line can cause'
+	@echo '***          inconsistencies with module symbol versions'
+endif
+endif
+endif
 	@echo '  Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)'
 
 #	We need to build init/vermagic.o before descending since all modules
@@ -424,6 +447,8 @@
 	$(Q)$(MAKE) $(build)=$(@D) $@
 %.o: %.c scripts FORCE
 	$(Q)$(MAKE) $(build)=$(@D) $@
+%/:      scripts prepare FORCE
+	$(Q)$(MAKE) $(build)=$(@D)
 %.ko: scripts FORCE
 	$(Q)$(MAKE) $(build)=$(@D) $@
 %.lst: %.c scripts FORCE
@@ -475,75 +500,33 @@
 	) > $@.tmp
 	@$(update-if-changed)
 
-# Generate module versions
 # ---------------------------------------------------------------------------
 
-# 	The targets are still named depend / dep for traditional
-#	reasons, but the only thing we do here is generating
-#	the module version checksums.
-
-.PHONY: depend dep $(patsubst %,_sfdep_%,$(SUBDIRS))
-
-depend dep: .hdepend
-
-#	.hdepend is our (misnomed) marker for whether we've
-#	generated module versions
-
-make-versions := $(strip $(if $(filter dep depend,$(MAKECMDGOALS)),1) \
-			 $(if $(wildcard .hdepend),,1))
-
-.hdepend: prepare FORCE
-ifneq ($(make-versions),)
-	@$(MAKE) include/linux/modversions.h
-	@touch $@
-endif
-
-ifdef CONFIG_MODVERSIONS
-
-# 	Update modversions.h, but only if it would change.
-
-.PHONY: __rm_tmp_export-objs
-__rm_tmp_export-objs: 
-	@rm -rf .tmp_export-objs
-
-include/linux/modversions.h: $(patsubst %,_modver_%,$(SUBDIRS))
-	@echo -n '  Generating $@'
-	@( echo "#ifndef _LINUX_MODVERSIONS_H";\
-	   echo "#define _LINUX_MODVERSIONS_H"; \
-	   echo "#include <linux/modsetver.h>"; \
-	   cd .tmp_export-objs >/dev/null; \
-	   for f in `find modules -name \*.ver -print | sort`; do \
-	     echo "#include <linux/$${f}>"; \
-	   done; \
-	   echo "#endif"; \
-	) > $@.tmp; \
-	$(update-if-changed)
-
-.PHONY: $(patsubst %, _modver_%, $(SUBDIRS))
-$(patsubst %, _modver_%, $(SUBDIRS)): __rm_tmp_export-objs
-	$(Q)$(MAKE) -f scripts/Makefile.modver obj=$(patsubst _modver_%,%,$@)
-
-else # !CONFIG_MODVERSIONS
-
-.PHONY: include/linux/modversions.h
-
-include/linux/modversions.h:
-
-endif # CONFIG_MODVERSIONS
+.PHONY: depend dep
+depend dep:
+	@echo '*** Warning: make $@ is unnecessary now.'
 
 # ---------------------------------------------------------------------------
 # Modules
 
 ifdef CONFIG_MODULES
 
+# 	By default, build modules as well
+
+all: modules
+
 #	Build modules
 
+.PHONY: modules __modversions
+modules: $(SUBDIRS) __modversions
+
 ifdef CONFIG_MODVERSIONS
-MODFLAGS += -include include/linux/modversions.h
-endif
 
-.PHONY: modules
-modules: $(SUBDIRS)
+__modversions: vmlinux $(SUBDIRS)
+	@echo '  Recording module symbol versions.';
+	$(Q)$(MAKE) -rR -f scripts/Makefile.modver
+
+endif
 
 #	Install modules
 
@@ -574,6 +557,7 @@
 .PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
 $(patsubst %, _modinst_%, $(SUBDIRS)) :
 	$(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@)
+
 else # CONFIG_MODULES
 
 # Modules not configured
@@ -624,7 +608,7 @@
 
 rpm:	clean spec
 	find . $(RCS_FIND_IGNORE) \
-		\( -size 0 -o -name .depend -o -name .hdepend \) \
+		\( -size 0 -o -name .depend -o -name .hdepend\) \
 		-type f -print | xargs rm -f
 	set -e; \
 	cd $(TOPDIR)/.. ; \
@@ -718,25 +702,26 @@
 	.menuconfig.log \
 	include/asm \
 	.hdepend include/linux/modversions.h \
-	tags TAGS kernel.spec \
+	tags TAGS cscope kernel.spec \
 	.tmp*
 
 # Directories removed with 'make mrproper'
 MRPROPER_DIRS += \
+	$(MODVERDIR) \
 	.tmp_export-objs \
 	include/config \
 	include/linux/modules
 
 # clean - Delete all intermediate files
 #
-clean-dirs += $(ALL_SUBDIRS) Documentation/DocBook scripts
-
-$(addprefix _clean_,$(clean-dirs)):
+clean-dirs += $(addprefix _clean_,$(ALL_SUBDIRS) Documentation/DocBook scripts)
+.PHONY: $(clean-dirs) clean archclean mrproper archmrproper distclean
+$(clean-dirs):
 	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
 
 quiet_cmd_rmclean = RM  $$(CLEAN_FILES)
 cmd_rmclean	  = rm -f $(CLEAN_FILES)
-clean: archclean $(addprefix _clean_,$(clean-dirs))
+clean: archclean $(clean-dirs)
 	$(call cmd,rmclean)
 	@find . $(RCS_FIND_IGNORE) \
 	 	\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
@@ -775,6 +760,9 @@
 	       -name '*.[chS]' -print )
 endef
 
+quiet_cmd_cscope = MAKE   $@
+cmd_cscope = $(all-sources) | cscope -k -b -i -
+
 quiet_cmd_TAGS = MAKE   $@
 cmd_TAGS = $(all-sources) | etags -
 
@@ -786,6 +774,9 @@
 	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
 	$(all-sources) | xargs ctags $$CTAGSF -a
 endef
+
+cscope: FORCE
+	$(call cmd,cscope)
 
 TAGS: FORCE
 	$(call cmd,TAGS)
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/arch/alpha/Kconfig	Mon Feb 10 10:39:30 2003
@@ -458,6 +458,11 @@
 
 	  If unsure, say N.
 
+config EARLY_PRINTK
+	bool
+	depends on ALPHA_GENERIC || ALPHA_SRM
+	default y
+
 config ALPHA_EISA
 	bool
 	depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE
@@ -630,7 +635,7 @@
 	  of course).
 
 	  This driver is also available as a module and will be called
-	  srm_env.o then.
+	  srm_env then.
 
 config BINFMT_AOUT
 	tristate "Kernel support for a.out (ECOFF) binaries"
@@ -650,7 +655,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -688,7 +693,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -713,7 +718,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config BINFMT_EM86
@@ -728,7 +733,7 @@
 
 	  You may answer M to compile the emulation support as a module and
 	  later load the module when you want to use a Linux/Intel binary. The
-	  module will be called binfmt_em86.o. If unsure, say Y.
+	  module will be called binfmt_em86. If unsure, say Y.
 
 source "drivers/parport/Kconfig"
 
@@ -785,7 +790,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -821,7 +826,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -915,7 +920,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile
--- a/arch/alpha/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/alpha/Makefile	Mon Feb 10 10:39:29 2003
@@ -90,7 +90,7 @@
 # BWX is most important, but we don't really want any emulation ever.
 CFLAGS += $(cflags-y) -Wa,-mev6
 
-HEAD := arch/alpha/kernel/head.o
+head-y := arch/alpha/kernel/head.o
 
 core-y			+= arch/alpha/kernel/ arch/alpha/mm/
 core-$(CONFIG_MATHEMU)  += arch/alpha/math-emu/
@@ -124,8 +124,6 @@
 
 archclean:
 	$(Q)$(MAKE) -f scripts/Makefile.clean obj=$(boot)
-
-archmrproper:
 
 CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h.tmp \
 	       include/asm-$(ARCH)/asm_offsets.h
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile	Mon Feb 10 10:39:26 2003
+++ b/arch/alpha/kernel/Makefile	Mon Feb 10 10:39:26 2003
@@ -6,8 +6,6 @@
 
 EXTRA_AFLAGS	:= $(CFLAGS)
 
-export-objs := alpha_ksyms.o core_marvel.o core_titan.o
-
 obj-y    := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
 	    irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \
 	    alpha_ksyms.o systbls.o err_common.o
@@ -35,7 +33,12 @@
 
 obj-y	 += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o
 
+obj-y    += srmcons.o
+
 else
+
+# Misc support
+obj-$(CONFIG_ALPHA_SRM)		+= srmcons.o
 
 # Core logic support
 obj-$(CONFIG_ALPHA_APECS)	+= core_apecs.o
diff -Nru a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
--- a/arch/alpha/kernel/alpha_ksyms.c	Mon Feb 10 10:39:23 2003
+++ b/arch/alpha/kernel/alpha_ksyms.c	Mon Feb 10 10:39:23 2003
@@ -40,7 +40,6 @@
 
 extern struct hwrpb_struct *hwrpb;
 extern void dump_thread(struct pt_regs *, struct user *);
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 extern spinlock_t rtc_lock;
 
 /* these are C runtime functions with special calling conventions: */
@@ -144,7 +143,9 @@
 #endif
 
 EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_elf_thread);
+EXPORT_SYMBOL(dump_elf_task);
+EXPORT_SYMBOL(dump_elf_task_fp);
 EXPORT_SYMBOL(hwrpb);
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(alpha_read_fp_reg);
diff -Nru a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
--- a/arch/alpha/kernel/core_irongate.c	Mon Feb 10 10:39:29 2003
+++ b/arch/alpha/kernel/core_irongate.c	Mon Feb 10 10:39:29 2003
@@ -27,13 +27,11 @@
 #include <asm/core_irongate.h>
 #undef __EXTERN_INLINE
 
+#include <linux/bootmem.h>
+
 #include "proto.h"
 #include "pci_impl.h"
 
-#undef DEBUG_IRONGATE 		/* define to enable verbose Irongate debug */
-
-#define IRONGATE_DEFAULT_AGP_APER_SIZE	(256*1024*1024) /* 256MB */
-
 /*
  * BIOS32-style PCI interface:
  */
@@ -46,6 +44,7 @@
 # define DBG_CFG(args)
 #endif
 
+igcsr32 *IronECC;
 
 /*
  * Given a bus, device, and function number, compute resulting
@@ -165,143 +164,6 @@
 	.write =	irongate_write_config,
 };
 
-#ifdef DEBUG_IRONGATE
-static void
-irongate_register_dump(const char *function_name)
-{
-	printk("%s: Irongate registers:\n"
-	       "\tFunction 0:\n"
-	       "\tdev_vendor\t0x%08x\n"
-	       "\tstat_cmd\t0x%08x\n"
-	       "\tclass\t\t0x%08x\n"
-	       "\tlatency\t\t0x%08x\n"
-	       "\tbar0\t\t0x%08x\n"
-	       "\tbar1\t\t0x%08x\n"
-	       "\tbar2\t\t0x%08x\n"
-	       "\trsrvd0[0]\t0x%08x\n"
-	       "\trsrvd0[1]\t0x%08x\n"
-	       "\trsrvd0[2]\t0x%08x\n"
-	       "\trsrvd0[3]\t0x%08x\n"
-	       "\trsrvd0[4]\t0x%08x\n"
-	       "\trsrvd0[5]\t0x%08x\n"
-	       "\tcapptr\t\t0x%08x\n"
-	       "\trsrvd1[0]\t0x%08x\n"
-	       "\trsrvd1[1]\t0x%08x\n"
-	       "\tbacsr10\t\t0x%08x\n"
-	       "\tbacsr32\t\t0x%08x\n"
-	       "\tbacsr54\t\t0x%08x\n"
-	       "\trsrvd2[0]\t0x%08x\n"
-	       "\tdrammap\t\t0x%08x\n"
-	       "\tdramtm\t\t0x%08x\n"
-	       "\tdramms\t\t0x%08x\n"
-	       "\trsrvd3[0]\t0x%08x\n"
-	       "\tbiu0\t\t0x%08x\n"
-	       "\tbiusip\t\t0x%08x\n"
-	       "\trsrvd4[0]\t0x%08x\n"
-	       "\trsrvd4[1]\t0x%08x\n"
-	       "\tmro\t\t0x%08x\n"
-	       "\trsrvd5[0]\t0x%08x\n"
-	       "\trsrvd5[1]\t0x%08x\n"
-	       "\trsrvd5[2]\t0x%08x\n"
-	       "\twhami\t\t0x%08x\n"
-	       "\tpciarb\t\t0x%08x\n"
-	       "\tpcicfg\t\t0x%08x\n"
-	       "\trsrvd6[0]\t0x%08x\n"
-	       "\trsrvd6[1]\t0x%08x\n"
-	       "\trsrvd6[2]\t0x%08x\n"
-	       "\trsrvd6[3]\t0x%08x\n"
-	       "\trsrvd6[4]\t0x%08x\n"
-	       "\tagpcap\t\t0x%08x\n"
-	       "\tagpstat\t\t0x%08x\n"
-	       "\tagpcmd\t\t0x%08x\n"
-	       "\tagpva\t\t0x%08x\n"
-	       "\tagpmode\t\t0x%08x\n"
-
-	       "\n\tFunction 1:\n"
-	       "\tdev_vendor:\t0x%08x\n"
-	       "\tcmd_status:\t0x%08x\n"
-	       "\trevid_etc :\t0x%08x\n"
-	       "\thtype_etc :\t0x%08x\n"
-	       "\trsrvd0[0] :\t0x%08x\n"
-	       "\trsrvd0[1] :\t0x%08x\n"
-	       "\tbus_nmbers:\t0x%08x\n"
-	       "\tio_baselim:\t0x%08x\n"
-	       "\tmem_bselim:\t0x%08x\n"
-	       "\tpf_baselib:\t0x%08x\n"
-	       "\trsrvd1[0] :\t0x%08x\n"
-	       "\trsrvd1[1] :\t0x%08x\n"
-	       "\tio_baselim:\t0x%08x\n"
-	       "\trsrvd2[0] :\t0x%08x\n"
-	       "\trsrvd2[1] :\t0x%08x\n"
-	       "\tinterrupt :\t0x%08x\n",
-
-	       function_name,
-	       IRONGATE0->dev_vendor,
-	       IRONGATE0->stat_cmd,
-	       IRONGATE0->class,
-	       IRONGATE0->latency,
-	       IRONGATE0->bar0,
-	       IRONGATE0->bar1,
-	       IRONGATE0->bar2,
-	       IRONGATE0->rsrvd0[0],
-	       IRONGATE0->rsrvd0[1],
-	       IRONGATE0->rsrvd0[2],
-	       IRONGATE0->rsrvd0[3],
-	       IRONGATE0->rsrvd0[4],
-	       IRONGATE0->rsrvd0[5],
-	       IRONGATE0->capptr,
-	       IRONGATE0->rsrvd1[0],
-	       IRONGATE0->rsrvd1[1],
-	       IRONGATE0->bacsr10,
-	       IRONGATE0->bacsr32,
-	       IRONGATE0->bacsr54,
-	       IRONGATE0->rsrvd2[0],
-	       IRONGATE0->drammap,
-	       IRONGATE0->dramtm,
-	       IRONGATE0->dramms,
-	       IRONGATE0->rsrvd3[0],
-	       IRONGATE0->biu0,
-	       IRONGATE0->biusip,
-	       IRONGATE0->rsrvd4[0],
-	       IRONGATE0->rsrvd4[1],
-	       IRONGATE0->mro,
-	       IRONGATE0->rsrvd5[0],
-	       IRONGATE0->rsrvd5[1],
-	       IRONGATE0->rsrvd5[2],
-	       IRONGATE0->whami,
-	       IRONGATE0->pciarb,
-	       IRONGATE0->pcicfg,
-	       IRONGATE0->rsrvd6[0],
-	       IRONGATE0->rsrvd6[1],
-	       IRONGATE0->rsrvd6[2],
-	       IRONGATE0->rsrvd6[3],
-	       IRONGATE0->rsrvd6[4],
-	       IRONGATE0->agpcap,
-	       IRONGATE0->agpstat,
-	       IRONGATE0->agpcmd,
-	       IRONGATE0->agpva,
-	       IRONGATE0->agpmode,
-	       IRONGATE1->dev_vendor,
-	       IRONGATE1->stat_cmd,
-	       IRONGATE1->class,
-	       IRONGATE1->htype,
-	       IRONGATE1->rsrvd0[0],
-	       IRONGATE1->rsrvd0[1],
-	       IRONGATE1->busnos,
-	       IRONGATE1->io_baselim_regs,
-	       IRONGATE1->mem_baselim,
-	       IRONGATE1->pfmem_baselim,
-	       IRONGATE1->rsrvd1[0],
-	       IRONGATE1->rsrvd1[1],
-	       IRONGATE1->io_baselim,
-	       IRONGATE1->rsrvd2[0],
-	       IRONGATE1->rsrvd2[1],
-	       IRONGATE1->interrupt );
-}
-#else
-#define irongate_register_dump(x)
-#endif
-
 int
 irongate_pci_clr_err(void)
 {
@@ -315,11 +177,11 @@
 	mb();
 	IRONGATE_jd = IRONGATE0->stat_cmd;  /* re-read to force write */
 
-	IRONGATE_jd = IRONGATE0->dramms;
-	printk("Iron dramms %x\n", IRONGATE_jd);
-	IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+	IRONGATE_jd = *IronECC;
+	printk("Iron ECC %x\n", IRONGATE_jd);
+	*IronECC = IRONGATE_jd; /* write again clears error bits */
 	mb();
-	IRONGATE_jd = IRONGATE0->dramms;  /* re-read to force write */
+	IRONGATE_jd = *IronECC;  /* re-read to force write */
 
 	/* Clear ALI NMI */
         nmi_ctl = inb(0x61);
@@ -328,28 +190,88 @@
         nmi_ctl &= ~0x0c;
         outb(nmi_ctl, 0x61);
 
-	IRONGATE_jd = IRONGATE0->dramms;
+	IRONGATE_jd = *IronECC;
 	if (IRONGATE_jd & 0x300) goto again;
 
 	return 0;
 }
 
+#define IRONGATE_3GB 0xc0000000UL
+
+/* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some
+   memory for PCI. At this point we just reserve memory above 3Gb. Most
+   of this memory will be freed after PCI setup is done. */
+static void __init
+albacore_init_arch(void)
+{
+	unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+	unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL;
+	struct percpu_struct *cpu;
+	int pal_rev, pal_var;
+
+	cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+	pal_rev = cpu->pal_revision & 0xffff;
+	pal_var = (cpu->pal_revision >> 16) & 0xff;
+
+	/* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up
+	   the CPU incorrectly (leave speculative stores enabled),
+	   which causes memory corruption under certain conditions.
+	   Issue a warning for such consoles. */
+	if (alpha_using_srm &&
+	    (pal_rev < 0x13e ||	(pal_rev == 0x13e && pal_var < 2)))
+		printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 "
+				    "or later\n");
+
+	if (pci_mem > IRONGATE_3GB)
+		pci_mem = IRONGATE_3GB;
+	IRONGATE0->pci_mem = pci_mem;
+	alpha_mv.min_mem_address = pci_mem;
+	if (memtop > pci_mem) {
+#ifdef CONFIG_BLK_DEV_INITRD
+		extern unsigned long initrd_start, initrd_end;
+		extern void *move_initrd(unsigned long);
+
+		/* Move the initrd out of the way. */
+		if (initrd_end && __pa(initrd_end) > pci_mem) {
+			unsigned long size;
+
+			size = initrd_end - initrd_start;
+			free_bootmem(__pa(initrd_start), PAGE_ALIGN(size));
+			if (!move_initrd(pci_mem))
+				printk("irongate_init_arch: initrd too big "
+				       "(%ldK)\ndisabling initrd\n",
+				       size / 1024);
+		}
+#endif
+		reserve_bootmem(pci_mem, memtop - pci_mem);
+		printk("irongate_init_arch: temporarily reserving "
+			"region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
+	}
+}
+
+static void __init
+irongate_setup_agp(void)
+{
+	/* Disable the GART window. AGPGART doesn't work due to yet
+	   unresolved memory coherency issues... */
+	IRONGATE0->agpva = IRONGATE0->agpva & ~0xf;
+	alpha_agpgart_size = 0;
+}
+
 void __init
 irongate_init_arch(void)
 {
 	struct pci_controller *hose;
+	int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006;	/* Albacore? */
+
+	IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms;
 
-	IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
 	irongate_pci_clr_err();
-	irongate_register_dump(__FUNCTION__);
 
-	/*
-	 * HACK: set AGP aperture size to 256MB.
-	 * This should really be changed during PCI probe, when the
-	 * size of the aperture the AGP card wants is known.
-	 */
-	printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva);
-	IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007;
+	if (amd761)
+		albacore_init_arch();
+
+	irongate_setup_agp();
 
 	/*
 	 * Create our single hose.
@@ -380,89 +302,9 @@
  * IO map and AGP support
  */
 #include <linux/vmalloc.h>
-#include <asm/pgalloc.h>
-
-static inline void 
-irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 
-		     unsigned long phys_addr, unsigned long flags)
-{
-	unsigned long end;
-	unsigned long pfn;
-
-	address &= ~PMD_MASK;
-	end = address + size;
-	if (end > PMD_SIZE)
-		end = PMD_SIZE;
-	if (address >= end)
-		BUG();
-	pfn = phys_addr >> PAGE_SHIFT;
-	do {
-		if (!pte_none(*pte)) {
-			printk("irongate_remap_area_pte: page already exists\n");
-			BUG();
-		}
-		set_pte(pte, pfn_pte(pfn,
-				     __pgprot(_PAGE_VALID | _PAGE_ASM | 
-					      _PAGE_KRE | _PAGE_KWE | flags)));
-		address += PAGE_SIZE;
-		pfn++;
-		pte++;
-	} while (address && (address < end));
-}
-
-static inline int 
-irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 
-		     unsigned long phys_addr, unsigned long flags)
-{
-	unsigned long end;
-
-	address &= ~PGDIR_MASK;
-	end = address + size;
-	if (end > PGDIR_SIZE)
-		end = PGDIR_SIZE;
-	phys_addr -= address;
-	if (address >= end)
-		BUG();
-	do {
-		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
-		if (!pte)
-			return -ENOMEM;
-		irongate_remap_area_pte(pte, address, end - address, 
-				     address + phys_addr, flags);
-		address = (address + PMD_SIZE) & PMD_MASK;
-		pmd++;
-	} while (address && (address < end));
-	return 0;
-}
-
-static int
-irongate_remap_area_pages(unsigned long address, unsigned long phys_addr,
-		       unsigned long size, unsigned long flags)
-{
-	pgd_t * dir;
-	unsigned long end = address + size;
-
-	phys_addr -= address;
-	dir = pgd_offset(&init_mm, address);
-	flush_cache_all();
-	if (address >= end)
-		BUG();
-	do {
-		pmd_t *pmd;
-		pmd = pmd_alloc(&init_mm, dir, address);
-		if (!pmd)
-			return -ENOMEM;
-		if (irongate_remap_area_pmd(pmd, address, end - address,
-					 phys_addr + address, flags))
-			return -ENOMEM;
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		dir++;
-	} while (address && (address < end));
-	return 0;
-}
-
 #include <linux/agp_backend.h>
 #include <linux/agpgart.h>
+#include <asm/pgalloc.h>
 
 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
@@ -477,15 +319,13 @@
 	unsigned long vaddr;
 	unsigned long baddr, last;
 	u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
-	unsigned long gart_bus_addr, gart_aper_size;
-
-	gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
-			PCI_BASE_ADDRESS_MEM_MASK; 
+	unsigned long gart_bus_addr;
 
-	if (!gart_bus_addr) /* FIXME - there must be a better way!!! */
+	if (!alpha_agpgart_size)
 		return addr + IRONGATE_MEM;
 
-	gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */
+	gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
+			PCI_BASE_ADDRESS_MEM_MASK; 
 
 	/* 
 	 * Check for within the AGP aperture...
@@ -495,7 +335,7 @@
 		 * Check the AGP area
 		 */
 		if (addr >= gart_bus_addr && addr + size - 1 < 
-		    gart_bus_addr + gart_aper_size)
+		    gart_bus_addr + alpha_agpgart_size)
 			break;
 
 		/*
@@ -549,8 +389,8 @@
 		cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
 		pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
 
-		if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr), 
-					   pte, PAGE_SIZE, 0)) {
+		if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
+					     pte, PAGE_SIZE, 0)) {
 			printk("AGP ioremap: FAILED to map...\n");
 			vfree(area->addr);
 			return (unsigned long)NULL;
diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
--- a/arch/alpha/kernel/core_marvel.c	Mon Feb 10 10:39:23 2003
+++ b/arch/alpha/kernel/core_marvel.c	Mon Feb 10 10:39:23 2003
@@ -732,21 +732,6 @@
 EXPORT_SYMBOL(marvel_ioremap);
 EXPORT_SYMBOL(marvel_iounmap);
 #endif
-
-/*
- * SRMCons support
- *
- * Marvel doesn't have a real serial console -- it's either graphics or 
- * server management based. If we're running on the server management based
- * console, allow the srmcons callback driver to be a console device.
- */
-int
-marvel_srmcons_allowed(void)
-{
-	u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
-
-	return (pu64[7] == 2);
-}
 
 
 /*
@@ -874,8 +859,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024)
-
 struct marvel_agp_aperture {
 	struct pci_iommu_arena *arena;
 	long pg_start;
@@ -887,11 +870,14 @@
 {
 	struct marvel_agp_aperture *aper;
 
+	if (!alpha_agpgart_size)
+		return -ENOMEM;
+
 	aper = kmalloc(sizeof(*aper), GFP_KERNEL);
 	if (aper == NULL) return -ENOMEM;
 
 	aper->arena = agp->hose->sg_pci;
-	aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE;
+	aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
 	aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
 				       aper->pg_count - 1);
 
diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
--- a/arch/alpha/kernel/core_titan.c	Mon Feb 10 10:39:24 2003
+++ b/arch/alpha/kernel/core_titan.c	Mon Feb 10 10:39:24 2003
@@ -580,8 +580,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024)
-
 struct titan_agp_aperture {
 	struct pci_iommu_arena *arena;
 	long pg_start;
@@ -593,12 +591,15 @@
 {
 	struct titan_agp_aperture *aper;
 
+	if (!alpha_agpgart_size)
+		return -ENOMEM;
+
 	aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL);
 	if (aper == NULL)
 		return -ENOMEM;
 
 	aper->arena = agp->hose->sg_pci;
-	aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE;
+	aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
 	aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
 				       aper->pg_count - 1);
 	if (aper->pg_start < 0) {
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c	Mon Feb 10 10:39:30 2003
+++ b/arch/alpha/kernel/irq.c	Mon Feb 10 10:39:30 2003
@@ -534,7 +534,7 @@
 #else
 		for (j = 0; j < NR_CPUS; j++)
 			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]);
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %c%s",
diff -Nru a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
--- a/arch/alpha/kernel/pci_impl.h	Mon Feb 10 10:39:32 2003
+++ b/arch/alpha/kernel/pci_impl.h	Mon Feb 10 10:39:32 2003
@@ -71,6 +71,8 @@
 
 #define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024)
 
+#define DEFAULT_AGP_APER_SIZE	(64*1024*1024)
+
 /* 
  * A small note about bridges and interrupts.  The DECchip 21050 (and
  * later) adheres to the PCI-PCI bridge specification.  This says that
@@ -152,6 +154,8 @@
 
 /* Indicate that we trust the console to configure things properly.  */
 extern int pci_probe_only;
+
+extern unsigned long alpha_agpgart_size;
 
 extern void common_init_pci(void);
 extern u8 common_swizzle(struct pci_dev *, u8 *);
diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c	Mon Feb 10 10:39:31 2003
+++ b/arch/alpha/kernel/process.c	Mon Feb 10 10:39:31 2003
@@ -313,7 +313,7 @@
 }
 
 /*
- * fill in the user structure for a core dump..
+ * Fill in the user structure for an ECOFF core dump.
  */
 void
 dump_thread(struct pt_regs * pt, struct user * dump)
@@ -373,12 +373,81 @@
 	memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
 }
 
-int
-dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
+/*
+ * Fill in the user structure for a ELF core dump.
+ */
+void
+dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti)
 {
 	/* switch stack follows right below pt_regs: */
-	struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
-	memcpy(r, sw->fp, 32 * 8);
+	struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
+
+	dest[ 0] = pt->r0;
+	dest[ 1] = pt->r1;
+	dest[ 2] = pt->r2;
+	dest[ 3] = pt->r3;
+	dest[ 4] = pt->r4;
+	dest[ 5] = pt->r5;
+	dest[ 6] = pt->r6;
+	dest[ 7] = pt->r7;
+	dest[ 8] = pt->r8;
+	dest[ 9] = sw->r9;
+	dest[10] = sw->r10;
+	dest[11] = sw->r11;
+	dest[12] = sw->r12;
+	dest[13] = sw->r13;
+	dest[14] = sw->r14;
+	dest[15] = sw->r15;
+	dest[16] = pt->r16;
+	dest[17] = pt->r17;
+	dest[18] = pt->r18;
+	dest[19] = pt->r19;
+	dest[20] = pt->r20;
+	dest[21] = pt->r21;
+	dest[22] = pt->r22;
+	dest[23] = pt->r23;
+	dest[24] = pt->r24;
+	dest[25] = pt->r25;
+	dest[26] = pt->r26;
+	dest[27] = pt->r27;
+	dest[28] = pt->r28;
+	dest[29] = pt->gp;
+	dest[30] = rdusp();
+	dest[31] = pt->pc;
+
+	/* Once upon a time this was the PS value.  Which is stupid
+	   since that is always 8 for usermode.  Usurped for the more
+	   useful value of the thread's UNIQUE field.  */
+	dest[32] = ti->pcb.unique;
+}
+
+int
+dump_elf_task(elf_greg_t *dest, struct task_struct *task)
+{
+	struct thread_info *ti;
+	struct pt_regs *pt;
+
+	ti = task->thread_info;
+	pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
+
+	dump_elf_thread(dest, pt, ti);
+
+	return 1;
+}
+
+int
+dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
+{
+	struct thread_info *ti;
+	struct pt_regs *pt;
+	struct switch_stack *sw;
+
+	ti = task->thread_info;
+	pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
+	sw = (struct switch_stack *)pt - 1;
+
+	memcpy(dest, sw->fp, 32 * 8);
+
 	return 1;
 }
 
diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
--- a/arch/alpha/kernel/proto.h	Mon Feb 10 10:39:24 2003
+++ b/arch/alpha/kernel/proto.h	Mon Feb 10 10:39:24 2003
@@ -53,7 +53,6 @@
 extern int marvel_cpuid_to_nid(int);
 extern unsigned long marvel_node_mem_start(int);
 extern unsigned long marvel_node_mem_size(int);
-extern int marvel_srmcons_allowed(void);
 extern struct _alpha_agp_info *marvel_agp_info(void);
 struct io7 *marvel_find_io7(int pe);
 struct io7 *marvel_next_io7(struct io7 *prev);
@@ -109,9 +108,15 @@
 /* setup.c */
 extern unsigned long srm_hae;
 extern int boot_cpuid;
-extern int srmcons_output;
+
+/* srmcons.c */
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
 extern void register_srm_console(void);
 extern void unregister_srm_console(void);
+#else
+#define register_srm_console()
+#define unregister_srm_console()
+#endif
 
 /* smp.c */
 extern void setup_smp(void);
diff -Nru a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
--- a/arch/alpha/kernel/ptrace.c	Mon Feb 10 10:39:32 2003
+++ b/arch/alpha/kernel/ptrace.c	Mon Feb 10 10:39:32 2003
@@ -102,7 +102,9 @@
 
 	if (regno == 30) {
 		addr = &task->thread_info->pcb.usp;
-	} else if (regno == 31 || regno > 64) {
+	} else if (regno == 65) {
+		addr = &task->thread_info->pcb.unique;
+	} else if (regno == 31 || regno > 65) {
 		zero = 0;
 		addr = &zero;
 	} else {
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Mon Feb 10 10:39:24 2003
+++ b/arch/alpha/kernel/setup.c	Mon Feb 10 10:39:24 2003
@@ -77,18 +77,25 @@
 
  * "srmcons" specified in the boot command arguments allows us to
  * see kernel messages during the period of time before the true
- * console device is "registered" during console_init(). As of this
- * version (2.4.10), time_init() is the last Alpha-specific code
- * called before console_init(), so we put "unregister" code
- * there to prevent schizophrenic console behavior later... ;-}
+ * console device is "registered" during console_init(). 
+ * As of this version (2.5.59), console_init() will call
+ * disable_early_printk() as the last action before initializing
+ * the console drivers. That's the last possible time srmcons can be 
+ * unregistered without interfering with console behavior.
  *
- * By default, OFF; set it with a bootcommand arg of "srmcons".
+ * By default, OFF; set it with a bootcommand arg of "srmcons" or 
+ * "console=srm". The meaning of these two args is:
+ *     "srmcons"     - early callback prints 
+ *     "console=srm" - full callback based console, including early prints
  */
 int srmcons_output = 0;
 
 /* Enforce a memory size limit; useful for testing. By default, none. */
 unsigned long mem_size_limit = 0;
 
+/* Set AGP GART window size (0 means disabled). */
+unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
+
 #ifdef CONFIG_ALPHA_GENERIC
 struct alpha_machine_vector alpha_mv;
 int alpha_using_srm;
@@ -461,57 +468,6 @@
 #undef PFN_PHYS
 #undef PFN_MAX
 
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
-/*
- *      Manage the SRM callbacks as a "console".
- */
-static struct console srmcons;
-
-void __init register_srm_console(void)
-{
-        register_console(&srmcons);
-}
-
-void __init unregister_srm_console(void)
-{
-        unregister_console(&srmcons);
-}
-
-static void srm_console_write(struct console *co, const char *s,
-                                unsigned count)
-{
-	srm_printk(s);
-}
-
-static kdev_t srm_console_device(struct console *c)
-{
-	/* Huh? */
-        return mk_kdev(TTY_MAJOR, 64 + c->index);
-}
-
-static int __init srm_console_setup(struct console *co, char *options)
-{
-	return 1;
-}
-
-static struct console srmcons = {
-	.name		= "srm0",
-	.write		= srm_console_write,
-	.device		= srm_console_device,
-	.setup		= srm_console_setup,
-	.flags		= CON_PRINTBUFFER | CON_ENABLED, /* fake it out */
-	.index		= -1,
-};
-
-#else
-void __init register_srm_console(void)
-{
-}
-void __init unregister_srm_console(void)
-{
-}
-#endif
-
 void __init
 setup_arch(char **cmdline_p)
 {
@@ -574,7 +530,16 @@
 			continue;
 		}
 		if (strncmp(p, "srmcons", 7) == 0) {
-			srmcons_output = 1;
+			srmcons_output |= 1;
+			continue;
+		}
+		if (strncmp(p, "console=srm", 11) == 0) {
+			srmcons_output |= 2;
+			continue;
+		}
+		if (strncmp(p, "gartsize=", 9) == 0) {
+			alpha_agpgart_size =
+				get_mem_size_limit(p+9) << PAGE_SHIFT;
 			continue;
 		}
 	}
@@ -585,6 +550,13 @@
 	/* If we want SRM console printk echoing early, do it now. */
 	if (alpha_using_srm && srmcons_output) {
 		register_srm_console();
+
+		/*
+		 * If "console=srm" was specified, clear the srmcons_output
+		 * flag now so that time.c won't unregister_srm_console
+		 */
+		if (srmcons_output & 2)
+			srmcons_output = 0;
 	}
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -686,6 +658,15 @@
 	setup_smp();
 #endif
 	paging_init();
+}
+
+void __init
+disable_early_printk(void)
+{
+	if (alpha_using_srm && srmcons_output) {
+		unregister_srm_console();
+		srmcons_output = 0;
+	}
 }
 
 static char sys_unknown[] = "Unknown";
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Mon Feb 10 10:39:27 2003
+++ b/arch/alpha/kernel/signal.c	Mon Feb 10 10:39:27 2003
@@ -63,7 +63,7 @@
 		unsigned long block, unblock;
 
 		newmask &= _BLOCKABLE;
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		oldmask = current->blocked.sig[0];
 
 		unblock = oldmask & ~newmask;
@@ -76,7 +76,7 @@
 			sigemptyset(&current->blocked);
 		current->blocked.sig[0] = newmask;
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 		(&regs)->r0 = 0;		/* special no error return */
 	}
@@ -150,11 +150,11 @@
 	sigset_t oldset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	oldset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
@@ -177,11 +177,11 @@
 		return -EFAULT;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	oldset = current->blocked;
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
@@ -284,10 +284,10 @@
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(&frame->sc, regs, sw))
 		goto give_sigsegv;
@@ -323,10 +323,10 @@
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
 		goto give_sigsegv;
@@ -562,11 +562,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Mon Feb 10 10:39:24 2003
+++ b/arch/alpha/kernel/smp.c	Mon Feb 10 10:39:24 2003
@@ -544,9 +544,6 @@
 	smp_tune_scheduling(boot_cpuid);
 	smp_setup_percpu_timer(boot_cpuid);
 
-	/* We have already have the boot CPU online.. */
-	set_bit(boot_cpuid, &cpu_online_map);
-
 	/* Nothing to do on a UP box, or when told not to.  */
 	if (smp_num_probed == 1 || max_cpus == 0) {
 		cpu_present_mask = 1UL << boot_cpuid;
@@ -574,7 +571,11 @@
 void __devinit
 smp_prepare_boot_cpu(void)
 {
+	/*
+	 * Mark the boot cpu (current cpu) as both present and online
+	 */ 
 	set_bit(smp_processor_id(), &cpu_present_mask);
+	set_bit(smp_processor_id(), &cpu_online_map);
 }
 
 int __devinit
diff -Nru a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/srmcons.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,361 @@
+/*
+ *	linux/arch/alpha/kernel/srmcons.c
+ *
+ * Callback based driver for SRM Console console device.
+ * (TTY driver and console driver)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+
+#include <asm/console.h>
+#include <asm/uaccess.h>
+
+
+static spinlock_t srmcons_callback_lock = SPIN_LOCK_UNLOCKED;
+static int srm_is_registered_console = 0;
+
+/* 
+ * The TTY driver
+ */
+#define MAX_SRM_CONSOLE_DEVICES 1	/* only support 1 console device */
+
+static int srmcons_refcount;
+static struct tty_struct *srmcons_table[MAX_SRM_CONSOLE_DEVICES];
+static struct termios *srmcons_termios[MAX_SRM_CONSOLE_DEVICES];
+static struct termios *srmcons_termios_locked[MAX_SRM_CONSOLE_DEVICES];
+
+struct srmcons_private {
+	struct tty_struct *tty;
+	struct timer_list timer;
+	spinlock_t lock;
+};
+
+typedef union _srmcons_result {
+	struct {
+		unsigned long c :61;
+		unsigned long status :3;
+	} bits;
+	long as_long;
+} srmcons_result;
+
+/* called with callback_lock held */
+static int
+srmcons_do_receive_chars(struct tty_struct *tty)
+{
+	srmcons_result result;
+	int count = 0, loops = 0;
+
+	do {
+		result.as_long = callback_getc(0);
+		if (result.bits.status < 2) {
+			tty_insert_flip_char(tty, (char)result.bits.c, 0);
+			count++;
+		}
+	} while((result.bits.status & 1) && (++loops < 10));
+
+	if (count)
+		tty_schedule_flip(tty);
+
+	return count;
+}
+
+static void
+srmcons_receive_chars(unsigned long data)
+{
+	struct srmcons_private *srmconsp = (struct srmcons_private *)data;
+	unsigned long flags;
+	int incr = 10;
+
+	local_irq_save(flags);
+	if (spin_trylock(&srmcons_callback_lock)) {
+		if (!srmcons_do_receive_chars(srmconsp->tty))
+			incr = 100;
+		spin_unlock(&srmcons_callback_lock);
+	} 
+
+	spin_lock(&srmconsp->lock);
+	if (srmconsp->tty) {
+		srmconsp->timer.expires = jiffies + incr;
+		add_timer(&srmconsp->timer);
+	}
+	spin_unlock(&srmconsp->lock);
+
+	local_irq_restore(flags);
+}
+
+/* called with callback_lock held */
+static int
+srmcons_do_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	unsigned char *str_cr = "\r";
+	long c, remaining = count;
+	srmcons_result result;
+	unsigned char *cur;
+	int need_cr;
+
+	for (cur = (unsigned char *)buf; remaining > 0; ) {
+		need_cr = 0;
+		/* 
+		 * Break it up into reasonable size chunks to allow a chance
+		 * for input to get in
+		 */
+		for (c = 0; c < min_t(long, 128L, remaining) && !need_cr; c++)
+			if (cur[c] == '\n')
+				need_cr = 1;
+		
+		while (c > 0) {
+			result.as_long = callback_puts(0, cur, c);
+			c -= result.bits.c;
+			remaining -= result.bits.c;
+			cur += result.bits.c;
+
+			/*
+			 * Check for pending input iff a tty was provided
+			 */
+			if (tty)
+				srmcons_do_receive_chars(tty);
+		}
+
+		while (need_cr) {
+			result.as_long = callback_puts(0, str_cr, 1);
+			if (result.bits.c > 0)
+				need_cr = 0;
+		}
+	}
+	return count;
+}
+
+static int
+srmcons_write(struct tty_struct *tty, int from_user,
+	      const unsigned char *buf, int count)
+{
+	unsigned long flags;
+
+	if (from_user) {
+		unsigned char tmp[512];
+		int ret = 0;
+		size_t c;
+
+		while ((c = count) > 0) {
+			if (c > sizeof(tmp))
+				c = sizeof(tmp);
+			
+			c -= copy_from_user(tmp, buf, c);
+
+			if (!c) { 
+				printk("%s: EFAULT (count %d)\n",
+				       __FUNCTION__, count);
+				return -EFAULT;
+			}
+
+			spin_lock_irqsave(&srmcons_callback_lock, flags);
+			srmcons_do_write(tty, tmp, c);
+			spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+
+		return ret;
+	}
+
+	spin_lock_irqsave(&srmcons_callback_lock, flags);
+	srmcons_do_write(tty, buf, count);
+	spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+
+	return count;
+}
+
+static int
+srmcons_write_room(struct tty_struct *tty)
+{
+	return 512;
+}
+
+static int
+srmcons_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;
+}
+
+static int
+srmcons_get_private_struct(struct srmcons_private **ps)
+{
+	static struct srmcons_private *srmconsp = NULL;
+	static spinlock_t srmconsp_lock = SPIN_LOCK_UNLOCKED;
+	unsigned long flags;
+	int retval = 0;
+
+	spin_lock_irqsave(&srmconsp_lock, flags);
+
+	do {
+		if (srmconsp != NULL) {
+			*ps = srmconsp;
+			break;
+		}
+
+		srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
+		if (srmconsp == NULL) {
+			retval = -ENOMEM;
+			break;
+		}
+
+		srmconsp->tty = NULL;
+		srmconsp->lock = SPIN_LOCK_UNLOCKED;
+		init_timer(&srmconsp->timer);
+
+		*ps = srmconsp;
+	} while(0);
+
+	spin_unlock_irqrestore(&srmconsp_lock, flags);
+
+	return retval;
+}
+
+static int
+srmcons_open(struct tty_struct *tty, struct file *filp)
+{
+	struct srmcons_private *srmconsp;
+	unsigned long flags;
+	int retval;
+
+	retval = srmcons_get_private_struct(&srmconsp);
+	if (retval)
+		return retval;
+
+	spin_lock_irqsave(&srmconsp->lock, flags);
+
+	if (!srmconsp->tty) {
+		tty->driver_data = srmconsp;
+
+		srmconsp->tty = tty;
+		srmconsp->timer.function = srmcons_receive_chars;
+		srmconsp->timer.data = (unsigned long)srmconsp;
+		srmconsp->timer.expires = jiffies + 10;
+		add_timer(&srmconsp->timer);
+	}
+
+	spin_unlock_irqrestore(&srmconsp->lock, flags);
+
+	return 0;
+}
+
+static void
+srmcons_close(struct tty_struct *tty, struct file *filp)
+{
+	struct srmcons_private *srmconsp = tty->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&srmconsp->lock, flags);
+
+	if (tty->count == 1) {
+		srmconsp->tty = NULL;
+		del_timer(&srmconsp->timer);
+	}
+
+	spin_unlock_irqrestore(&srmconsp->lock, flags);
+}
+
+
+static struct tty_driver srmcons_driver = {
+	.driver_name	= "srm",
+	.name		= "srm",
+	.magic		= TTY_DRIVER_MAGIC,
+	.major		= 0, 	/* dynamic */
+	.minor_start	= 0,
+	.num		= MAX_SRM_CONSOLE_DEVICES,
+	.type		= TTY_DRIVER_TYPE_SYSTEM,
+	.subtype	= SYSTEM_TYPE_SYSCONS,
+
+	.table		= srmcons_table,
+	.termios	= srmcons_termios,
+	.termios_locked	= srmcons_termios_locked,
+	.refcount	= &srmcons_refcount,
+
+	.open		= srmcons_open,
+	.close		= srmcons_close,
+	.write		= srmcons_write,
+	.write_room	= srmcons_write_room,
+	.chars_in_buffer= srmcons_chars_in_buffer,
+};
+
+static int __init
+srmcons_init(void)
+{
+	if (srm_is_registered_console) {
+		srmcons_driver.init_termios = tty_std_termios;
+		return tty_register_driver(&srmcons_driver);
+	}
+
+	return -ENODEV;
+}
+
+module_init(srmcons_init);
+
+
+/*
+ * The console driver
+ */
+static void
+srm_console_write(struct console *co, const char *s, unsigned count)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&srmcons_callback_lock, flags);
+	srmcons_do_write(NULL, s, count);
+	spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+}
+
+static kdev_t
+srm_console_device(struct console *co)
+{
+	return mk_kdev(srmcons_driver.major,
+		       srmcons_driver.minor_start + co->index);
+}
+
+static int __init
+srm_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+static struct console srmcons = {
+	.name		= "srm",
+	.write		= srm_console_write,
+	.device		= srm_console_device,
+	.setup		= srm_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+void __init
+register_srm_console(void)
+{
+	if (!srm_is_registered_console) {
+		callback_open_console();
+		register_console(&srmcons);
+		srm_is_registered_console = 1;
+	}
+}
+
+void __init
+unregister_srm_console(void)
+{
+	if (srm_is_registered_console) {
+		callback_close_console();
+		unregister_console(&srmcons);
+		srm_is_registered_console = 0;
+	}
+}
diff -Nru a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
--- a/arch/alpha/kernel/sys_nautilus.c	Mon Feb 10 10:39:25 2003
+++ b/arch/alpha/kernel/sys_nautilus.c	Mon Feb 10 10:39:25 2003
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/reboot.h>
+#include <linux/bootmem.h>
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
@@ -163,7 +164,7 @@
 	}
 
 	printk(KERN_CRIT "NAUTILUS Machine check 0x%lx "
-			 "[%s  System Machine Check (NMI)]\n",
+			 "[%s System Machine Check (NMI)]\n",
 	       vector, mchk_class);
 
 	naut_sys_machine_check(vector, la_ptr, regs);
@@ -174,6 +175,70 @@
 	mb();
 }
 
+extern void free_reserved_mem(void *, void *);
+
+void __init
+nautilus_init_pci(void)
+{
+	struct pci_controller *hose = hose_head;
+	struct pci_bus *bus;
+	struct pci_dev *irongate;
+	unsigned long saved_io_start, saved_io_end;
+	unsigned long saved_mem_start, saved_mem_end;
+	unsigned long bus_align, bus_size, pci_mem;
+	unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+
+	/* Scan our single hose.  */
+	bus = pci_scan_bus(0, alpha_mv.pci_ops, hose);
+	hose->bus = bus;
+	hose->last_busno = bus->subordinate;
+
+	/* We're going to size the root bus, so we must
+	   - have a non-NULL PCI device associated with the bus
+	   - preserve hose resources. */
+	irongate = pci_find_slot(0, 0);
+	bus->self = irongate;
+	saved_io_start = bus->resource[0]->start;
+	saved_io_end = bus->resource[0]->end;
+	saved_mem_start = bus->resource[1]->start;
+	saved_mem_end = bus->resource[1]->end;
+
+	pci_bus_size_bridges(bus);
+
+	/* Don't care about IO. */
+	bus->resource[0]->start = saved_io_start;
+	bus->resource[0]->end = saved_io_end;
+
+	bus_align = bus->resource[1]->start;
+	bus_size = bus->resource[1]->end + 1 - bus_align;
+	/* Align to 16Mb. */
+	if (bus_align < 0x1000000UL)
+		bus_align = 0x1000000UL;
+
+	/* Restore hose MEM resource. */
+	bus->resource[1]->start = saved_mem_start;
+	bus->resource[1]->end = saved_mem_end;
+
+	pci_mem = (0x100000000UL - bus_size) & -bus_align;
+
+	if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) {
+		free_reserved_mem(__va(alpha_mv.min_mem_address),
+				  __va(pci_mem));
+		printk("nautilus_init_arch: %ldk freed\n",
+			(pci_mem - alpha_mv.min_mem_address) >> 10);
+	}
+
+	alpha_mv.min_mem_address = pci_mem;
+	if ((IRONGATE0->dev_vendor >> 16) > 0x7006)	/* Albacore? */
+		IRONGATE0->pci_mem = pci_mem;
+
+	pci_bus_assign_resources(bus);
+
+	/* To break the loop in common_swizzle() */
+	bus->self = NULL;
+
+	pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
+}
 
 /*
  * The System Vectors
@@ -196,7 +261,7 @@
 	.init_arch		= irongate_init_arch,
 	.init_irq		= nautilus_init_irq,
 	.init_rtc		= common_init_rtc,
-	.init_pci		= common_init_pci,
+	.init_pci		= nautilus_init_pci,
 	.kill_arch		= nautilus_kill_arch,
 	.pci_map_irq		= nautilus_map_irq,
 	.pci_swizzle		= common_swizzle,
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c	Mon Feb 10 10:39:27 2003
+++ b/arch/alpha/kernel/time.c	Mon Feb 10 10:39:27 2003
@@ -44,6 +44,7 @@
 #include <asm/hwrpb.h>
 
 #include <linux/mc146818rtc.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 
 #include "proto.h"
@@ -51,7 +52,6 @@
 
 u64 jiffies_64;
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;	/* kernel/timer.c */
 
 static int set_rtc_mmss(unsigned long);
@@ -106,7 +106,7 @@
 		alpha_do_profile(regs->pc);
 #endif
 
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 
 	/*
 	 * Calculate how many ticks have passed since the last update,
@@ -138,7 +138,7 @@
 		state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
 	}
 
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 void
@@ -383,21 +383,6 @@
 
 	/* Startup the timer source. */
 	alpha_mv.init_rtc();
-
-	/*
-	 * If we had wanted SRM console printk echoing early, undo it now.
-	 *
-	 * "srmcons" specified in the boot command arguments allows us to
-	 * see kernel messages during the period of time before the true
-	 * console device is "registered" during console_init(). As of this
-	 * version (2.4.10), time_init() is the last Alpha-specific code
-	 * called before console_init(), so we put this "unregister" code
-	 * here to prevent schizophrenic console behavior later... ;-}
-	 */
-	if (alpha_using_srm && srmcons_output) {
-		unregister_srm_console();
-		srmcons_output = 0;
-	}
 }
 
 /*
@@ -410,18 +395,20 @@
 void
 do_gettimeofday(struct timeval *tv)
 {
-	unsigned long sec, usec, lost, flags;
+	unsigned long flags;
+	unsigned long sec, usec, lost, seq;
 	unsigned long delta_cycles, delta_usec, partial_tick;
 
-	read_lock_irqsave(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	delta_cycles = rpcc() - state.last_time;
-	sec = xtime.tv_sec;
-	usec = (xtime.tv_nsec / 1000);
-	partial_tick = state.partial_tick;
-	lost = jiffies - wall_jiffies;
+		delta_cycles = rpcc() - state.last_time;
+		sec = xtime.tv_sec;
+		usec = (xtime.tv_nsec / 1000);
+		partial_tick = state.partial_tick;
+		lost = jiffies - wall_jiffies;
 
-	read_unlock_irqrestore(&xtime_lock, flags);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 #ifdef CONFIG_SMP
 	/* Until and unless we figure out how to get cpu cycle counters
@@ -463,7 +450,7 @@
 	unsigned long delta_usec;
 	long sec, usec;
 	
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 
 	/* The offset that is added into time in do_gettimeofday above
 	   must be subtracted out here to keep a coherent view of the
@@ -494,7 +481,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/Kconfig	Mon Feb 10 10:39:27 2003
@@ -577,7 +577,7 @@
 	  your machine has an FPA or floating point co-processor podule.
 
 	  It is also possible to say M to build the emulator as a module
-	  (nwfpe.o) or indeed to leave it out altogether. However, unless you
+	  (nwfpe) or indeed to leave it out altogether. However, unless you
 	  know what you are doing this can easily render your machine
 	  unbootable. Saying Y is the safe option.
 
@@ -599,7 +599,7 @@
 	  choose NWFPE.
 
 	  It is also possible to say M to build the emulator as a module
-	  (fastfpe.o).  But keep in mind that you should only load the FP
+	  (fastfpe).  But keep in mind that you should only load the FP
 	  emulator early in the bootup.  You should never change from NWFPE to
 	  FASTFPE or vice versa in an active system!
 
@@ -654,7 +654,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -684,7 +684,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -709,7 +709,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config PM
@@ -804,7 +804,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  apm.o.
+	  apm.
 
 config ARTHUR
 	tristate "RISC OS personality"
@@ -814,7 +814,7 @@
 	  Acorn RISC OS/Arthur binaries under Linux. This code is still very
 	  experimental; if this sounds frightening, say N and sleep in peace.
 	  You can also say M here to compile this support as a module (which
-	  will be called arthur.o).
+	  will be called arthur).
 
 config CMDLINE
 	string "Default kernel command string"
@@ -946,7 +946,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -973,7 +973,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -1036,7 +1036,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile	Mon Feb 10 10:39:25 2003
+++ b/arch/arm/Makefile	Mon Feb 10 10:39:25 2003
@@ -17,7 +17,7 @@
 CFLAGS		:=$(CFLAGS:-O2=-Os)
 
 ifeq ($(CONFIG_FRAME_POINTER),y)
-CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
+CFLAGS		+=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
 endif
 
 ifeq ($(CONFIG_DEBUG_INFO),y)
@@ -36,7 +36,7 @@
 # series of macros.
 arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
 arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
-arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 -march=armv5
+arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 -march=armv5te
 arch-$(CONFIG_CPU_XSCALE)	:=-D__LINUX_ARM_ARCH__=5 -march=armv4 -Wa,-mxscale #-march=armv5te
 
 # This selects how we optimise for the processor.
@@ -61,7 +61,7 @@
 
 ifeq ($(CONFIG_CPU_26),y)
 PROCESSOR	:= armo
-HEAD		:= arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o
+head-y		:= arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o
 LDFLAGS_BLOB	+= --oformat elf26-littlearm
   ifeq ($(CONFIG_ROM_KERNEL),y)
     DATAADDR	 := 0x02080000
@@ -73,7 +73,7 @@
 
 ifeq ($(CONFIG_CPU_32),y)
 PROCESSOR	:= armv
-HEAD		:= arch/arm/kernel/head.o arch/arm/kernel/init_task.o
+head-y		:= arch/arm/kernel/head.o arch/arm/kernel/init_task.o
 LDFLAGS_BLOB	+= --oformat elf32-littlearm
 textaddr-y	:= 0xC0008000
 endif
@@ -124,10 +124,10 @@
 endif
 
 # If we have a machine-specific directory, then include it in the build.
+core-y				+= arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
 ifneq ($(MACHINE),)
 core-y				+= arch/arm/mach-$(MACHINE)/
 endif
-core-y				+= arch/arm/kernel/ arch/arm/mm/
 core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwfpe/
 core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 
@@ -181,7 +181,6 @@
 	include/asm-arm/mach-types.h
 
 # We use MRPROPER_FILES and CLEAN_FILES now
-archmrproper:
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 
diff -Nru a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
--- a/arch/arm/boot/compressed/head.S	Mon Feb 10 10:39:32 2003
+++ b/arch/arm/boot/compressed/head.S	Mon Feb 10 10:39:32 2003
@@ -664,5 +664,5 @@
 reloc_end:
 
 		.align
-		.section ".stack", "aw"
+		.section ".stack", "w"
 user_stack:	.space	4096
diff -Nru a/arch/arm/common/Makefile b/arch/arm/common/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/Makefile	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-$(CONFIG_SA1111)	+= sa1111.o sa1111-pcibuf.o sa1111-pcipool.o
+
+obj-$(CONFIG_PCI_HOST_PLX90X0)	+= plx90x0.o
+obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
diff -Nru a/arch/arm/common/plx90x0.c b/arch/arm/common/plx90x0.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/plx90x0.c	Mon Feb 10 10:39:24 2003
@@ -0,0 +1,178 @@
+/* 
+ * Driver for PLX Technology PCI9000-series host bridge.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Since the following functions are all very similar, the common parts
+ * are pulled out into these macros.
+ */
+
+#define PLX_CLEAR_CONFIG						\
+	__raw_writel(0, PLX_BASE + 0xac);				\
+	local_irq_restore(flags); }
+
+#define PLX_SET_CONFIG							\
+	{ unsigned long flags;						\
+	local_irq_save(flags);						\
+	__raw_writel((1<<31 | (bus->number << 16)			\
+		| (devfn << 8) | (where & ~3)				\
+		| ((bus->number == 0)?0:1)), PLX_BASE + 0xac);		\
+
+#define PLX_CONFIG_WRITE(size)						\
+	PLX_SET_CONFIG							\
+	__raw_write##size(value, PCIO_BASE + (where & 3));		\
+	if (__raw_readw(PLX_BASE + 0x6) & 0x2000)			\
+		__raw_writew(0x2000, PLX_BASE + 0x6);			\
+	PLX_CLEAR_CONFIG						\
+	return PCIBIOS_SUCCESSFUL;
+
+#define PLX_CONFIG_READ(size)						\
+	PLX_SET_CONFIG							\
+	*value = __raw_read##size(PCIO_BASE + (where & 3));		\
+	if (__raw_readw(PLX_BASE + 0x6) & 0x2000) {			\
+		__raw_writew(0x2000, PLX_BASE + 0x6);			\
+		*value = 0xffffffffUL;					\
+	}								\
+	PLX_CLEAR_CONFIG						\
+	return PCIBIOS_SUCCESSFUL;
+
+/* Configuration space access routines */
+
+static int 
+plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where,
+		     int where, int size, u32 *value)
+{
+	switch (size) {
+	case 1:
+		PLX_CONFIG_READ(b)
+		break;
+	case 2:
+		PLX_CONFIG_READ(w)
+		break;
+	case 4:
+		PLX_CONFIG_READ(l)
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int 
+plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where,
+		      int where, int size, u32 value)
+{
+	switch (size) {
+	case 1:
+		PLX_CONFIG_WRITE(b)
+		break;
+	case 2:
+		PLX_CONFIG_WRITE(w)
+		break;
+	case 4:
+		PLX_CONFIG_WRITE(l)
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops plx90x0_ops = 
+{
+	.read	= plx90x0_read_config,
+	.write	= plx90x0_write_config,
+};
+
+static void 
+plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
+{
+	printk("PLX90x0: machine check %04x (pc=%08lx)\n", 
+	       readw(PLX_BASE + 6), regs->ARM_pc);
+	__raw_writew(0xf000, PLX_BASE + 6);
+}
+
+/*
+ * Initialise the PCI system.
+ */
+
+void __init
+plx90x0_init(struct arm_sysdata *sysdata)
+{
+	static const unsigned long int base = PLX_BASE;
+	char *what;
+	unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
+
+	/* Have a sniff around and see which PLX device is present. */
+	unsigned long id = __raw_readl(base + 0xf0);
+	
+#if 0
+	/* This check was a good idea, but can fail.  The PLX9060 puts no
+	   default value in these registers unless NB# is asserted (which it
+	   isn't on these cards).  */
+	if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
+		return;		/* Nothing found */
+#endif
+
+	/* Found one - now work out what it is. */
+	switch (id >> 16) {
+	case 0:		/* PCI_DEVICE_ID_PLX_9060 */
+		what = "PCI9060";
+		break;
+	case PCI_DEVICE_ID_PLX_9060ES:
+		what = "PCI9060ES";
+		break;
+	case PCI_DEVICE_ID_PLX_9060SD:
+		what = "PCI9060SD";		/* uhuhh.. */
+		break;
+	case PCI_DEVICE_ID_PLX_9080:
+		what = "PCI9080";
+		break;
+	default:
+		printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
+		       id >> 16);
+		return;
+	}
+	
+	printk("PCI: PLX Technology %s host bridge found.\n", what);
+	
+	/* Now set it up for both master and slave accesses. */
+	__raw_writel(0xffff0147,	base + 0x4);
+	__raw_writeb(32,		base + 0xd);
+	__raw_writel(0x8 | bar,		base + 0x18);
+	__raw_writel(0xf8000008,	base + 0x80);
+	__raw_writel(0x40000001,	base + 0x84);
+	__raw_writel(0,			base + 0x88);
+	__raw_writel(0,			base + 0x8c);
+	__raw_writel(0x11,		base + 0x94);
+	__raw_writel(0xC3 + (4 << 28)
+		+ (8 << 11) + (1 << 10)
+		     + (1 << 24),	base + 0x98);
+	__raw_writel(0xC0000000,	base + 0x9c);
+	__raw_writel(PLX_MEM_START,	base + 0xa0);
+	__raw_writel(PLX_IO_START,	base + 0xa4);
+	__raw_writel(0x3,		base + 0xa8);
+	__raw_writel(0,			base + 0xac);
+	__raw_writel(0x10001,		base + 0xe8);
+	__raw_writel(0x8000767e,	base + 0xec);
+	
+	request_irq(IRQ_SYSERR, plx_syserr_handler, 0, 
+		    "system error", NULL);
+
+	pci_scan_bus(0, &plx90x0_ops, sysdata);
+}
diff -Nru a/arch/arm/common/sa1111-pcibuf.c b/arch/arm/common/sa1111-pcibuf.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/sa1111-pcibuf.c	Mon Feb 10 10:39:22 2003
@@ -0,0 +1,551 @@
+/*
+ *  linux/arch/arm/mach-sa1100/pci-sa1111.c
+ *
+ *  Special pci_{map/unmap/dma_sync}_* routines for SA-1111.
+ *
+ *  These functions utilize bouncer buffers to compensate for a bug in
+ *  the SA-1111 hardware which don't allow DMA to/from addresses
+ *  certain addresses above 1MB.
+ *
+ *  Re-written by Christopher Hoover <ch@murgatroid.com>
+ *  Original version by Brad Parker (brad@heeltoe.com)
+ *
+ *  Copyright (C) 2002 Hewlett Packard Company.
+ *
+ *  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/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+#include <asm/hardware/sa1111.h>
+
+//#define DEBUG
+#ifdef DEBUG
+#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0)
+#else
+#define DPRINTK(...) do { } while (0)
+#endif
+
+//#define STATS
+#ifdef STATS
+#define DO_STATS(X) do { X ; } while (0)
+#else
+#define DO_STATS(X) do { } while (0)
+#endif
+
+/* ************************************************** */
+
+struct safe_buffer {
+	struct list_head node;
+
+	/* original request */
+	void		*ptr;
+	size_t		size;
+	int		direction;
+
+	/* safe buffer info */
+	struct pci_pool *pool;
+	void		*safe;
+	dma_addr_t	safe_dma_addr;
+};
+
+LIST_HEAD(safe_buffers);
+
+
+#define SIZE_SMALL	1024
+#define SIZE_LARGE	(4*1024)
+
+static struct pci_pool *small_buffer_pool, *large_buffer_pool;
+
+#ifdef STATS
+static unsigned long sbp_allocs __initdata = 0;
+static unsigned long lbp_allocs __initdata = 0;
+static unsigned long total_allocs __initdata= 0;
+
+static void print_alloc_stats(void)
+{
+	printk(KERN_INFO
+	       "sa1111_pcibuf: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
+	       sbp_allocs, lbp_allocs,
+	       total_allocs - sbp_allocs - lbp_allocs, total_allocs);
+}
+#endif
+
+static int __init
+create_safe_buffer_pools(void)
+{
+	small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
+					    SIZE_SMALL,
+					    0 /* byte alignment */,
+					    0 /* no page-crossing issues */);
+	if (0 == small_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate small pci pool\n");
+		return -1;
+	}
+
+	large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
+					    SIZE_LARGE,
+					    0 /* byte alignment */,
+					    0 /* no page-crossing issues */);
+	if (0 == large_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate large pci pool\n");
+		pci_pool_destroy(small_buffer_pool);
+		small_buffer_pool = 0;
+		return -1;
+	}
+
+	printk(KERN_INFO
+	       "sa1111_pcibuf: buffer sizes: small=%u, large=%u\n",
+	       SIZE_SMALL, SIZE_LARGE);
+
+	return 0;
+}
+
+static void __exit
+destroy_safe_buffer_pools(void)
+{
+	if (small_buffer_pool)
+		pci_pool_destroy(small_buffer_pool);
+	if (large_buffer_pool)
+		pci_pool_destroy(large_buffer_pool);
+
+	small_buffer_pool = large_buffer_pool = 0;
+}
+
+
+/* allocate a 'safe' buffer and keep track of it */
+static struct safe_buffer *
+alloc_safe_buffer(void *ptr, size_t size, int direction)
+{
+	struct safe_buffer *buf;
+	struct pci_pool *pool;
+	void *safe;
+	dma_addr_t safe_dma_addr;
+
+	DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n",
+		__func__, ptr, size, direction);
+
+	DO_STATS ( total_allocs++ );
+
+	buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
+	if (buf == 0) {
+		printk(KERN_WARNING "%s: kmalloc failed\n", __func__);
+		return 0;
+	}
+
+	if (size <= SIZE_SMALL) {
+		pool = small_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+
+		DO_STATS ( sbp_allocs++ );
+	} else if (size <= SIZE_LARGE) {
+		pool = large_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+
+		DO_STATS ( lbp_allocs++ );
+	} else {
+		pool = 0;
+		safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size,
+					    &safe_dma_addr);
+	}
+
+	if (safe == 0) {
+		printk(KERN_WARNING
+		       "%s: could not alloc dma memory (size=%d)\n",
+		       __func__, size);
+		kfree(buf);
+		return 0;
+	}
+
+#ifdef STATS
+	if (total_allocs % 1000 == 0)
+		print_alloc_stats();
+#endif
+
+	BUG_ON(sa1111_check_dma_bug(safe_dma_addr));	// paranoia
+
+	buf->ptr = ptr;
+	buf->size = size;
+	buf->direction = direction;
+	buf->pool = pool;
+	buf->safe = safe;
+	buf->safe_dma_addr = safe_dma_addr;
+
+	MOD_INC_USE_COUNT;
+	list_add(&buf->node, &safe_buffers);
+
+	return buf;
+}
+
+/* determine if a buffer is from our "safe" pool */
+static struct safe_buffer *
+find_safe_buffer(dma_addr_t safe_dma_addr)
+{
+	struct list_head *entry;
+
+	list_for_each(entry, &safe_buffers) {
+		struct safe_buffer *b =
+			list_entry(entry, struct safe_buffer, node);
+
+		if (b->safe_dma_addr == safe_dma_addr) {
+			return b;
+		}
+	}
+
+	return 0;
+}
+
+static void
+free_safe_buffer(struct safe_buffer *buf)
+{
+	DPRINTK("%s(buf=%p)\n", __func__, buf);
+
+	list_del(&buf->node);
+
+	if (buf->pool)
+		pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
+	else
+		pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe,
+				    buf->safe_dma_addr);
+	kfree(buf);
+
+	MOD_DEC_USE_COUNT;
+}
+
+static inline int
+dma_range_is_safe(dma_addr_t addr, size_t size)
+{
+	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr);
+
+	/* Any address within one megabyte of the start of the target
+         * bank will be OK.  This is an overly conservative test:
+         * other addresses can be OK depending on the dram
+         * configuration.  (See sa1111.c:sa1111_check_dma_bug() * for
+         * details.)
+	 *
+	 * We take care to ensure the entire dma region is within
+	 * the safe range.
+	 */
+
+	return ((physaddr + size - 1) < (1<<20));
+}
+
+/* ************************************************** */
+
+#ifdef STATS
+static unsigned long map_op_count __initdata = 0;
+static unsigned long bounce_count __initdata = 0;
+
+static void print_map_stats(void)
+{
+	printk(KERN_INFO
+	       "sa1111_pcibuf: map_op_count=%lu, bounce_count=%lu\n",
+	       map_op_count, bounce_count);
+}
+#endif
+
+static dma_addr_t
+map_single(void *ptr, size_t size, int direction)
+{
+	dma_addr_t dma_addr;
+
+	DO_STATS ( map_op_count++ );
+
+	dma_addr = virt_to_bus(ptr);
+
+	if (!dma_range_is_safe(dma_addr, size)) {
+		struct safe_buffer *buf;
+
+		DO_STATS ( bounce_count++ ) ;
+
+		buf = alloc_safe_buffer(ptr, size, direction);
+		if (buf == 0) {
+			printk(KERN_ERR
+			       "%s: unable to map unsafe buffer %p!\n",
+			       __func__, ptr);
+			return 0;
+		}
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		if ((direction == PCI_DMA_TODEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__, ptr, buf->safe, size);
+			memcpy(buf->safe, ptr, size);
+		}
+		consistent_sync(buf->safe, size, direction);
+
+		dma_addr = buf->safe_dma_addr;
+	} else {
+		consistent_sync(ptr, size, direction);
+	}
+
+#ifdef STATS
+	if (map_op_count % 1000 == 0)
+		print_map_stats();
+#endif
+
+	return dma_addr;
+}
+
+static void
+unmap_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	struct safe_buffer *buf;
+
+	buf = find_safe_buffer(dma_addr);
+
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+
+		DO_STATS ( bounce_count++ );
+
+		if ((direction == PCI_DMA_FROMDEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+		}
+		free_safe_buffer(buf);
+	}
+}
+
+static void
+sync_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	struct safe_buffer *buf;
+
+	buf = find_safe_buffer(dma_addr);
+
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		DO_STATS ( bounce_count++ );
+
+		switch (direction) {
+		case PCI_DMA_FROMDEVICE:
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+			break;
+		case PCI_DMA_TODEVICE:
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__,buf->ptr, buf->safe, size);
+			memcpy(buf->safe, buf->ptr, size);
+			break;
+		case PCI_DMA_BIDIRECTIONAL:
+			BUG();	/* is this allowed?  what does it mean? */
+		default:
+			BUG();
+		}
+		consistent_sync(buf->safe, size, direction);
+	} else {
+		consistent_sync(bus_to_virt(dma_addr), size, direction);
+	}
+}
+
+/* ************************************************** */
+
+/*
+ * see if a buffer address is in an 'unsafe' range.  if it is
+ * allocate a 'safe' buffer and copy the unsafe buffer into it.
+ * substitute the safe buffer for the unsafe one.
+ * (basically move the buffer from an unsafe area to a safe one)
+ */
+dma_addr_t
+sa1111_map_single(void *ptr, size_t size, int direction)
+{
+	unsigned long flags;
+	dma_addr_t dma_addr;
+
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+	       __func__, ptr, size, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	dma_addr = map_single(ptr, size, direction);
+
+	local_irq_restore(flags);
+
+	return dma_addr;
+}
+
+/*
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer.  (basically return things back to the way they
+ * should be)
+ */
+
+void
+sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	unsigned long flags;
+
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	unmap_single(dma_addr, size, direction);
+
+	local_irq_restore(flags);
+}
+
+int
+sa1111_map_sg(struct scatterlist *sg, int nents, int direction)
+{
+	unsigned long flags;
+	int i;
+
+	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
+		__func__, sg, nents, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	for (i = 0; i < nents; i++, sg++) {
+		struct page *page = sg->page;
+		unsigned int offset = sg->offset;
+		unsigned int length = sg->length;
+		void *ptr = page_address(page) + offset;
+
+		sg->dma_address =
+			map_single(ptr, length, direction);
+	}
+
+	local_irq_restore(flags);
+
+	return nents;
+}
+
+void
+sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction)
+{
+	unsigned long flags;
+	int i;
+
+	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
+		__func__, sg, nents, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	for (i = 0; i < nents; i++, sg++) {
+		dma_addr_t dma_addr = sg->dma_address;
+		unsigned int length = sg->length;
+
+		unmap_single(dma_addr, length, direction);
+	}
+
+	local_irq_restore(flags);
+}
+
+void
+sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	unsigned long flags;
+
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
+
+	local_irq_save(flags);
+
+	sync_single(dma_addr, size, direction);
+
+	local_irq_restore(flags);
+}
+
+void
+sa1111_dma_sync_sg(struct scatterlist *sg, int nents, int direction)
+{
+	unsigned long flags;
+	int i;
+
+	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
+		__func__, sg, nents, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	for (i = 0; i < nents; i++, sg++) {
+		dma_addr_t dma_addr = sg->dma_address;
+		unsigned int length = sg->length;
+
+		sync_single(dma_addr, length, direction);
+	}
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(sa1111_map_single);
+EXPORT_SYMBOL(sa1111_unmap_single);
+EXPORT_SYMBOL(sa1111_map_sg);
+EXPORT_SYMBOL(sa1111_unmap_sg);
+EXPORT_SYMBOL(sa1111_dma_sync_single);
+EXPORT_SYMBOL(sa1111_dma_sync_sg);
+
+/* **************************************** */
+
+static int __init sa1111_pcibuf_init(void)
+{
+	int ret;
+
+	printk(KERN_DEBUG
+	       "sa1111_pcibuf: initializing SA-1111 DMA workaround\n");
+
+	ret = create_safe_buffer_pools();
+
+	return ret;
+}
+module_init(sa1111_pcibuf_init);
+
+static void __exit sa1111_pcibuf_exit(void)
+{
+	BUG_ON(!list_empty(&safe_buffers));
+
+#ifdef STATS
+	print_alloc_stats();
+	print_map_stats();
+#endif
+
+	destroy_safe_buffer_pools();
+}
+module_exit(sa1111_pcibuf_exit);
+
+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
+MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111.");
+MODULE_LICENSE("GPL");
diff -Nru a/arch/arm/common/sa1111-pcipool.c b/arch/arm/common/sa1111-pcipool.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/sa1111-pcipool.c	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,390 @@
+/*
+  NOTE:
+
+  this code was lifted straight out of drivers/pci/pci.c;
+  when compiling for the Intel StrongARM SA-1110/SA-1111 the
+  usb-ohci.c driver needs these routines even when the architecture
+  has no pci bus...
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+
+#include <asm/page.h>
+
+/*
+ * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
+ * small blocks are easily used by drivers for bus mastering controllers.
+ * This should probably be sharing the guts of the slab allocator.
+ */
+
+struct pci_pool {	/* the pool */
+	struct list_head	page_list;
+	spinlock_t		lock;
+	size_t			blocks_per_page;
+	size_t			size;
+	struct pci_dev		*dev;
+	size_t			allocation;
+	char			name [32];
+	wait_queue_head_t	waitq;
+};
+
+struct pci_page {	/* cacheable header for 'allocation' bytes */
+	struct list_head	page_list;
+	void			*vaddr;
+	dma_addr_t		dma;
+	unsigned long		bitmap [0];
+};
+
+#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
+#define	POOL_POISON_BYTE	0xa7
+
+// #define CONFIG_PCIPOOL_DEBUG
+
+static inline const char *slot_name(const struct pci_pool *pool)
+{
+	const struct pci_dev *pdev = pool->dev;
+
+	if (pdev == 0)
+		return "[0]";
+
+	else if (pcidev_is_sa1111(pdev))
+		return "[SA-1111]";
+	else
+		return pdev->slot_name;
+}
+
+
+/**
+ * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
+ * @name: name of pool, for diagnostics
+ * @pdev: pci device that will be doing the DMA
+ * @size: size of the blocks in this pool.
+ * @align: alignment requirement for blocks; must be a power of two
+ * @allocation: returned blocks won't cross this boundary (or zero)
+ * Context: !in_interrupt()
+ *
+ * Returns a pci allocation pool with the requested characteristics, or
+ * null if one can't be created.  Given one of these pools, pci_pool_alloc()
+ * may be used to allocate memory.  Such memory will all have "consistent"
+ * DMA mappings, accessible by the device and its driver without using
+ * cache flushing primitives.  The actual size of blocks allocated may be
+ * larger than requested because of alignment.
+ *
+ * If allocation is nonzero, objects returned from pci_pool_alloc() won't
+ * cross that size boundary.  This is useful for devices which have
+ * addressing restrictions on individual DMA transfers, such as not crossing
+ * boundaries of 4KBytes.
+ */
+struct pci_pool *
+pci_pool_create (const char *name, struct pci_dev *pdev,
+	size_t size, size_t align, size_t allocation)
+{
+	struct pci_pool		*retval;
+
+	if (align == 0)
+		align = 1;
+	if (size == 0)
+		return 0;
+	else if (size < align)
+		size = align;
+	else if ((size % align) != 0) {
+		size += align + 1;
+		size &= ~(align - 1);
+	}
+
+	if (allocation == 0) {
+		if (PAGE_SIZE < size)
+			allocation = size;
+		else
+			allocation = PAGE_SIZE;
+		// FIXME: round up for less fragmentation
+	} else if (allocation < size)
+		return 0;
+
+	if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL)))
+		return retval;
+
+	strncpy (retval->name, name, sizeof retval->name);
+	retval->name [sizeof retval->name - 1] = 0;
+
+	retval->dev = pdev;
+	INIT_LIST_HEAD (&retval->page_list);
+	spin_lock_init (&retval->lock);
+	retval->size = size;
+	retval->allocation = allocation;
+	retval->blocks_per_page = allocation / size;
+	init_waitqueue_head (&retval->waitq);
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
+		slot_name(retval), retval->name, size,
+		retval->blocks_per_page, allocation);
+#endif
+
+	return retval;
+}
+
+
+static struct pci_page *
+pool_alloc_page (struct pci_pool *pool, int mem_flags)
+{
+	struct pci_page	*page;
+	int		mapsize;
+
+	mapsize = pool->blocks_per_page;
+	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	mapsize *= sizeof (long);
+
+	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+	if (!page)
+		return 0;
+	page->vaddr = pci_alloc_consistent (pool->dev,
+					    pool->allocation,
+					    &page->dma);
+	if (page->vaddr) {
+		memset (page->bitmap, 0xff, mapsize);	// bit set == free
+#ifdef	CONFIG_DEBUG_SLAB
+		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+		list_add (&page->page_list, &pool->page_list);
+	} else {
+		kfree (page);
+		page = 0;
+	}
+	return page;
+}
+
+
+static inline int
+is_page_busy (int blocks, unsigned long *bitmap)
+{
+	while (blocks > 0) {
+		if (*bitmap++ != ~0UL)
+			return 1;
+		blocks -= BITS_PER_LONG;
+	}
+	return 0;
+}
+
+static void
+pool_free_page (struct pci_pool *pool, struct pci_page *page)
+{
+	dma_addr_t	dma = page->dma;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
+	list_del (&page->page_list);
+	kfree (page);
+}
+
+
+/**
+ * pci_pool_destroy - destroys a pool of pci memory blocks.
+ * @pool: pci pool that will be destroyed
+ *
+ * Caller guarantees that no more memory from the pool is in use,
+ * and that nothing will try to use the pool after this call.
+ */
+void
+pci_pool_destroy (struct pci_pool *pool)
+{
+	unsigned long		flags;
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
+		slot_name(pool), pool->name);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	while (!list_empty (&pool->page_list)) {
+		struct pci_page		*page;
+		page = list_entry (pool->page_list.next,
+				struct pci_page, page_list);
+		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
+			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
+				slot_name(pool), pool->name, page->vaddr);
+			/* leak the still-in-use consistent memory */
+			list_del (&page->page_list);
+			kfree (page);
+		} else
+			pool_free_page (pool, page);
+	}
+	spin_unlock_irqrestore (&pool->lock, flags);
+	kfree (pool);
+}
+
+
+/**
+ * pci_pool_alloc - get a block of consistent memory
+ * @pool: pci pool that will produce the block
+ * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
+ * @handle: pointer to dma address of block
+ *
+ * This returns the kernel virtual address of a currently unused block,
+ * and reports its dma address through the handle.
+ * If such a memory block can't be allocated, null is returned.
+ */
+void *
+pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+	int			map, block;
+	size_t			offset;
+	void			*retval;
+
+restart:
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		int		i;
+		page = list_entry (entry, struct pci_page, page_list);
+		/* only cachable accesses here ... */
+		for (map = 0, i = 0;
+				i < pool->blocks_per_page;
+				i += BITS_PER_LONG, map++) {
+			if (page->bitmap [map] == 0)
+				continue;
+			block = ffz (~ page->bitmap [map]);
+			if ((i + block) < pool->blocks_per_page) {
+				clear_bit (block, &page->bitmap [map]);
+				offset = (BITS_PER_LONG * map) + block;
+				offset *= pool->size;
+				goto ready;
+			}
+		}
+	}
+	if (!(page = pool_alloc_page (pool, mem_flags))) {
+		if (mem_flags == SLAB_KERNEL) {
+			DECLARE_WAITQUEUE (wait, current);
+
+			current->state = TASK_INTERRUPTIBLE;
+			add_wait_queue (&pool->waitq, &wait);
+			spin_unlock_irqrestore (&pool->lock, flags);
+
+			schedule_timeout (POOL_TIMEOUT_JIFFIES);
+
+			current->state = TASK_RUNNING;
+			remove_wait_queue (&pool->waitq, &wait);
+			goto restart;
+		}
+		retval = 0;
+		goto done;
+	}
+
+	clear_bit (0, &page->bitmap [0]);
+	offset = 0;
+ready:
+	retval = offset + page->vaddr;
+	*handle = offset + page->dma;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return retval;
+}
+
+
+static struct pci_page *
+pool_find_page (struct pci_pool *pool, dma_addr_t dma)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		page = list_entry (entry, struct pci_page, page_list);
+		if (dma < page->dma)
+			continue;
+		if (dma < (page->dma + pool->allocation))
+			goto done;
+	}
+	page = 0;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return page;
+}
+
+
+/**
+ * pci_pool_free - put block back into pci pool
+ * @pool: the pci pool holding the block
+ * @vaddr: virtual address of block
+ * @dma: dma address of block
+ *
+ * Caller promises neither device nor driver will again touch this block
+ * unless it is first re-allocated.
+ */
+void
+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
+{
+	struct pci_page		*page;
+	unsigned long		flags;
+	int			map, block;
+
+	if ((page = pool_find_page (pool, dma)) == 0) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+
+	block = dma - page->dma;
+	block /= pool->size;
+	map = block / BITS_PER_LONG;
+	block %= BITS_PER_LONG;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+	if (page->bitmap [map] & (1UL << block)) {
+		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, dma);
+		return;
+	}
+	memset (vaddr, POOL_POISON_BYTE, pool->size);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	set_bit (block, &page->bitmap [map]);
+	if (waitqueue_active (&pool->waitq))
+		wake_up (&pool->waitq);
+	/*
+	 * Resist a temptation to do
+	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
+	 * it is not interrupt safe. Better have empty pages hang around.
+	 */
+	spin_unlock_irqrestore (&pool->lock, flags);
+}
+
+EXPORT_SYMBOL (pci_pool_create);
+EXPORT_SYMBOL (pci_pool_destroy);
+EXPORT_SYMBOL (pci_pool_alloc);
+EXPORT_SYMBOL (pci_pool_free);
+
+/* **************************************** */
+
+static int __init pcipool_init(void)
+{
+	MOD_INC_USE_COUNT;	/* never unload */
+
+	return 0;
+}
+module_init(pcipool_init);
+
+MODULE_LICENSE("GPL");
diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/sa1111.c	Mon Feb 10 10:39:32 2003
@@ -0,0 +1,1107 @@
+/*
+ * linux/arch/arm/mach-sa1100/sa1111.c
+ *
+ * SA1111 support
+ *
+ * Original code by John Dorsey
+ *
+ * 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 file contains all generic SA1111 support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware/sa1111.h>
+
+/*
+ * We keep the following data for the overall SA1111.  Note that the
+ * struct device and struct resource are "fake"; they should be supplied
+ * by the bus above us.  However, in the interests of getting all SA1111
+ * drivers converted over to the device model, we provide this as an
+ * anchor point for all the other drivers.
+ */
+struct sa1111 {
+	struct device	*dev;
+	struct resource	res;
+	int		irq;
+	spinlock_t	lock;
+	void		*base;
+};
+
+/*
+ * We _really_ need to eliminate this.  Its only users
+ * are the PWM and DMA checking code.
+ */
+static struct sa1111 *g_sa1111;
+
+static struct sa1111_dev usb_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [USB Controller]",
+	},
+	.skpcr_mask	= SKPCR_UCLKEN,
+	.devid		= SA1111_DEVID_USB,
+	.irq = {
+		IRQ_USBPWR,
+		IRQ_HCIM,
+		IRQ_HCIBUFFACC,
+		IRQ_HCIRMTWKP,
+		IRQ_NHCIMFCIR,
+		IRQ_USB_PORT_RESUME
+	},
+};
+
+static struct sa1111_dev sac_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [Audio Controller]",
+	},
+	.skpcr_mask	= SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+	.devid		= SA1111_DEVID_SAC,
+	.irq = {
+		AUDXMTDMADONEA,
+		AUDXMTDMADONEB,
+		AUDRCVDMADONEA,
+		AUDRCVDMADONEB
+	},
+};
+
+static struct sa1111_dev ssp_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [SSP Controller]",
+	},
+	.skpcr_mask	= SKPCR_SCLKEN,
+	.devid		= SA1111_DEVID_SSP,
+};
+
+static struct sa1111_dev kbd_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [PS2]",
+	},
+	.skpcr_mask	= SKPCR_PTCLKEN,
+	.devid		= SA1111_DEVID_PS2,
+	.irq = {
+		IRQ_TPRXINT,
+		IRQ_TPTXINT
+	},
+};
+
+static struct sa1111_dev mse_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [PS2]",
+	},
+	.skpcr_mask	= SKPCR_PMCLKEN,
+	.devid		= SA1111_DEVID_PS2,
+	.irq = {
+		IRQ_MSRXINT,
+		IRQ_MSTXINT
+	},
+};
+
+static struct sa1111_dev int_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [Interrupt Controller]",
+	},
+	.skpcr_mask	= 0,
+	.devid		= SA1111_DEVID_INT,
+};
+
+static struct sa1111_dev pcmcia_dev = {
+	.dev = {
+		.name	= "Intel Corporation SA1111 [PCMCIA Controller]",
+	},
+	.skpcr_mask	= 0,
+	.devid		= SA1111_DEVID_PCMCIA,
+	.irq = {
+		IRQ_S0_READY_NINT,
+		IRQ_S0_CD_VALID,
+		IRQ_S0_BVD1_STSCHG,
+		IRQ_S1_READY_NINT,
+		IRQ_S1_CD_VALID,
+		IRQ_S1_BVD1_STSCHG,
+	},
+};
+
+static struct sa1111_dev *devs[] = {
+	&usb_dev,
+	&sac_dev,
+	&ssp_dev,
+	&kbd_dev,
+	&mse_dev,
+	&pcmcia_dev,
+};
+
+static unsigned int dev_offset[] = {
+	SA1111_USB,
+	0x0600,
+	0x0800,
+	SA1111_KBD,
+	SA1111_MSE,
+	0x1800,
+};
+
+/*
+ * SA1111 interrupt support.  Since clearing an IRQ while there are
+ * active IRQs causes the interrupt output to pulse, the upper levels
+ * will call us again if there are more interrupts to process.
+ */
+static void
+sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+	unsigned int stat0, stat1, i;
+
+	stat0 = INTSTATCLR0;
+	stat1 = INTSTATCLR1;
+
+	INTSTATCLR0 = stat0;
+
+	desc->chip->ack(irq);
+
+	INTSTATCLR1 = stat1;
+
+	if (stat0 == 0 && stat1 == 0) {
+		do_bad_IRQ(irq, desc, regs);
+		return;
+	}
+
+	for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
+		if (stat0 & 1)
+			do_edge_IRQ(i, irq_desc + i, regs);
+
+	for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
+		if (stat1 & 1)
+			do_edge_IRQ(i, irq_desc + i, regs);
+
+	/* For level-based interrupts */
+	desc->chip->unmask(irq);
+}
+
+#define SA1111_IRQMASK_LO(x)	(1 << (x - IRQ_SA1111_START))
+#define SA1111_IRQMASK_HI(x)	(1 << (x - IRQ_SA1111_START - 32))
+
+static void sa1111_ack_irq(unsigned int irq)
+{
+}
+
+static void sa1111_mask_lowirq(unsigned int irq)
+{
+	INTEN0 &= ~SA1111_IRQMASK_LO(irq);
+}
+
+static void sa1111_unmask_lowirq(unsigned int irq)
+{
+	INTEN0 |= SA1111_IRQMASK_LO(irq);
+}
+
+/*
+ * Attempt to re-trigger the interrupt.  The SA1111 contains a register
+ * (INTSET) which claims to do this.  However, in practice no amount of
+ * manipulation of INTEN and INTSET guarantees that the interrupt will
+ * be triggered.  In fact, its very difficult, if not impossible to get
+ * INTSET to re-trigger the interrupt.
+ */
+static void sa1111_rerun_lowirq(unsigned int irq)
+{
+	unsigned int mask = SA1111_IRQMASK_LO(irq);
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		INTPOL0 ^= mask;
+		INTPOL0 ^= mask;
+		if (INTSTATCLR1 & mask)
+			break;
+	}
+
+	if (i == 8)
+		printk(KERN_ERR "Danger Will Robinson: failed to "
+			"re-trigger IRQ%d\n", irq);
+}
+
+static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
+{
+	unsigned int mask = SA1111_IRQMASK_LO(irq);
+
+	if (flags == IRQT_PROBE)
+		return 0;
+
+	if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
+		return -EINVAL;
+
+	if (flags & __IRQT_RISEDGE)
+		INTPOL0 &= ~mask;
+	else
+		INTPOL0 |= mask;
+	WAKE_POL0 = INTPOL0;
+
+	return 0;
+}
+
+static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
+{
+	unsigned int mask = SA1111_IRQMASK_LO(irq);
+
+	if (on)
+		WAKE_EN0 |= mask;
+	else
+		WAKE_EN0 &= ~mask;
+
+	return 0;
+}
+
+static struct irqchip sa1111_low_chip = {
+	.ack		= sa1111_ack_irq,
+	.mask		= sa1111_mask_lowirq,
+	.unmask		= sa1111_unmask_lowirq,
+	.rerun		= sa1111_rerun_lowirq,
+	.type		= sa1111_type_lowirq,
+	.wake		= sa1111_wake_lowirq,
+};
+
+static void sa1111_mask_highirq(unsigned int irq)
+{
+	INTEN1 &= ~SA1111_IRQMASK_HI(irq);
+}
+
+static void sa1111_unmask_highirq(unsigned int irq)
+{
+	INTEN1 |= SA1111_IRQMASK_HI(irq);
+}
+
+/*
+ * Attempt to re-trigger the interrupt.  The SA1111 contains a register
+ * (INTSET) which claims to do this.  However, in practice no amount of
+ * manipulation of INTEN and INTSET guarantees that the interrupt will
+ * be triggered.  In fact, its very difficult, if not impossible to get
+ * INTSET to re-trigger the interrupt.
+ */
+static void sa1111_rerun_highirq(unsigned int irq)
+{
+	unsigned int mask = SA1111_IRQMASK_HI(irq);
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		INTPOL1 ^= mask;
+		INTPOL1 ^= mask;
+		if (INTSTATCLR1 & mask)
+			break;
+	}
+
+	if (i == 8)
+		printk(KERN_ERR "Danger Will Robinson: failed to "
+			"re-trigger IRQ%d\n", irq);
+}
+
+static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
+{
+	unsigned int mask = SA1111_IRQMASK_HI(irq);
+
+	if (flags == IRQT_PROBE)
+		return 0;
+
+	if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
+		return -EINVAL;
+
+	if (flags & __IRQT_RISEDGE)
+		INTPOL1 &= ~mask;
+	else
+		INTPOL1 |= mask;
+	WAKE_POL1 = INTPOL1;
+
+	return 0;
+}
+
+static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
+{
+	unsigned int mask = SA1111_IRQMASK_HI(irq);
+
+	if (on)
+		WAKE_EN1 |= mask;
+	else
+		WAKE_EN1 &= ~mask;
+
+	return 0;
+}
+
+static struct irqchip sa1111_high_chip = {
+	.ack		= sa1111_ack_irq,
+	.mask		= sa1111_mask_highirq,
+	.unmask		= sa1111_unmask_highirq,
+	.rerun		= sa1111_rerun_highirq,
+	.type		= sa1111_type_highirq,
+	.wake		= sa1111_wake_highirq,
+};
+
+static void __init sa1111_init_irq(struct sa1111_dev *sadev)
+{
+	unsigned int irq;
+
+	/*
+	 * We're guaranteed that this region hasn't been taken.
+	 */
+	request_mem_region(sadev->res.start, 512, "irqs");
+
+	/* disable all IRQs */
+	sa1111_writel(0, sadev->mapbase + SA1111_INTEN0);
+	sa1111_writel(0, sadev->mapbase + SA1111_INTEN1);
+	sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0);
+	sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1);
+
+	/*
+	 * detect on rising edge.  Note: Feb 2001 Errata for SA1111
+	 * specifies that S0ReadyInt and S1ReadyInt should be '1'.
+	 */
+	sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0);
+	sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) |
+		      SA1111_IRQMASK_HI(IRQ_S1_READY_NINT),
+		      sadev->mapbase + SA1111_INTPOL1);
+
+	/* clear all IRQs */
+	sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0);
+	sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1);
+
+	for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+		set_irq_chip(irq, &sa1111_low_chip);
+		set_irq_handler(irq, do_edge_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+		set_irq_chip(irq, &sa1111_high_chip);
+		set_irq_handler(irq, do_edge_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	/*
+	 * Register SA1111 interrupt
+	 */
+	set_irq_type(sadev->irq[0], IRQT_RISING);
+	set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler);
+}
+
+/*
+ * Bring the SA1111 out of reset.  This requires a set procedure:
+ *  1. nRESET asserted (by hardware)
+ *  2. CLK turned on from SA1110
+ *  3. nRESET deasserted
+ *  4. VCO turned on, PLL_BYPASS turned off
+ *  5. Wait lock time, then assert RCLKEn
+ *  7. PCR set to allow clocking of individual functions
+ *
+ * Until we've done this, the only registers we can access are:
+ *   SBI_SKCR
+ *   SBI_SMCR
+ *   SBI_SKID
+ */
+static void sa1111_wake(struct sa1111 *sachip)
+{
+	unsigned long flags, r;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+
+	/*
+	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+	 * (SA-1110 Developer's Manual, section 9.1.2.1)
+	 */
+	GAFR |= GPIO_32_768kHz;
+	GPDR |= GPIO_32_768kHz;
+	TUCR = TUCR_3_6864MHz;
+
+	/*
+	 * Turn VCO on, and disable PLL Bypass.
+	 */
+	r = sa1111_readl(sachip->base + SA1111_SKCR);
+	r &= ~SKCR_VCO_OFF;
+	sa1111_writel(r, sachip->base + SA1111_SKCR);
+	r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
+	sa1111_writel(r, sachip->base + SA1111_SKCR);
+
+	/*
+	 * Wait lock time.  SA1111 manual _doesn't_
+	 * specify a figure for this!  We choose 100us.
+	 */
+	udelay(100);
+
+	/*
+	 * Enable RCLK.  We also ensure that RDYEN is set.
+	 */
+	r |= SKCR_RCLKEN | SKCR_RDYEN;
+	sa1111_writel(r, sachip->base + SA1111_SKCR);
+
+	/*
+	 * Wait 14 RCLK cycles for the chip to finish coming out
+	 * of reset. (RCLK=24MHz).  This is 590ns.
+	 */
+	udelay(1);
+
+	/*
+	 * Ensure all clocks are initially off.
+	 */
+	sa1111_writel(0, sachip->base + SA1111_SKPCR);
+
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+void
+sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
+		     unsigned int cas_latency)
+{
+	unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
+
+	if (cas_latency == 3)
+		smcr |= SMCR_CLAT;
+
+	sa1111_writel(smcr, sachip->base + SA1111_SMCR);
+}
+
+static void
+sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset)
+{
+	snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
+		 "%4.4x", offset);
+
+	sadev->dev.parent = sachip->dev;
+	sadev->dev.bus    = &sa1111_bus_type;
+	sadev->res.start  = sachip->res.start + offset;
+	sadev->res.end    = sadev->res.start + 511;
+	sadev->res.name   = sadev->dev.name;
+	sadev->res.flags  = IORESOURCE_MEM;
+	sadev->mapbase    = sachip->base + offset;
+
+	if (request_resource(&sachip->res, &sadev->res)) {
+		printk("SA1111: failed to allocate resource for %s\n",
+			sadev->res.name);
+		return;
+	}
+
+	device_register(&sadev->dev);
+}
+
+/**
+ *	sa1111_probe - probe for a single SA1111 chip.
+ *	@phys_addr: physical address of device.
+ *
+ *	Probe for a SA1111 chip.  This must be called
+ *	before any other SA1111-specific code.
+ *
+ *	Returns:
+ *	%-ENODEV	device not found.
+ *	%-EBUSY		physical address already marked in-use.
+ *	%0		successful.
+ */
+static int __init
+__sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
+{
+	struct sa1111 *sachip;
+	unsigned long id;
+	unsigned int has_devs, val;
+	int i, ret = -ENODEV;
+
+	sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL);
+	if (!sachip)
+		return -ENOMEM;
+
+	memset(sachip, 0, sizeof(struct sa1111));
+
+	spin_lock_init(&sachip->lock);
+
+	sachip->dev = me;
+	dev_set_drvdata(sachip->dev, sachip);
+
+	sachip->res.name  = me->name;
+	sachip->res.start = phys_addr;
+	sachip->res.end   = phys_addr + 0x2000;
+	sachip->irq = irq;
+
+	if (request_resource(&iomem_resource, &sachip->res)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/*
+	 * Map the whole region.  This also maps the
+	 * registers for our children.
+	 */
+	sachip->base = ioremap(phys_addr, PAGE_SIZE * 2);
+	if (!sachip->base) {
+		ret = -ENOMEM;
+		goto release;
+	}
+
+	/*
+	 * Probe for the chip.  Only touch the SBI registers.
+	 */
+	id = sa1111_readl(sachip->base + SA1111_SKID);
+	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
+		printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
+		ret = -ENODEV;
+		goto unmap;
+	}
+
+	printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
+		"silicon revision %lx, metal revision %lx\n",
+		(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+
+	/*
+	 * We found it.  Wake the chip up, and initialise.
+	 */
+	sa1111_wake(sachip);
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(sachip, 1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 * (currently, we always enable it.)
+	 */
+	val = sa1111_readl(sachip->base + SA1111_SKPCR);
+	sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR);
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	/*
+	 * The interrupt controller must be initialised before any
+	 * other device to ensure that the interrupts are available.
+	 */
+	int_dev.irq[0] = irq;
+	sa1111_init_one_child(sachip, &int_dev, SA1111_INTC);
+	sa1111_init_irq(&int_dev);
+
+	g_sa1111 = sachip;
+
+	has_devs = ~0;
+	if (machine_is_assabet() || machine_is_jornada720() ||
+	    machine_is_badge4())
+		has_devs &= ~(1 << 4);
+	else
+		has_devs &= ~(1 << 1);
+
+	for (i = 0; i < ARRAY_SIZE(devs); i++)
+		if (has_devs & (1 << i))
+			sa1111_init_one_child(sachip, devs[i], dev_offset[i]);
+
+	return 0;
+
+ unmap:
+	iounmap(sachip->base);
+ release:
+	release_resource(&sachip->res);
+ out:
+	kfree(sachip);
+	return ret;
+}
+
+static void __sa1111_remove(struct sa1111 *sachip)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devs); i++) {
+		put_device(&devs[i]->dev);
+		release_resource(&devs[i]->res);
+	}
+
+	iounmap(sachip->base);
+	release_resource(&sachip->res);
+	kfree(sachip);
+}
+
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller.  If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ */
+int sa1111_check_dma_bug(dma_addr_t addr)
+{
+	struct sa1111 *sachip = g_sa1111;
+	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int)addr);
+	unsigned int smcr;
+
+	/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+	 * User's Guide" mentions that jumpers R51 and R52 control the
+	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+	 * SDRAM bank 1 on Neponset). The default configuration selects
+	 * Assabet, so any address in bank 1 is necessarily invalid.
+	 */
+	if ((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000)
+	  	return -1;
+
+	/* The bug only applies to buffers located more than one megabyte
+	 * above the start of the target bank:
+	 */
+	if (physaddr<(1<<20))
+		return 0;
+
+	smcr = sa1111_readl(sachip->base + SA1111_SMCR);
+	switch (FExtr(smcr, SMCR_DRAC)) {
+	case 01: /* 10 row + bank address bits, A<20> must not be set */
+	  	if (physaddr & (1<<20))
+		  	return -1;
+		break;
+	case 02: /* 11 row + bank address bits, A<23> must not be set */
+	  	if (physaddr & (1<<23))
+		  	return -1;
+		break;
+	case 03: /* 12 row + bank address bits, A<24> must not be set */
+	  	if (physaddr & (1<<24))
+		  	return -1;
+		break;
+	case 04: /* 13 row + bank address bits, A<25> must not be set */
+	  	if (physaddr & (1<<25))
+		  	return -1;
+		break;
+	case 05: /* 14 row + bank address bits, A<20> must not be set */
+	  	if (physaddr & (1<<20))
+		  	return -1;
+		break;
+	case 06: /* 15 row + bank address bits, A<20> must not be set */
+	  	if (physaddr & (1<<20))
+		  	return -1;
+		break;
+	default:
+	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n",
+		       __FUNCTION__, FExtr(smcr, SMCR_DRAC));
+		return -1;
+	}
+
+	return 0;
+}
+
+struct sa1111_save_data {
+	unsigned int	skcr;
+	unsigned int	skpcr;
+	unsigned int	skcdr;
+	unsigned char	skaud;
+	unsigned char	skpwm0;
+	unsigned char	skpwm1;
+
+	/*
+	 * Interrupt controller
+	 */
+	unsigned int	intpol0;
+	unsigned int	intpol1;
+	unsigned int	inten0;
+	unsigned int	inten1;
+	unsigned int	wakepol0;
+	unsigned int	wakepol1;
+	unsigned int	wakeen0;
+	unsigned int	wakeen1;
+};
+
+static int sa1111_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct sa1111 *sachip = dev_get_drvdata(dev);
+	unsigned long flags;
+	char *base;
+
+	/*
+	 * Save state.
+	 */
+	if (level == SUSPEND_SAVE_STATE ||
+	    level == SUSPEND_DISABLE ||
+	    level == SUSPEND_POWER_DOWN) {
+		struct sa1111_save_data *save;
+
+		if (!dev->saved_state)
+			dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
+		if (!dev->saved_state)
+			return -ENOMEM;
+
+		save = (struct sa1111_save_data *)dev->saved_state;
+
+		spin_lock_irqsave(&sachip->lock, flags);
+		base = sachip->base;
+		save->skcr     = sa1111_readl(base + SA1111_SKCR);
+		save->skpcr    = sa1111_readl(base + SA1111_SKPCR);
+		save->skcdr    = sa1111_readl(base + SA1111_SKCDR);
+		save->skaud    = sa1111_readl(base + SA1111_SKAUD);
+		save->skpwm0   = sa1111_readl(base + SA1111_SKPWM0);
+		save->skpwm1   = sa1111_readl(base + SA1111_SKPWM1);
+
+		base = sachip->base + SA1111_INTC;
+		save->intpol0  = sa1111_readl(base + SA1111_INTPOL0);
+		save->intpol1  = sa1111_readl(base + SA1111_INTPOL1);
+		save->inten0   = sa1111_readl(base + SA1111_INTEN0);
+		save->inten1   = sa1111_readl(base + SA1111_INTEN1);
+		save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0);
+		save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1);
+		save->wakeen0  = sa1111_readl(base + SA1111_WAKEEN0);
+		save->wakeen1  = sa1111_readl(base + SA1111_WAKEEN1);
+		spin_unlock_irqrestore(&sachip->lock, flags);
+	}
+
+	/*
+	 * Disable.
+	 */
+	if (level == SUSPEND_DISABLE && state == 4) {
+		unsigned int val;
+
+		spin_lock_irqsave(&sachip->lock, flags);
+		base = sachip->base;
+
+		sa1111_writel(0, base + SA1111_SKPWM0);
+		sa1111_writel(0, base + SA1111_SKPWM1);
+		val = sa1111_readl(base + SA1111_SKCR);
+		sa1111_writel(val | SKCR_SLEEP, base + SA1111_SKCR);
+
+		spin_unlock_irqrestore(&sachip->lock, flags);
+	}
+
+	return 0;
+}
+
+/*
+ *	sa1111_resume - Restore the SA1111 device state.
+ *	@dev: device to restore
+ *	@level: resume level
+ *
+ *	Restore the general state of the SA1111; clock control and
+ *	interrupt controller.  Other parts of the SA1111 must be
+ *	restored by their respective drivers, and must be called
+ *	via LDM after this function.
+ */
+static int sa1111_resume(struct device *dev, u32 level)
+{
+	struct sa1111 *sachip = dev_get_drvdata(dev);
+	struct sa1111_save_data *save;
+	unsigned long flags, id;
+	char *base;
+
+	if (level != RESUME_RESTORE_STATE && level != RESUME_ENABLE)
+		return 0;
+
+	save = (struct sa1111_save_data *)dev->saved_state;
+	if (!save)
+		return 0;
+
+	dev->saved_state = NULL;
+
+	/*
+	 * Ensure that the SA1111 is still here.
+	 */
+	id = sa1111_readl(sachip->base + SA1111_SKID);
+	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
+		__sa1111_remove(sachip);
+		dev_set_drvdata(dev, NULL);
+		kfree(save);
+		return 0;
+	}
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_wake(sachip);
+
+	base = sachip->base;
+	sa1111_writel(save->skcr,     base + SA1111_SKCR);
+	sa1111_writel(save->skpcr,    base + SA1111_SKPCR);
+	sa1111_writel(save->skcdr,    base + SA1111_SKCDR);
+	sa1111_writel(save->skaud,    base + SA1111_SKAUD);
+	sa1111_writel(save->skpwm0,   base + SA1111_SKPWM0);
+	sa1111_writel(save->skpwm1,   base + SA1111_SKPWM1);
+
+	base = sachip->base + SA1111_INTC;
+	sa1111_writel(save->intpol0,  base + SA1111_INTPOL0);
+	sa1111_writel(save->intpol1,  base + SA1111_INTPOL1);
+	sa1111_writel(save->inten0,   base + SA1111_INTEN0);
+	sa1111_writel(save->inten1,   base + SA1111_INTEN1);
+	sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0);
+	sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1);
+	sa1111_writel(save->wakeen0,  base + SA1111_WAKEEN0);
+	sa1111_writel(save->wakeen1,  base + SA1111_WAKEEN1);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	kfree(save);
+
+	return 0;
+}
+
+static int sa1111_probe(struct device *dev)
+{
+	return -ENODEV;
+}
+
+static int sa1111_remove(struct device *dev)
+{
+	struct sa1111 *sachip = dev_get_drvdata(dev);
+
+	if (sachip) {
+		__sa1111_remove(sachip);
+		dev_set_drvdata(dev, NULL);
+
+		kfree(dev->saved_state);
+		dev->saved_state = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ *	Not sure if this should be on the system bus or not yet.
+ *	We really want some way to register a system device at
+ *	the per-machine level, and then have this driver pick
+ *	up the registered devices.
+ *
+ *	We also need to handle the SDRAM configuration for
+ *	PXA250/SA1110 machine classes.
+ */
+static struct device_driver sa1111_device_driver = {
+	.name		= "sa1111",
+	.bus		= &system_bus_type,
+	.probe		= sa1111_probe,
+	.remove		= sa1111_remove,
+	.suspend	= sa1111_suspend,
+	.resume		= sa1111_resume,
+};
+
+/*
+ *	Register the SA1111 driver with LDM.
+ */
+static int sa1111_driver_init(void)
+{
+	driver_register(&sa1111_device_driver);
+	return 0;
+}
+
+arch_initcall(sa1111_driver_init);
+
+static struct sys_device sa1111_device = {
+	.name		= "SA1111",
+	.id		= 0,
+	.root		= NULL,
+	.dev = {
+		.name	= "Intel Corporation SA1111",
+		.driver	= &sa1111_device_driver,
+	},
+};
+
+int sa1111_init(unsigned long phys, unsigned int irq)
+{
+	int ret;
+
+	snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys);
+
+	ret = sys_device_register(&sa1111_device);
+	if (ret)
+		printk("sa1111 device_register failed: %d\n", ret);
+
+	return __sa1111_probe(&sa1111_device.dev, phys, irq);
+}
+
+/*
+ *	Get the parent device driver (us) structure
+ *	from a child function device
+ */
+static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev)
+{
+	return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent);
+}
+
+/*
+ * The bits in the opdiv field are non-linear.
+ */
+static unsigned char opdiv_table[] = { 1, 4, 2, 8 };
+
+static unsigned int __sa1111_pll_clock(struct sa1111 *sachip)
+{
+	unsigned int skcdr, fbdiv, ipdiv, opdiv;
+
+	skcdr = sa1111_readl(sachip->base + SA1111_SKCDR);
+
+	fbdiv = (skcdr & 0x007f) + 2;
+	ipdiv = ((skcdr & 0x0f80) >> 7) + 2;
+	opdiv = opdiv_table[(skcdr & 0x3000) >> 12];
+
+	return 3686400 * fbdiv / (ipdiv * opdiv);
+}
+
+/**
+ *	sa1111_pll_clock - return the current PLL clock frequency.
+ *	@sadev: SA1111 function block
+ *
+ *	BUG: we should look at SKCR.  We also blindly believe that
+ *	the chip is being fed with the 3.6864MHz clock.
+ *
+ *	Returns the PLL clock in Hz.
+ */
+unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+
+	return __sa1111_pll_clock(sachip);
+}
+
+/**
+ *	sa1111_select_audio_mode - select I2S or AC link mode
+ *	@sadev: SA1111 function block
+ *	@mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S
+ *
+ *	Frob the SKCR to select AC Link mode or I2S mode for
+ *	the audio block.
+ */
+void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+
+	val = sa1111_readl(sachip->base + SA1111_SKCR);
+	if (mode == SA1111_AUDIO_I2S) {
+		val &= ~SKCR_SELAC;
+	} else {
+		val |= SKCR_SELAC;
+	}
+	sa1111_writel(val, sachip->base + SA1111_SKCR);
+
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+/**
+ *	sa1111_set_audio_rate - set the audio sample rate
+ *	@sadev: SA1111 SAC function block
+ *	@rate: sample rate to select
+ */
+int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+	unsigned int div;
+
+	if (sadev->devid != SA1111_DEVID_SAC)
+		return -EINVAL;
+
+	div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate;
+	if (div == 0)
+		div = 1;
+	if (div > 128)
+		div = 128;
+
+	sa1111_writel(div - 1, sachip->base + SA1111_SKAUD);
+
+	return 0;
+}
+
+/**
+ *	sa1111_get_audio_rate - get the audio sample rate
+ *	@sadev: SA1111 SAC function block device
+ */
+int sa1111_get_audio_rate(struct sa1111_dev *sadev)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+	unsigned long div;
+
+	if (sadev->devid != SA1111_DEVID_SAC)
+		return -EINVAL;
+
+	div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1;
+
+	return __sa1111_pll_clock(sachip) / (256 * div);
+}
+
+/*
+ * Individual device operations.
+ */
+
+/**
+ *	sa1111_enable_device - enable an on-chip SA1111 function block
+ *	@sadev: SA1111 function block device to enable
+ */
+void sa1111_enable_device(struct sa1111_dev *sadev)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	val = sa1111_readl(sachip->base + SA1111_SKPCR);
+	sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+/**
+ *	sa1111_disable_device - disable an on-chip SA1111 function block
+ *	@sadev: SA1111 function block device to disable
+ */
+void sa1111_disable_device(struct sa1111_dev *sadev)
+{
+	struct sa1111 *sachip = sa1111_chip_driver(sadev);
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	val = sa1111_readl(sachip->base + SA1111_SKPCR);
+	sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+/*
+ *	SA1111 "Register Access Bus."
+ *
+ *	We model this as a regular bus type, and hang devices directly
+ *	off this.
+ */
+static int sa1111_match(struct device *_dev, struct device_driver *_drv)
+{
+	struct sa1111_dev *dev = SA1111_DEV(_dev);
+	struct sa1111_driver *drv = SA1111_DRV(_drv);
+
+	return dev->devid == drv->devid;
+}
+
+struct bus_type sa1111_bus_type = {
+	.name	= "RAB",
+	.match	= sa1111_match,
+};
+
+static int sa1111_rab_bus_init(void)
+{
+	return bus_register(&sa1111_bus_type);
+}
+
+postcore_initcall(sa1111_rab_bus_init);
+
+EXPORT_SYMBOL(sa1111_check_dma_bug);
+EXPORT_SYMBOL(sa1111_select_audio_mode);
+EXPORT_SYMBOL(sa1111_set_audio_rate);
+EXPORT_SYMBOL(sa1111_get_audio_rate);
+EXPORT_SYMBOL(sa1111_enable_device);
+EXPORT_SYMBOL(sa1111_disable_device);
+EXPORT_SYMBOL(sa1111_pll_clock);
+EXPORT_SYMBOL(sa1111_bus_type);
diff -Nru a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/via82c505.c	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,94 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/mach/pci.h>
+
+#define MAX_SLOTS		7
+
+#define CONFIG_CMD(bus, devfn, where)   (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+static int
+via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		      int size, u32 *value)
+{
+	outl(CONFIG_CMD(bus,devfn,where),0xCF8);
+	switch (size) {
+	case 1:
+		*value=inb(0xCFC + (where&3));
+		break;
+	case 2:
+		*value=inw(0xCFC + (where&2));
+		break;
+	case 4:
+		*value=inl(0xCFC);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		       int size, u32 value)
+{
+	outl(CONFIG_CMD(bus,devfn,where),0xCF8);
+	switch (size) {
+	case 1:
+		outb(value, 0xCFC + (where&3));
+		break;
+	case 2:
+		outw(value, 0xCFC + (where&2));
+		break;
+	case 4:
+		outl(value, 0xCFC);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops via82c505_ops = {
+	.read	= via82c505_read_config,
+	.write	= via82c505_write_config,
+};
+
+void __init via82c505_preinit(void *sysdata)
+{
+	printk(KERN_DEBUG "PCI: VIA 82c505\n");
+	if (!request_region(0xA8,2,"via config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
+		return;
+	}
+	if (!request_region(0xCF8,8,"pci config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
+		release_region(0xA8, 2);
+		return;
+	}
+
+	/* Enable compatible Mode */
+	outb(0x96,0xA8);
+	outb(0x18,0xA9);
+	outb(0x93,0xA8);
+	outb(0xd0,0xA9);
+
+}
+
+int __init via82c505_setup(int nr, struct pci_sys_data *sys)
+{
+	return (nr == 0);
+}
+
+struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata)
+{
+	if (nr == 0)
+		return pci_scan_bus(0, &via82c505_ops, sysdata);
+
+	return NULL;
+}
diff -Nru a/arch/arm/def-configs/hackkit b/arch/arm/def-configs/hackkit
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/def-configs/hackkit	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,654 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_SWAP=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_PXA 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_IOP310 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+
+#
+# CLPS711X/EP721X Implementations
+#
+
+#
+# Epxa10db
+#
+
+#
+# Footbridge Implementations
+#
+
+#
+# IOP310 Implementation Options
+#
+
+#
+# IOP310 Chipset Features
+#
+
+#
+# Intel PXA250/210 Implementations
+#
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+CONFIG_SA1100_HACKKIT=y
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_STORK is not set
+# CONFIG_SA1100_USB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_SA1100=y
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+
+#
+# General setup
+#
+CONFIG_DISCONTIGMEM=y
+CONFIG_ISA=y
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_24_API=y
+CONFIG_CPU_FREQ_26_API=y
+# CONFIG_HOTPLUG is not set
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT 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
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_EDB7312 is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_INET_ECN=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_XFRM_USER is not set
+# CONFIG_IPV6 is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE 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_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+
+#
+# Wireless ISA/PCI cards support
+#
+# CONFIG_WAVELAN is not set
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices (depends on LLC=y)
+#
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_TSLIBDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# 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_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_SA1100_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_XFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_EXPORTFS is not set
+# CONFIG_CIFS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# 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_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 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+
+#
+# Console Switches
+#
+# CONFIG_SWITCHES is not set
+
+#
+# USB support
+#
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_KALLSYMS=y
+CONFIG_DEBUG_LL=y
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
diff -Nru a/arch/arm/def-configs/trizeps b/arch/arm/def-configs/trizeps
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/def-configs/trizeps	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,852 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_PXA 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_IOP310 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CEIVA is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+
+#
+# Epxa10db
+#
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# IOP310 Implementation Options
+#
+# CONFIG_ARCH_IQ80310 is not set
+# CONFIG_IOP310_AAU is not set
+# CONFIG_IOP310_DMA is not set
+# CONFIG_IOP310_MU is not set
+# CONFIG_IOP310_PMON is not set
+
+#
+# Intel PXA250/210 Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_ARCH_PXA_IDP is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+CONFIG_SA1100_TRIZEPS=y
+CONFIG_TRIZEPS_MFTB2=y
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_STORK is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+# CONFIG_SA1111 is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_CPU_XSCALE is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_32v5 is not set
+# CONFIG_ARM_THUMB is not set
+
+#
+# General setup
+#
+CONFIG_DISCONTIGMEM=y
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_FIQ is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_FREQ_24_API is not set
+# CONFIG_CPU_FREQ_26_API is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=m
+# CONFIG_PCMCIA_SA1111 is not set
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_APM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/hda2 1"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_CONCAT=m
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_AFS_PARTS=m
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=m
+# CONFIG_MTD_2PARTS_IPAQ is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_CEIVA is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_PNP_NAMES is not set
+# CONFIG_PNP_DEBUG is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_LLC is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE 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_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000_NAPI is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP 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=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_HERMES is not set
+CONFIG_AIRO_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# 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 is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+CONFIG_NET_PCMCIA_RADIO=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_AIRONET4500_CS is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_IDE_ICSIDE is not set
+# CONFIG_BLK_DEV_IDEDMA_ICS is not set
+# CONFIG_IDEDMA_ICS_AUTO is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_BLK_DEV_IDE_RAPIDE is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_TSLIBDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_RPCKBD is not set
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_SA1111 is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDDLER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
+# CONFIG_INPUT_JOYDUMP is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT_PCSPKR is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+# CONFIG_SERIAL_ACORN is not set
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_SCx200_I2C is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_BIT_SA1100_GPIO is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PROC=m
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+# CONFIG_CIFS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_ZISOFS_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
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# Console Switches
+#
+# CONFIG_SWITCHES is not set
+# CONFIG_SWITCHES_SA1100 is not set
+# CONFIG_SWITCHES_UCB1X00 is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -Nru a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
--- a/arch/arm/kernel/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/arm/kernel/Makefile	Mon Feb 10 10:39:32 2003
@@ -15,8 +15,6 @@
 obj-n		:=
 obj-		:=
 
-export-objs	:= armksyms.o apm.o dma.o ecard.o fiq.o io.o time.o
-
 obj-$(CONFIG_APM)		+= apm.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o time-acorn.o
 obj-$(CONFIG_ARCH_CLPS7500)	+= time-acorn.o
@@ -26,8 +24,6 @@
 obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o
-obj-$(CONFIG_PCI_HOST_PLX90X0)	+= plx90x0.o
-obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
 
 ifneq ($(MACHINE),ebsa110)
   obj-y		+= io.o
diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
--- a/arch/arm/kernel/ecard.c	Mon Feb 10 10:39:30 2003
+++ b/arch/arm/kernel/ecard.c	Mon Feb 10 10:39:30 2003
@@ -881,6 +881,90 @@
 		get_ecard_dev_info);
 }
 
+#define ec_set_resource(ec,nr,st,sz,flg)			\
+	do {							\
+		(ec)->resource[nr].name = ec->dev.name;		\
+		(ec)->resource[nr].start = st;			\
+		(ec)->resource[nr].end = (st) + (sz) - 1;	\
+		(ec)->resource[nr].flags = flg;			\
+	} while (0)
+
+static void __init ecard_init_resources(struct expansion_card *ec)
+{
+	unsigned long base = PODSLOT_IOC4_BASE;
+	unsigned int slot = ec->slot_no;
+	int i;
+
+	if (slot < 4) {
+		ec_set_resource(ec, ECARD_RES_MEMC,
+				PODSLOT_MEMC_BASE + (slot << 14),
+				PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
+		base = PODSLOT_IOC0_BASE;
+	}
+
+#ifdef CONFIG_ARCH_RPC
+	if (slot < 8) {
+		ec_set_resource(ec, ECARD_RES_EASI,
+				PODSLOT_EASI_BASE + (slot << 24),
+				PODSLOT_EASI_SIZE, IORESOURCE_MEM);
+	}
+
+	if (slot == 8) {
+		ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE,
+				NETSLOT_SIZE, IORESOURCE_MEM);
+	} else
+#endif
+
+	for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
+		ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+				base + (slot << 14) + (i << 19),
+				PODSLOT_IOC_SIZE, IORESOURCE_MEM);
+	}
+
+	for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+		if (ec->resource[i].start &&
+		    request_resource(&iomem_resource, &ec->resource[i])) {
+			printk(KERN_ERR "%s: resource(s) not available\n",
+				ec->dev.bus_id);
+			ec->resource[i].end -= ec->resource[i].start;
+			ec->resource[i].start = 0;
+		}
+	}
+}
+
+static ssize_t ecard_show_irq(struct device *dev, char *buf)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	return sprintf(buf, "%u\n", ec->irq);
+}
+
+static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL);
+
+static ssize_t ecard_show_dma(struct device *dev, char *buf)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	return sprintf(buf, "%u\n", ec->dma);
+}
+
+static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL);
+
+static ssize_t ecard_show_resources(struct device *dev, char *buf)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	char *str = buf;
+	int i;
+
+	for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+		str += sprintf(str, "%08lx %08lx %08lx\n",
+				ec->resource[i].start,
+				ec->resource[i].end,
+				ec->resource[i].flags);
+
+	return str - buf;
+}
+
+static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL);
+
 /*
  * Probe for an expansion card.
  *
@@ -949,6 +1033,16 @@
 			break;
 		}
 
+	snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
+	snprintf(ec->dev.name, sizeof(ec->dev.name), "ecard %04x:%04x",
+		 ec->cid.manufacturer, ec->cid.product);
+	ec->dev.parent = NULL;
+	ec->dev.bus    = &ecard_bus_type;
+	ec->dev.dma_mask = &ec->dma_mask;
+	ec->dma_mask = (u64)0xffffffff;
+
+	ecard_init_resources(ec);
+
 	/*
 	 * hook the interrupt handlers
 	 */
@@ -974,14 +1068,10 @@
 	*ecp = ec;
 	slot_to_expcard[slot] = ec;
 
-	snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot);
-	strcpy(ec->dev.name, "fixme!");
-	ec->dev.parent = NULL;
-	ec->dev.bus    = &ecard_bus_type;
-	ec->dev.dma_mask = &ec->dma_mask;
-	ec->dma_mask = (u64)0xffffffff;
-
 	device_register(&ec->dev);
+	device_create_file(&ec->dev, &dev_attr_dma);
+	device_create_file(&ec->dev, &dev_attr_irq);
+	device_create_file(&ec->dev, &dev_attr_resource);
 
 	return 0;
 
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	Mon Feb 10 10:39:22 2003
+++ b/arch/arm/kernel/irq.c	Mon Feb 10 10:39:22 2003
@@ -78,7 +78,8 @@
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
  *
- *	Disable the selected interrupt line.  We do this lazily.
+ *	Disable the selected interrupt line.  Enables and disables
+ *	are nested.  We do this lazily.
  *
  *	This function may be called from IRQ context.
  */
@@ -88,8 +89,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (!desc->depth++)
-		desc->enabled = 0;
+	desc->disable_depth++;
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
@@ -107,24 +107,25 @@
 {
 	struct irqdesc *desc = irq_desc + irq;
 	unsigned long flags;
-	int pending = 0;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (unlikely(!desc->depth)) {
+	if (unlikely(!desc->disable_depth)) {
 		printk("enable_irq(%u) unbalanced from %p\n", irq,
 			__builtin_return_address(0));
-	} else if (!--desc->depth) {
+	} else if (!--desc->disable_depth) {
 		desc->probing = 0;
-		desc->enabled = 1;
 		desc->chip->unmask(irq);
-		pending = desc->pending;
-		desc->pending = 0;
+
 		/*
-		 * If the interrupt was waiting to be processed,
-		 * retrigger it.
+		 * If the interrupt is waiting to be processed,
+		 * try to re-run it.  We can't directly run it
+		 * from here since the caller might be in an
+		 * interrupt-protected region.
 		 */
-		if (pending)
+		if (desc->pending) {
+			desc->pending = 0;
 			desc->chip->rerun(irq);
+		}
 	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
@@ -264,7 +265,7 @@
 	 * we shouldn't process the IRQ.  Instead, turn on the
 	 * hardware masks.
 	 */
-	if (unlikely(desc->running || !desc->enabled))
+	if (unlikely(desc->running || desc->disable_depth))
 		goto running;
 
 	/*
@@ -286,13 +287,13 @@
 		if (!action)
 			break;
 
-		if (desc->pending && desc->enabled) {
+		if (desc->pending && !desc->disable_depth) {
 			desc->pending = 0;
 			desc->chip->unmask(irq);
 		}
 
 		__do_irq(irq, action, regs);
-	} while (desc->pending && desc->enabled);
+	} while (desc->pending && !desc->disable_depth);
 
 	desc->running = 0;
 
@@ -328,7 +329,7 @@
 	 */
 	desc->chip->ack(irq);
 
-	if (likely(desc->enabled)) {
+	if (likely(!desc->disable_depth)) {
 		kstat_cpu(cpu).irqs[irq]++;
 
 		/*
@@ -338,7 +339,7 @@
 		if (action) {
 			__do_irq(irq, desc->action, regs);
 
-			if (likely(desc->enabled &&
+			if (likely(!desc->disable_depth &&
 				   !check_irq_lock(desc, irq, regs)))
 				desc->chip->unmask(irq);
 		}
@@ -390,14 +391,13 @@
 	if (handle == do_bad_IRQ) {
 		desc->chip->mask(irq);
 		desc->chip->ack(irq);
-		desc->depth = 1;
-		desc->enabled = 0;
+		desc->disable_depth = 1;
 	}
 	desc->handle = handle;
 	if (handle != do_bad_IRQ && is_chained) {
 		desc->valid = 0;
 		desc->probe_ok = 0;
-		desc->depth = 0;
+		desc->disable_depth = 0;
 		desc->chip->unmask(irq);
 	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
@@ -512,10 +512,9 @@
  		desc->probing = 0;
 		desc->running = 0;
 		desc->pending = 0;
-		desc->depth = 1;
+		desc->disable_depth = 1;
 		if (!desc->noautoenable) {
-			desc->depth = 0;
-			desc->enabled = 1;
+			desc->disable_depth = 0;
 			desc->chip->unmask(irq);
 		}
 	}
diff -Nru a/arch/arm/kernel/plx90x0.c b/arch/arm/kernel/plx90x0.c
--- a/arch/arm/kernel/plx90x0.c	Mon Feb 10 10:39:24 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,178 +0,0 @@
-/* 
- * Driver for PLX Technology PCI9000-series host bridge.
- *
- * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/ptrace.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-
-/*
- * Since the following functions are all very similar, the common parts
- * are pulled out into these macros.
- */
-
-#define PLX_CLEAR_CONFIG						\
-	__raw_writel(0, PLX_BASE + 0xac);				\
-	local_irq_restore(flags); }
-
-#define PLX_SET_CONFIG							\
-	{ unsigned long flags;						\
-	local_irq_save(flags);						\
-	__raw_writel((1<<31 | (bus->number << 16)			\
-		| (devfn << 8) | (where & ~3)				\
-		| ((bus->number == 0)?0:1)), PLX_BASE + 0xac);		\
-
-#define PLX_CONFIG_WRITE(size)						\
-	PLX_SET_CONFIG							\
-	__raw_write##size(value, PCIO_BASE + (where & 3));		\
-	if (__raw_readw(PLX_BASE + 0x6) & 0x2000)			\
-		__raw_writew(0x2000, PLX_BASE + 0x6);			\
-	PLX_CLEAR_CONFIG						\
-	return PCIBIOS_SUCCESSFUL;
-
-#define PLX_CONFIG_READ(size)						\
-	PLX_SET_CONFIG							\
-	*value = __raw_read##size(PCIO_BASE + (where & 3));		\
-	if (__raw_readw(PLX_BASE + 0x6) & 0x2000) {			\
-		__raw_writew(0x2000, PLX_BASE + 0x6);			\
-		*value = 0xffffffffUL;					\
-	}								\
-	PLX_CLEAR_CONFIG						\
-	return PCIBIOS_SUCCESSFUL;
-
-/* Configuration space access routines */
-
-static int 
-plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where,
-		     int where, int size, u32 *value)
-{
-	switch (size) {
-	case 1:
-		PLX_CONFIG_READ(b)
-		break;
-	case 2:
-		PLX_CONFIG_READ(w)
-		break;
-	case 4:
-		PLX_CONFIG_READ(l)
-		break;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int 
-plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where,
-		      int where, int size, u32 value)
-{
-	switch (size) {
-	case 1:
-		PLX_CONFIG_WRITE(b)
-		break;
-	case 2:
-		PLX_CONFIG_WRITE(w)
-		break;
-	case 4:
-		PLX_CONFIG_WRITE(l)
-		break;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops plx90x0_ops = 
-{
-	.read	= plx90x0_read_config,
-	.write	= plx90x0_write_config,
-};
-
-static void 
-plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
-{
-	printk("PLX90x0: machine check %04x (pc=%08lx)\n", 
-	       readw(PLX_BASE + 6), regs->ARM_pc);
-	__raw_writew(0xf000, PLX_BASE + 6);
-}
-
-/*
- * Initialise the PCI system.
- */
-
-void __init
-plx90x0_init(struct arm_sysdata *sysdata)
-{
-	static const unsigned long int base = PLX_BASE;
-	char *what;
-	unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
-
-	/* Have a sniff around and see which PLX device is present. */
-	unsigned long id = __raw_readl(base + 0xf0);
-	
-#if 0
-	/* This check was a good idea, but can fail.  The PLX9060 puts no
-	   default value in these registers unless NB# is asserted (which it
-	   isn't on these cards).  */
-	if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
-		return;		/* Nothing found */
-#endif
-
-	/* Found one - now work out what it is. */
-	switch (id >> 16) {
-	case 0:		/* PCI_DEVICE_ID_PLX_9060 */
-		what = "PCI9060";
-		break;
-	case PCI_DEVICE_ID_PLX_9060ES:
-		what = "PCI9060ES";
-		break;
-	case PCI_DEVICE_ID_PLX_9060SD:
-		what = "PCI9060SD";		/* uhuhh.. */
-		break;
-	case PCI_DEVICE_ID_PLX_9080:
-		what = "PCI9080";
-		break;
-	default:
-		printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
-		       id >> 16);
-		return;
-	}
-	
-	printk("PCI: PLX Technology %s host bridge found.\n", what);
-	
-	/* Now set it up for both master and slave accesses. */
-	__raw_writel(0xffff0147,	base + 0x4);
-	__raw_writeb(32,		base + 0xd);
-	__raw_writel(0x8 | bar,		base + 0x18);
-	__raw_writel(0xf8000008,	base + 0x80);
-	__raw_writel(0x40000001,	base + 0x84);
-	__raw_writel(0,			base + 0x88);
-	__raw_writel(0,			base + 0x8c);
-	__raw_writel(0x11,		base + 0x94);
-	__raw_writel(0xC3 + (4 << 28)
-		+ (8 << 11) + (1 << 10)
-		     + (1 << 24),	base + 0x98);
-	__raw_writel(0xC0000000,	base + 0x9c);
-	__raw_writel(PLX_MEM_START,	base + 0xa0);
-	__raw_writel(PLX_IO_START,	base + 0xa4);
-	__raw_writel(0x3,		base + 0xa8);
-	__raw_writel(0,			base + 0xac);
-	__raw_writel(0x10001,		base + 0xe8);
-	__raw_writel(0x8000767e,	base + 0xec);
-	
-	request_irq(IRQ_SYSERR, plx_syserr_handler, 0, 
-		    "system error", NULL);
-
-	pci_scan_bus(0, &plx90x0_ops, sysdata);
-}
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/kernel/setup.c	Mon Feb 10 10:39:27 2003
@@ -20,6 +20,7 @@
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <linux/root_dev.h>
+#include <linux/cpu.h>
 
 #include <asm/elf.h>
 #include <asm/hardware.h>
@@ -690,6 +691,15 @@
 #endif
 #endif
 }
+
+static struct cpu cpu[1];
+
+static int __init topology_init(void)
+{
+	return register_cpu(cpu, 0, NULL);
+}
+
+subsys_initcall(topology_init);
 
 static const char *hwcap_str[] = {
 	"swp",
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c	Mon Feb 10 10:39:23 2003
+++ b/arch/arm/kernel/signal.c	Mon Feb 10 10:39:23 2003
@@ -59,11 +59,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->ARM_r0 = -EINTR;
 
 	while (1) {
@@ -87,11 +87,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->ARM_r0 = -EINTR;
 
 	while (1) {
@@ -207,10 +207,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(regs, &frame->sc))
 		goto badframe;
@@ -247,10 +247,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -477,12 +477,12 @@
 			ka->sa.sa_handler = SIG_DFL;
 
 		if (!(ka->sa.sa_flags & SA_NODEFER)) {
-			spin_lock_irq(&tsk->sig->siglock);
+			spin_lock_irq(&tsk->sighand->siglock);
 			sigorsets(&tsk->blocked, &tsk->blocked,
 				  &ka->sa.sa_mask);
 			sigaddset(&tsk->blocked, sig);
 			recalc_sigpending();
-			spin_unlock_irq(&tsk->sig->siglock);
+			spin_unlock_irq(&tsk->sighand->siglock);
 		}
 		return;
 	}
@@ -521,9 +521,9 @@
 		unsigned long signr = 0;
 		struct k_sigaction *ka;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		signr = dequeue_signal(&current->blocked, &info);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 		if (!signr)
 			break;
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	Mon Feb 10 10:39:29 2003
+++ b/arch/arm/kernel/time.c	Mon Feb 10 10:39:29 2003
@@ -34,7 +34,6 @@
 
 u64 jiffies_64;
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
 /* this needs a better home */
@@ -148,18 +147,20 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec, lost;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = gettimeoffset();
-
-	lost = jiffies - wall_jiffies;
-	if (lost)
-		usec += lost * USECS_PER_JIFFY;
-
-	sec = xtime.tv_sec;
-	usec += xtime.tv_nsec / 1000;
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = gettimeoffset();
+
+		lost = jiffies - wall_jiffies;
+		if (lost)
+			usec += lost * USECS_PER_JIFFY;
+
+		sec = xtime.tv_sec;
+		usec += xtime.tv_nsec / 1000;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	/* usec may have gone up a lot: be safe */
 	while (usec >= 1000000) {
@@ -173,7 +174,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
@@ -194,7 +195,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 static struct irqaction timer_irq = {
diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c	Mon Feb 10 10:39:26 2003
+++ b/arch/arm/kernel/traps.c	Mon Feb 10 10:39:26 2003
@@ -53,7 +53,8 @@
 void dump_backtrace_entry(unsigned long where, unsigned long from)
 {
 	printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
-	print_symbol("  %s\n", where);
+	print_symbol("  %s", where);
+	printk("\n");
 }
 
 /*
diff -Nru a/arch/arm/kernel/via82c505.c b/arch/arm/kernel/via82c505.c
--- a/arch/arm/kernel/via82c505.c	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,94 +0,0 @@
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/ptrace.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <asm/mach/pci.h>
-
-#define MAX_SLOTS		7
-
-#define CONFIG_CMD(bus, devfn, where)   (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
-
-static int
-via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-		      int size, u32 *value)
-{
-	outl(CONFIG_CMD(bus,devfn,where),0xCF8);
-	switch (size) {
-	case 1:
-		*value=inb(0xCFC + (where&3));
-		break;
-	case 2:
-		*value=inw(0xCFC + (where&2));
-		break;
-	case 4:
-		*value=inl(0xCFC);
-		break;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-		       int size, u32 value)
-{
-	outl(CONFIG_CMD(bus,devfn,where),0xCF8);
-	switch (size) {
-	case 1:
-		outb(value, 0xCFC + (where&3));
-		break;
-	case 2:
-		outw(value, 0xCFC + (where&2));
-		break;
-	case 4:
-		outl(value, 0xCFC);
-		break;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops via82c505_ops = {
-	.read	= via82c505_read_config,
-	.write	= via82c505_write_config,
-};
-
-void __init via82c505_preinit(void *sysdata)
-{
-	printk(KERN_DEBUG "PCI: VIA 82c505\n");
-	if (!request_region(0xA8,2,"via config")) {
-		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
-		return;
-	}
-	if (!request_region(0xCF8,8,"pci config")) {
-		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
-		release_region(0xA8, 2);
-		return;
-	}
-
-	/* Enable compatible Mode */
-	outb(0x96,0xA8);
-	outb(0x18,0xA9);
-	outb(0x93,0xA8);
-	outb(0xd0,0xA9);
-
-}
-
-int __init via82c505_setup(int nr, struct pci_sys_data *sys)
-{
-	return (nr == 0);
-}
-
-struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata)
-{
-	if (nr == 0)
-		return pci_scan_bus(0, &via82c505_ops, sysdata);
-
-	return NULL;
-}
diff -Nru a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile
--- a/arch/arm/mach-adifcc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/arm/mach-adifcc/Makefile	Mon Feb 10 10:39:23 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:=
diff -Nru a/arch/arm/mach-anakin/Makefile b/arch/arm/mach-anakin/Makefile
--- a/arch/arm/mach-anakin/Makefile	Mon Feb 10 10:39:28 2003
+++ b/arch/arm/mach-anakin/Makefile	Mon Feb 10 10:39:28 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mach-arc/Makefile b/arch/arm/mach-arc/Makefile
--- a/arch/arm/mach-arc/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/arm/mach-arc/Makefile	Mon Feb 10 10:39:24 2003
@@ -10,8 +10,6 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= oldlatches.o
-
 obj-$(CONFIG_DEBUG_LL)	+= debug.o
 
 EXTRA_TARGETS 		:= head.o
diff -Nru a/arch/arm/mach-clps7500/Makefile b/arch/arm/mach-clps7500/Makefile
--- a/arch/arm/mach-clps7500/Makefile	Mon Feb 10 10:39:28 2003
+++ b/arch/arm/mach-clps7500/Makefile	Mon Feb 10 10:39:28 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile
--- a/arch/arm/mach-ebsa110/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/mach-ebsa110/Makefile	Mon Feb 10 10:39:27 2003
@@ -4,11 +4,9 @@
 
 # Object file lists.
 
-obj-y			:= core.o io.o time.o
+obj-y			:= core.o io.o
 obj-m			:=
 obj-n			:=
 obj-			:=
-
-export-objs		:= io.o
 
 obj-$(CONFIG_LEDS)	+= leds.o
diff -Nru a/arch/arm/mach-ebsa110/time.c b/arch/arm/mach-ebsa110/time.c
--- a/arch/arm/mach-ebsa110/time.c	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,112 +0,0 @@
-/*
- *  linux/arch/arm/mach-ebsa110/time.c
- *
- *  Copyright (C) 2001 Russell King
- *
- * 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/init.h>
-
-#include <asm/io.h>
-
-#define PIT_CTRL		(PIT_BASE + 0x0d)
-#define PIT_T2			(PIT_BASE + 0x09)
-#define PIT_T1			(PIT_BASE + 0x05)
-#define PIT_T0			(PIT_BASE + 0x01)
-
-/*
- * This is the rate at which your MCLK signal toggles (in Hz)
- * This was measured on a 10 digit frequency counter sampling
- * over 1 second.
- */
-#define MCLK	47894000
-
-/*
- * This is the rate at which the PIT timers get clocked
- */
-#define CLKBY7	(MCLK / 7)
-
-/*
- * If CLKBY7 is larger than this, then we must do software
- * division of the timer interrupt.
- */
-#if CLKBY7 > 6553500
-#define DIVISOR	2
-#else
-#define DIVISOR 1
-#endif
-
-/*
- * This is the counter value
- */
-#define COUNT	((CLKBY7 + (DIVISOR * HZ / 2)) / (DIVISOR * HZ))
-
-extern unsigned long (*gettimeoffset)(void);
-
-static unsigned long divisor;
-
-/*
- * Get the time offset from the system PIT.  Note that if we have missed an
- * interrupt, then the PIT counter will roll over (ie, be negative).
- * This actually works out to be convenient.
- */
-static unsigned long ebsa110_gettimeoffset(void)
-{
-	unsigned long offset, count;
-
-	__raw_writeb(0x40, PIT_CTRL);
-	count = __raw_readb(PIT_T1);
-	count |= __raw_readb(PIT_T1) << 8;
-
-	/*
-	 * If count > COUNT, make the number negative.
-	 */
-	if (count > COUNT)
-		count |= 0xffff0000;
-
-	offset = COUNT * (DIVISOR - divisor);
-	offset -= count;
-
-	/*
-	 * `offset' is in units of timer counts.  Convert
-	 * offset to units of microseconds.
-	 */
-	offset = offset * (1000000 / HZ) / (COUNT * DIVISOR);
-
-	return offset;
-}
-
-int ebsa110_reset_timer(void)
-{
-	u32 count;
-
-	/* latch and read timer 1 */
-	__raw_writeb(0x40, PIT_CTRL);
-	count = __raw_readb(PIT_T1);
-	count |= __raw_readb(PIT_T1) << 8;
-
-	count += COUNT;
-
-	__raw_writeb(count & 0xff, PIT_T1);
-	__raw_writeb(count >> 8, PIT_T1);
-
-	if (divisor == 0)
-		divisor = DIVISOR;
-	divisor -= 1;
-	return divisor;
-}
-
-void __init ebsa110_setup_timer(void)
-{
-	/*
-	 * Timer 1, mode 2, LSB/MSB
-	 */
-	__raw_writeb(0x70, PIT_CTRL);
-	__raw_writeb(COUNT & 0xff, PIT_T1);
-	__raw_writeb(COUNT >> 8, PIT_T1);
-	divisor = DIVISOR - 1;
-
-	gettimeoffset = ebsa110_gettimeoffset;
-}
diff -Nru a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile
--- a/arch/arm/mach-epxa10db/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/arm/mach-epxa10db/Makefile	Mon Feb 10 10:39:32 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
--- a/arch/arm/mach-footbridge/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/mach-footbridge/Makefile	Mon Feb 10 10:39:27 2003
@@ -9,8 +9,6 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= arch.o netwinder-hw.o
-
 pci-$(CONFIG_ARCH_CATS) += cats-pci.o
 pci-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o
 pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
diff -Nru a/arch/arm/mach-ftvpci/Makefile b/arch/arm/mach-ftvpci/Makefile
--- a/arch/arm/mach-ftvpci/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/arm/mach-ftvpci/Makefile	Mon Feb 10 10:39:33 2003
@@ -9,7 +9,5 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
-
 obj-$(CONFIG_PCI)	+= pci.o
 obj-$(CONFIG_LEDS)	+= leds.o
diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
--- a/arch/arm/mach-integrator/pci_v3.c	Mon Feb 10 10:39:30 2003
+++ b/arch/arm/mach-integrator/pci_v3.c	Mon Feb 10 10:39:30 2003
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 
 #include <asm/hardware.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/pci.h>
@@ -119,7 +120,7 @@
  *              function = which function
  *		offset = configuration space register we are interested in
  *
- * description:	this routine will generate a platform dependant config
+ * description:	this routine will generate a platform dependent config
  *		address.
  *
  * calls:	none
@@ -295,7 +296,7 @@
 		v = __raw_readw(addr);
 		break;
 
-	case 4:
+	default:
 		v = __raw_readl(addr);
 		break;
 	}
diff -Nru a/arch/arm/mach-iop310/Makefile b/arch/arm/mach-iop310/Makefile
--- a/arch/arm/mach-iop310/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/arm/mach-iop310/Makefile	Mon Feb 10 10:39:32 2003
@@ -10,8 +10,6 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:=
-
 obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o
 
 ifneq ($(CONFIG_XSCALE_PMU_TIMER),y)
diff -Nru a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile
--- a/arch/arm/mach-l7200/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/arm/mach-l7200/Makefile	Mon Feb 10 10:39:33 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/mach-pxa/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-export-objs := generic.o irq.o dma.o sa1111.o
-
 # Common support (must be linked before board specific support)
 obj-y += generic.o irq.o dma.o
 obj-$(CONFIG_SA1111) += sa1111.o
diff -Nru a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile
--- a/arch/arm/mach-rpc/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/mach-rpc/Makefile	Mon Feb 10 10:39:27 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
--- a/arch/arm/mach-sa1100/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/arch/arm/mach-sa1100/Kconfig	Mon Feb 10 10:39:33 2003
@@ -165,6 +165,13 @@
 	  handheld computer.  See <http://www.hp.com/jornada/products/720>
 	  for details.
 
+config SA1100_HACKKIT
+	bool "HackKit Core CPU Board"
+	depends on ARCH_SA1100
+	help
+	  Say Y here to support the HackKit Core CPU Board
+	  <http://hackkit.eletztrick.de>;
+
 config SA1100_HUW_WEBPANEL
 	bool "HuW WebPanel"
 	depends on ARCH_SA1100
@@ -306,6 +313,18 @@
 	help
 	  Say Y here if you intend to run this kernel on the Stork
 	  handheld computer.
+
+#config SA1100_TRIZEPS
+#	bool "Trizeps"
+#	depends on ARCH_SA1100
+#	help
+#	  :: write me ::
+
+#config TRIZEPS_MFTB2
+#	bool "MFTB2"
+#	depends on SA1100_TRIZEPS
+#	help
+#	  :: write me ::
 
 config SA1100_USB
 	tristate "SA1100 USB function support"
diff -Nru a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
--- a/arch/arm/mach-sa1100/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/arm/mach-sa1100/Makefile	Mon Feb 10 10:39:33 2003
@@ -9,31 +9,25 @@
 obj-  :=
 led-y := leds.o
 
-export-objs := dma.o generic.o pcipool.o pm.o sa1111.o sa1111-pcibuf.o
-
 # This needs to be cleaned up.  We probably need to have SA1100
 # and SA1110 config symbols.
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET)		+= cpu-sa1110.o
 obj-$(CONFIG_SA1100_CERF)		+= cpu-sa1110.o
+obj-$(CONFIG_SA1100_HACKKIT)		+= cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART)		+= cpu-sa1100.o
 obj-$(CONFIG_SA1100_PT_SYSTEM3)		+= cpu-sa1110.o
 endif
 
-# Next, the SA1111 stuff.
-obj-$(CONFIG_SA1111)			+= sa1111.o sa1111-pcibuf.o pcipool.o
-
 # Specific board support
 obj-$(CONFIG_SA1100_ADSBITSY)		+= adsbitsy.o
 led-$(CONFIG_SA1100_ADSBITSY)		+= leds-adsbitsy.o
 
 obj-$(CONFIG_SA1100_ASSABET)		+= assabet.o
-export-objs				+= assabet.o
 led-$(CONFIG_SA1100_ASSABET)		+= leds-assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET)		+= neponset.o
 
 obj-$(CONFIG_SA1100_BADGE4)		+= badge4.o
-export-objs				+= badge4.o
 led-$(CONFIG_SA1100_BADGE4)		+= leds-badge4.o
 
 obj-$(CONFIG_SA1100_BRUTUS)		+= brutus.o
@@ -45,12 +39,9 @@
 obj-$(CONFIG_SA1100_EMPEG)		+= empeg.o
 
 obj-$(CONFIG_SA1100_FLEXANET)		+= flexanet.o
-export-objs				+= flexanet.o
 led-$(CONFIG_SA1100_FLEXANET)		+= leds-flexanet.o
 
 obj-$(CONFIG_SA1100_FREEBIRD)		+= freebird.o
-export-objs				+= freebird.o
-
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT)	+= graphicsclient.o
 led-$(CONFIG_SA1100_GRAPHICSCLIENT)	+= leds-graphicsclient.o
 
@@ -58,10 +49,11 @@
 led-$(CONFIG_SA1100_GRAPHICSMASTER)	+= leds-graphicsmaster.o
 
 obj-$(CONFIG_SA1100_H3600)		+= h3600.o
-export-objs				+= h3600.o
+
+obj-$(CONFIG_SA1100_HACKKIT)		+= hackkit.o
+led-$(CONFIG_SA1100_HACKKIT)		+= leds-hackkit.o
 
 obj-$(CONFIG_SA1100_HUW_WEBPANEL)	+= huw_webpanel.o
-export-objs				+= huw_webpanel.o
 
 obj-$(CONFIG_SA1100_ITSY)		+= itsy.o
 
@@ -92,12 +84,12 @@
 led-$(CONFIG_SA1100_SIMPAD)		+= leds-simpad.o  
 
 obj-$(CONFIG_SA1100_STORK)		+= stork.o
-export-objs				+= stork.o
+
+obj-$(CONFIG_SA1100_TRIZEPS)		+= trizeps.o
 
 obj-$(CONFIG_SA1100_XP860)		+= xp860.o
 
 obj-$(CONFIG_SA1100_YOPY)		+= yopy.o
-export-objs				+= yopy.o
 
 # LEDs support
 obj-$(CONFIG_LEDS) += $(led-y)
@@ -106,4 +98,4 @@
 #obj-$(CONFIG_SA1100_USB)		+= usb/
 
 # Miscelaneous functions
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM)			+= pm.o sleep.o
diff -Nru a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-sa1100/hackkit.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-sa1100/hackkit.c
+ *
+ * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * This file contains all HackKit tweaks. Based on original work from
+ * Nicolas Pitre's assabet fixes
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+/**********************************************************************
+ *  prototypes
+ */
+
+/* init funcs */
+static void __init get_hackkit_scr(void);
+static int __init hackkit_init(void);
+static void __init hackkit_init_irq(void);
+static void __init hackkit_map_io(void);
+
+static u_int hackkit_get_mctrl(struct uart_port *port);
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
+
+/**********************************************************************
+ *  global data
+ */
+
+/**********************************************************************
+ *  static data
+ */
+
+static struct map_desc hackkit_io_desc[] __initdata = {
+ /* virtual     physical    length      type */
+  { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */
+};
+
+static struct sa1100_port_fns hackkit_port_fns __initdata = {
+	.set_mctrl	= hackkit_set_mctrl,
+	.get_mctrl	= hackkit_get_mctrl,
+	.pm		= hackkit_uart_pm,
+};
+
+/**********************************************************************
+ *  Static functions
+ */
+
+static void __init hackkit_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(hackkit_io_desc, ARRAY_SIZE(hackkit_io_desc));
+
+	sa1100_register_uart_fns(&hackkit_port_fns);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+static void __init hackkit_init_irq(void)
+{
+	/* none used yet */
+}
+
+/**
+ *	hackkit_uart_pm - powermgmt callback function for system 3 UART
+ *	@port: uart port structure
+ *	@state: pm state
+ *	@oldstate: old pm state
+ *
+ */
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	/* TODO: switch on/off uart in powersave mode */
+}
+
+/*
+ * Note! this can be called from IRQ context.
+ * FIXME: No modem ctrl lines yet.
+ */
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+#if 0
+	if (port->mapbase == _Ser1UTCR0) {
+		u_int set = 0, clear = 0;
+
+		if (mctrl & TIOCM_RTS)
+			set |= PT_CTRL2_RS1_RTS;
+		else
+			clear |= PT_CTRL2_RS1_RTS;
+
+		if (mctrl & TIOCM_DTR)
+			set |= PT_CTRL2_RS1_DTR;
+		else
+			clear |= PT_CTRL2_RS1_DTR;
+
+		PTCTRL2_clear(clear);
+		PTCTRL2_set(set);
+	}
+#endif
+}
+
+static u_int hackkit_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+#if 0
+	u_int irqsr = PT_IRQSR;
+
+	/* need 2 reads to read current value */
+	irqsr = PT_IRQSR;
+
+	/* TODO: check IRQ source register for modem/com
+	 status lines and set them correctly. */
+#endif
+
+	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	return ret;
+}
+
+static int __init hackkit_init(void)
+{
+	int ret = 0;
+
+	if ( !machine_is_hackkit() ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	hackkit_init_irq();
+
+	ret = 0;
+DONE:
+	return ret;
+}
+
+/**********************************************************************
+ *  Exported Functions
+ */
+
+/**********************************************************************
+ *  kernel magic macros
+ */
+arch_initcall(hackkit_init);
+
+MACHINE_START(HACKKIT, "HackKit Cpu Board")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	MAPIO(hackkit_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Nru a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-sa1100/leds-hackkit.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-hackkit.c
+ *
+ * based on leds-lart.c
+ *
+ * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
+ *
+ * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
+ * as cpu led, the green one is used as timer led.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_GREEN    GPIO_GPIO23
+#define LED_RED    GPIO_GPIO22
+#define LED_MASK  (LED_RED | LED_GREEN)
+
+void hackkit_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch(evt) {
+		case led_start:
+			/* pin 22/23 are outputs */
+			GPDR |= LED_MASK;
+			hw_led_state = LED_MASK;
+			led_state = LED_STATE_ENABLED;
+			break;
+
+		case led_stop:
+			led_state &= ~LED_STATE_ENABLED;
+			break;
+
+		case led_claim:
+			led_state |= LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+		case led_release:
+			led_state &= ~LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+#ifdef CONFIG_LEDS_TIMER
+		case led_timer:
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state ^= LED_GREEN;
+			break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+		case led_idle_start:
+			/* The LART people like the LED to be off when the
+			   system is idle... */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_idle_end:
+			/* ... and on if the system is not idle */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state |= LED_RED;
+			break;
+#endif
+
+		case led_red_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_red_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_RED;
+			break;
+
+		case led_green_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_GREEN;
+			break;
+
+		case led_green_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_GREEN;
+			break;
+
+		default:
+			break;
+	}
+
+	/* Now set the GPIO state, or nothing will happen at all */
+	if (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	local_irq_restore(flags);
+}
diff -Nru a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
--- a/arch/arm/mach-sa1100/leds.c	Mon Feb 10 10:39:24 2003
+++ b/arch/arm/mach-sa1100/leds.c	Mon Feb 10 10:39:24 2003
@@ -29,6 +29,8 @@
 		leds_event = flexanet_leds_event;
 	if (machine_is_graphicsclient())
 		leds_event = graphicsclient_leds_event;
+	if (machine_is_hackkit())
+		leds_event = hackkit_leds_event;
 	if (machine_is_lart())
 		leds_event = lart_leds_event;
 	if (machine_is_pfs168())
diff -Nru a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h
--- a/arch/arm/mach-sa1100/leds.h	Mon Feb 10 10:39:30 2003
+++ b/arch/arm/mach-sa1100/leds.h	Mon Feb 10 10:39:30 2003
@@ -5,6 +5,7 @@
 extern void cerf_leds_event(led_event_t evt);
 extern void flexanet_leds_event(led_event_t evt);
 extern void graphicsclient_leds_event(led_event_t evt);
+extern void hackkit_leds_event(led_event_t evt);
 extern void lart_leds_event(led_event_t evt);
 extern void pfs168_leds_event(led_event_t evt);
 extern void graphicsmaster_leds_event(led_event_t evt);
diff -Nru a/arch/arm/mach-sa1100/pcipool.c b/arch/arm/mach-sa1100/pcipool.c
--- a/arch/arm/mach-sa1100/pcipool.c	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,390 +0,0 @@
-/*
-  NOTE:
-
-  this code was lifted straight out of drivers/pci/pci.c;
-  when compiling for the Intel StrongARM SA-1110/SA-1111 the
-  usb-ohci.c driver needs these routines even when the architecture
-  has no pci bus...
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-
-#include <asm/page.h>
-
-/*
- * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
- * small blocks are easily used by drivers for bus mastering controllers.
- * This should probably be sharing the guts of the slab allocator.
- */
-
-struct pci_pool {	/* the pool */
-	struct list_head	page_list;
-	spinlock_t		lock;
-	size_t			blocks_per_page;
-	size_t			size;
-	struct pci_dev		*dev;
-	size_t			allocation;
-	char			name [32];
-	wait_queue_head_t	waitq;
-};
-
-struct pci_page {	/* cacheable header for 'allocation' bytes */
-	struct list_head	page_list;
-	void			*vaddr;
-	dma_addr_t		dma;
-	unsigned long		bitmap [0];
-};
-
-#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
-#define	POOL_POISON_BYTE	0xa7
-
-// #define CONFIG_PCIPOOL_DEBUG
-
-static inline const char *slot_name(const struct pci_pool *pool)
-{
-	const struct pci_dev *pdev = pool->dev;
-
-	if (pdev == 0)
-		return "[0]";
-
-	else if (pcidev_is_sa1111(pdev))
-		return "[SA-1111]";
-	else
-		return pdev->slot_name;
-}
-
-
-/**
- * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
- * @name: name of pool, for diagnostics
- * @pdev: pci device that will be doing the DMA
- * @size: size of the blocks in this pool.
- * @align: alignment requirement for blocks; must be a power of two
- * @allocation: returned blocks won't cross this boundary (or zero)
- * Context: !in_interrupt()
- *
- * Returns a pci allocation pool with the requested characteristics, or
- * null if one can't be created.  Given one of these pools, pci_pool_alloc()
- * may be used to allocate memory.  Such memory will all have "consistent"
- * DMA mappings, accessible by the device and its driver without using
- * cache flushing primitives.  The actual size of blocks allocated may be
- * larger than requested because of alignment.
- *
- * If allocation is nonzero, objects returned from pci_pool_alloc() won't
- * cross that size boundary.  This is useful for devices which have
- * addressing restrictions on individual DMA transfers, such as not crossing
- * boundaries of 4KBytes.
- */
-struct pci_pool *
-pci_pool_create (const char *name, struct pci_dev *pdev,
-	size_t size, size_t align, size_t allocation)
-{
-	struct pci_pool		*retval;
-
-	if (align == 0)
-		align = 1;
-	if (size == 0)
-		return 0;
-	else if (size < align)
-		size = align;
-	else if ((size % align) != 0) {
-		size += align + 1;
-		size &= ~(align - 1);
-	}
-
-	if (allocation == 0) {
-		if (PAGE_SIZE < size)
-			allocation = size;
-		else
-			allocation = PAGE_SIZE;
-		// FIXME: round up for less fragmentation
-	} else if (allocation < size)
-		return 0;
-
-	if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL)))
-		return retval;
-
-	strncpy (retval->name, name, sizeof retval->name);
-	retval->name [sizeof retval->name - 1] = 0;
-
-	retval->dev = pdev;
-	INIT_LIST_HEAD (&retval->page_list);
-	spin_lock_init (&retval->lock);
-	retval->size = size;
-	retval->allocation = allocation;
-	retval->blocks_per_page = allocation / size;
-	init_waitqueue_head (&retval->waitq);
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
-		slot_name(retval), retval->name, size,
-		retval->blocks_per_page, allocation);
-#endif
-
-	return retval;
-}
-
-
-static struct pci_page *
-pool_alloc_page (struct pci_pool *pool, int mem_flags)
-{
-	struct pci_page	*page;
-	int		mapsize;
-
-	mapsize = pool->blocks_per_page;
-	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	mapsize *= sizeof (long);
-
-	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
-	if (!page)
-		return 0;
-	page->vaddr = pci_alloc_consistent (pool->dev,
-					    pool->allocation,
-					    &page->dma);
-	if (page->vaddr) {
-		memset (page->bitmap, 0xff, mapsize);	// bit set == free
-#ifdef	CONFIG_DEBUG_SLAB
-		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-#endif
-		list_add (&page->page_list, &pool->page_list);
-	} else {
-		kfree (page);
-		page = 0;
-	}
-	return page;
-}
-
-
-static inline int
-is_page_busy (int blocks, unsigned long *bitmap)
-{
-	while (blocks > 0) {
-		if (*bitmap++ != ~0UL)
-			return 1;
-		blocks -= BITS_PER_LONG;
-	}
-	return 0;
-}
-
-static void
-pool_free_page (struct pci_pool *pool, struct pci_page *page)
-{
-	dma_addr_t	dma = page->dma;
-
-#ifdef	CONFIG_DEBUG_SLAB
-	memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-#endif
-	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
-	list_del (&page->page_list);
-	kfree (page);
-}
-
-
-/**
- * pci_pool_destroy - destroys a pool of pci memory blocks.
- * @pool: pci pool that will be destroyed
- *
- * Caller guarantees that no more memory from the pool is in use,
- * and that nothing will try to use the pool after this call.
- */
-void
-pci_pool_destroy (struct pci_pool *pool)
-{
-	unsigned long		flags;
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
-		slot_name(pool), pool->name);
-#endif
-
-	spin_lock_irqsave (&pool->lock, flags);
-	while (!list_empty (&pool->page_list)) {
-		struct pci_page		*page;
-		page = list_entry (pool->page_list.next,
-				struct pci_page, page_list);
-		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
-			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
-				slot_name(pool), pool->name, page->vaddr);
-			/* leak the still-in-use consistent memory */
-			list_del (&page->page_list);
-			kfree (page);
-		} else
-			pool_free_page (pool, page);
-	}
-	spin_unlock_irqrestore (&pool->lock, flags);
-	kfree (pool);
-}
-
-
-/**
- * pci_pool_alloc - get a block of consistent memory
- * @pool: pci pool that will produce the block
- * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
- * @handle: pointer to dma address of block
- *
- * This returns the kernel virtual address of a currently unused block,
- * and reports its dma address through the handle.
- * If such a memory block can't be allocated, null is returned.
- */
-void *
-pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-	int			map, block;
-	size_t			offset;
-	void			*retval;
-
-restart:
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		int		i;
-		page = list_entry (entry, struct pci_page, page_list);
-		/* only cachable accesses here ... */
-		for (map = 0, i = 0;
-				i < pool->blocks_per_page;
-				i += BITS_PER_LONG, map++) {
-			if (page->bitmap [map] == 0)
-				continue;
-			block = ffz (~ page->bitmap [map]);
-			if ((i + block) < pool->blocks_per_page) {
-				clear_bit (block, &page->bitmap [map]);
-				offset = (BITS_PER_LONG * map) + block;
-				offset *= pool->size;
-				goto ready;
-			}
-		}
-	}
-	if (!(page = pool_alloc_page (pool, mem_flags))) {
-		if (mem_flags == SLAB_KERNEL) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			current->state = TASK_INTERRUPTIBLE;
-			add_wait_queue (&pool->waitq, &wait);
-			spin_unlock_irqrestore (&pool->lock, flags);
-
-			schedule_timeout (POOL_TIMEOUT_JIFFIES);
-
-			current->state = TASK_RUNNING;
-			remove_wait_queue (&pool->waitq, &wait);
-			goto restart;
-		}
-		retval = 0;
-		goto done;
-	}
-
-	clear_bit (0, &page->bitmap [0]);
-	offset = 0;
-ready:
-	retval = offset + page->vaddr;
-	*handle = offset + page->dma;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return retval;
-}
-
-
-static struct pci_page *
-pool_find_page (struct pci_pool *pool, dma_addr_t dma)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		page = list_entry (entry, struct pci_page, page_list);
-		if (dma < page->dma)
-			continue;
-		if (dma < (page->dma + pool->allocation))
-			goto done;
-	}
-	page = 0;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return page;
-}
-
-
-/**
- * pci_pool_free - put block back into pci pool
- * @pool: the pci pool holding the block
- * @vaddr: virtual address of block
- * @dma: dma address of block
- *
- * Caller promises neither device nor driver will again touch this block
- * unless it is first re-allocated.
- */
-void
-pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
-{
-	struct pci_page		*page;
-	unsigned long		flags;
-	int			map, block;
-
-	if ((page = pool_find_page (pool, dma)) == 0) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, (unsigned long) dma);
-		return;
-	}
-
-	block = dma - page->dma;
-	block /= pool->size;
-	map = block / BITS_PER_LONG;
-	block %= BITS_PER_LONG;
-
-#ifdef	CONFIG_DEBUG_SLAB
-	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, (unsigned long) dma);
-		return;
-	}
-	if (page->bitmap [map] & (1UL << block)) {
-		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, dma);
-		return;
-	}
-	memset (vaddr, POOL_POISON_BYTE, pool->size);
-#endif
-
-	spin_lock_irqsave (&pool->lock, flags);
-	set_bit (block, &page->bitmap [map]);
-	if (waitqueue_active (&pool->waitq))
-		wake_up (&pool->waitq);
-	/*
-	 * Resist a temptation to do
-	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
-	 * it is not interrupt safe. Better have empty pages hang around.
-	 */
-	spin_unlock_irqrestore (&pool->lock, flags);
-}
-
-EXPORT_SYMBOL (pci_pool_create);
-EXPORT_SYMBOL (pci_pool_destroy);
-EXPORT_SYMBOL (pci_pool_alloc);
-EXPORT_SYMBOL (pci_pool_free);
-
-/* **************************************** */
-
-static int __init pcipool_init(void)
-{
-	MOD_INC_USE_COUNT;	/* never unload */
-
-	return 0;
-}
-module_init(pcipool_init);
-
-MODULE_LICENSE("GPL");
diff -Nru a/arch/arm/mach-sa1100/sa1111-pcibuf.c b/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- a/arch/arm/mach-sa1100/sa1111-pcibuf.c	Mon Feb 10 10:39:22 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,551 +0,0 @@
-/*
- *  linux/arch/arm/mach-sa1100/pci-sa1111.c
- *
- *  Special pci_{map/unmap/dma_sync}_* routines for SA-1111.
- *
- *  These functions utilize bouncer buffers to compensate for a bug in
- *  the SA-1111 hardware which don't allow DMA to/from addresses
- *  certain addresses above 1MB.
- *
- *  Re-written by Christopher Hoover <ch@murgatroid.com>
- *  Original version by Brad Parker (brad@heeltoe.com)
- *
- *  Copyright (C) 2002 Hewlett Packard Company.
- *
- *  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/init.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-#include <asm/hardware/sa1111.h>
-
-//#define DEBUG
-#ifdef DEBUG
-#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0)
-#else
-#define DPRINTK(...) do { } while (0)
-#endif
-
-//#define STATS
-#ifdef STATS
-#define DO_STATS(X) do { X ; } while (0)
-#else
-#define DO_STATS(X) do { } while (0)
-#endif
-
-/* ************************************************** */
-
-struct safe_buffer {
-	struct list_head node;
-
-	/* original request */
-	void		*ptr;
-	size_t		size;
-	int		direction;
-
-	/* safe buffer info */
-	struct pci_pool *pool;
-	void		*safe;
-	dma_addr_t	safe_dma_addr;
-};
-
-LIST_HEAD(safe_buffers);
-
-
-#define SIZE_SMALL	1024
-#define SIZE_LARGE	(4*1024)
-
-static struct pci_pool *small_buffer_pool, *large_buffer_pool;
-
-#ifdef STATS
-static unsigned long sbp_allocs __initdata = 0;
-static unsigned long lbp_allocs __initdata = 0;
-static unsigned long total_allocs __initdata= 0;
-
-static void print_alloc_stats(void)
-{
-	printk(KERN_INFO
-	       "sa1111_pcibuf: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
-	       sbp_allocs, lbp_allocs,
-	       total_allocs - sbp_allocs - lbp_allocs, total_allocs);
-}
-#endif
-
-static int __init
-create_safe_buffer_pools(void)
-{
-	small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer",
-					    SA1111_FAKE_PCIDEV,
-					    SIZE_SMALL,
-					    0 /* byte alignment */,
-					    0 /* no page-crossing issues */);
-	if (0 == small_buffer_pool) {
-		printk(KERN_ERR
-		       "sa1111_pcibuf: could not allocate small pci pool\n");
-		return -1;
-	}
-
-	large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer",
-					    SA1111_FAKE_PCIDEV,
-					    SIZE_LARGE,
-					    0 /* byte alignment */,
-					    0 /* no page-crossing issues */);
-	if (0 == large_buffer_pool) {
-		printk(KERN_ERR
-		       "sa1111_pcibuf: could not allocate large pci pool\n");
-		pci_pool_destroy(small_buffer_pool);
-		small_buffer_pool = 0;
-		return -1;
-	}
-
-	printk(KERN_INFO
-	       "sa1111_pcibuf: buffer sizes: small=%u, large=%u\n",
-	       SIZE_SMALL, SIZE_LARGE);
-
-	return 0;
-}
-
-static void __exit
-destroy_safe_buffer_pools(void)
-{
-	if (small_buffer_pool)
-		pci_pool_destroy(small_buffer_pool);
-	if (large_buffer_pool)
-		pci_pool_destroy(large_buffer_pool);
-
-	small_buffer_pool = large_buffer_pool = 0;
-}
-
-
-/* allocate a 'safe' buffer and keep track of it */
-static struct safe_buffer *
-alloc_safe_buffer(void *ptr, size_t size, int direction)
-{
-	struct safe_buffer *buf;
-	struct pci_pool *pool;
-	void *safe;
-	dma_addr_t safe_dma_addr;
-
-	DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n",
-		__func__, ptr, size, direction);
-
-	DO_STATS ( total_allocs++ );
-
-	buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
-	if (buf == 0) {
-		printk(KERN_WARNING "%s: kmalloc failed\n", __func__);
-		return 0;
-	}
-
-	if (size <= SIZE_SMALL) {
-		pool = small_buffer_pool;
-		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
-
-		DO_STATS ( sbp_allocs++ );
-	} else if (size <= SIZE_LARGE) {
-		pool = large_buffer_pool;
-		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
-
-		DO_STATS ( lbp_allocs++ );
-	} else {
-		pool = 0;
-		safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size,
-					    &safe_dma_addr);
-	}
-
-	if (safe == 0) {
-		printk(KERN_WARNING
-		       "%s: could not alloc dma memory (size=%d)\n",
-		       __func__, size);
-		kfree(buf);
-		return 0;
-	}
-
-#ifdef STATS
-	if (total_allocs % 1000 == 0)
-		print_alloc_stats();
-#endif
-
-	BUG_ON(sa1111_check_dma_bug(safe_dma_addr));	// paranoia
-
-	buf->ptr = ptr;
-	buf->size = size;
-	buf->direction = direction;
-	buf->pool = pool;
-	buf->safe = safe;
-	buf->safe_dma_addr = safe_dma_addr;
-
-	MOD_INC_USE_COUNT;
-	list_add(&buf->node, &safe_buffers);
-
-	return buf;
-}
-
-/* determine if a buffer is from our "safe" pool */
-static struct safe_buffer *
-find_safe_buffer(dma_addr_t safe_dma_addr)
-{
-	struct list_head *entry;
-
-	list_for_each(entry, &safe_buffers) {
-		struct safe_buffer *b =
-			list_entry(entry, struct safe_buffer, node);
-
-		if (b->safe_dma_addr == safe_dma_addr) {
-			return b;
-		}
-	}
-
-	return 0;
-}
-
-static void
-free_safe_buffer(struct safe_buffer *buf)
-{
-	DPRINTK("%s(buf=%p)\n", __func__, buf);
-
-	list_del(&buf->node);
-
-	if (buf->pool)
-		pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
-	else
-		pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe,
-				    buf->safe_dma_addr);
-	kfree(buf);
-
-	MOD_DEC_USE_COUNT;
-}
-
-static inline int
-dma_range_is_safe(dma_addr_t addr, size_t size)
-{
-	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr);
-
-	/* Any address within one megabyte of the start of the target
-         * bank will be OK.  This is an overly conservative test:
-         * other addresses can be OK depending on the dram
-         * configuration.  (See sa1111.c:sa1111_check_dma_bug() * for
-         * details.)
-	 *
-	 * We take care to ensure the entire dma region is within
-	 * the safe range.
-	 */
-
-	return ((physaddr + size - 1) < (1<<20));
-}
-
-/* ************************************************** */
-
-#ifdef STATS
-static unsigned long map_op_count __initdata = 0;
-static unsigned long bounce_count __initdata = 0;
-
-static void print_map_stats(void)
-{
-	printk(KERN_INFO
-	       "sa1111_pcibuf: map_op_count=%lu, bounce_count=%lu\n",
-	       map_op_count, bounce_count);
-}
-#endif
-
-static dma_addr_t
-map_single(void *ptr, size_t size, int direction)
-{
-	dma_addr_t dma_addr;
-
-	DO_STATS ( map_op_count++ );
-
-	dma_addr = virt_to_bus(ptr);
-
-	if (!dma_range_is_safe(dma_addr, size)) {
-		struct safe_buffer *buf;
-
-		DO_STATS ( bounce_count++ ) ;
-
-		buf = alloc_safe_buffer(ptr, size, direction);
-		if (buf == 0) {
-			printk(KERN_ERR
-			       "%s: unable to map unsafe buffer %p!\n",
-			       __func__, ptr);
-			return 0;
-		}
-
-		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
-			__func__,
-			buf->ptr, (void *) virt_to_bus(buf->ptr),
-			buf->safe, (void *) buf->safe_dma_addr);
-
-		if ((direction == PCI_DMA_TODEVICE) ||
-		    (direction == PCI_DMA_BIDIRECTIONAL)) {
-			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
-				__func__, ptr, buf->safe, size);
-			memcpy(buf->safe, ptr, size);
-		}
-		consistent_sync(buf->safe, size, direction);
-
-		dma_addr = buf->safe_dma_addr;
-	} else {
-		consistent_sync(ptr, size, direction);
-	}
-
-#ifdef STATS
-	if (map_op_count % 1000 == 0)
-		print_map_stats();
-#endif
-
-	return dma_addr;
-}
-
-static void
-unmap_single(dma_addr_t dma_addr, size_t size, int direction)
-{
-	struct safe_buffer *buf;
-
-	buf = find_safe_buffer(dma_addr);
-
-	if (buf) {
-		BUG_ON(buf->size != size);
-		BUG_ON(buf->direction != direction);
-
-		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
-			__func__,
-			buf->ptr, (void *) virt_to_bus(buf->ptr),
-			buf->safe, (void *) buf->safe_dma_addr);
-
-
-		DO_STATS ( bounce_count++ );
-
-		if ((direction == PCI_DMA_FROMDEVICE) ||
-		    (direction == PCI_DMA_BIDIRECTIONAL)) {
-			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
-				__func__, buf->safe, buf->ptr, size);
-			memcpy(buf->ptr, buf->safe, size);
-		}
-		free_safe_buffer(buf);
-	}
-}
-
-static void
-sync_single(dma_addr_t dma_addr, size_t size, int direction)
-{
-	struct safe_buffer *buf;
-
-	buf = find_safe_buffer(dma_addr);
-
-	if (buf) {
-		BUG_ON(buf->size != size);
-		BUG_ON(buf->direction != direction);
-
-		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
-			__func__,
-			buf->ptr, (void *) virt_to_bus(buf->ptr),
-			buf->safe, (void *) buf->safe_dma_addr);
-
-		DO_STATS ( bounce_count++ );
-
-		switch (direction) {
-		case PCI_DMA_FROMDEVICE:
-			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
-				__func__, buf->safe, buf->ptr, size);
-			memcpy(buf->ptr, buf->safe, size);
-			break;
-		case PCI_DMA_TODEVICE:
-			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
-				__func__,buf->ptr, buf->safe, size);
-			memcpy(buf->safe, buf->ptr, size);
-			break;
-		case PCI_DMA_BIDIRECTIONAL:
-			BUG();	/* is this allowed?  what does it mean? */
-		default:
-			BUG();
-		}
-		consistent_sync(buf->safe, size, direction);
-	} else {
-		consistent_sync(bus_to_virt(dma_addr), size, direction);
-	}
-}
-
-/* ************************************************** */
-
-/*
- * see if a buffer address is in an 'unsafe' range.  if it is
- * allocate a 'safe' buffer and copy the unsafe buffer into it.
- * substitute the safe buffer for the unsafe one.
- * (basically move the buffer from an unsafe area to a safe one)
- */
-dma_addr_t
-sa1111_map_single(void *ptr, size_t size, int direction)
-{
-	unsigned long flags;
-	dma_addr_t dma_addr;
-
-	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
-	       __func__, ptr, size, direction);
-
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	local_irq_save(flags);
-
-	dma_addr = map_single(ptr, size, direction);
-
-	local_irq_restore(flags);
-
-	return dma_addr;
-}
-
-/*
- * see if a mapped address was really a "safe" buffer and if so, copy
- * the data from the safe buffer back to the unsafe buffer and free up
- * the safe buffer.  (basically return things back to the way they
- * should be)
- */
-
-void
-sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
-{
-	unsigned long flags;
-
-	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
-		__func__, (void *) dma_addr, size, direction);
-
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	local_irq_save(flags);
-
-	unmap_single(dma_addr, size, direction);
-
-	local_irq_restore(flags);
-}
-
-int
-sa1111_map_sg(struct scatterlist *sg, int nents, int direction)
-{
-	unsigned long flags;
-	int i;
-
-	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, direction);
-
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	local_irq_save(flags);
-
-	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg->page;
-		unsigned int offset = sg->offset;
-		unsigned int length = sg->length;
-		void *ptr = page_address(page) + offset;
-
-		sg->dma_address =
-			map_single(ptr, length, direction);
-	}
-
-	local_irq_restore(flags);
-
-	return nents;
-}
-
-void
-sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction)
-{
-	unsigned long flags;
-	int i;
-
-	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, direction);
-
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	local_irq_save(flags);
-
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
-
-		unmap_single(dma_addr, length, direction);
-	}
-
-	local_irq_restore(flags);
-}
-
-void
-sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction)
-{
-	unsigned long flags;
-
-	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
-		__func__, (void *) dma_addr, size, direction);
-
-	local_irq_save(flags);
-
-	sync_single(dma_addr, size, direction);
-
-	local_irq_restore(flags);
-}
-
-void
-sa1111_dma_sync_sg(struct scatterlist *sg, int nents, int direction)
-{
-	unsigned long flags;
-	int i;
-
-	DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
-		__func__, sg, nents, direction);
-
-	BUG_ON(direction == PCI_DMA_NONE);
-
-	local_irq_save(flags);
-
-	for (i = 0; i < nents; i++, sg++) {
-		dma_addr_t dma_addr = sg->dma_address;
-		unsigned int length = sg->length;
-
-		sync_single(dma_addr, length, direction);
-	}
-
-	local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(sa1111_map_single);
-EXPORT_SYMBOL(sa1111_unmap_single);
-EXPORT_SYMBOL(sa1111_map_sg);
-EXPORT_SYMBOL(sa1111_unmap_sg);
-EXPORT_SYMBOL(sa1111_dma_sync_single);
-EXPORT_SYMBOL(sa1111_dma_sync_sg);
-
-/* **************************************** */
-
-static int __init sa1111_pcibuf_init(void)
-{
-	int ret;
-
-	printk(KERN_DEBUG
-	       "sa1111_pcibuf: initializing SA-1111 DMA workaround\n");
-
-	ret = create_safe_buffer_pools();
-
-	return ret;
-}
-module_init(sa1111_pcibuf_init);
-
-static void __exit sa1111_pcibuf_exit(void)
-{
-	BUG_ON(!list_empty(&safe_buffers));
-
-#ifdef STATS
-	print_alloc_stats();
-	print_map_stats();
-#endif
-
-	destroy_safe_buffer_pools();
-}
-module_exit(sa1111_pcibuf_exit);
-
-MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
-MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111.");
-MODULE_LICENSE("GPL");
diff -Nru a/arch/arm/mach-sa1100/sa1111.c b/arch/arm/mach-sa1100/sa1111.c
--- a/arch/arm/mach-sa1100/sa1111.c	Mon Feb 10 10:39:32 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1107 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/sa1111.c
- *
- * SA1111 support
- *
- * Original code by John Dorsey
- *
- * 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 file contains all generic SA1111 support.
- *
- * All initialization functions provided here are intended to be called
- * from machine specific code with proper arguments when required.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware/sa1111.h>
-
-/*
- * We keep the following data for the overall SA1111.  Note that the
- * struct device and struct resource are "fake"; they should be supplied
- * by the bus above us.  However, in the interests of getting all SA1111
- * drivers converted over to the device model, we provide this as an
- * anchor point for all the other drivers.
- */
-struct sa1111 {
-	struct device	*dev;
-	struct resource	res;
-	int		irq;
-	spinlock_t	lock;
-	void		*base;
-};
-
-/*
- * We _really_ need to eliminate this.  Its only users
- * are the PWM and DMA checking code.
- */
-static struct sa1111 *g_sa1111;
-
-static struct sa1111_dev usb_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [USB Controller]",
-	},
-	.skpcr_mask	= SKPCR_UCLKEN,
-	.devid		= SA1111_DEVID_USB,
-	.irq = {
-		IRQ_USBPWR,
-		IRQ_HCIM,
-		IRQ_HCIBUFFACC,
-		IRQ_HCIRMTWKP,
-		IRQ_NHCIMFCIR,
-		IRQ_USB_PORT_RESUME
-	},
-};
-
-static struct sa1111_dev sac_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [Audio Controller]",
-	},
-	.skpcr_mask	= SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
-	.devid		= SA1111_DEVID_SAC,
-	.irq = {
-		AUDXMTDMADONEA,
-		AUDXMTDMADONEB,
-		AUDRCVDMADONEA,
-		AUDRCVDMADONEB
-	},
-};
-
-static struct sa1111_dev ssp_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [SSP Controller]",
-	},
-	.skpcr_mask	= SKPCR_SCLKEN,
-	.devid		= SA1111_DEVID_SSP,
-};
-
-static struct sa1111_dev kbd_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [PS2]",
-	},
-	.skpcr_mask	= SKPCR_PTCLKEN,
-	.devid		= SA1111_DEVID_PS2,
-	.irq = {
-		IRQ_TPRXINT,
-		IRQ_TPTXINT
-	},
-};
-
-static struct sa1111_dev mse_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [PS2]",
-	},
-	.skpcr_mask	= SKPCR_PMCLKEN,
-	.devid		= SA1111_DEVID_PS2,
-	.irq = {
-		IRQ_MSRXINT,
-		IRQ_MSTXINT
-	},
-};
-
-static struct sa1111_dev int_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [Interrupt Controller]",
-	},
-	.skpcr_mask	= 0,
-	.devid		= SA1111_DEVID_INT,
-};
-
-static struct sa1111_dev pcmcia_dev = {
-	.dev = {
-		.name	= "Intel Corporation SA1111 [PCMCIA Controller]",
-	},
-	.skpcr_mask	= 0,
-	.devid		= SA1111_DEVID_PCMCIA,
-	.irq = {
-		IRQ_S0_READY_NINT,
-		IRQ_S0_CD_VALID,
-		IRQ_S0_BVD1_STSCHG,
-		IRQ_S1_READY_NINT,
-		IRQ_S1_CD_VALID,
-		IRQ_S1_BVD1_STSCHG,
-	},
-};
-
-static struct sa1111_dev *devs[] = {
-	&usb_dev,
-	&sac_dev,
-	&ssp_dev,
-	&kbd_dev,
-	&mse_dev,
-	&pcmcia_dev,
-};
-
-static unsigned int dev_offset[] = {
-	SA1111_USB,
-	0x0600,
-	0x0800,
-	SA1111_KBD,
-	SA1111_MSE,
-	0x1800,
-};
-
-/*
- * SA1111 interrupt support.  Since clearing an IRQ while there are
- * active IRQs causes the interrupt output to pulse, the upper levels
- * will call us again if there are more interrupts to process.
- */
-static void
-sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
-{
-	unsigned int stat0, stat1, i;
-
-	stat0 = INTSTATCLR0;
-	stat1 = INTSTATCLR1;
-
-	INTSTATCLR0 = stat0;
-
-	desc->chip->ack(irq);
-
-	INTSTATCLR1 = stat1;
-
-	if (stat0 == 0 && stat1 == 0) {
-		do_bad_IRQ(irq, desc, regs);
-		return;
-	}
-
-	for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
-		if (stat0 & 1)
-			do_edge_IRQ(i, irq_desc + i, regs);
-
-	for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
-		if (stat1 & 1)
-			do_edge_IRQ(i, irq_desc + i, regs);
-
-	/* For level-based interrupts */
-	desc->chip->unmask(irq);
-}
-
-#define SA1111_IRQMASK_LO(x)	(1 << (x - IRQ_SA1111_START))
-#define SA1111_IRQMASK_HI(x)	(1 << (x - IRQ_SA1111_START - 32))
-
-static void sa1111_ack_irq(unsigned int irq)
-{
-}
-
-static void sa1111_mask_lowirq(unsigned int irq)
-{
-	INTEN0 &= ~SA1111_IRQMASK_LO(irq);
-}
-
-static void sa1111_unmask_lowirq(unsigned int irq)
-{
-	INTEN0 |= SA1111_IRQMASK_LO(irq);
-}
-
-/*
- * Attempt to re-trigger the interrupt.  The SA1111 contains a register
- * (INTSET) which claims to do this.  However, in practice no amount of
- * manipulation of INTEN and INTSET guarantees that the interrupt will
- * be triggered.  In fact, its very difficult, if not impossible to get
- * INTSET to re-trigger the interrupt.
- */
-static void sa1111_rerun_lowirq(unsigned int irq)
-{
-	unsigned int mask = SA1111_IRQMASK_LO(irq);
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		INTPOL0 ^= mask;
-		INTPOL0 ^= mask;
-		if (INTSTATCLR1 & mask)
-			break;
-	}
-
-	if (i == 8)
-		printk(KERN_ERR "Danger Will Robinson: failed to "
-			"re-trigger IRQ%d\n", irq);
-}
-
-static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
-{
-	unsigned int mask = SA1111_IRQMASK_LO(irq);
-
-	if (flags == IRQT_PROBE)
-		return 0;
-
-	if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
-		return -EINVAL;
-
-	if (flags & __IRQT_RISEDGE)
-		INTPOL0 &= ~mask;
-	else
-		INTPOL0 |= mask;
-	WAKE_POL0 = INTPOL0;
-
-	return 0;
-}
-
-static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
-{
-	unsigned int mask = SA1111_IRQMASK_LO(irq);
-
-	if (on)
-		WAKE_EN0 |= mask;
-	else
-		WAKE_EN0 &= ~mask;
-
-	return 0;
-}
-
-static struct irqchip sa1111_low_chip = {
-	.ack		= sa1111_ack_irq,
-	.mask		= sa1111_mask_lowirq,
-	.unmask		= sa1111_unmask_lowirq,
-	.rerun		= sa1111_rerun_lowirq,
-	.type		= sa1111_type_lowirq,
-	.wake		= sa1111_wake_lowirq,
-};
-
-static void sa1111_mask_highirq(unsigned int irq)
-{
-	INTEN1 &= ~SA1111_IRQMASK_HI(irq);
-}
-
-static void sa1111_unmask_highirq(unsigned int irq)
-{
-	INTEN1 |= SA1111_IRQMASK_HI(irq);
-}
-
-/*
- * Attempt to re-trigger the interrupt.  The SA1111 contains a register
- * (INTSET) which claims to do this.  However, in practice no amount of
- * manipulation of INTEN and INTSET guarantees that the interrupt will
- * be triggered.  In fact, its very difficult, if not impossible to get
- * INTSET to re-trigger the interrupt.
- */
-static void sa1111_rerun_highirq(unsigned int irq)
-{
-	unsigned int mask = SA1111_IRQMASK_HI(irq);
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		INTPOL1 ^= mask;
-		INTPOL1 ^= mask;
-		if (INTSTATCLR1 & mask)
-			break;
-	}
-
-	if (i == 8)
-		printk(KERN_ERR "Danger Will Robinson: failed to "
-			"re-trigger IRQ%d\n", irq);
-}
-
-static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
-{
-	unsigned int mask = SA1111_IRQMASK_HI(irq);
-
-	if (flags == IRQT_PROBE)
-		return 0;
-
-	if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
-		return -EINVAL;
-
-	if (flags & __IRQT_RISEDGE)
-		INTPOL1 &= ~mask;
-	else
-		INTPOL1 |= mask;
-	WAKE_POL1 = INTPOL1;
-
-	return 0;
-}
-
-static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
-{
-	unsigned int mask = SA1111_IRQMASK_HI(irq);
-
-	if (on)
-		WAKE_EN1 |= mask;
-	else
-		WAKE_EN1 &= ~mask;
-
-	return 0;
-}
-
-static struct irqchip sa1111_high_chip = {
-	.ack		= sa1111_ack_irq,
-	.mask		= sa1111_mask_highirq,
-	.unmask		= sa1111_unmask_highirq,
-	.rerun		= sa1111_rerun_highirq,
-	.type		= sa1111_type_highirq,
-	.wake		= sa1111_wake_highirq,
-};
-
-static void __init sa1111_init_irq(struct sa1111_dev *sadev)
-{
-	unsigned int irq;
-
-	/*
-	 * We're guaranteed that this region hasn't been taken.
-	 */
-	request_mem_region(sadev->res.start, 512, "irqs");
-
-	/* disable all IRQs */
-	sa1111_writel(0, sadev->mapbase + SA1111_INTEN0);
-	sa1111_writel(0, sadev->mapbase + SA1111_INTEN1);
-	sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0);
-	sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1);
-
-	/*
-	 * detect on rising edge.  Note: Feb 2001 Errata for SA1111
-	 * specifies that S0ReadyInt and S1ReadyInt should be '1'.
-	 */
-	sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0);
-	sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) |
-		      SA1111_IRQMASK_HI(IRQ_S1_READY_NINT),
-		      sadev->mapbase + SA1111_INTPOL1);
-
-	/* clear all IRQs */
-	sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0);
-	sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1);
-
-	for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
-		set_irq_chip(irq, &sa1111_low_chip);
-		set_irq_handler(irq, do_edge_IRQ);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-
-	for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
-		set_irq_chip(irq, &sa1111_high_chip);
-		set_irq_handler(irq, do_edge_IRQ);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-
-	/*
-	 * Register SA1111 interrupt
-	 */
-	set_irq_type(sadev->irq[0], IRQT_RISING);
-	set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler);
-}
-
-/*
- * Bring the SA1111 out of reset.  This requires a set procedure:
- *  1. nRESET asserted (by hardware)
- *  2. CLK turned on from SA1110
- *  3. nRESET deasserted
- *  4. VCO turned on, PLL_BYPASS turned off
- *  5. Wait lock time, then assert RCLKEn
- *  7. PCR set to allow clocking of individual functions
- *
- * Until we've done this, the only registers we can access are:
- *   SBI_SKCR
- *   SBI_SMCR
- *   SBI_SKID
- */
-static void sa1111_wake(struct sa1111 *sachip)
-{
-	unsigned long flags, r;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-
-	/*
-	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
-	 * (SA-1110 Developer's Manual, section 9.1.2.1)
-	 */
-	GAFR |= GPIO_32_768kHz;
-	GPDR |= GPIO_32_768kHz;
-	TUCR = TUCR_3_6864MHz;
-
-	/*
-	 * Turn VCO on, and disable PLL Bypass.
-	 */
-	r = sa1111_readl(sachip->base + SA1111_SKCR);
-	r &= ~SKCR_VCO_OFF;
-	sa1111_writel(r, sachip->base + SA1111_SKCR);
-	r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
-	sa1111_writel(r, sachip->base + SA1111_SKCR);
-
-	/*
-	 * Wait lock time.  SA1111 manual _doesn't_
-	 * specify a figure for this!  We choose 100us.
-	 */
-	udelay(100);
-
-	/*
-	 * Enable RCLK.  We also ensure that RDYEN is set.
-	 */
-	r |= SKCR_RCLKEN | SKCR_RDYEN;
-	sa1111_writel(r, sachip->base + SA1111_SKCR);
-
-	/*
-	 * Wait 14 RCLK cycles for the chip to finish coming out
-	 * of reset. (RCLK=24MHz).  This is 590ns.
-	 */
-	udelay(1);
-
-	/*
-	 * Ensure all clocks are initially off.
-	 */
-	sa1111_writel(0, sachip->base + SA1111_SKPCR);
-
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-
-/*
- * Configure the SA1111 shared memory controller.
- */
-void
-sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
-		     unsigned int cas_latency)
-{
-	unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
-
-	if (cas_latency == 3)
-		smcr |= SMCR_CLAT;
-
-	sa1111_writel(smcr, sachip->base + SA1111_SMCR);
-}
-
-static void
-sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset)
-{
-	snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
-		 "%4.4x", offset);
-
-	sadev->dev.parent = sachip->dev;
-	sadev->dev.bus    = &sa1111_bus_type;
-	sadev->res.start  = sachip->res.start + offset;
-	sadev->res.end    = sadev->res.start + 511;
-	sadev->res.name   = sadev->dev.name;
-	sadev->res.flags  = IORESOURCE_MEM;
-	sadev->mapbase    = sachip->base + offset;
-
-	if (request_resource(&sachip->res, &sadev->res)) {
-		printk("SA1111: failed to allocate resource for %s\n",
-			sadev->res.name);
-		return;
-	}
-
-	device_register(&sadev->dev);
-}
-
-/**
- *	sa1111_probe - probe for a single SA1111 chip.
- *	@phys_addr: physical address of device.
- *
- *	Probe for a SA1111 chip.  This must be called
- *	before any other SA1111-specific code.
- *
- *	Returns:
- *	%-ENODEV	device not found.
- *	%-EBUSY		physical address already marked in-use.
- *	%0		successful.
- */
-static int __init
-__sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
-{
-	struct sa1111 *sachip;
-	unsigned long id;
-	unsigned int has_devs, val;
-	int i, ret = -ENODEV;
-
-	sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL);
-	if (!sachip)
-		return -ENOMEM;
-
-	memset(sachip, 0, sizeof(struct sa1111));
-
-	spin_lock_init(&sachip->lock);
-
-	sachip->dev = me;
-	dev_set_drvdata(sachip->dev, sachip);
-
-	sachip->res.name  = me->name;
-	sachip->res.start = phys_addr;
-	sachip->res.end   = phys_addr + 0x2000;
-	sachip->irq = irq;
-
-	if (request_resource(&iomem_resource, &sachip->res)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	/*
-	 * Map the whole region.  This also maps the
-	 * registers for our children.
-	 */
-	sachip->base = ioremap(phys_addr, PAGE_SIZE * 2);
-	if (!sachip->base) {
-		ret = -ENOMEM;
-		goto release;
-	}
-
-	/*
-	 * Probe for the chip.  Only touch the SBI registers.
-	 */
-	id = sa1111_readl(sachip->base + SA1111_SKID);
-	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
-		printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
-		ret = -ENODEV;
-		goto unmap;
-	}
-
-	printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
-		"silicon revision %lx, metal revision %lx\n",
-		(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
-
-	/*
-	 * We found it.  Wake the chip up, and initialise.
-	 */
-	sa1111_wake(sachip);
-
-	/*
-	 * The SDRAM configuration of the SA1110 and the SA1111 must
-	 * match.  This is very important to ensure that SA1111 accesses
-	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
-	 * MBGNT signal, so we must have called sa1110_mb_disable()
-	 * beforehand.
-	 */
-	sa1111_configure_smc(sachip, 1,
-			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
-			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
-
-	/*
-	 * We only need to turn on DCLK whenever we want to use the
-	 * DMA.  It can otherwise be held firmly in the off position.
-	 * (currently, we always enable it.)
-	 */
-	val = sa1111_readl(sachip->base + SA1111_SKPCR);
-	sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR);
-
-	/*
-	 * Enable the SA1110 memory bus request and grant signals.
-	 */
-	sa1110_mb_enable();
-
-	/*
-	 * The interrupt controller must be initialised before any
-	 * other device to ensure that the interrupts are available.
-	 */
-	int_dev.irq[0] = irq;
-	sa1111_init_one_child(sachip, &int_dev, SA1111_INTC);
-	sa1111_init_irq(&int_dev);
-
-	g_sa1111 = sachip;
-
-	has_devs = ~0;
-	if (machine_is_assabet() || machine_is_jornada720() ||
-	    machine_is_badge4())
-		has_devs &= ~(1 << 4);
-	else
-		has_devs &= ~(1 << 1);
-
-	for (i = 0; i < ARRAY_SIZE(devs); i++)
-		if (has_devs & (1 << i))
-			sa1111_init_one_child(sachip, devs[i], dev_offset[i]);
-
-	return 0;
-
- unmap:
-	iounmap(sachip->base);
- release:
-	release_resource(&sachip->res);
- out:
-	kfree(sachip);
-	return ret;
-}
-
-static void __sa1111_remove(struct sa1111 *sachip)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devs); i++) {
-		put_device(&devs[i]->dev);
-		release_resource(&devs[i]->res);
-	}
-
-	iounmap(sachip->base);
-	release_resource(&sachip->res);
-	kfree(sachip);
-}
-
-/*
- * According to the "Intel StrongARM SA-1111 Microprocessor Companion
- * Chip Specification Update" (June 2000), erratum #7, there is a
- * significant bug in the SA1111 SDRAM shared memory controller.  If
- * an access to a region of memory above 1MB relative to the bank base,
- * it is important that address bit 10 _NOT_ be asserted. Depending
- * on the configuration of the RAM, bit 10 may correspond to one
- * of several different (processor-relative) address bits.
- *
- * This routine only identifies whether or not a given DMA address
- * is susceptible to the bug.
- */
-int sa1111_check_dma_bug(dma_addr_t addr)
-{
-	struct sa1111 *sachip = g_sa1111;
-	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int)addr);
-	unsigned int smcr;
-
-	/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module
-	 * User's Guide" mentions that jumpers R51 and R52 control the
-	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
-	 * SDRAM bank 1 on Neponset). The default configuration selects
-	 * Assabet, so any address in bank 1 is necessarily invalid.
-	 */
-	if ((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000)
-	  	return -1;
-
-	/* The bug only applies to buffers located more than one megabyte
-	 * above the start of the target bank:
-	 */
-	if (physaddr<(1<<20))
-		return 0;
-
-	smcr = sa1111_readl(sachip->base + SA1111_SMCR);
-	switch (FExtr(smcr, SMCR_DRAC)) {
-	case 01: /* 10 row + bank address bits, A<20> must not be set */
-	  	if (physaddr & (1<<20))
-		  	return -1;
-		break;
-	case 02: /* 11 row + bank address bits, A<23> must not be set */
-	  	if (physaddr & (1<<23))
-		  	return -1;
-		break;
-	case 03: /* 12 row + bank address bits, A<24> must not be set */
-	  	if (physaddr & (1<<24))
-		  	return -1;
-		break;
-	case 04: /* 13 row + bank address bits, A<25> must not be set */
-	  	if (physaddr & (1<<25))
-		  	return -1;
-		break;
-	case 05: /* 14 row + bank address bits, A<20> must not be set */
-	  	if (physaddr & (1<<20))
-		  	return -1;
-		break;
-	case 06: /* 15 row + bank address bits, A<20> must not be set */
-	  	if (physaddr & (1<<20))
-		  	return -1;
-		break;
-	default:
-	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n",
-		       __FUNCTION__, FExtr(smcr, SMCR_DRAC));
-		return -1;
-	}
-
-	return 0;
-}
-
-struct sa1111_save_data {
-	unsigned int	skcr;
-	unsigned int	skpcr;
-	unsigned int	skcdr;
-	unsigned char	skaud;
-	unsigned char	skpwm0;
-	unsigned char	skpwm1;
-
-	/*
-	 * Interrupt controller
-	 */
-	unsigned int	intpol0;
-	unsigned int	intpol1;
-	unsigned int	inten0;
-	unsigned int	inten1;
-	unsigned int	wakepol0;
-	unsigned int	wakepol1;
-	unsigned int	wakeen0;
-	unsigned int	wakeen1;
-};
-
-static int sa1111_suspend(struct device *dev, u32 state, u32 level)
-{
-	struct sa1111 *sachip = dev_get_drvdata(dev);
-	unsigned long flags;
-	char *base;
-
-	/*
-	 * Save state.
-	 */
-	if (level == SUSPEND_SAVE_STATE ||
-	    level == SUSPEND_DISABLE ||
-	    level == SUSPEND_POWER_DOWN) {
-		struct sa1111_save_data *save;
-
-		if (!dev->saved_state)
-			dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
-		if (!dev->saved_state)
-			return -ENOMEM;
-
-		save = (struct sa1111_save_data *)dev->saved_state;
-
-		spin_lock_irqsave(&sachip->lock, flags);
-		base = sachip->base;
-		save->skcr     = sa1111_readl(base + SA1111_SKCR);
-		save->skpcr    = sa1111_readl(base + SA1111_SKPCR);
-		save->skcdr    = sa1111_readl(base + SA1111_SKCDR);
-		save->skaud    = sa1111_readl(base + SA1111_SKAUD);
-		save->skpwm0   = sa1111_readl(base + SA1111_SKPWM0);
-		save->skpwm1   = sa1111_readl(base + SA1111_SKPWM1);
-
-		base = sachip->base + SA1111_INTC;
-		save->intpol0  = sa1111_readl(base + SA1111_INTPOL0);
-		save->intpol1  = sa1111_readl(base + SA1111_INTPOL1);
-		save->inten0   = sa1111_readl(base + SA1111_INTEN0);
-		save->inten1   = sa1111_readl(base + SA1111_INTEN1);
-		save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0);
-		save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1);
-		save->wakeen0  = sa1111_readl(base + SA1111_WAKEEN0);
-		save->wakeen1  = sa1111_readl(base + SA1111_WAKEEN1);
-		spin_unlock_irqrestore(&sachip->lock, flags);
-	}
-
-	/*
-	 * Disable.
-	 */
-	if (level == SUSPEND_DISABLE && state == 4) {
-		unsigned int val;
-
-		spin_lock_irqsave(&sachip->lock, flags);
-		base = sachip->base;
-
-		sa1111_writel(0, base + SA1111_SKPWM0);
-		sa1111_writel(0, base + SA1111_SKPWM1);
-		val = sa1111_readl(base + SA1111_SKCR);
-		sa1111_writel(val | SKCR_SLEEP, base + SA1111_SKCR);
-
-		spin_unlock_irqrestore(&sachip->lock, flags);
-	}
-
-	return 0;
-}
-
-/*
- *	sa1111_resume - Restore the SA1111 device state.
- *	@dev: device to restore
- *	@level: resume level
- *
- *	Restore the general state of the SA1111; clock control and
- *	interrupt controller.  Other parts of the SA1111 must be
- *	restored by their respective drivers, and must be called
- *	via LDM after this function.
- */
-static int sa1111_resume(struct device *dev, u32 level)
-{
-	struct sa1111 *sachip = dev_get_drvdata(dev);
-	struct sa1111_save_data *save;
-	unsigned long flags, id;
-	char *base;
-
-	if (level != RESUME_RESTORE_STATE && level != RESUME_ENABLE)
-		return 0;
-
-	save = (struct sa1111_save_data *)dev->saved_state;
-	if (!save)
-		return 0;
-
-	dev->saved_state = NULL;
-
-	/*
-	 * Ensure that the SA1111 is still here.
-	 */
-	id = sa1111_readl(sachip->base + SA1111_SKID);
-	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
-		__sa1111_remove(sachip);
-		dev_set_drvdata(dev, NULL);
-		kfree(save);
-		return 0;
-	}
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	sa1111_wake(sachip);
-
-	base = sachip->base;
-	sa1111_writel(save->skcr,     base + SA1111_SKCR);
-	sa1111_writel(save->skpcr,    base + SA1111_SKPCR);
-	sa1111_writel(save->skcdr,    base + SA1111_SKCDR);
-	sa1111_writel(save->skaud,    base + SA1111_SKAUD);
-	sa1111_writel(save->skpwm0,   base + SA1111_SKPWM0);
-	sa1111_writel(save->skpwm1,   base + SA1111_SKPWM1);
-
-	base = sachip->base + SA1111_INTC;
-	sa1111_writel(save->intpol0,  base + SA1111_INTPOL0);
-	sa1111_writel(save->intpol1,  base + SA1111_INTPOL1);
-	sa1111_writel(save->inten0,   base + SA1111_INTEN0);
-	sa1111_writel(save->inten1,   base + SA1111_INTEN1);
-	sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0);
-	sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1);
-	sa1111_writel(save->wakeen0,  base + SA1111_WAKEEN0);
-	sa1111_writel(save->wakeen1,  base + SA1111_WAKEEN1);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-
-	kfree(save);
-
-	return 0;
-}
-
-static int sa1111_probe(struct device *dev)
-{
-	return -ENODEV;
-}
-
-static int sa1111_remove(struct device *dev)
-{
-	struct sa1111 *sachip = dev_get_drvdata(dev);
-
-	if (sachip) {
-		__sa1111_remove(sachip);
-		dev_set_drvdata(dev, NULL);
-
-		kfree(dev->saved_state);
-		dev->saved_state = NULL;
-	}
-
-	return 0;
-}
-
-/*
- *	Not sure if this should be on the system bus or not yet.
- *	We really want some way to register a system device at
- *	the per-machine level, and then have this driver pick
- *	up the registered devices.
- *
- *	We also need to handle the SDRAM configuration for
- *	PXA250/SA1110 machine classes.
- */
-static struct device_driver sa1111_device_driver = {
-	.name		= "sa1111",
-	.bus		= &system_bus_type,
-	.probe		= sa1111_probe,
-	.remove		= sa1111_remove,
-	.suspend	= sa1111_suspend,
-	.resume		= sa1111_resume,
-};
-
-/*
- *	Register the SA1111 driver with LDM.
- */
-static int sa1111_driver_init(void)
-{
-	driver_register(&sa1111_device_driver);
-	return 0;
-}
-
-arch_initcall(sa1111_driver_init);
-
-static struct sys_device sa1111_device = {
-	.name		= "SA1111",
-	.id		= 0,
-	.root		= NULL,
-	.dev = {
-		.name	= "Intel Corporation SA1111",
-		.driver	= &sa1111_device_driver,
-	},
-};
-
-int sa1111_init(unsigned long phys, unsigned int irq)
-{
-	int ret;
-
-	snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys);
-
-	ret = sys_device_register(&sa1111_device);
-	if (ret)
-		printk("sa1111 device_register failed: %d\n", ret);
-
-	return __sa1111_probe(&sa1111_device.dev, phys, irq);
-}
-
-/*
- *	Get the parent device driver (us) structure
- *	from a child function device
- */
-static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev)
-{
-	return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent);
-}
-
-/*
- * The bits in the opdiv field are non-linear.
- */
-static unsigned char opdiv_table[] = { 1, 4, 2, 8 };
-
-static unsigned int __sa1111_pll_clock(struct sa1111 *sachip)
-{
-	unsigned int skcdr, fbdiv, ipdiv, opdiv;
-
-	skcdr = sa1111_readl(sachip->base + SA1111_SKCDR);
-
-	fbdiv = (skcdr & 0x007f) + 2;
-	ipdiv = ((skcdr & 0x0f80) >> 7) + 2;
-	opdiv = opdiv_table[(skcdr & 0x3000) >> 12];
-
-	return 3686400 * fbdiv / (ipdiv * opdiv);
-}
-
-/**
- *	sa1111_pll_clock - return the current PLL clock frequency.
- *	@sadev: SA1111 function block
- *
- *	BUG: we should look at SKCR.  We also blindly believe that
- *	the chip is being fed with the 3.6864MHz clock.
- *
- *	Returns the PLL clock in Hz.
- */
-unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-
-	return __sa1111_pll_clock(sachip);
-}
-
-/**
- *	sa1111_select_audio_mode - select I2S or AC link mode
- *	@sadev: SA1111 function block
- *	@mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S
- *
- *	Frob the SKCR to select AC Link mode or I2S mode for
- *	the audio block.
- */
-void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-
-	val = sa1111_readl(sachip->base + SA1111_SKCR);
-	if (mode == SA1111_AUDIO_I2S) {
-		val &= ~SKCR_SELAC;
-	} else {
-		val |= SKCR_SELAC;
-	}
-	sa1111_writel(val, sachip->base + SA1111_SKCR);
-
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-
-/**
- *	sa1111_set_audio_rate - set the audio sample rate
- *	@sadev: SA1111 SAC function block
- *	@rate: sample rate to select
- */
-int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned int div;
-
-	if (sadev->devid != SA1111_DEVID_SAC)
-		return -EINVAL;
-
-	div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate;
-	if (div == 0)
-		div = 1;
-	if (div > 128)
-		div = 128;
-
-	sa1111_writel(div - 1, sachip->base + SA1111_SKAUD);
-
-	return 0;
-}
-
-/**
- *	sa1111_get_audio_rate - get the audio sample rate
- *	@sadev: SA1111 SAC function block device
- */
-int sa1111_get_audio_rate(struct sa1111_dev *sadev)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long div;
-
-	if (sadev->devid != SA1111_DEVID_SAC)
-		return -EINVAL;
-
-	div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1;
-
-	return __sa1111_pll_clock(sachip) / (256 * div);
-}
-
-/*
- * Individual device operations.
- */
-
-/**
- *	sa1111_enable_device - enable an on-chip SA1111 function block
- *	@sadev: SA1111 function block device to enable
- */
-void sa1111_enable_device(struct sa1111_dev *sadev)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	val = sa1111_readl(sachip->base + SA1111_SKPCR);
-	sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-
-/**
- *	sa1111_disable_device - disable an on-chip SA1111 function block
- *	@sadev: SA1111 function block device to disable
- */
-void sa1111_disable_device(struct sa1111_dev *sadev)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	val = sa1111_readl(sachip->base + SA1111_SKPCR);
-	sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-
-/*
- *	SA1111 "Register Access Bus."
- *
- *	We model this as a regular bus type, and hang devices directly
- *	off this.
- */
-static int sa1111_match(struct device *_dev, struct device_driver *_drv)
-{
-	struct sa1111_dev *dev = SA1111_DEV(_dev);
-	struct sa1111_driver *drv = SA1111_DRV(_drv);
-
-	return dev->devid == drv->devid;
-}
-
-struct bus_type sa1111_bus_type = {
-	.name	= "RAB",
-	.match	= sa1111_match,
-};
-
-static int sa1111_rab_bus_init(void)
-{
-	return bus_register(&sa1111_bus_type);
-}
-
-postcore_initcall(sa1111_rab_bus_init);
-
-EXPORT_SYMBOL(sa1111_check_dma_bug);
-EXPORT_SYMBOL(sa1111_select_audio_mode);
-EXPORT_SYMBOL(sa1111_set_audio_rate);
-EXPORT_SYMBOL(sa1111_get_audio_rate);
-EXPORT_SYMBOL(sa1111_enable_device);
-EXPORT_SYMBOL(sa1111_disable_device);
-EXPORT_SYMBOL(sa1111_pll_clock);
-EXPORT_SYMBOL(sa1111_bus_type);
diff -Nru a/arch/arm/mach-sa1100/stork.c b/arch/arm/mach-sa1100/stork.c
--- a/arch/arm/mach-sa1100/stork.c	Mon Feb 10 10:39:29 2003
+++ b/arch/arm/mach-sa1100/stork.c	Mon Feb 10 10:39:29 2003
@@ -181,7 +181,7 @@
 {
     storkSetLatchB(STORK_TOUCH_SCREEN_DCLK);
     udelay(10);			 /* hmm wait 200ns (min) - ok this ought to be udelay(1) but that doesn't get */
-				 /* consistant values so I'm using 10 (urgh) */
+				 /* consistent values so I'm using 10 (urgh) */
     storkClearLatchB(STORK_TOUCH_SCREEN_DCLK);
     udelay(10);
 }
diff -Nru a/arch/arm/mach-sa1100/trizeps.c b/arch/arm/mach-sa1100/trizeps.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-sa1100/trizeps.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,232 @@
+/*
+ * linux/arch/arm/mach-sa1100/trizeps.c
+ *
+ * Authors:
+ * Andreas Hofer <ho@dsa-ac.de>,
+ * Peter Lueg <pl@dsa-ac.de>,
+ * Guennadi Liakhovetski <gl@dsa-ac.de>
+ *
+ * This file contains all Trizeps-specific tweaks.
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/arch/trizeps.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <asm/arch/serial.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+
+#include "generic.h"
+
+#undef DEBUG_TRIZEPS
+#ifdef DEBUG_TRIZEPS
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK( x... )
+#endif
+
+static struct tri_uart_cts_data_t tri_uart_cts_data[] = {
+	{ TRIZEPS_GPIO_UART1_CTS, 0, NULL, NULL,"int. UART1 cts" },
+	{ TRIZEPS_GPIO_UART2_CTS, 0, NULL, NULL,"int. UART2 cts" },
+	{ TRIZEPS_GPIO_UART3_CTS, 0, NULL, NULL,"int. UART3 cts" }
+};
+
+static void trizeps_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct tri_uart_cts_data_t * uart_data = (struct tri_uart_cts_data_t *)dev_id;
+	int cts = (!(GPLR & uart_data->cts_gpio));
+
+	/* NOTE: I suppose that we will not get any interrupts
+	   if the GPIO is not changed, so maybe
+	   the cts_prev_state can be removed ... */
+	if (cts != uart_data->cts_prev_state) {
+
+		uart_data->cts_prev_state = cts;
+		uart_handle_cts_change(uart_data->port, cts);
+		DPRINTK("(IRQ %d) changed (cts=%d) stop=%d\n",
+			irq, cts, uart_data->info->tty->hw_stopped);
+	}
+}
+
+static int
+trizeps_register_cts_intr(int gpio,
+			  int irq,
+			  struct tri_uart_cts_data_t *uart_data)
+{
+	int ret = 0;
+
+	if(irq != NO_IRQ)
+	{
+		set_irq_type(irq, IRQT_BOTHEDGE);
+
+		ret = request_irq(irq, trizeps_cts_intr,
+				  SA_INTERRUPT, uart_data->name, uart_data);
+		if (ret)
+			printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n", ret);
+	}
+	return ret;
+}
+
+static void trizeps_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser1UTCR0)
+	{
+		/**** ttySA1  ****/
+		if (mctrl & TIOCM_RTS)
+			GPCR |= TRIZEPS_GPIO_UART1_RTS;
+		else
+			GPSR |= TRIZEPS_GPIO_UART1_RTS;
+
+		DPRINTK("2 ttySA%d Set RTS %s\n",port->line,
+			mctrl & TIOCM_RTS ? "low" : "high");
+
+	}
+	else if (port->mapbase == _Ser3UTCR0)
+	{
+		/**** ttySA0  ****/
+	}
+	else
+	{
+		/**** ttySA2  ****/
+	}
+}
+
+static u_int trizeps_get_mctrl(struct uart_port *port)
+{
+	int result = TIOCM_CD | TIOCM_DSR;
+
+	if (port->mapbase == _Ser1UTCR0)
+	{
+		if (!(GPLR & TRIZEPS_GPIO_UART1_CTS))
+			result |= TIOCM_CTS;
+	}
+	else if (port->mapbase == _Ser2UTCR0)
+	{
+		result |= TIOCM_CTS;
+	}
+	else if (port->mapbase == _Ser3UTCR0)
+	{
+		result |= TIOCM_CTS;
+	}
+	else
+	{
+		result = TIOCM_CTS;
+	}
+
+	DPRINTK(" ttySA%d %s%s%s\n",port->line,
+		result & TIOCM_CD  ? "CD "  : "",
+		result & TIOCM_CTS ? "CTS " : "",
+		result & TIOCM_DSR ? "DSR " : "");
+
+	return result;
+}
+
+static struct sa1100_port_fns trizeps_port_fns __initdata = {
+	.set_mctrl =	trizeps_set_mctrl,
+	.get_mctrl =	trizeps_get_mctrl,
+};
+
+static void trizeps_power_off(void)
+{
+	printk("trizeps power off\n");
+	mdelay(100);
+	cli();
+	/* disable internal oscillator, float CS lines */
+	PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
+	/* enable wake-up on GPIO0 (Assabet...) */
+	PWER = GFER = GRER = 1;
+	/*
+	 * set scratchpad to zero, just in case it is used as a
+	 * restart address by the bootloader.
+	 */
+	PSPR = 0;
+
+	/*
+	 *  Power off
+	 *  -> disconnect AKku
+	 */
+	TRIZEPS_BCR_set(TRIZEPS_BCR0, TRIZEPS_MFT_OFF);
+
+	/*
+	 * if power supply no Akku
+	 * -> enter sleep mode
+	 */
+	PMCR = PMCR_SF;
+}
+
+static int __init trizeps_init(void)
+{
+	if (!machine_is_trizeps())
+		return -EINVAL;
+
+	DPRINTK(" \n");
+	pm_power_off = trizeps_power_off;
+
+	// Init UART2 for IrDA
+//	PPDR |= PPC_TXD2;           // Set TXD2 as output
+	Ser2UTCR4 = UTCR4_HSE;      // enable HSE
+	Ser2HSCR0 = 0;
+	Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR | HSSR0_RAB | HSSR0_FRE;
+
+	/* Init MECR */
+	MECR = 0x00060006;
+
+	/* Set up external serial IRQs */
+	GAFR &= ~(GPIO_GPIO16 | GPIO_GPIO17);  // no alternate function
+	GPDR &= ~(GPIO_GPIO16 | GPIO_GPIO17);  // Set to Input
+	set_irq_type(IRQ_GPIO16, IRQT_RISING);
+	set_irq_type(IRQ_GPIO17, IRQT_RISING);
+
+	return 0;
+}
+
+__initcall(trizeps_init);
+
+static struct map_desc trizeps_io_desc[] __initdata = {
+	/* virtual	physical	length	type */
+	{ 0xF0000000l, 0x30000000l, 0x00800000l, MT_DEVICE },
+	{ 0xF2000000l, 0x38000000l, 0x00800000l, MT_DEVICE },
+};
+
+static void __init trizeps_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(trizeps_io_desc, ARRAY_SIZE(trizeps_io_desc));
+
+	sa1100_register_uart_fns(&trizeps_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	sa1100_register_uart(2, 2);
+}
+
+MACHINE_START(TRIZEPS, "TRIZEPS")
+	MAINTAINER("DSA")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	MAPIO(trizeps_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Nru a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile
--- a/arch/arm/mach-shark/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/arm/mach-shark/Makefile	Mon Feb 10 10:39:23 2003
@@ -9,6 +9,4 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
-
 obj-$(CONFIG_LEDS)	+= leds.o
diff -Nru a/arch/arm/mach-tbox/Makefile b/arch/arm/mach-tbox/Makefile
--- a/arch/arm/mach-tbox/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/arm/mach-tbox/Makefile	Mon Feb 10 10:39:24 2003
@@ -9,4 +9,3 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= 
diff -Nru a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
--- a/arch/arm/mm/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/arm/mm/Makefile	Mon Feb 10 10:39:33 2003
@@ -8,8 +8,6 @@
 obj-m		:=
 obj-n		:=
 obj-		:=
-export-objs	:= proc-syms.o discontig.o
-
 ifeq ($(CONFIG_CPU_32),y)
 obj-y		+= consistent.o fault-armv.o ioremap.o mm-armv.o
 obj-$(CONFIG_MODULES) += proc-syms.o
diff -Nru a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
--- a/arch/arm/mm/proc-arm920.S	Mon Feb 10 10:39:23 2003
+++ b/arch/arm/mm/proc-arm920.S	Mon Feb 10 10:39:23 2003
@@ -297,7 +297,7 @@
  *
  * This is a little misleading, it is not intended to clean out
  * the i-cache but to make sure that any data written to the
- * range is made consistant.  This means that when we execute code
+ * range is made consistent.  This means that when we execute code
  * in that region, everything works as we expect.
  *
  * This generally means writing back data in the Dcache and
diff -Nru a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
--- a/arch/arm/mm/proc-arm922.S	Mon Feb 10 10:39:31 2003
+++ b/arch/arm/mm/proc-arm922.S	Mon Feb 10 10:39:31 2003
@@ -298,7 +298,7 @@
  *
  * This is a little misleading, it is not intended to clean out
  * the i-cache but to make sure that any data written to the
- * range is made consistant.  This means that when we execute code
+ * range is made consistent.  This means that when we execute code
  * in that region, everything works as we expect.
  *
  * This generally means writing back data in the Dcache and
diff -Nru a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
--- a/arch/arm/mm/proc-arm926.S	Mon Feb 10 10:39:27 2003
+++ b/arch/arm/mm/proc-arm926.S	Mon Feb 10 10:39:27 2003
@@ -147,7 +147,7 @@
  *
  * This is a little misleading, it is not intended to clean out
  * the i-cache but to make sure that any data written to the
- * range is made consistant.  This means that when we execute code
+ * range is made consistent.  This means that when we execute code
  * in that region, everything works as we expect.
  *
  * This generally means writing back data in the Dcache and
diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/arch/cris/Kconfig	Mon Feb 10 10:39:32 2003
@@ -55,7 +55,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config ETRAX_KGDB
@@ -587,7 +587,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -685,7 +685,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/cris/drivers/Kconfig b/arch/cris/drivers/Kconfig
--- a/arch/cris/drivers/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/arch/cris/drivers/Kconfig	Mon Feb 10 10:39:24 2003
@@ -366,7 +366,7 @@
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  parport.o.  If you have more than one parallel port and want to
+	  parport.  If you have more than one parallel port and want to
 	  specify which port and IRQ to be used by this driver at module load
 	  time, take a look at <file:Documentation/parport.txt>.
 
@@ -400,7 +400,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -463,7 +463,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -494,7 +494,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/ide.txt>. The module will be called ide-mod.o.
+	  <file:Documentation/ide.txt>. The module will be called ide-mod.
 	  Do not compile this driver as a module if your root file system (the
 	  one containing the directory /) is located on an IDE device.
 
@@ -516,7 +516,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ide-disk.o.  Do not compile this driver as a module
+	  will be called ide-disk.  Do not compile this driver as a module
 	  if your root file system (the one containing the directory /) is
 	  located on the IDE disk. If unsure, say Y.
 
@@ -544,7 +544,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ide-cd.o.
+	  will be called ide-cd.
 
 config BLK_DEV_IDEDMA
 	bool
@@ -859,7 +859,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbcore.o.  If you want to compile it as a
+	  The module will be called usbcore.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ETRAX_USB_HOST_PORT1
diff -Nru a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c
--- a/arch/cris/drivers/serial.c	Mon Feb 10 10:39:29 2003
+++ b/arch/cris/drivers/serial.c	Mon Feb 10 10:39:29 2003
@@ -318,7 +318,7 @@
 
 #include <asm/svinto.h>
 
-/* non-arch dependant serial structures are in linux/serial.h */
+/* non-arch dependent serial structures are in linux/serial.h */
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
 #include "serial.h"
diff -Nru a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
--- a/arch/cris/kernel/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/cris/kernel/Makefile	Mon Feb 10 10:39:29 2003
@@ -5,8 +5,6 @@
 
 EXTRA_TARGETS	:= head.o
 
-export-objs := ksyms.o
-
 obj-y   := process.o signal.o entry.o traps.o irq.o \
            ptrace.o setup.o time.o sys_cris.o shadows.o \
 	   debugport.o semaphore.o
diff -Nru a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
--- a/arch/cris/kernel/ptrace.c	Mon Feb 10 10:39:24 2003
+++ b/arch/cris/kernel/ptrace.c	Mon Feb 10 10:39:24 2003
@@ -18,7 +18,7 @@
  * PTRACE_DETACH works more simple in 2.4.10
  *
  * Revision 1.6  2001/07/25 16:08:47  bjornw
- * PTRACE_ATTACH bulk moved into arch-independant code in 2.4.7
+ * PTRACE_ATTACH bulk moved into arch-independent code in 2.4.7
  *
  * Revision 1.5  2001/03/26 14:24:28  orjanf
  * * Changed loop condition.
diff -Nru a/arch/cris/lib/old_checksum.c b/arch/cris/lib/old_checksum.c
--- a/arch/cris/lib/old_checksum.c	Mon Feb 10 10:39:31 2003
+++ b/arch/cris/lib/old_checksum.c	Mon Feb 10 10:39:31 2003
@@ -75,7 +75,7 @@
     sum += *((unsigned short *)buff)++;
   }
   if(endMarker - buff > 0) {
-    sum += *buff;                 /* add extra byte seperately */
+    sum += *buff;                 /* add extra byte separately */
   }
   BITOFF;
   return(sum);
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/Kconfig	Mon Feb 10 10:39:23 2003
@@ -573,7 +573,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called microcode.o.  If you want to compile it as
+	  The module will be called microcode.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.  If
 	  you use modprobe or kmod you may also want to add the line
 	  'alias char-major-10-184 microcode' to your /etc/modules.conf file.
@@ -859,7 +859,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  apm.o.
+	  apm.
 
 config APM_IGNORE_USER_SUSPEND
 	bool "Ignore USER SUSPEND"
@@ -983,6 +983,17 @@
 
 	  If in doubt, say N.
 
+config X86_ACPI_CPUFREQ
+	tristate "ACPI Processor P-States driver"
+	depends on CPU_FREQ && ACPI_PROCESSOR
+	help
+	  This driver adds a CPUFreq driver which utilizes the ACPI
+	  Processor Performance States.
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
+
 config X86_POWERNOW_K6
 	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
 	depends on CPU_FREQ
@@ -1151,7 +1162,7 @@
 	  If you don't know what to do here, say N.
 
 	  This support is also available as a module.  If compiled as a
-	  module, it will be called scx200.o.
+	  module, it will be called scx200.
 
 source "drivers/pci/Kconfig"
 
@@ -1277,7 +1288,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -1307,7 +1318,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -1332,7 +1343,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 endmenu
@@ -1388,7 +1399,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -1415,7 +1426,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -1519,7 +1530,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,8 +3,7 @@
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
+# for "archclean" cleaning up for this architecture.
 #
 # 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
@@ -76,7 +75,7 @@
 # default subarch .h files
 mflags-y += -Iinclude/asm-i386/mach-default
 
-HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
 
 libs-y 					+= arch/i386/lib/
 core-y					+= arch/i386/kernel/ \
@@ -92,8 +91,7 @@
 
 boot := arch/i386/boot
 
-.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
-		clean archclean archmrproper
+.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install
 
 all: bzImage
 
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/Makefile	Mon Feb 10 10:39:24 2003
@@ -4,8 +4,6 @@
 
 EXTRA_TARGETS := head.o init_task.o
 
-export-objs     := mca.o i386_ksyms.o time.o
-
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
 		pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o
@@ -34,5 +32,4 @@
 
 EXTRA_AFLAGS   := -traditional
 
-export-objs += scx200.o
 obj-$(CONFIG_SCx200)		+= scx200.o
diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
--- a/arch/i386/kernel/acpi.c	Mon Feb 10 10:39:31 2003
+++ b/arch/i386/kernel/acpi.c	Mon Feb 10 10:39:31 2003
@@ -303,8 +303,7 @@
 
 
 int __init
-acpi_boot_init (
-	char			*cmdline)
+acpi_boot_init (void)
 {
 	int			result = 0;
 
@@ -317,7 +316,7 @@
 	/* 
 	 * Initialize the ACPI boot-time table parser.
 	 */
-	result = acpi_table_init(cmdline);
+	result = acpi_table_init();
 	if (result)
 		return result;
 
@@ -454,6 +453,7 @@
 
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
+unsigned long acpi_video_flags;
 extern char wakeup_start, wakeup_end;
 
 extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
@@ -520,4 +520,20 @@
 	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
 }
 
+static int __init acpi_sleep_setup(char *str)
+{
+	while ((str != NULL) && (*str != '\0')) {
+		if (strncmp(str, "s3_bios", 7) == 0)
+			acpi_video_flags = 1;
+		if (strncmp(str, "s3_mode", 7) == 0)
+			acpi_video_flags |= 2;
+		str = strchr(str, ',');
+		if (str != NULL)
+			str += strspn(str, ", \t");
+	}
+	return 1;
+}
+
+
+__setup("acpi_sleep=", acpi_sleep_setup);
 #endif /*CONFIG_ACPI_SLEEP*/
diff -Nru a/arch/i386/kernel/acpi_wakeup.S b/arch/i386/kernel/acpi_wakeup.S
--- a/arch/i386/kernel/acpi_wakeup.S	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/acpi_wakeup.S	Mon Feb 10 10:39:24 2003
@@ -41,20 +41,19 @@
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
-#if 1
+	testl	$1, video_flags - wakeup_code
+	jz	1f
 	lcall   $0xc000,$3
-#endif
-#if 0
+1:
+
+	testl	$2, video_flags - wakeup_code
+	jz	1f
 	mov	video_mode - wakeup_code, %ax
 	call	mode_set
-#endif
+1:
 
 	# set up page table
-#if 1
 	movl	$swapper_pg_dir-__PAGE_OFFSET, %eax
-#else
-	movl    (real_save_cr3 - wakeup_data), %eax
-#endif
 	movl	%eax, %cr3
 
 	# make sure %cr4 is set correctly (features, etc)
@@ -86,6 +85,7 @@
 real_save_cr4:	.long 0
 real_magic:	.long 0
 video_mode:	.long 0
+video_flags:	.long 0
 
 bogus_real_magic:
 	movw	$0x0e00 + 'B', %fs:(0x12)
@@ -254,6 +254,8 @@
 
 	movl	saved_videomode, %edx
 	movl	%edx, video_mode - wakeup_start (%eax)
+	movl	acpi_video_flags, %edx
+	movl	%edx, video_flags - wakeup_start (%eax)
 	movl	$0x12345678, real_magic - wakeup_start (%eax)
 	movl	$0x12345678, saved_magic
 	ret
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/kernel/apm.c	Mon Feb 10 10:39:23 2003
@@ -215,6 +215,7 @@
 #include <linux/miscdevice.h>
 #include <linux/apm_bios.h>
 #include <linux/init.h>
+#include <linux/time.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
 #include <linux/kernel.h>
@@ -227,7 +228,6 @@
 
 #include <linux/sysrq.h>
 
-extern rwlock_t xtime_lock;
 extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
@@ -1264,7 +1264,7 @@
 		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
 	}
 	/* serialize with the timer interrupt */
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 
 	/* protect against access to timer chip registers */
 	spin_lock(&i8253_lock);
@@ -1276,7 +1276,7 @@
 	ignore_normal_resume = 1;
 
 	spin_unlock(&i8253_lock);
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 
 	if (err == APM_NO_ERROR)
 		err = APM_SUCCESS;
@@ -1301,10 +1301,10 @@
 	int	err;
 
 	/* serialize with the timer interrupt */
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/* If needed, notify drivers here */
 	get_time_diff();
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 
 	err = set_system_power_state(APM_STATE_STANDBY);
 	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
@@ -1393,9 +1393,9 @@
 			ignore_bounce = 1;
 			if ((event != APM_NORMAL_RESUME)
 			    || (ignore_normal_resume == 0)) {
-				write_lock_irq(&xtime_lock);
+				write_seqlock_irq(&xtime_lock);
 				set_time();
-				write_unlock_irq(&xtime_lock);
+				write_sequnlock_irq(&xtime_lock);
 				pm_send_all(PM_RESUME, (void *)0);
 				queue_event(event, NULL);
 			}
@@ -1410,9 +1410,9 @@
 			break;
 
 		case APM_UPDATE_TIME:
-			write_lock_irq(&xtime_lock);
+			write_seqlock_irq(&xtime_lock);
 			set_time();
-			write_unlock_irq(&xtime_lock);
+			write_sequnlock_irq(&xtime_lock);
 			break;
 
 		case APM_CRITICAL_SUSPEND:
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
--- a/arch/i386/kernel/cpu/cpufreq/Makefile	Mon Feb 10 10:39:26 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile	Mon Feb 10 10:39:26 2003
@@ -5,3 +5,10 @@
 obj-$(CONFIG_ELAN_CPUFREQ)	+= elanfreq.o
 obj-$(CONFIG_X86_LONGRUN)	+= longrun.o  
 obj-$(CONFIG_X86_GX_SUSPMOD)    += gx-suspmod.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)	+= acpi.o
+
+ifdef CONFIG_X86_ACPI_CPUFREQ
+  ifdef CONFIG_ACPI_DEBUG
+    EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT
+  endif
+endif
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,696 @@
+/*
+ * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 71 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2002, 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#define ACPI_PROCESSOR_COMPONENT	0x01000000
+#define ACPI_PROCESSOR_CLASS		"processor"
+#define ACPI_PROCESSOR_DRIVER_NAME	"ACPI Processor P-States Driver"
+#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
+#define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
+
+#define _COMPONENT		ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME		("acpi_processor_perf")
+
+MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
+MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+
+/* Performance Management */
+
+static struct acpi_processor_performance	*performance;
+static struct cpufreq_driver			acpi_cpufreq_driver;
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+	.open 		= acpi_processor_perf_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static int 
+acpi_processor_get_performance_control (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*pct = NULL;
+	union acpi_object	obj = {0};
+	struct acpi_pct_register *reg = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
+
+	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pct = (union acpi_object *) buffer.pointer;
+	if (!pct || (pct->type != ACPI_TYPE_PACKAGE) 
+		|| (pct->package.count != 2)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	/*
+	 * control_register
+	 */
+
+	obj = pct->package.elements[0];
+
+	if ((obj.type != ACPI_TYPE_BUFFER) 
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Invalid _PCT data (control_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	reg = (struct acpi_pct_register *) (obj.buffer.pointer);
+
+	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unsupported address space [%d] (control_register)\n",
+			(u32) reg->space_id));
+		result = -EFAULT;
+		goto end;
+	}
+
+	pr->performance->control_register = (u16) reg->address;
+
+	/*
+	 * status_register
+	 */
+
+	obj = pct->package.elements[1];
+
+	if ((obj.type != ACPI_TYPE_BUFFER) 
+		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
+		|| (obj.buffer.pointer == NULL)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+			"Invalid _PCT data (status_register)\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	reg = (struct acpi_pct_register *) (obj.buffer.pointer);
+
+	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unsupported address space [%d] (status_register)\n",
+			(u32) reg->space_id));
+		result = -EFAULT;
+		goto end;
+	}
+
+	pr->performance->status_register = (u16) reg->address;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"control_register[0x%04x] status_register[0x%04x]\n",
+		pr->performance->control_register,
+		pr->performance->status_register));
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int 
+acpi_processor_get_performance_states (
+	struct acpi_processor*	pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_buffer	format = {sizeof("NNNNNN"), "NNNNNN"};
+	struct acpi_buffer	state = {0, NULL};
+	union acpi_object 	*pss = NULL;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
+
+	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+	if(ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	pss = (union acpi_object *) buffer.pointer;
+	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+		result = -EFAULT;
+		goto end;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", 
+		pss->package.count));
+
+	if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
+		pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Limiting number of states to max (%d)\n", 
+			ACPI_PROCESSOR_MAX_PERFORMANCE));
+	}
+	else
+		pr->performance->state_count = pss->package.count;
+
+	if (pr->performance->state_count > 1)
+		pr->flags.performance = 1;
+
+	for (i = 0; i < pr->performance->state_count; i++) {
+
+		struct acpi_processor_px *px = &(pr->performance->states[i]);
+
+		state.length = sizeof(struct acpi_processor_px);
+		state.pointer = px;
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
+
+		status = acpi_extract_package(&(pss->package.elements[i]), 
+			&format, &state);
+		if (ACPI_FAILURE(status)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
+			result = -EFAULT;
+			goto end;
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
+			i, 
+			(u32) px->core_frequency, 
+			(u32) px->power, 
+			(u32) px->transition_latency, 
+			(u32) px->bus_master_latency,
+			(u32) px->control, 
+			(u32) px->status));
+	}
+
+end:
+	acpi_os_free(buffer.pointer);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_set_performance (
+	struct acpi_processor	*pr,
+	int			state)
+{
+	u16			port = 0;
+	u8			value = 0;
+	int			i = 0;
+	struct cpufreq_freqs    cpufreq_freqs;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (!pr->flags.performance)
+		return_VALUE(-ENODEV);
+
+	if (state >= pr->performance->state_count) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
+			"Invalid target state (P%d)\n", state));
+		return_VALUE(-ENODEV);
+	}
+
+	if (state < pr->performance_platform_limit) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
+			"Platform limit (P%d) overrides target state (P%d)\n",
+			pr->performance->platform_limit, state));
+		return_VALUE(-ENODEV);
+	}
+
+	if (state == pr->performance->state) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"Already at target state (P%d)\n", state));
+		return_VALUE(0);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
+		pr->performance->state, state));
+
+	/* cpufreq frequency struct */
+	cpufreq_freqs.cpu = pr->id;
+	cpufreq_freqs.old = pr->performance->states[pr->performance->state].core_frequency;
+	cpufreq_freqs.new = pr->performance->states[state].core_frequency;
+
+	/* notify cpufreq */
+	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
+
+	/*
+	 * First we write the target state's 'control' value to the
+	 * control_register.
+	 */
+
+	port = pr->performance->control_register;
+	value = (u16) pr->performance->states[state].control;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Writing 0x%02x to port 0x%04x\n", value, port));
+
+	outb(value, port); 
+
+	/*
+	 * Then we read the 'status_register' and compare the value with the
+	 * target state's 'status' to make sure the transition was successful.
+	 * Note that we'll poll for up to 1ms (100 cycles of 10us) before
+	 * giving up.
+	 */
+
+	port = pr->performance->status_register;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Looking for 0x%02x from port 0x%04x\n",
+		(u8) pr->performance->states[state].status, port));
+
+	for (i=0; i<100; i++) {
+		value = inb(port);
+		if (value == (u8) pr->performance->states[state].status)
+			break;
+		udelay(10);
+	}
+
+	/* notify cpufreq */
+	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
+
+	if (value != pr->performance->states[state].status) {
+		unsigned int tmp = cpufreq_freqs.new;
+		cpufreq_freqs.new = cpufreq_freqs.old;
+		cpufreq_freqs.old = tmp;
+		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
+		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+		"Transition successful after %d microseconds\n",
+		i * 10));
+
+	pr->performance->state = state;
+
+	return_VALUE(0);
+}
+
+static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
+
+	if (!pr)
+		goto end;
+
+	if (!pr->flags.performance) {
+		seq_puts(seq, "<not supported>\n");
+		goto end;
+	}
+
+	seq_printf(seq, "state count:             %d\n"
+			"active state:            P%d\n",
+			pr->performance->state_count,
+			pr->performance->state);
+
+	seq_puts(seq, "states:\n");
+	for (i = 0; i < pr->performance->state_count; i++)
+		seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
+			(i == pr->performance->state?'*':' '), i,
+			(u32) pr->performance->states[i].core_frequency,
+			(u32) pr->performance->states[i].power,
+			(u32) pr->performance->states[i].transition_latency);
+
+end:
+	return 0;
+}
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_processor_perf_seq_show,
+						PDE(inode)->data);
+}
+
+static int
+acpi_processor_write_performance (
+        struct file		*file,
+        const char		*buffer,
+        unsigned long		count,
+        void			*data)
+{
+	int			result = 0;
+	struct acpi_processor	*pr = (struct acpi_processor *) data;
+	char			state_string[12] = {'\0'};
+	unsigned int            new_state = 0;
+	struct cpufreq_policy   policy;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
+
+	if (!pr || !pr->performance || (count > sizeof(state_string) - 1))
+		return_VALUE(-EINVAL);
+	
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	state_string[count] = '\0';
+	new_state = simple_strtoul(state_string, NULL, 0);
+
+	cpufreq_get_policy(&policy, pr->id);
+
+	policy.cpu = pr->id;
+	policy.max = pr->performance->states[new_state].core_frequency * 1000;
+
+	result = cpufreq_set_policy(&policy);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(count);
+}
+
+
+static int
+acpi_cpufreq_setpolicy (
+	struct cpufreq_policy   *policy)
+{
+	struct acpi_processor *pr = performance[policy->cpu].pr;
+	unsigned int next_state = 0;
+	unsigned int result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
+
+	result = cpufreq_frequency_table_setpolicy(policy, 
+			&performance[policy->cpu].freq_table[pr->limit.state.px],
+			&next_state);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_set_performance (pr, next_state);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_cpufreq_verify (
+	struct cpufreq_policy   *policy)
+{
+	unsigned int result = 0;
+	unsigned int cpu = policy->cpu;
+	struct acpi_processor *pr = performance[policy->cpu].pr;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
+
+	result = cpufreq_frequency_table_verify(policy, 
+			&performance[cpu].freq_table[pr->limit.state.px]);
+
+	cpufreq_verify_within_limits(
+		policy, 
+		performance[cpu].states[performance[cpu].state_count - 1].core_frequency * 1000,
+		performance[cpu].states[pr->limit.state.px].core_frequency * 1000);
+
+	return_VALUE(result);
+}
+
+
+static int
+acpi_processor_get_performance_info (
+	struct acpi_processor	*pr)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	acpi_handle		handle = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
+
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	status = acpi_get_handle(pr->handle, "_PCT", &handle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
+			"ACPI-based processor performance control unavailable\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	result = acpi_processor_get_performance_control(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_performance_states(pr);
+	if (result)
+		return_VALUE(result);
+
+	result = acpi_processor_get_platform_limit(pr);
+	if (result)
+		return_VALUE(result);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_cpufreq_cpu_init (
+	struct cpufreq_policy   *policy)
+{
+	unsigned int		i;
+	unsigned int		cpu = policy->cpu;
+	struct acpi_processor  *pr = NULL;
+	unsigned int		result = 0;
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
+
+	acpi_processor_register_performance(&performance[cpu], &pr, cpu);
+
+	pr = performance[cpu].pr;
+	if (!pr)
+		return_VALUE(-ENODEV);
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VALUE(-ENODEV);
+
+	result = acpi_processor_get_performance_info(performance[cpu].pr);
+	if (result)
+		return_VALUE(-ENODEV);
+
+	/* capability check */
+	if (!pr->flags.performance)
+		return_VALUE(-ENODEV);
+
+	/* detect transition latency */
+	policy->cpuinfo.transition_latency = 0;
+	for (i=0;i<performance[cpu].state_count;i++) {
+		if (performance[cpu].states[i].transition_latency > policy->cpuinfo.transition_latency)
+			policy->cpuinfo.transition_latency = performance[cpu].states[i].transition_latency;
+	}
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+
+	/* table init */
+	for (i=0; i<=performance[cpu].state_count; i++)
+	{
+		performance[cpu].freq_table[i].index = i;
+		if (i<performance[cpu].state_count)
+			performance[cpu].freq_table[i].frequency = performance[cpu].states[i].core_frequency * 1000;
+		else
+			performance[cpu].freq_table[i].frequency = CPUFREQ_TABLE_END;
+	}
+
+#ifdef CONFIG_CPU_FREQ_24_API
+	acpi_cpufreq_driver.cpu_cur_freq[policy->cpu] = performance[cpu].states[pr->limit.state.px].core_frequency * 1000;
+#endif
+
+	result = cpufreq_frequency_table_cpuinfo(policy, &performance[cpu].freq_table[0]);
+
+	/* add file 'performance' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_PERFORMANCE));
+	else {
+		entry->proc_fops = &acpi_processor_perf_fops;
+		entry->write_proc = acpi_processor_write_performance;
+		entry->data = acpi_driver_data(device);
+	}
+
+	return_VALUE(result);
+}
+
+
+static int __init
+acpi_cpufreq_init (void)
+{
+	int                     result = 0;
+	int                     current_state = 0;
+	int                     i = 0;
+	struct acpi_processor   *pr;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
+
+	/* alloc memory */
+	if (performance)
+		return_VALUE(-EBUSY);
+
+	performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL);
+	if (!performance)
+		return_VALUE(-ENOMEM);
+
+	memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance));
+
+	/* register struct acpi_performance performance */
+	for (i=0; i<NR_CPUS; i++) {
+		if (cpu_online(i))
+			acpi_processor_register_performance(&performance[i], &pr, i);
+	}
+
+	/* initialize  */
+	for (i=0; i<NR_CPUS; i++) {
+		if (cpu_online(i) && performance[i].pr)
+			result = acpi_processor_get_performance_info(performance[i].pr);
+	}
+
+	/* test it on one CPU */
+	for (i=0; i<NR_CPUS; i++) {
+		pr = performance[i].pr;
+		if (pr && pr->flags.performance)
+			goto found_capable_cpu;
+	}
+	result = -ENODEV;
+	goto err;
+
+ found_capable_cpu:
+	current_state = pr->performance->state;
+
+	if (current_state == pr->limit.state.px) {
+		result = acpi_processor_set_performance(pr, (pr->performance->state_count - 1));
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
+			result = -ENODEV;
+			goto err;
+		}
+	}
+
+	result = acpi_processor_set_performance(pr, pr->limit.state.px);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
+		result = -ENODEV;
+		goto err;
+	}
+	
+	if (current_state != 0) {
+		result = acpi_processor_set_performance(pr, current_state);
+		if (result) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
+			result = -ENODEV;
+			goto err;
+		}
+	}
+
+	result = cpufreq_register_driver(&acpi_cpufreq_driver);
+	if (result)
+		goto err;
+
+	return_VALUE(0);
+
+	/* error handling */
+ err:
+	/* unregister struct acpi_performance performance */
+	for (i=0; i<NR_CPUS; i++) {
+		if (performance[i].pr) {
+			performance[i].pr->flags.performance = 0;
+			performance[i].pr->performance = NULL;
+			performance[i].pr = NULL;
+		}
+	}
+
+	kfree(performance);
+
+	return_VALUE(result);
+}
+
+
+static void __exit
+acpi_cpufreq_exit (void)
+{
+	int                     i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_exit");
+
+	for (i=0; i<NR_CPUS; i++) {
+		if (performance[i].pr)
+			performance[i].pr->flags.performance = 0;
+	}
+
+	 cpufreq_unregister_driver(&acpi_cpufreq_driver);
+
+	/* unregister struct acpi_performance performance */
+	for (i=0; i<NR_CPUS; i++) {
+		if (performance[i].pr) {
+			performance[i].pr->flags.performance = 0;
+			performance[i].pr->performance = NULL;
+			performance[i].pr = NULL;
+		}
+	}
+
+	kfree(performance);
+
+	return_VOID;
+}
+
+static struct cpufreq_driver acpi_cpufreq_driver = {
+	.verify 	= acpi_cpufreq_verify,
+	.setpolicy	= acpi_cpufreq_setpolicy,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= NULL,
+	.policy		= NULL,
+	.name		= "acpi-cpufreq",
+};
+
+
+late_initcall(acpi_cpufreq_init);
+module_exit(acpi_cpufreq_exit);
diff -Nru a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile
--- a/arch/i386/kernel/cpu/mtrr/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/kernel/cpu/mtrr/Makefile	Mon Feb 10 10:39:23 2003
@@ -3,4 +3,3 @@
 obj-y		+= cyrix.o
 obj-y		+= centaur.o
 
-export-objs	:= main.o
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Mon Feb 10 10:39:25 2003
+++ b/arch/i386/kernel/dmi_scan.c	Mon Feb 10 10:39:25 2003
@@ -450,17 +450,6 @@
 }
 
 /*
- * ASUS K7V-RM has broken ACPI table defining sleep modes
- */
-
-static __init int broken_acpi_Sx(struct dmi_blacklist *d)
-{
-	printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n");
-	dmi_broken |= BROKEN_ACPI_Sx;
-	return 0;
-}
-
-/*
  * Toshiba keyboard likes to repeat keys when they are not repeated.
  */
 
@@ -744,12 +733,6 @@
 	{ broken_pirq, "Dell PowerEdge 8450", {		/* Bad $PIR */
 			MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"),
 			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-			
-	{ broken_acpi_Sx, "ASUS K7V-RM", {		/* Bad ACPI Sx table */
-			MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
-			MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
-			NO_MATCH, NO_MATCH
 			} },
 			
 	{ broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c
--- a/arch/i386/kernel/edd.c	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/edd.c	Mon Feb 10 10:39:24 2003
@@ -1,6 +1,6 @@
 /*
  * linux/arch/i386/kernel/edd.c
- *  Copyright (C) 2002 Dell Computer Corporation
+ *  Copyright (C) 2002, 2003 Dell Computer Corporation
  *  by Matt Domsch <Matt_Domsch@dell.com>
  *
  * BIOS Enhanced Disk Drive Services (EDD)
@@ -11,7 +11,7 @@
  * fn41 - Check Extensions Present and
  * fn48 - Get Device Parametes with EDD extensions
  * made in setup.S, copied to safe structures in setup.c,
- * and presents it in driverfs.
+ * and presents it in sysfs.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -30,8 +30,6 @@
  *
  * TODO:
  * - Add IDE and USB disk device support
- * - Get symlink creator helper functions exported from
- *   drivers/base instead of duplicating them here.
  * - move edd.[ch] to better locations if/when one is decided
  */
 
@@ -46,18 +44,18 @@
 #include <linux/limits.h>
 #include <linux/device.h>
 #include <linux/pci.h>
-#include <asm/edd.h>
 #include <linux/device.h>
 #include <linux/blkdev.h>
+#include <asm/edd.h>
 /* FIXME - this really belongs in include/scsi/scsi.h */
 #include <../drivers/scsi/scsi.h>
 #include <../drivers/scsi/hosts.h>
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
-MODULE_DESCRIPTION("driverfs interface to BIOS EDD information");
+MODULE_DESCRIPTION("sysfs interface to BIOS EDD information");
 MODULE_LICENSE("GPL");
 
-#define EDD_VERSION "0.07 2002-Oct-24"
+#define EDD_VERSION "0.09 2003-Jan-22"
 #define EDD_DEVICE_NAME_SIZE 16
 #define REPORT_URL "http://domsch.com/linux/edd30/results.html"
 
@@ -78,6 +76,7 @@
 static int edd_dev_is_type(struct edd_device *edev, const char *type);
 static struct pci_dev *edd_get_pci_dev(struct edd_device *edev);
 static struct scsi_device *edd_find_matching_scsi_device(struct edd_device *edev);
+static int kernel_has_scsi(void);
 
 static struct edd_device *edd_devices[EDDMAXNR];
 
@@ -93,6 +92,7 @@
 {
 	return edev->info;
 }
+
 static inline void
 edd_dev_set_info(struct edd_device *edev, struct edd_info *info)
 {
@@ -263,8 +263,8 @@
 edd_show_raw_data(struct edd_device *edev, char *buf)
 {
 	struct edd_info *info = edd_dev_get_info(edev);
-	int i, rc, warn_padding = 0, email = 0, nonzero_path = 0,
-		len = sizeof (*edd) - 4, found_pci=0;
+	int i, warn_padding = 0, nonzero_path = 0,
+		len = sizeof (*info) - 4, found_pci=0;
 	uint8_t checksum = 0, c = 0;
 	char *p = buf;
 	struct pci_dev *pci_dev=NULL;
@@ -277,7 +277,7 @@
 		len = info->params.length;
 
 	p += snprintf(p, left, "int13 fn48 returned data:\n\n");
-	p += edd_dump_raw_data(p, left, ((char *) edd) + 4, len);
+	p += edd_dump_raw_data(p, left, ((char *) info) + 4, len);
 
 	/* Spec violation.  Adaptec AIC7899 returns 0xDDBE
 	   here, when it should be 0xBEDD.
@@ -286,7 +286,6 @@
 	if (info->params.key == 0xDDBE) {
 		p += snprintf(p, left,
 			     "Warning: Spec violation.  Key should be 0xBEDD, is 0xDDBE\n");
-		email++;
 	}
 
 	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
@@ -294,7 +293,7 @@
 	}
 
 	for (i = 30; i <= 73; i++) {
-		c = *(((uint8_t *) edd) + i + 4);
+		c = *(((uint8_t *) info) + i + 4);
 		if (c)
 			nonzero_path++;
 		checksum += c;
@@ -303,12 +302,10 @@
 	if (checksum) {
 		p += snprintf(p, left,
 			     "Warning: Spec violation.  Device Path checksum invalid.\n");
-		email++;
 	}
 
 	if (!nonzero_path) {
 		p += snprintf(p, left, "Error: Spec violation.  Empty device path.\n");
-		email++;
 		goto out;
 	}
 
@@ -326,45 +323,35 @@
 	if (warn_padding) {
 		p += snprintf(p, left,
 			     "Warning: Spec violation.  Padding should be 0x20.\n");
-		email++;
 	}
 
-	rc = edd_dev_is_type(edev, "PCI");
-	if (!rc) {
-		pci_dev = pci_find_slot(info->params.interface_path.pci.bus,
-					PCI_DEVFN(info->params.interface_path.
-						  pci.slot,
-						  info->params.interface_path.
-						  pci.function));
+	if (edd_dev_is_type(edev, "PCI")) {
+		pci_dev = edd_get_pci_dev(edev);
 		if (!pci_dev) {
 			p += snprintf(p, left, "Error: BIOS says this is a PCI device, but the OS doesn't know\n");
 			p += snprintf(p, left, "  about a PCI device at %02x:%02x.%d\n",
 				     info->params.interface_path.pci.bus,
 				     info->params.interface_path.pci.slot,
 				     info->params.interface_path.pci.function);
-			email++;
 		}
 		else {
 			found_pci++;
 		}
 	}
 
-	if (found_pci && !edd_dev_is_type(edev, "SCSI")) {
+	if (found_pci && kernel_has_scsi() && edd_dev_is_type(edev, "SCSI")) {
 		sd = edd_find_matching_scsi_device(edev);
 		if (!sd) {
 			p += snprintf(p, left, "Error: BIOS says this is a SCSI device, but\n");
 			p += snprintf(p, left, "  the OS doesn't know about this SCSI device.\n");
 			p += snprintf(p, left, "  Do you have it's driver module loaded?\n");
-			email++;
 		}
 	}
 
 out:
-	if (email) {
-		p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL);
-		p += snprintf(p, left, "to see if this has been reported.  If not,\n");
-		p += snprintf(p, left, "please send the information requested there.\n");
-	}
+	p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL);
+	p += snprintf(p, left, "to see if this device has been reported.  If not,\n");
+	p += snprintf(p, left, "please send the information requested there.\n");
 
 	return (p - buf);
 }
@@ -502,8 +489,8 @@
 {
 	struct edd_info *info = edd_dev_get_info(edev);
 	if (!edev || !info)
-		return 1;
-	return !info->params.num_default_cylinders;
+		return 0;
+	return info->params.num_default_cylinders > 0;
 }
 
 static int
@@ -511,8 +498,8 @@
 {
 	struct edd_info *info = edd_dev_get_info(edev);
 	if (!edev || !info)
-		return 1;
-	return !info->params.num_default_heads;
+		return 0;
+	return info->params.num_default_heads > 0;
 }
 
 static int
@@ -520,8 +507,8 @@
 {
 	struct edd_info *info = edd_dev_get_info(edev);
 	if (!edev || !info)
-		return 1;
-	return !info->params.sectors_per_track;
+		return 0;
+	return info->params.sectors_per_track > 0;
 }
 
 static int
@@ -532,24 +519,24 @@
 	char c;
 
 	if (!edev || !info)
-		return 1;
+		return 0;
 
 	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
-		return 1;
+		return 0;
 	}
 
 	for (i = 30; i <= 73; i++) {
-		c = *(((uint8_t *) edd) + i + 4);
+		c = *(((uint8_t *) info) + i + 4);
 		if (c) {
 			nonzero_path++;
 			break;
 		}
 	}
 	if (!nonzero_path) {
-		return 1;
+		return 0;
 	}
 
-	return 0;
+	return 1;
 }
 
 static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, NULL);
@@ -590,7 +577,23 @@
 	NULL,
 };
 
+/**
+ *	edd_release - free edd structure
+ *	@kobj:	kobject of edd structure
+ *
+ *	This is called when the refcount of the edd structure
+ *	reaches 0. This should happen right after we unregister,
+ *	but just in case, we use the release callback anyway.
+ */
+
+static void edd_release(struct kobject * kobj)
+{
+	struct edd_device * dev = to_edd_device(kobj);
+	kfree(dev);
+}
+
 static struct kobj_type ktype_edd = {
+	.release	= edd_release,
 	.sysfs_ops	= &edd_attr_ops,
 	.default_attrs	= def_attrs,
 };
@@ -598,27 +601,24 @@
 static decl_subsys(edd,&ktype_edd);
 
 
-
 /**
  * edd_dev_is_type() - is this EDD device a 'type' device?
  * @edev
  * @type - a host bus or interface identifier string per the EDD spec
  *
- * Returns 0 if it is a 'type' device, nonzero otherwise.
+ * Returns 1 (TRUE) if it is a 'type' device, 0 otherwise.
  */
 static int
 edd_dev_is_type(struct edd_device *edev, const char *type)
 {
-	int rc;
 	struct edd_info *info = edd_dev_get_info(edev);
-	if (!edev || !info)
-		return 1;
 
-	rc = strncmp(info->params.host_bus_type, type, strlen(type));
-	if (!rc)
-		return 0;
-
-	return strncmp(info->params.interface_type, type, strlen(type));
+	if (edev && type && info) {
+		if (!strncmp(info->params.host_bus_type, type, strlen(type)) ||
+		    !strncmp(info->params.interface_type, type, strlen(type)))
+			return 1;
+	}
+	return 0;
 }
 
 /**
@@ -631,16 +631,14 @@
 edd_get_pci_dev(struct edd_device *edev)
 {
 	struct edd_info *info = edd_dev_get_info(edev);
-	int rc;
-
-	rc = edd_dev_is_type(edev, "PCI");
-	if (rc)
-		return NULL;
 
-	return pci_find_slot(info->params.interface_path.pci.bus,
-			     PCI_DEVFN(info->params.interface_path.pci.slot,
-				       info->params.interface_path.pci.
-				       function));
+	if (edd_dev_is_type(edev, "PCI")) {
+		return pci_find_slot(info->params.interface_path.pci.bus,
+				     PCI_DEVFN(info->params.interface_path.pci.slot,
+					       info->params.interface_path.pci.
+					       function));
+	}
+	return NULL;
 }
 
 static int
@@ -653,105 +651,117 @@
 	return sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev");
 }
 
+/*
+ * FIXME - as of 15-Jan-2003, there are some non-"scsi_device"s on the
+ * scsi_bus list.  The following functions could possibly mis-access
+ * memory in that case.  This is actually a problem with the SCSI
+ * layer, which is being addressed there.  Until then, don't use the
+ * SCSI functions.
+ */
+
+#undef CONFIG_SCSI
+#undef CONFIG_SCSI_MODULE
+#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
+
+struct edd_match_data {
+	struct edd_device	* edev;
+	struct scsi_device	* sd;
+};
+
 /**
  * edd_match_scsidev()
  * @edev - EDD device is a known SCSI device
  * @sd - scsi_device with host who's parent is a PCI controller
  * 
- * returns 0 on success, 1 on failure
+ * returns 1 if a match is found, 0 if not.
  */
-static int
-edd_match_scsidev(struct edd_device *edev, struct scsi_device *sd)
+static int edd_match_scsidev(struct device * dev, void * d)
 {
-	struct edd_info *info = edd_dev_get_info(edev);
-
-	if (!edev || !sd || !info)
-		return 1;
-
-	if ((sd->channel == info->params.interface_path.pci.channel) &&
-	    (sd->id == info->params.device_path.scsi.id) &&
-	    (sd->lun == info->params.device_path.scsi.lun)) {
-		return 0;
+	struct edd_match_data * data = (struct edd_match_data *)d;
+	struct edd_info *info = edd_dev_get_info(data->edev);
+	struct scsi_device * sd = to_scsi_device(dev);
+
+	if (info) {
+		if ((sd->channel == info->params.interface_path.pci.channel) &&
+		    (sd->id == info->params.device_path.scsi.id) &&
+		    (sd->lun == info->params.device_path.scsi.lun)) {
+			data->sd = sd;
+			return 1;
+		}
 	}
-
-	return 1;
+	return 0;
 }
 
 /**
  * edd_find_matching_device()
  * @edev - edd_device to match
  *
- * Returns struct scsi_device * on success,
- * or NULL on failure.
- * This assumes that all children of the PCI controller
- * are scsi_hosts, and that all children of scsi_hosts
- * are scsi_devices.
- * The reference counting probably isn't the best it could be.
+ * Search the SCSI devices for a drive that matches the EDD 
+ * device descriptor we have. If we find a match, return it,
+ * otherwise, return NULL.
  */
 
-#define children_to_dev(n) container_of(n,struct device,node)
 static struct scsi_device *
 edd_find_matching_scsi_device(struct edd_device *edev)
 {
-	struct list_head *sdev_node;
-	int rc = 1;
-	struct scsi_device *sd = NULL;
-	struct pci_dev *pci_dev;
-
-	rc = edd_dev_is_type(edev, "SCSI");
-	if (rc)
-		return NULL;
+	struct edd_match_data data;
+	struct bus_type * scsi_bus = find_bus("scsi");
 
-	pci_dev = edd_get_pci_dev(edev);
-	if (!pci_dev)
+	if (!scsi_bus) {
 		return NULL;
+	}
 
-	get_device(&pci_dev->dev);
+	data.edev = edev;
 
-	list_for_each(sdev_node, &pci_dev->dev.children) {
-		struct device *sdev_dev = children_to_dev(sdev_node);
-		get_device(sdev_dev);
-		sd = to_scsi_device(sdev_dev);
-		rc = edd_match_scsidev(edev, sd);
-		put_device(sdev_dev);
-		if (!rc)
-			break;
+	if (edd_dev_is_type(edev, "SCSI")) {
+		if (bus_for_each_dev(scsi_bus,NULL,&data,edd_match_scsidev))
+			return data.sd;
 	}
-
-	put_device(&pci_dev->dev);
-	return rc ? NULL : sd;
+	return NULL;
 }
 
 static int
 edd_create_symlink_to_scsidev(struct edd_device *edev)
 {
-
-	struct scsi_device *sdev;
 	struct pci_dev *pci_dev;
-	struct edd_info *info = edd_dev_get_info(edev);
-	int rc;
+	int rc = -EINVAL;
 
-	rc = edd_dev_is_type(edev, "PCI");
-	if (rc)
-		return rc;
-
-	pci_dev = pci_find_slot(info->params.interface_path.pci.bus,
-				PCI_DEVFN(info->params.interface_path.pci.slot,
-					  info->params.interface_path.pci.
-					  function));
-	if (!pci_dev)
-		return 1;
+	pci_dev = edd_get_pci_dev(edev);
+	if (pci_dev) {
+		struct scsi_device * sdev = edd_find_matching_scsi_device(edev);
+		if (sdev && get_device(&sdev->sdev_driverfs_dev)) {
+			rc = sysfs_create_link(&edev->kobj,
+					       &sdev->sdev_driverfs_dev.kobj,
+					       "disc");
+			put_device(&sdev->sdev_driverfs_dev);
+		}
+	}
+	return rc;
+}
 
-	sdev = edd_find_matching_scsi_device(edev);
-	if (!sdev)
-		return 1;
+static int kernel_has_scsi(void)
+{
+	return 1;
+}
 
-	get_device(&sdev->sdev_driverfs_dev);
-	rc = sysfs_create_link(&edev->kobj,&sdev->sdev_driverfs_dev.kobj, "disc");
-	put_device(&sdev->sdev_driverfs_dev);
+#else
+static int kernel_has_scsi(void)
+{
+	return 0;
+}
 
-	return rc;
+static struct scsi_device *
+edd_find_matching_scsi_device(struct edd_device *edev)
+{
+	return NULL;
 }
+static int
+edd_create_symlink_to_scsidev(struct edd_device *edev)
+{
+	return -ENOSYS;
+}
+#endif
+
 
 static inline void
 edd_device_unregister(struct edd_device *edev)
@@ -759,7 +769,7 @@
 	kobject_unregister(&edev->kobj);
 }
 
-static void populate_dir(struct edd_device * edev)
+static void edd_populate_dir(struct edd_device * edev)
 {
 	struct edd_attribute * attr;
 	int error = 0;
@@ -767,7 +777,7 @@
 
 	for (i = 0; (attr = edd_attrs[i]) && !error; i++) {
 		if (!attr->test || 
-		    (attr->test && !attr->test(edev)))
+		    (attr->test && attr->test(edev)))
 			error = sysfs_create_file(&edev->kobj,&attr->attr);
 	}
 	
@@ -791,12 +801,12 @@
 	kobj_set_kset_s(edev,edd_subsys);
 	error = kobject_register(&edev->kobj);
 	if (!error)
-		populate_dir(edev);
+		edd_populate_dir(edev);
 	return error;
 }
 
 /**
- * edd_init() - creates driverfs tree of EDD data
+ * edd_init() - creates sysfs tree of EDD data
  *
  * This assumes that eddnr and edd were
  * assigned in setup.c already.
@@ -845,10 +855,8 @@
 	struct edd_device *edev;
 
 	for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
-		if ((edev = edd_devices[i])) {
+		if ((edev = edd_devices[i]))
 			edd_device_unregister(edev);
-			kfree(edev);
-		}
 	}
 	firmware_unregister(&edd_subsys);
 }
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/entry.S	Mon Feb 10 10:39:24 2003
@@ -792,8 +792,8 @@
 	.long sys_io_getevents
 	.long sys_io_submit
 	.long sys_io_cancel
-	.long sys_ni_syscall 	/* 250 sys_alloc_hugepages - reuse this */
-	.long sys_ni_syscall	/* was sys_free_hugepages - reuse this */
+	.long sys_fadvise64	/* 250 */
+	.long sys_ni_syscall
 	.long sys_exit_group
 	.long sys_lookup_dcookie
 	.long sys_epoll_create
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	Mon Feb 10 10:39:33 2003
+++ b/arch/i386/kernel/i386_ksyms.c	Mon Feb 10 10:39:33 2003
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/tty.h>
 #include <linux/highmem.h>
+#include <linux/time.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
diff -Nru a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
--- a/arch/i386/kernel/init_task.c	Mon Feb 10 10:39:33 2003
+++ b/arch/i386/kernel/init_task.c	Mon Feb 10 10:39:33 2003
@@ -11,6 +11,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /*
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/io_apic.c	Mon Feb 10 10:39:24 2003
@@ -207,19 +207,34 @@
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-#if CONFIG_SMP
-
-typedef struct {
-	unsigned int cpu;
-	unsigned long timestamp;
-} ____cacheline_aligned irq_balance_t;
-
-static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned
-			= { [ 0 ... NR_IRQS-1 ] = { 0, 0 } };
+#if defined(CONFIG_SMP)
+# include <asm/processor.h>	/* kernel_thread() */
+# include <linux/kernel_stat.h>	/* kstat */
+# include <linux/slab.h>		/* kmalloc() */
+# include <linux/timer.h>	/* time_after() */
+ 
+# if CONFIG_BALANCED_IRQ_DEBUG
+#  define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
+#  define Dprintk(x...) do { TDprintk(x); } while (0)
+# else
+#  define TDprintk(x...) 
+#  define Dprintk(x...) 
+# endif
 
 extern unsigned long irq_affinity [NR_IRQS];
-
-#endif
+unsigned long __cacheline_aligned irq_balance_mask [NR_IRQS];
+static int irqbalance_disabled __initdata = 0;
+static int physical_balance = 0;
+
+struct irq_cpu_info {
+	unsigned long * last_irq;
+	unsigned long * irq_delta;
+	unsigned long irq;
+} irq_cpu_data[NR_CPUS];
+
+#define CPU_IRQ(cpu)		(irq_cpu_data[cpu].irq)
+#define LAST_CPU_IRQ(cpu,irq)   (irq_cpu_data[cpu].last_irq[irq])
+#define IRQ_DELTA(cpu,irq) 	(irq_cpu_data[cpu].irq_delta[irq])
 
 #define IDLE_ENOUGH(cpu,now) \
 		(idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1))
@@ -227,10 +242,224 @@
 #define IRQ_ALLOWED(cpu,allowed_mask) \
 		((1 << cpu) & (allowed_mask))
 
-#if CONFIG_SMP
+#define CPU_TO_PACKAGEINDEX(i) \
+		((physical_balance && i > cpu_sibling_map[i]) ? cpu_sibling_map[i] : i)
+
+#define MAX_BALANCED_IRQ_INTERVAL	(5*HZ)
+#define MIN_BALANCED_IRQ_INTERVAL	(HZ/2)
+#define BALANCED_IRQ_MORE_DELTA		(HZ/10)
+#define BALANCED_IRQ_LESS_DELTA		(HZ)
+
+long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
+					 
+static inline void balance_irq(int cpu, int irq);
+
+static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
+{
+	int i, j;
+	Dprintk("Rotating IRQs among CPUs.\n");
+	for (i = 0; i < NR_CPUS; i++) {
+		for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) {
+			if (!irq_desc[j].action)
+				continue;
+			/* Is it a significant load ?  */
+			if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < useful_load_threshold)
+				continue;
+			balance_irq(i, j);
+		}
+	}
+	balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
+		balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);	
+	return;
+}
+
+static void do_irq_balance(void)
+{
+	int i, j;
+	unsigned long max_cpu_irq = 0, min_cpu_irq = (~0);
+	unsigned long move_this_load = 0;
+	int max_loaded = 0, min_loaded = 0;
+	unsigned long useful_load_threshold = balanced_irq_interval + 10;
+	int selected_irq;
+	int tmp_loaded, first_attempt = 1;
+	unsigned long tmp_cpu_irq;
+	unsigned long imbalance = 0;
+	unsigned long allowed_mask;
+	unsigned long target_cpu_mask;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		int package_index;
+		CPU_IRQ(i) = 0;
+		if (!cpu_online(i))
+			continue;
+		package_index = CPU_TO_PACKAGEINDEX(i);
+		for (j = 0; j < NR_IRQS; j++) {
+			unsigned long value_now, delta;
+			/* Is this an active IRQ? */
+			if (!irq_desc[j].action)
+				continue;
+			if ( package_index == i )
+				IRQ_DELTA(package_index,j) = 0;
+			/* Determine the total count per processor per IRQ */
+			value_now = (unsigned long) kstat_cpu(i).irqs[j];
+
+			/* Determine the activity per processor per IRQ */
+			delta = value_now - LAST_CPU_IRQ(i,j);
+
+			/* Update last_cpu_irq[][] for the next time */
+			LAST_CPU_IRQ(i,j) = value_now;
+
+			/* Ignore IRQs whose rate is less than the clock */
+			if (delta < useful_load_threshold)
+				continue;
+			/* update the load for the processor or package total */
+			IRQ_DELTA(package_index,j) += delta;
+
+			/* Keep track of the higher numbered sibling as well */
+			if (i != package_index)
+				CPU_IRQ(i) += delta;
+			/*
+			 * We have sibling A and sibling B in the package
+			 *
+			 * cpu_irq[A] = load for cpu A + load for cpu B
+			 * cpu_irq[B] = load for cpu B
+			 */
+			CPU_IRQ(package_index) += delta;
+		}
+	}
+	/* Find the least loaded processor package */
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_online(i))
+			continue;
+		if (physical_balance && i > cpu_sibling_map[i])
+			continue;
+		if (min_cpu_irq > CPU_IRQ(i)) {
+			min_cpu_irq = CPU_IRQ(i);
+			min_loaded = i;
+		}
+	}
+	max_cpu_irq = ULONG_MAX;
+
+tryanothercpu:
+	/* Look for heaviest loaded processor.
+	 * We may come back to get the next heaviest loaded processor.
+	 * Skip processors with trivial loads.
+	 */
+	tmp_cpu_irq = 0;
+	tmp_loaded = -1;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_online(i))
+			continue;
+		if (physical_balance && i > cpu_sibling_map[i])
+			continue;
+		if (max_cpu_irq <= CPU_IRQ(i)) 
+			continue;
+		if (tmp_cpu_irq < CPU_IRQ(i)) {
+			tmp_cpu_irq = CPU_IRQ(i);
+			tmp_loaded = i;
+		}
+	}
 
-#define IRQ_BALANCE_INTERVAL (HZ/50)
+	if (tmp_loaded == -1) {
+ 	 /* In the case of small number of heavy interrupt sources, 
+	  * loading some of the cpus too much. We use Ingo's original 
+	  * approach to rotate them around.
+	  */
+		if (!first_attempt && imbalance >= useful_load_threshold) {
+			rotate_irqs_among_cpus(useful_load_threshold);
+			return;
+		}
+		goto not_worth_the_effort;
+	}
+	
+	first_attempt = 0;		/* heaviest search */
+	max_cpu_irq = tmp_cpu_irq;	/* load */
+	max_loaded = tmp_loaded;	/* processor */
+	imbalance = (max_cpu_irq - min_cpu_irq) / 2;
 	
+	Dprintk("max_loaded cpu = %d\n", max_loaded);
+	Dprintk("min_loaded cpu = %d\n", min_loaded);
+	Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq);
+	Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq);
+	Dprintk("load imbalance = %lu\n", imbalance);
+
+	/* if imbalance is less than approx 10% of max load, then
+	 * observe diminishing returns action. - quit
+	 */
+	if (imbalance < (max_cpu_irq >> 3)) {
+		Dprintk("Imbalance too trivial\n");
+		goto not_worth_the_effort;
+	}
+
+tryanotherirq:
+	/* if we select an IRQ to move that can't go where we want, then
+	 * see if there is another one to try.
+	 */
+	move_this_load = 0;
+	selected_irq = -1;
+	for (j = 0; j < NR_IRQS; j++) {
+		/* Is this an active IRQ? */
+		if (!irq_desc[j].action)
+			continue;
+		if (imbalance <= IRQ_DELTA(max_loaded,j))
+			continue;
+		/* Try to find the IRQ that is closest to the imbalance
+		 * without going over.
+		 */
+		if (move_this_load < IRQ_DELTA(max_loaded,j)) {
+			move_this_load = IRQ_DELTA(max_loaded,j);
+			selected_irq = j;
+		}
+	}
+	if (selected_irq == -1) {
+		goto tryanothercpu;
+	}
+
+	imbalance = move_this_load;
+	
+	/* For physical_balance case, we accumlated both load
+	 * values in the one of the siblings cpu_irq[],
+	 * to use the same code for physical and logical processors
+	 * as much as possible. 
+	 *
+	 * NOTE: the cpu_irq[] array holds the sum of the load for
+	 * sibling A and sibling B in the slot for the lowest numbered
+	 * sibling (A), _AND_ the load for sibling B in the slot for
+	 * the higher numbered sibling.
+	 *
+	 * We seek the least loaded sibling by making the comparison
+	 * (A+B)/2 vs B
+	 */
+	if (physical_balance && (CPU_IRQ(min_loaded) >> 1) > CPU_IRQ(cpu_sibling_map[min_loaded]))
+		min_loaded = cpu_sibling_map[min_loaded];
+
+	allowed_mask = cpu_online_map & irq_affinity[selected_irq];
+	target_cpu_mask = 1 << min_loaded;
+
+	if (target_cpu_mask & allowed_mask) {
+		irq_desc_t *desc = irq_desc + selected_irq;
+		Dprintk("irq = %d moved to cpu = %d\n", selected_irq, min_loaded);
+		/* mark for change destination */
+		spin_lock(&desc->lock);
+		irq_balance_mask[selected_irq] = target_cpu_mask;
+		spin_unlock(&desc->lock);
+		/* Since we made a change, come back sooner to 
+		 * check for more variation.
+		 */
+		balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
+			balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);	
+		return;
+	}
+	goto tryanotherirq;
+
+not_worth_the_effort:
+	/* if we did not find an IRQ to move, then adjust the time interval upward */
+	balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL,
+		balanced_irq_interval + BALANCED_IRQ_MORE_DELTA);	
+	Dprintk("IRQ worth rotating not found\n");
+	return;
+}
+
 static unsigned long move(int curr_cpu, unsigned long allowed_mask, unsigned long now, int direction)
 {
 	int search_idle = 1;
@@ -257,34 +486,113 @@
 	return cpu;
 }
 
-static inline void balance_irq(int irq)
+static inline void balance_irq (int cpu, int irq)
 {
-	irq_balance_t *entry = irq_balance + irq;
 	unsigned long now = jiffies;
-
+	unsigned long allowed_mask;
+	unsigned int new_cpu;
+		
 	if (no_balance_irq)
 		return;
 
-	if (unlikely(time_after(now, entry->timestamp + IRQ_BALANCE_INTERVAL))) {
-		unsigned long allowed_mask;
-		unsigned int new_cpu;
-		int random_number;
-
-		rdtscl(random_number);
-		random_number &= 1;
-
-		allowed_mask = cpu_online_map & irq_affinity[irq];
-		entry->timestamp = now;
-		new_cpu = move(entry->cpu, allowed_mask, now, random_number);
-		if (entry->cpu != new_cpu) {
-			entry->cpu = new_cpu;
-			set_ioapic_affinity(irq, cpu_to_logical_apicid(new_cpu));
+	allowed_mask = cpu_online_map & irq_affinity[irq];
+	new_cpu = move(cpu, allowed_mask, now, 1);
+	if (cpu != new_cpu) {
+		irq_desc_t *desc = irq_desc + irq;
+		spin_lock(&desc->lock);
+		irq_balance_mask[irq] = cpu_to_logical_apicid(new_cpu);
+		spin_unlock(&desc->lock);
+	}
+}
+
+int balanced_irq(void *unused)
+{
+	int i;
+	unsigned long prev_balance_time = jiffies;
+	long time_remaining = balanced_irq_interval;
+	daemonize();
+	sigfillset(&current->blocked);
+	sprintf(current->comm, "kirqd");
+	
+	/* push everything to CPU 0 to give us a starting point.  */
+	for (i = 0 ; i < NR_IRQS ; i++)
+		irq_balance_mask[i] = 1 << 0;
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		time_remaining = schedule_timeout(time_remaining);
+		if (time_after(jiffies, prev_balance_time+balanced_irq_interval)) {
+			Dprintk("balanced_irq: calling do_irq_balance() %lu\n", jiffies);
+			do_irq_balance();
+			prev_balance_time = jiffies;
+			time_remaining = balanced_irq_interval;
 		}
+        }
+}
+
+static int __init balanced_irq_init(void)
+{
+	int i;
+	struct cpuinfo_x86 *c;
+        c = &boot_cpu_data;
+	if (irqbalance_disabled)
+		return 0;
+	/* Enable physical balance only if more than 1 physical processor is present */
+	if (smp_num_siblings > 1 && cpu_online_map >> 2)
+		physical_balance = 1;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_online(i))
+			continue;
+		irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
+		irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
+		if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
+			printk(KERN_ERR "balanced_irq_init: out of memory");
+			goto failed;
+		}
+		memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS);
+		memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS);
+	}
+	
+	printk(KERN_INFO "Starting balanced_irq\n");
+	if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) 
+		return 0;
+	else 
+		printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
+failed:
+	for (i = 0; i < NR_CPUS; i++) {
+		if(irq_cpu_data[i].irq_delta)
+			kfree(irq_cpu_data[i].irq_delta);
+		if(irq_cpu_data[i].last_irq)
+			kfree(irq_cpu_data[i].last_irq);
 	}
+	return 0;
 }
+
+static int __init irqbalance_disable(char *str)
+{
+	irqbalance_disabled = 1;
+	return 0;
+}
+
+__setup("noirqbalance", irqbalance_disable);
+
+static void set_ioapic_affinity (unsigned int irq, unsigned long mask);
+
+static inline void move_irq(int irq)
+{
+	/* note - we hold the desc->lock */
+	if (unlikely(irq_balance_mask[irq])) {
+		set_ioapic_affinity(irq, irq_balance_mask[irq]);
+		irq_balance_mask[irq] = 0;
+	}
+}
+
+__initcall(balanced_irq_init);
+
 #else /* !SMP */
-static inline void balance_irq(int irq) { }
-#endif
+static inline void move_irq(int irq) { }
+#endif /* defined(CONFIG_SMP) */
+
 
 /*
  * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
@@ -1307,7 +1615,7 @@
  */
 static void ack_edge_ioapic_irq(unsigned int irq)
 {
-	balance_irq(irq);
+	move_irq(irq);
 	if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
 					== (IRQ_PENDING | IRQ_DISABLED))
 		mask_IO_APIC_irq(irq);
@@ -1347,7 +1655,7 @@
 	unsigned long v;
 	int i;
 
-	balance_irq(irq);
+	move_irq(irq);
 /*
  * It appears there is an erratum which affects at least version 0x11
  * of I/O APIC (that's the 82093AA and cores integrated into various
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/kernel/irq.c	Mon Feb 10 10:39:23 2003
@@ -338,9 +338,9 @@
 
 		__asm__ __volatile__("andl %%esp,%0" :
 					"=r" (esp) : "0" (8191));
-		if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
+		if (unlikely(esp < (sizeof(struct thread_info) + 1024))) {
 			printk("do_IRQ: stack overflow: %ld\n",
-				esp - sizeof(struct task_struct));
+				esp - sizeof(struct thread_info));
 			dump_stack();
 		}
 	}
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Mon Feb 10 10:39:22 2003
+++ b/arch/i386/kernel/process.c	Mon Feb 10 10:39:22 2003
@@ -86,7 +86,7 @@
  */
 void default_idle(void)
 {
-	if (current_cpu_data.hlt_works_ok && !hlt_counter) {
+	if (!hlt_counter && current_cpu_data.hlt_works_ok) {
 		local_irq_disable();
 		if (!need_resched())
 			safe_halt();
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Mon Feb 10 10:39:27 2003
+++ b/arch/i386/kernel/setup.c	Mon Feb 10 10:39:27 2003
@@ -474,7 +474,7 @@
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 unsigned char eddnr;
-struct edd_info edd[EDDNR];
+struct edd_info edd[EDDMAXNR];
 /**
  * copy_edd() - Copy the BIOS EDD information
  *              from empty_zero_page into a safe place.
@@ -900,7 +900,7 @@
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
 	if (!acpi_disabled)
-		acpi_boot_init(*cmdline_p);
+		acpi_boot_init();
 #endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	if (smp_found_config)
diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c	Mon Feb 10 10:39:26 2003
+++ b/arch/i386/kernel/signal.c	Mon Feb 10 10:39:26 2003
@@ -37,11 +37,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->eax = -EINTR;
 	while (1) {
@@ -66,11 +66,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->eax = -EINTR;
 	while (1) {
@@ -224,10 +224,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (restore_sigcontext(regs, &frame->sc, &eax))
 		goto badframe;
@@ -252,10 +252,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
 		goto badframe;
@@ -513,7 +513,7 @@
 handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
 	struct pt_regs * regs)
 {
-	struct k_sigaction *ka = &current->sig->action[sig-1];
+	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
 	/* Are we from a system call? */
 	if (regs->orig_eax >= 0) {
@@ -547,11 +547,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	Mon Feb 10 10:39:27 2003
+++ b/arch/i386/kernel/time.c	Mon Feb 10 10:39:27 2003
@@ -70,7 +70,6 @@
 
 unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
@@ -87,19 +86,21 @@
  */
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = timer->get_offset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += (xtime.tv_nsec / 1000);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin(&xtime_lock);
+
+		usec = timer->get_offset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry(&xtime_lock, seq));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -112,7 +113,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
@@ -133,7 +134,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /*
@@ -266,6 +267,41 @@
 }
 
 /*
+ * Lost tick detection and compensation
+ */
+static inline void detect_lost_tick(void)
+{
+	/* read time since last interrupt */
+	unsigned long delta = timer->get_offset();
+	static unsigned long dbg_print;
+	
+	/* check if delta is greater then two ticks */
+	if(delta >= 2*(1000000/HZ)){
+
+		/*
+		 * only print debug info first 5 times
+		 */
+		/*
+		 * AKPM: disable this for now; it's nice, but irritating.
+		 */
+		if (0 && dbg_print < 5) {
+			printk(KERN_WARNING "\nWarning! Detected %lu "
+				"micro-second gap between interrupts.\n",
+				delta);
+			printk(KERN_WARNING "  Compensating for %lu lost "
+				"ticks.\n",
+				delta/(1000000/HZ)-1);
+			dump_stack();
+			dbg_print++;
+		}
+		/* calculate number of missed ticks */
+		delta = delta/(1000000/HZ)-1;
+		jiffies += delta;
+	}
+		
+}
+
+/*
  * This is the same as the above, except we _also_ save the current
  * Time Stamp Counter value at the time of the timer interrupt, so that
  * we later on can estimate the time of day more exactly.
@@ -279,13 +315,14 @@
 	 * the irq version of write_lock because as just said we have irq
 	 * locally disabled. -arca
 	 */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 
+	detect_lost_tick();
 	timer->mark_offset();
  
 	do_timer_interrupt(irq, NULL, regs);
 
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 
 }
 
diff -Nru a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
--- a/arch/i386/kernel/timers/timer_pit.c	Mon Feb 10 10:39:31 2003
+++ b/arch/i386/kernel/timers/timer_pit.c	Mon Feb 10 10:39:31 2003
@@ -76,7 +76,7 @@
 static unsigned long get_offset_pit(void)
 {
 	int count;
-
+	unsigned long flags;
 	static int count_p = LATCH;    /* for the first call after boot */
 	static unsigned long jiffies_p = 0;
 
@@ -85,8 +85,7 @@
 	 */
 	unsigned long jiffies_t;
 
-	/* gets recalled with irq locally disabled */
-	spin_lock(&i8253_lock);
+	spin_lock_irqsave(&i8253_lock, flags);
 	/* timer count may underflow right here */
 	outb_p(0x00, 0x43);	/* latch the count ASAP */
 
@@ -108,7 +107,7 @@
                 count = LATCH - 1;
         }
 	
-	spin_unlock(&i8253_lock);
+	spin_unlock_irqrestore(&i8253_lock, flags);
 
 	/*
 	 * avoiding timer inconsistencies (they are rare, but they happen)...
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/kernel/traps.c	Mon Feb 10 10:39:24 2003
@@ -514,6 +514,10 @@
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* It's safe to allow irq's after DR6 has been saved */
+	if (regs->eflags & X86_EFLAGS_IF)
+		local_irq_enable();
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
@@ -831,7 +835,7 @@
 #endif
 
 	set_trap_gate(0,&divide_error);
-	set_trap_gate(1,&debug);
+	set_intr_gate(1,&debug);
 	set_intr_gate(2,&nmi);
 	set_system_gate(3,&int3);	/* int3-5 can be called from all */
 	set_system_gate(4,&overflow);
diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/kernel/vm86.c	Mon Feb 10 10:39:23 2003
@@ -512,10 +512,10 @@
 		return 1; /* we let this handle by the calling routine */
 	if (current->ptrace & PT_PTRACED) {
 		unsigned long flags;
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		sigdelset(&current->blocked, SIGTRAP);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 	}
 	send_sig(SIGTRAP, current, 1);
 	current->thread.trap_no = trapno;
diff -Nru a/arch/i386/mach-voyager/Makefile b/arch/i386/mach-voyager/Makefile
--- a/arch/i386/mach-voyager/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/i386/mach-voyager/Makefile	Mon Feb 10 10:39:23 2003
@@ -8,8 +8,6 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 EXTRA_CFLAGS	+= -I../kernel
-export-objs	:=
-
 obj-y			:= setup.o voyager_basic.o voyager_thread.o
 
 obj-$(CONFIG_SMP)	+= voyager_smp.o voyager_cat.o
diff -Nru a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
--- a/arch/i386/mm/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/i386/mm/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux i386-specific parts of the memory manager.
 #
 
-export-objs := pageattr.o
-
 obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o
 
 obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	Mon Feb 10 10:39:32 2003
+++ b/arch/i386/mm/hugetlbpage.c	Mon Feb 10 10:39:32 2003
@@ -26,7 +26,6 @@
 int     htlbpage_max;
 static long    htlbzone_pages;
 
-struct vm_operations_struct hugetlb_vm_ops;
 static LIST_HEAD(htlbpage_freelist);
 static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 
@@ -46,6 +45,7 @@
 	htlbpagemem--;
 	spin_unlock(&htlbpage_lock);
 	set_page_count(page, 1);
+	page->lru.prev = (void *)huge_page_release;
 	for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
 		clear_highpage(&page[i]);
 	return page;
@@ -134,6 +134,7 @@
 		page = pte_page(pte);
 		if (pages) {
 			page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
+			get_page(page);
 			pages[i] = page;
 		}
 		if (vmas)
@@ -150,6 +151,82 @@
 	return i;
 }
 
+#if 0	/* This is just for testing */
+struct page *
+follow_huge_addr(struct mm_struct *mm,
+	struct vm_area_struct *vma, unsigned long address, int write)
+{
+	unsigned long start = address;
+	int length = 1;
+	int nr;
+	struct page *page;
+
+	nr = follow_hugetlb_page(mm, vma, &page, NULL, &start, &length, 0);
+	if (nr == 1)
+		return page;
+	return NULL;
+}
+
+/*
+ * If virtual address `addr' lies within a huge page, return its controlling
+ * VMA, else NULL.
+ */
+struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr)
+{
+	if (mm->used_hugetlb) {
+		struct vm_area_struct *vma = find_vma(mm, addr);
+		if (vma && is_vm_hugetlb_page(vma))
+			return vma;
+	}
+	return NULL;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return 0;
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd, int write)
+{
+	return NULL;
+}
+
+#else
+
+struct page *
+follow_huge_addr(struct mm_struct *mm,
+	struct vm_area_struct *vma, unsigned long address, int write)
+{
+	return NULL;
+}
+
+struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr)
+{
+	return NULL;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_PSE);
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd, int write)
+{
+	struct page *page;
+
+	page = pte_page(*(pte_t *)pmd);
+	if (page) {
+		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
+		get_page(page);
+	}
+	return page;
+}
+#endif
+
 void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
@@ -171,7 +248,8 @@
 	free_huge_page(page);
 }
 
-void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+void unmap_hugepage_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
@@ -181,8 +259,6 @@
 	BUG_ON(start & (HPAGE_SIZE - 1));
 	BUG_ON(end & (HPAGE_SIZE - 1));
 
-	spin_lock(&htlbpage_lock);
-	spin_unlock(&htlbpage_lock);
 	for (address = start; address < end; address += HPAGE_SIZE) {
 		pte = huge_pte_offset(mm, address);
 		if (pte_none(*pte))
@@ -195,7 +271,9 @@
 	flush_tlb_range(vma, start, end);
 }
 
-void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length)
+void
+zap_hugepage_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long length)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	spin_lock(&mm->page_table_lock);
@@ -206,6 +284,7 @@
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
+	struct inode *inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -229,6 +308,7 @@
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
+			loff_t i_size;
 			page = alloc_hugetlb_page();
 			if (!page) {
 				ret = -ENOMEM;
@@ -240,6 +320,9 @@
 				free_huge_page(page);
 				goto out;
 			}
+			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
+			if (i_size > inode->i_size)
+				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
@@ -283,8 +366,8 @@
 				break;
 		}
 		page = list_entry(p, struct page, list);
-		if ((page_zone(page))->name[0] != 'H') // Look for non-Highmem
-				map = page;
+		if (!PageHighMem(page))
+			map = page;
 	}
 	if (map) {
 		list_del(&map->list);
@@ -298,8 +381,8 @@
 
 int set_hugetlb_mem_size(int count)
 {
-	int j, lcount;
-	struct page *page, *map;
+	int lcount;
+	struct page *page;
 	extern long htlbzone_pages;
 	extern struct list_head htlbpage_freelist;
 
@@ -315,11 +398,6 @@
 			page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
 			if (page == NULL)
 				break;
-			map = page;
-			for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-				SetPageReserved(map);
-				map++;
-			}
 			spin_lock(&htlbpage_lock);
 			list_add(&page->list, &htlbpage_freelist);
 			htlbpagemem++;
@@ -341,7 +419,8 @@
 	return (int) htlbzone_pages;
 }
 
-int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length)
+int hugetlb_sysctl_handler(ctl_table *table, int write,
+		struct file *file, void *buffer, size_t *length)
 {
 	proc_dointvec(table, write, file, buffer, length);
 	htlbpage_max = set_hugetlb_mem_size(htlbpage_max);
@@ -358,15 +437,13 @@
 
 static int __init hugetlb_init(void)
 {
-	int i, j;
+	int i;
 	struct page *page;
 
 	for (i = 0; i < htlbpage_max; ++i) {
 		page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
 		if (!page)
 			break;
-		for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j)
-			SetPageReserved(&page[j]);
 		spin_lock(&htlbpage_lock);
 		list_add(&page->list, &htlbpage_freelist);
 		spin_unlock(&htlbpage_lock);
@@ -395,7 +472,14 @@
 	return 1;
 }
 
-static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+/*
+ * We cannot handle pagefaults against hugetlb pages at all.  They cause
+ * handle_mm_fault() to try to instantiate regular-sized pages in the
+ * hugegpage VMA.  do_page_fault() is supposed to trap this, so BUG is we get
+ * this far.
+ */
+static struct page *hugetlb_nopage(struct vm_area_struct *vma,
+				unsigned long address, int unused)
 {
 	BUG();
 	return NULL;
diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c
--- a/arch/i386/mm/init.c	Mon Feb 10 10:39:30 2003
+++ b/arch/i386/mm/init.c	Mon Feb 10 10:39:30 2003
@@ -508,20 +508,36 @@
 #endif
 }
 
-#if CONFIG_X86_PAE
-struct kmem_cache_s *pae_pgd_cachep;
+#include <linux/slab.h>
+
+kmem_cache_t *pmd_cache;
+kmem_cache_t *pgd_cache;
+
+void pmd_ctor(void *, kmem_cache_t *, unsigned long);
+void pgd_ctor(void *, kmem_cache_t *, unsigned long);
 
 void __init pgtable_cache_init(void)
 {
+	if (PTRS_PER_PMD > 1) {
+		pmd_cache = kmem_cache_create("pae_pmd",
+						PTRS_PER_PMD*sizeof(pmd_t),
+						0,
+						SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
+						pmd_ctor,
+						NULL);
+
+		if (!pmd_cache)
+			panic("pgtable_cache_init(): cannot create pmd cache");
+	}
+
         /*
          * PAE pgds must be 16-byte aligned:
          */
-        pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
-                SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
-        if (!pae_pgd_cachep)
-                panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
+        pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), 0,
+                SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, pgd_ctor, NULL);
+        if (!pgd_cache)
+                panic("pgtable_cache_init(): Cannot create pgd cache");
 }
-#endif
 
 /* Put this after the callers, so that it cannot be inlined */
 static int do_test_wp_bit(void)
diff -Nru a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
--- a/arch/i386/mm/pgtable.c	Mon Feb 10 10:39:33 2003
+++ b/arch/i386/mm/pgtable.c	Mon Feb 10 10:39:33 2003
@@ -166,61 +166,60 @@
 	return pte;
 }
 
-#if CONFIG_X86_PAE
+extern kmem_cache_t *pmd_cache;
+extern kmem_cache_t *pgd_cache;
 
-pgd_t *pgd_alloc(struct mm_struct *mm)
+void pmd_ctor(void *__pmd, kmem_cache_t *pmd_cache, unsigned long flags)
 {
-	int i;
-	pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
-
-	if (pgd) {
-		for (i = 0; i < USER_PTRS_PER_PGD; i++) {
-			unsigned long pmd = __get_free_page(GFP_KERNEL);
-			if (!pmd)
-				goto out_oom;
-			clear_page(pmd);
-			set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
-		}
-		memcpy(pgd + USER_PTRS_PER_PGD,
-			swapper_pg_dir + USER_PTRS_PER_PGD,
-			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-	}
-	return pgd;
-out_oom:
-	for (i--; i >= 0; i--)
-		free_page((unsigned long)__va(pgd_val(pgd[i])-1));
-	kmem_cache_free(pae_pgd_cachep, pgd);
-	return NULL;
+	clear_page(__pmd);
 }
 
-void pgd_free(pgd_t *pgd)
+void pgd_ctor(void *__pgd, kmem_cache_t *pgd_cache, unsigned long flags)
 {
-	int i;
+	pgd_t *pgd = __pgd;
 
-	for (i = 0; i < USER_PTRS_PER_PGD; i++)
-		free_page((unsigned long)__va(pgd_val(pgd[i])-1));
-	kmem_cache_free(pae_pgd_cachep, pgd);
+	if (PTRS_PER_PMD == 1)
+		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+	memcpy(pgd + USER_PTRS_PER_PGD,
+		swapper_pg_dir + USER_PTRS_PER_PGD,
+		(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 }
 
-#else
-
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+	int i;
+	pgd_t *pgd = kmem_cache_alloc(pgd_cache, SLAB_KERNEL);
 
-	if (pgd) {
-		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
-		memcpy(pgd + USER_PTRS_PER_PGD,
-			swapper_pg_dir + USER_PTRS_PER_PGD,
-			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	if (PTRS_PER_PMD == 1)
+		return pgd;
+	else if (!pgd)
+		return NULL;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+		pmd_t *pmd = kmem_cache_alloc(pmd_cache, SLAB_KERNEL);
+		if (!pmd)
+			goto out_oom;
+		set_pgd(pgd + i, __pgd(1 + __pa((unsigned long long)((unsigned long)pmd))));
 	}
 	return pgd;
+
+out_oom:
+	for (i--; i >= 0; --i)
+		kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+	kmem_cache_free(pgd_cache, (void *)pgd);
+	return NULL;
 }
 
 void pgd_free(pgd_t *pgd)
 {
-	free_page((unsigned long)pgd);
-}
+	int i;
 
-#endif /* CONFIG_X86_PAE */
+	if (PTRS_PER_PMD > 1) {
+		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+			set_pgd(pgd + i, __pgd(0));
+		}
+	}
 
+	kmem_cache_free(pgd_cache, (void *)pgd);
+}
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/arch/ia64/Kconfig	Mon Feb 10 10:39:32 2003
@@ -502,7 +502,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 if !IA64_HP_SIM
@@ -611,7 +611,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -640,7 +640,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -767,6 +767,9 @@
 
 
 menu "Kernel hacking"
+
+config FSYS
+	bool "Light-weight system-call support (via epc)"
 
 choice
 	prompt "Physical memory granularity"
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/Makefile	Mon Feb 10 10:39:23 2003
@@ -5,7 +5,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 1998-2002 by David Mosberger-Tang <davidm@hpl.hp.com>
+# Copyright (C) 1998-2003 by David Mosberger-Tang <davidm@hpl.hp.com>
 #
 
 NM := $(CROSS_COMPILE)nm -B
@@ -23,6 +23,16 @@
 
 GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
+GAS_STATUS=$(shell arch/ia64/scripts/check-gas $(CC))
+
+ifeq ($(GAS_STATUS),buggy)
+$(error Sorry, you need a newer version of the assember, one that is built from	\
+	a source-tree that post-dates 18-Dec-2002.  You can find a pre-compiled	\
+	static binary of such an assembler at:					\
+										\
+		ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
+endif
+
 ifneq ($(GCC_VERSION),2)
 	cflags-y += -frename-registers --param max-inline-insns=5000
 endif
@@ -31,7 +41,7 @@
 cflags-$(CONFIG_IA64_SGI_SN)		+= -DBRINGUP
 
 CFLAGS += $(cflags-y)
-HEAD := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
+head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
 
 libs-y				+= arch/ia64/lib/
 core-y				+= arch/ia64/kernel/ arch/ia64/mm/
@@ -48,26 +58,36 @@
 drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
 drivers-$(CONFIG_IA64_SGI_SN)	+= arch/ia64/sn/fakeprom/
 
-makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/boot $(1)
-maketool =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/tools $(1)
+boot := arch/ia64/boot
+tools := arch/ia64/tools
 
-.PHONY: boot compressed archclean archmrproper include/asm-ia64/offsets.h
+.PHONY: boot compressed include/asm-ia64/offsets.h
 
-all compressed: vmlinux.gz
+all: vmlinux
+
+compressed: vmlinux.gz
 
 vmlinux.gz: vmlinux
-	$(call makeboot,vmlinux.gz)
+	$(Q)$(MAKE) $(build)=$(boot) vmlinux.gz
+
+check: vmlinux
+	arch/ia64/scripts/unwcheck.sh vmlinux
 
-archmrproper:
 archclean:
-	$(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/ia64/boot
+	$(Q)$(MAKE) $(clean)=$(boot)
+	$(Q)$(MAKE) $(clean)=$(tools)
 
 CLEAN_FILES += include/asm-ia64/offsets.h vmlinux.gz bootloader
 
 prepare: include/asm-ia64/offsets.h
 
 boot:	lib/lib.a vmlinux
-	$(call makeboot,$@)
+	$(Q)$(MAKE) $(build)=$(boot) $@
 
 include/asm-ia64/offsets.h: include/asm include/linux/version.h include/config/MARKER
-	$(call maketool,$@)
+	$(Q)$(MAKE) $(build)=$(tools) $@
+
+define archhelp
+  echo '  compressed	- Build compressed kernel image'
+  echo '  boot		- Build vmlinux and bootloader for Ski simulator'
+endef
diff -Nru a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
--- a/arch/ia64/dig/setup.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/dig/setup.c	Mon Feb 10 10:39:24 2003
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
@@ -56,7 +56,7 @@
 	if (!ia64_boot_param->console_info.num_rows
 	    || !ia64_boot_param->console_info.num_cols)
 	{
-		printk("dig_setup: warning: invalid screen-info, guessing 80x25\n");
+		printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n");
 		orig_x = 0;
 		orig_y = 0;
 		num_cols = 80;
diff -Nru a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile
--- a/arch/ia64/hp/common/Makefile	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/hp/common/Makefile	Mon Feb 10 10:39:31 2003
@@ -5,6 +5,4 @@
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-export-objs := sba_iommu.o
-
 obj-y := sba_iommu.o
diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
--- a/arch/ia64/hp/common/sba_iommu.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/hp/common/sba_iommu.c	Mon Feb 10 10:39:23 2003
@@ -288,20 +288,19 @@
 	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
 	uint rcnt;
 
-	/* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */
-	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
+	printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
 		 msg, rptr, pide & (BITS_PER_LONG - 1), *rptr);
 
 	rcnt = 0;
 	while (rcnt < BITS_PER_LONG) {
-		printk("%s %2d %p %016Lx\n",
-			(rcnt == (pide & (BITS_PER_LONG - 1)))
-				? "    -->" : "       ",
-			rcnt, ptr, *ptr );
+		printk(KERN_DEBUG "%s %2d %p %016Lx\n",
+		       (rcnt == (pide & (BITS_PER_LONG - 1)))
+		       ? "    -->" : "       ",
+		       rcnt, ptr, *ptr );
 		rcnt++;
 		ptr++;
 	}
-	printk("%s", msg);
+	printk(KERN_DEBUG "%s", msg);
 }
 
 
@@ -363,11 +362,9 @@
 sba_dump_sg(struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
 	while (nents-- > 0) {
-		printk(" %d : DMA %08lx/%05x CPU %p\n",
-				nents,
-				(unsigned long) sba_sg_iova(startsg),
-				sba_sg_iova_len(startsg),
-				sba_sg_address(startsg));
+		printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
+		       (unsigned long) sba_sg_iova(startsg), sba_sg_iova_len(startsg),
+		       sba_sg_address(startsg));
 		startsg++;
 	}
 }
@@ -1451,9 +1448,10 @@
 			    sba_dev->ioc[i].res_map;
 		} else {
 			u64 reserved_iov;
-			
+
 			/* Yet another 1.x hack */
-			printk("zx1 1.x: Starting resource hint offset into IOV space to avoid initial zero value IOVA\n");
+			printk(KERN_DEBUG "zx1 1.x: Starting resource hint offset into "
+			       "IOV space to avoid initial zero value IOVA\n");
 			sba_dev->ioc[i].res_hint = (unsigned long *)
 			    &(sba_dev->ioc[i].res_map[L1_CACHE_BYTES]);
 
@@ -1632,7 +1630,7 @@
 	       device->slot_name, hpa);
 
 	if ((hw_rev & 0xFF) < 0x20) {
-		printk("%s: SBA rev less than 2.0 not supported", DRIVER_NAME);
+		printk(KERN_INFO "%s: SBA rev less than 2.0 not supported", DRIVER_NAME);
 		return;
 	}
 
diff -Nru a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
--- a/arch/ia64/hp/sim/simeth.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ia64/hp/sim/simeth.c	Mon Feb 10 10:39:29 2003
@@ -1,7 +1,7 @@
 /*
  * Simulated Ethernet Driver
  *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  */
 #include <linux/config.h>
@@ -116,7 +116,7 @@
 {
 	int r;
 
-	printk("simeth: v%s\n", simeth_version);
+	printk(KERN_INFO "simeth: v%s\n", simeth_version);
 
 	r = simeth_probe1();
 
@@ -235,7 +235,8 @@
 	/* Fill in the fields of the device structure with ethernet-generic values. */
 	ether_setup(dev);
 
-	printk("%s: hosteth=%s simfd=%d, HwAddr", dev->name, simeth_device, local->simfd);
+	printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
+	       dev->name, simeth_device, local->simfd);
 	for(i = 0; i < ETH_ALEN; i++) {
 		printk(" %2.2x", dev->dev_addr[i]);
 	}
@@ -251,7 +252,7 @@
 simeth_open(struct net_device *dev)
 {
 	if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
-		printk ("simeth: unable to get IRQ %d.\n", dev->irq);
+		printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq);
 		return -EAGAIN;
 	}
 
@@ -312,11 +313,12 @@
 			if (strcmp(dev->name, ifa->ifa_label) == 0) break;
 	}
 	if ( ifa == NULL ) {
-		printk("simeth_open: can't find device %s's ifa\n", dev->name);
+		printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name);
 		return NOTIFY_DONE;
 	}
 
-	printk("simeth_device_event: %s ipaddr=0x%x\n", dev->name, htonl(ifa->ifa_local));
+	printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
+	       dev->name, htonl(ifa->ifa_local));
 
 	/*
 	 * XXX Fix me
@@ -330,7 +332,8 @@
 		netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
 		netdev_detach(local->simfd);
 
-	printk("simeth: netdev_attach/detach: event=%s ->%d\n", event == NETDEV_UP ? "attach":"detach", r);
+	printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
+	       event == NETDEV_UP ? "attach":"detach", r);
 
 	return NOTIFY_DONE;
 }
@@ -460,7 +463,8 @@
 		 */
 		len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
 		if ( len == 0 ) {
-			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", dev->name, SIMETH_RECV_MAX-rcv_count);
+			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n",
+						       dev->name, SIMETH_RECV_MAX-rcv_count);
 			break;
 		}
 #if 0
diff -Nru a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
--- a/arch/ia64/hp/sim/simscsi.c	Mon Feb 10 10:39:26 2003
+++ b/arch/ia64/hp/sim/simscsi.c	Mon Feb 10 10:39:26 2003
@@ -1,7 +1,7 @@
 /*
  * Simulated SCSI driver.
  *
- * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
+ * Copyright (C) 1999, 2001-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -87,7 +87,8 @@
 {
 	/* XXX Fix me we may need to strcpy() ? */
 	if (strlen(s) > MAX_ROOT_LEN) {
-		printk("simscsi_setup: prefix too long---using default %s\n", simscsi_root);
+		printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
+		       simscsi_root);
 	}
 	simscsi_root = s;
 	return 1;
@@ -354,7 +355,7 @@
 			break;
 
 		      case START_STOP:
-			printk("START_STOP\n");
+			printk(KERN_ERR "START_STOP\n");
 			break;
 
 		      default:
@@ -380,7 +381,7 @@
 int
 simscsi_host_reset (Scsi_Cmnd *sc)
 {
-	printk ("simscsi_host_reset: not implemented\n");
+	printk(KERN_ERR "simscsi_host_reset: not implemented\n");
 	return 0;
 }
 
diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
--- a/arch/ia64/hp/sim/simserial.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/hp/sim/simserial.c	Mon Feb 10 10:39:27 2003
@@ -7,7 +7,7 @@
  * case means sys_sim.c console (goes via the simulator). The code hereafter
  * is completely leveraged from the serial.c driver.
  *
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
@@ -195,7 +195,7 @@
 	 */
 	info = IRQ_ports[irq];
 	if (!info || !info->tty) {
-		printk("simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
+		printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
 		return;
 	}
 	/*
@@ -219,13 +219,13 @@
 static void do_serial_bh(void)
 {
 	run_task_queue(&tq_serial);
-	printk("do_serial_bh: called\n");
+	printk(KERN_ERR "do_serial_bh: called\n");
 }
 #endif
 
 static void do_softint(void *private_)
 {
-	printk("simserial: do_softint called\n");
+	printk(KERN_ERR "simserial: do_softint called\n");
 }
 
 static void rs_put_char(struct tty_struct *tty, unsigned char ch)
@@ -439,7 +439,7 @@
 {
 	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
 
-	printk("simrs_throttle called\n");
+	printk(KERN_INFO "simrs_throttle called\n");
 }
 
 static void rs_unthrottle(struct tty_struct * tty)
@@ -452,7 +452,7 @@
 		else
 			rs_send_xchar(tty, START_CHAR(tty));
 	}
-	printk("simrs_unthrottle called\n");
+	printk(KERN_INFO "simrs_unthrottle called\n");
 }
 
 /*
@@ -474,29 +474,29 @@
 
 	switch (cmd) {
 		case TIOCMGET:
-			printk("rs_ioctl: TIOCMGET called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
 			return -EINVAL;
 		case TIOCMBIS:
 		case TIOCMBIC:
 		case TIOCMSET:
-			printk("rs_ioctl: TIOCMBIS/BIC/SET called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
 			return -EINVAL;
 		case TIOCGSERIAL:
-			printk("simrs_ioctl TIOCGSERIAL called\n");
+			printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
 			return 0;
 		case TIOCSSERIAL:
-			printk("simrs_ioctl TIOCSSERIAL called\n");
+			printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n");
 			return 0;
 		case TIOCSERCONFIG:
-			printk("rs_ioctl: TIOCSERCONFIG called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n");
 			return -EINVAL;
 
 		case TIOCSERGETLSR: /* Get line status register */
-			printk("rs_ioctl: TIOCSERGETLSR called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n");
 			return  -EINVAL;
 
 		case TIOCSERGSTRUCT:
-			printk("rs_ioctl: TIOCSERGSTRUCT called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n");
 #if 0
 			if (copy_to_user((struct async_struct *) arg,
 					 info, sizeof(struct async_struct)))
@@ -511,7 +511,7 @@
 		 * Caller should use TIOCGICOUNT to see which one it was
 		 */
 		case TIOCMIWAIT:
-			printk("rs_ioctl: TIOCMIWAIT: called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
 			return 0;
 		/*
 		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -520,13 +520,13 @@
 		 *     RI where only 0->1 is counted.
 		 */
 		case TIOCGICOUNT:
-			printk("rs_ioctl: TIOCGICOUNT called\n");
+			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
 			return 0;
 
 		case TIOCSERGWILD:
 		case TIOCSERSWILD:
 			/* "setserial -W" is called in Debian boot */
-			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n");
 			return 0;
 
 		default:
@@ -596,7 +596,7 @@
 						     IRQ_T(info), "serial", NULL);
 
 				if (retval)
-					printk("serial shutdown: request_irq: error %d"
+					printk(KERN_ERR "serial shutdown: request_irq: error %d"
 					       "  Couldn't reacquire IRQ.\n", retval);
 			} else
 				free_irq(state->irq, NULL);
@@ -654,12 +654,12 @@
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		printk("rs_close: bad serial port count; tty->count is 1, "
+		printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
 		       "state->count is %d\n", state->count);
 		state->count = 1;
 	}
 	if (--state->count < 0) {
-		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
 		       info->line, state->count);
 		state->count = 0;
 	}
@@ -1013,7 +1013,7 @@
 static inline void show_serial_version(void)
 {
 	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
-	printk(" no serial options enabled\n");
+	printk(KERN_INFO " no serial options enabled\n");
 }
 
 /*
diff -Nru a/arch/ia64/hp/zx1/hpzx1_misc.c b/arch/ia64/hp/zx1/hpzx1_misc.c
--- a/arch/ia64/hp/zx1/hpzx1_misc.c	Mon Feb 10 10:39:26 2003
+++ b/arch/ia64/hp/zx1/hpzx1_misc.c	Mon Feb 10 10:39:26 2003
@@ -1,9 +1,9 @@
 /*
  * Misc. support for HP zx1 chipset support
  *
- * Copyright (C) 2002 Hewlett-Packard Co
- * Copyright (C) 2002 Alex Williamson <alex_williamson@hp.com>
- * Copyright (C) 2002 Bjorn Helgaas <bjorn_helgaas@hp.com>
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
+ *	Alex Williamson <alex_williamson@hp.com>
+ *	Bjorn Helgaas <bjorn_helgaas@hp.com>
  */
 
 
@@ -17,7 +17,7 @@
 #include <asm/dma.h>
 #include <asm/iosapic.h>
 
-extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *,
+extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, struct acpi_object_list *,
 					  unsigned long *);
 
 #define PFX "hpzx1: "
@@ -190,31 +190,31 @@
 	hpzx1_devices++;
 }
 
-typedef struct {
+struct acpi_hp_vendor_long {
 	u8	guid_id;
 	u8	guid[16];
 	u8	csr_base[8];
 	u8	csr_length[8];
-} acpi_hp_vendor_long;
+};
 
 #define HP_CCSR_LENGTH	0x21
 #define HP_CCSR_TYPE	0x2
 #define HP_CCSR_GUID	EFI_GUID(0x69e9adf9, 0x924f, 0xab5f,				\
 				 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
 
-extern acpi_status acpi_get_crs(acpi_handle, acpi_buffer *);
-extern acpi_resource *acpi_get_crs_next(acpi_buffer *, int *);
-extern acpi_resource_data *acpi_get_crs_type(acpi_buffer *, int *, int);
-extern void acpi_dispose_crs(acpi_buffer *);
+extern acpi_status acpi_get_crs(acpi_handle, struct acpi_buffer *);
+extern struct acpi_resource *acpi_get_crs_next(struct acpi_buffer *, int *);
+extern union acpi_resource_data *acpi_get_crs_type(struct acpi_buffer *, int *, int);
+extern void acpi_dispose_crs(struct acpi_buffer *);
 
 static acpi_status
 hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
 {
 	int i, offset = 0;
 	acpi_status status;
-	acpi_buffer buf;
-	acpi_resource_vendor *res;
-	acpi_hp_vendor_long *hp_res;
+	struct acpi_buffer buf;
+	struct acpi_resource_vendor *res;
+	struct acpi_hp_vendor_long *hp_res;
 	efi_guid_t vendor_guid;
 
 	*csr_base = 0;
@@ -226,14 +226,14 @@
 		return status;
 	}
 
-	res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
+	res = (struct acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
 	if (!res) {
 		printk(KERN_ERR PFX "Failed to find config space for device\n");
 		acpi_dispose_crs(&buf);
 		return AE_NOT_FOUND;
 	}
 
-	hp_res = (acpi_hp_vendor_long *)(res->reserved);
+	hp_res = (struct acpi_hp_vendor_long *)(res->reserved);
 
 	if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {
 		printk(KERN_ERR PFX "Unknown Vendor data\n");
@@ -288,7 +288,7 @@
 {
 	u64 csr_base = 0, csr_length = 0;
 	acpi_status status;
-	NATIVE_UINT busnum;
+	acpi_native_uint busnum;
 	char *name = context;
 	char fullname[32];
 
diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
--- a/arch/ia64/ia32/binfmt_elf32.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ia64/ia32/binfmt_elf32.c	Mon Feb 10 10:39:32 2003
@@ -44,7 +44,6 @@
 
 static void elf32_set_personality (void);
 
-#define ELF_PLAT_INIT(_r)		ia64_elf32_init(_r)
 #define setup_arg_pages(bprm)		ia32_setup_arg_pages(bprm)
 #define elf_map				elf32_map
 
diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
--- a/arch/ia64/ia32/ia32_entry.S	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/ia32/ia32_entry.S	Mon Feb 10 10:39:27 2003
@@ -95,12 +95,19 @@
 GLOBAL_ENTRY(ia32_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret1:
 #endif
 	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -264,7 +271,7 @@
 	data8 sys_setreuid	/* 16-bit version */	  /* 70 */
 	data8 sys_setregid	/* 16-bit version */
 	data8 sys32_sigsuspend
-	data8 sys32_sigpending
+	data8 compat_sys_sigpending
 	data8 sys_sethostname
 	data8 sys32_setrlimit	  /* 75 */
 	data8 sys32_old_getrlimit
@@ -290,8 +297,8 @@
 	data8 sys_getpriority
 	data8 sys_setpriority
 	data8 sys32_ni_syscall	  /* old profil syscall holder */
-	data8 sys32_statfs
-	data8 sys32_fstatfs	  /* 100 */
+	data8 compat_sys_statfs
+	data8 compat_sys_fstatfs	  /* 100 */
 	data8 sys32_ioperm
 	data8 sys32_socketcall
 	data8 sys_syslog
@@ -317,7 +324,7 @@
 	data8 sys32_modify_ldt
 	data8 sys32_ni_syscall	/* adjtimex */
 	data8 sys32_mprotect	  /* 125 */
-	data8 sys32_sigprocmask
+	data8 compat_sys_sigprocmask
 	data8 sys32_ni_syscall	/* create_module */
 	data8 sys32_ni_syscall	/* init_module */
 	data8 sys32_ni_syscall	/* delete_module */
diff -Nru a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
--- a/arch/ia64/ia32/ia32_ioctl.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ia64/ia32/ia32_ioctl.c	Mon Feb 10 10:39:30 2003
@@ -510,6 +510,6 @@
 			return(sg_ioctl_trans(fd, cmd, arg));
 
 	}
-	printk("%x:unimplemented IA32 ioctl system call\n", cmd);
+	printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd);
 	return -EINVAL;
 }
diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
--- a/arch/ia64/ia32/ia32_signal.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/ia32/ia32_signal.c	Mon Feb 10 10:39:23 2003
@@ -56,7 +56,7 @@
        int sig;
        struct sigcontext_ia32 sc;
        struct _fpstate_ia32 fpstate;
-       unsigned int extramask[_IA32_NSIG_WORDS-1];
+       unsigned int extramask[_COMPAT_NSIG_WORDS-1];
        char retcode[8];
 };
 
@@ -463,7 +463,7 @@
 }
 
 asmlinkage long
-ia32_rt_sigsuspend (sigset32_t *uset, unsigned int sigsetsize, struct sigscratch *scr)
+ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigscratch *scr)
 {
 	extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
 	sigset_t oldset, set;
@@ -479,13 +479,13 @@
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	{
 		oldset = current->blocked;
 		current->blocked = set;
 		recalc_sigpending();
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/*
 	 * The return below usually returns to the signal handler.  We need to pre-set the
@@ -504,7 +504,7 @@
 asmlinkage long
 ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
 {
-	return ia32_rt_sigsuspend((sigset32_t *)&mask, sizeof(mask), scr);
+	return ia32_rt_sigsuspend((compat_sigset_t *)&mask, sizeof(mask), scr);
 }
 
 asmlinkage long
@@ -530,14 +530,14 @@
 	int ret;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset32_t))
+	if (sigsetsize != sizeof(compat_sigset_t))
 		return -EINVAL;
 
 	if (act) {
 		ret = get_user(handler, &act->sa_handler);
 		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
 		ret |= get_user(restorer, &act->sa_restorer);
-		ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(sigset32_t));
+		ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
 		if (ret)
 			return -EFAULT;
 
@@ -550,7 +550,7 @@
 		ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
 		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
-		ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset32_t));
+		ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
 	}
 	return ret;
 }
@@ -560,7 +560,7 @@
 					   size_t sigsetsize);
 
 asmlinkage long
-sys32_rt_sigprocmask (int how, sigset32_t *set, sigset32_t *oset, unsigned int sigsetsize)
+sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize)
 {
 	mm_segment_t old_fs = get_fs();
 	sigset_t s;
@@ -587,13 +587,7 @@
 }
 
 asmlinkage long
-sys32_sigprocmask (int how, unsigned int *set, unsigned int *oset)
-{
-	return sys32_rt_sigprocmask(how, (sigset32_t *) set, (sigset32_t *) oset, sizeof(*set));
-}
-
-asmlinkage long
-sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo,
+sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo,
 		struct compat_timespec *uts, unsigned int sigsetsize)
 {
 	extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *,
@@ -605,16 +599,13 @@
 	sigset_t s;
 	int ret;
 
-	if (copy_from_user(&s.sig, uthese, sizeof(sigset32_t)))
+	if (copy_from_user(&s.sig, uthese, sizeof(compat_sigset_t)))
+		return -EFAULT;
+	if (uts && get_compat_timespec(&t, uts))
 		return -EFAULT;
-	if (uts) {
-		ret = get_user(t.tv_sec, &uts->tv_sec);
-		ret |= get_user(t.tv_nsec, &uts->tv_nsec);
-		if (ret)
-			return -EFAULT;
-	}
 	set_fs(KERNEL_DS);
-	ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
+	ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
+			sigsetsize);
 	set_fs(old_fs);
 	if (ret >= 0 && uinfo) {
 		if (copy_siginfo_to_user32(uinfo, &info))
@@ -648,7 +639,7 @@
 	int ret;
 
 	if (act) {
-		old_sigset32_t mask;
+		compat_old_sigset_t mask;
 
 		ret = get_user(handler, &act->sa_handler);
 		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
@@ -866,7 +857,7 @@
 
 	err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
 
-	if (_IA32_NSIG_WORDS > 1)
+	if (_COMPAT_NSIG_WORDS > 1)
 		err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
 				      sizeof(frame->extramask));
 
@@ -1011,15 +1002,15 @@
 		goto badframe;
 
 	if (__get_user(set.sig[0], &frame->sc.oldmask)
-	    || (_IA32_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
+	    || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
 							 sizeof(frame->extramask))))
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = (sigset_t) set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext_ia32(regs, &frame->sc, &eax))
 		goto badframe;
@@ -1047,10 +1038,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked =  set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
 		goto badframe;
diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
--- a/arch/ia64/ia32/ia32_support.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/ia32/ia32_support.c	Mon Feb 10 10:39:23 2003
@@ -95,8 +95,6 @@
 	struct pt_regs *regs = ia64_task_regs(t);
 	int nr = smp_processor_id();	/* LDT and TSS depend on CPU number: */
 
-	nr = smp_processor_id();
-
 	eflag = t->thread.eflag;
 	fsr = t->thread.fsr;
 	fcr = t->thread.fcr;
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ia64/ia32/sys_ia32.c	Mon Feb 10 10:39:29 2003
@@ -6,7 +6,7 @@
  * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
  * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 2000-2002 Hewlett-Packard Co
+ * Copyright (C) 2000-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * These routines maintain argument size conversion between 32bit and 64bit
@@ -609,61 +609,6 @@
 	return retval;
 }
 
-static inline int
-put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
-		return -EFAULT;
-
-	err = __put_user(kbuf->f_type, &ubuf->f_type);
-	err |= __put_user(kbuf->f_bsize, &ubuf->f_bsize);
-	err |= __put_user(kbuf->f_blocks, &ubuf->f_blocks);
-	err |= __put_user(kbuf->f_bfree, &ubuf->f_bfree);
-	err |= __put_user(kbuf->f_bavail, &ubuf->f_bavail);
-	err |= __put_user(kbuf->f_files, &ubuf->f_files);
-	err |= __put_user(kbuf->f_ffree, &ubuf->f_ffree);
-	err |= __put_user(kbuf->f_namelen, &ubuf->f_namelen);
-	err |= __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
-	err |= __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
-	return err;
-}
-
-extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
-
-asmlinkage long
-sys32_statfs (const char *path, struct statfs32 *buf)
-{
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_statfs(path, &s);
-	set_fs(old_fs);
-	if (put_statfs(buf, &s))
-		return -EFAULT;
-	return ret;
-}
-
-extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
-
-asmlinkage long
-sys32_fstatfs (unsigned int fd, struct statfs32 *buf)
-{
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_fstatfs(fd, &s);
-	set_fs(old_fs);
-	if (put_statfs(buf, &s))
-		return -EFAULT;
-	return ret;
-}
-
 static inline long
 get_tv32 (struct timeval *o, struct compat_timeval *i)
 {
@@ -1849,10 +1794,10 @@
 
 struct ipc64_perm32 {
 	key_t key;
-	__kernel_uid32_t32 uid;
-	__kernel_gid32_t32 gid;
-	__kernel_uid32_t32 cuid;
-	__kernel_gid32_t32 cgid;
+	compat_uid32_t uid;
+	compat_gid32_t gid;
+	compat_uid32_t cuid;
+	compat_gid32_t cgid;
 	compat_mode_t mode;
 	unsigned short __pad1;
 	unsigned short seq;
@@ -1895,8 +1840,8 @@
 	unsigned short msg_cbytes;
 	unsigned short msg_qnum;
 	unsigned short msg_qbytes;
-	__kernel_ipc_pid_t32 msg_lspid;
-	__kernel_ipc_pid_t32 msg_lrpid;
+	compat_ipc_pid_t msg_lspid;
+	compat_ipc_pid_t msg_lrpid;
 };
 
 struct msqid64_ds32 {
@@ -1922,8 +1867,8 @@
 	compat_time_t   shm_atime;
 	compat_time_t   shm_dtime;
 	compat_time_t   shm_ctime;
-	__kernel_ipc_pid_t32 shm_cpid;
-	__kernel_ipc_pid_t32 shm_lpid;
+	compat_ipc_pid_t shm_cpid;
+	compat_ipc_pid_t shm_lpid;
 	unsigned short shm_nattch;
 };
 
@@ -2011,6 +1956,10 @@
 	else
 		fourth.__pad = (void *)A(pad);
 	switch (third) {
+	      default:
+		err = -EINVAL;
+		break;
+
 	      case IPC_INFO:
 	      case IPC_RMID:
 	      case IPC_SET:
@@ -2399,7 +2348,7 @@
 
 static long
 semtimedop32(int semid, struct sembuf *tsems, int nsems,
-	     const struct timespec32 *timeout32)
+	     const struct compat_timespec *timeout32)
 {
 	struct timespec t;
 	if (get_user (t.tv_sec, &timeout32->tv_sec) ||
@@ -2422,7 +2371,7 @@
 		return sys_semtimedop(first, (struct sembuf *)AA(ptr), second, NULL);
 	      case SEMTIMEDOP:
 		return semtimedop32(first, (struct sembuf *)AA(ptr), second,
-				    (const struct timespec32 *)AA(fifth));
+				    (const struct compat_timespec *)AA(fifth));
 	      case SEMGET:
 		return sys_semget(first, second, third);
 	      case SEMCTL:
@@ -3475,12 +3424,6 @@
 	return ret;
 }
 
-asmlinkage long
-sys32_sigpending (unsigned int *set)
-{
-	return do_sigpending(set, sizeof(*set));
-}
-
 struct sysinfo32 {
 	s32 uptime;
 	u32 loads[3];
@@ -3536,7 +3479,7 @@
 	set_fs(KERNEL_DS);
 	ret = sys_sched_rr_get_interval(pid, &t);
 	set_fs(old_fs);
-	if (put_user (t.tv_sec, &interval->tv_sec) || put_user (t.tv_nsec, &interval->tv_nsec))
+	if (put_compat_timespec(&t, interval))
 		return -EFAULT;
 	return ret;
 }
diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/Makefile	Mon Feb 10 10:39:33 2003
@@ -4,14 +4,13 @@
 
 EXTRA_TARGETS	:= head.o init_task.o
 
-export-objs := ia64_ksyms.o
-
 obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o \
 	 irq.o irq_ia64.o irq_lsapic.o ivt.o \
 	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o \
 	 semaphore.o setup.o	\
 	 signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
 
+obj-$(CONFIG_FSYS) += fsys.o
 obj-$(CONFIG_IOSAPIC) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/acpi.c	Mon Feb 10 10:39:27 2003
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1999 VA Linux Systems
  *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
+ *  Copyright (C) 2000, 2002-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *  Copyright (C) 2000 Intel Corp.
  *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
@@ -75,20 +75,20 @@
 
 	rsdp_phys = acpi_find_rsdp();
 	if (!rsdp_phys) {
-		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
 		return "dig";
 	}
 
 	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
 	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
-		printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
 		return "dig";
 	}
 
 	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
 	hdr = &xsdt->header;
 	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
-		printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
 		return "dig";
 	}
 
@@ -128,7 +128,7 @@
  * with a list of acpi_resource structures.
  */
 acpi_status
-acpi_get_crs (acpi_handle obj, acpi_buffer *buf)
+acpi_get_crs (acpi_handle obj, struct acpi_buffer *buf)
 {
 	acpi_status result;
 	buf->length = 0;
@@ -144,10 +144,10 @@
 	return acpi_get_current_resources(obj, buf);
 }
 
-acpi_resource *
-acpi_get_crs_next (acpi_buffer *buf, int *offset)
+struct acpi_resource *
+acpi_get_crs_next (struct acpi_buffer *buf, int *offset)
 {
-	acpi_resource *res;
+	struct acpi_resource *res;
 
 	if (*offset >= buf->length)
 		return NULL;
@@ -157,11 +157,11 @@
 	return res;
 }
 
-acpi_resource_data *
-acpi_get_crs_type (acpi_buffer *buf, int *offset, int type)
+union acpi_resource_data *
+acpi_get_crs_type (struct acpi_buffer *buf, int *offset, int type)
 {
 	for (;;) {
-		acpi_resource *res = acpi_get_crs_next(buf, offset);
+		struct acpi_resource *res = acpi_get_crs_next(buf, offset);
 		if (!res)
 			return NULL;
 		if (res->id == type)
@@ -170,7 +170,7 @@
 }
 
 void
-acpi_dispose_crs (acpi_buffer *buf)
+acpi_dispose_crs (struct acpi_buffer *buf)
 {
 	kfree(buf->pointer);
 }
@@ -199,7 +199,7 @@
 		/* correctable platform error interrupt */
 		vector = platform_intr_list[int_type];
 	} else
-		printk("acpi_request_vector(): invalid interrupt type\n");
+		printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
 	return vector;
 }
 
@@ -249,7 +249,7 @@
 
 	acpi_table_print_madt_entry(header);
 
-	printk("CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
+	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
 
 	if (lsapic->flags.enabled) {
 		available_cpus++;
@@ -478,8 +478,8 @@
 	len = sizeof(struct acpi_table_header) + 8
 		+ slit->localities * slit->localities;
 	if (slit->header.length != len) {
-		printk("ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
-		      len, slit->header.length);
+		printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
+		       len, slit->header.length);
 		memset(numa_slit, 10, sizeof(numa_slit));
 		return;
 	}
@@ -514,8 +514,8 @@
 	size = (size << 32) | ma->length_lo;
 
 	if (num_memblks >= NR_MEMBLKS) {
-		printk("Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
-			size/(1024*1024), paddr);
+		printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
+		       size/(1024*1024), paddr);
 		return;
 	}
 
@@ -545,8 +545,8 @@
 
 	if (min_hole_size) {
 		if (min_hole_size > size) {
-			printk("Too huge memory hole. Ignoring %ld MBytes at %lx\n",
-				size/(1024*1024), paddr);
+			printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
+			       size/(1024*1024), paddr);
 			return;
 		}
 	}
@@ -605,8 +605,8 @@
 	for (i = 0; i < srat_num_cpus; i++)
 		node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
 
-	printk("Number of logical nodes in system = %d\n", numnodes);
-	printk("Number of memory chunks in system = %d\n", num_memblks);
+	printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
+	printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks);
 
 	if (!slit_table) return;
 	memset(numa_slit, -1, sizeof(numa_slit));
@@ -638,7 +638,7 @@
 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
 {
 	struct acpi_table_header *fadt_header;
-	fadt_descriptor_rev2 *fadt;
+	struct fadt_descriptor_rev2 *fadt;
 	u32 sci_irq, gsi_base;
 	char *iosapic_address;
 
@@ -649,7 +649,7 @@
 	if (fadt_header->revision != 3)
 		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */
 
-	fadt = (fadt_descriptor_rev2 *) fadt_header;
+	fadt = (struct fadt_descriptor_rev2 *) fadt_header;
 
 	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
 		acpi_kbd_controller_present = 0;
@@ -806,7 +806,7 @@
 
 #ifdef CONFIG_SMP
 	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
+		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
 	smp_boot_data.cpu_count = total_cpus;
@@ -817,7 +817,7 @@
 #endif
 #endif
 	/* Make boot-up look pretty */
-	printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 	return 0;
 }
 
@@ -886,6 +886,28 @@
 		return isa_irq_to_vector(irq);
 
 	return gsi_to_vector(irq);
+}
+
+int __init
+acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
+{
+	int vector = 0;
+	u32 irq_base;
+	char *iosapic_address;
+
+	if (acpi_madt->flags.pcat_compat && (gsi < 16))
+		return isa_irq_to_vector(gsi);
+
+	if (!iosapic_register_intr)
+		return 0;
+
+	/* Find the IOSAPIC */
+	if (!acpi_find_iosapic(gsi, &irq_base, &iosapic_address)) {
+		/* Turn it on */
+		vector = iosapic_register_intr (gsi, polarity, trigger,
+						irq_base, iosapic_address);
+	}
+	return vector;
 }
 
 #endif /* CONFIG_ACPI_BOOT */
diff -Nru a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c
--- a/arch/ia64/kernel/brl_emu.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ia64/kernel/brl_emu.c	Mon Feb 10 10:39:30 2003
@@ -195,7 +195,7 @@
 		/*
 		 *  The target address contains unimplemented bits.
 		 */
-		printk("Woah! Unimplemented Instruction Address Trap!\n");
+		printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n");
 		siginfo.si_signo = SIGILL;
 		siginfo.si_errno = 0;
 		siginfo.si_flags = 0;
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/kernel/efi.c	Mon Feb 10 10:39:23 2003
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -33,15 +33,6 @@
 
 #define EFI_DEBUG	0
 
-#ifdef CONFIG_HUGETLB_PAGE
-
-/* By default at total of 512MB is reserved huge pages. */
-#define HTLBZONE_SIZE_DEFAULT  0x20000000
-
-unsigned long htlbzone_pages = (HTLBZONE_SIZE_DEFAULT >> HPAGE_SHIFT);
-
-#endif
-
 extern efi_status_t efi_call_phys (void *, ...);
 
 struct efi efi;
@@ -374,7 +365,7 @@
 				prev_valid = 1;
 			} else {
 				if (curr.start < prev.start)
-					printk("Oops: EFI memory table not ordered!\n");
+					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
 
 				if (prev.end == curr.start) {
 					/* merge two consecutive memory ranges */
@@ -446,7 +437,8 @@
 		 * dedicated ITR for the PAL code.
 		 */
 		if ((vaddr & mask) == (KERNEL_START & mask)) {
-			printk("%s: no need to install ITR for PAL code\n", __FUNCTION__);
+			printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
+			       __FUNCTION__);
 			continue;
 		}
 
@@ -454,7 +446,7 @@
 			panic("Woah!  PAL code size bigger than a granule!");
 
 		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
-		printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
+		printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
 		       smp_processor_id(), md->phys_addr,
 		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
@@ -497,27 +489,8 @@
 				++cp;
 		}
 	}
-#ifdef CONFIG_HUGETLB_PAGE
-	/* Just duplicating the above algo for lpzone start */
-	for (cp = saved_command_line; *cp; ) {
-		if (memcmp(cp, "lpmem=", 6) == 0) {
-			cp += 6;
-			htlbzone_pages = memparse(cp, &end);
-			htlbzone_pages = (htlbzone_pages >> HPAGE_SHIFT);
-			if (end != cp)
-				break;
-			cp = end;
-		} else {
-			while (*cp != ' ' && *cp)
-				++cp;
-			while (*cp == ' ')
-				++cp;
-		}
-	}
-	printk("Total HugeTLB_Page memory pages requested  0x%lx \n", htlbzone_pages);
-#endif
 	if (mem_limit != ~0UL)
-		printk("Ignoring memory above %luMB\n", mem_limit >> 20);
+		printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20);
 
 	efi.systab = __va(ia64_boot_param->efi_systab);
 
@@ -529,7 +502,7 @@
 	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
 		panic("Woah! EFI system table signature incorrect\n");
 	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
-		printk("Warning: EFI system table major version mismatch: "
+		printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
 		       "got %d.%02d, expected %d.%02d\n",
 		       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
 		       EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
@@ -544,7 +517,7 @@
 		vendor[i] = '\0';
 	}
 
-	printk("EFI v%u.%.02u by %s:",
+	printk(KERN_INFO "EFI v%u.%.02u by %s:",
 	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
 
 	for (i = 0; i < efi.systab->nr_tables; i++) {
@@ -636,7 +609,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WC mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			} else if (md->attribute & EFI_MEMORY_WT) {
@@ -646,7 +619,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WT mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			}
@@ -658,7 +631,8 @@
 			       efi_desc_size, ia64_boot_param->efi_memdesc_version,
 			       ia64_boot_param->efi_memmap);
 	if (status != EFI_SUCCESS) {
-		printk("Warning: unable to switch EFI into virtual mode (status=%lu)\n", status);
+		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode "
+		       "(status=%lu)\n", status);
 		return;
 	}
 
diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/kernel/entry.S	Mon Feb 10 10:39:24 2003
@@ -3,7 +3,7 @@
  *
  * Kernel entry points.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -22,8 +22,8 @@
 /*
  * Global (preserved) predicate usage on syscall entry/exit path:
  *
- *	pKern:		See entry.h.
- *	pUser:		See entry.h.
+ *	pKStk:		See entry.h.
+ *	pUStk:		See entry.h.
  *	pSys:		See entry.h.
  *	pNonSys:	!pSys
  */
@@ -63,7 +63,7 @@
 	sxt4 r8=r8			// return 64-bit result
 	;;
 	stf.spill [sp]=f0
-(p6)	cmp.ne pKern,pUser=r0,r0	// a successful execve() lands us in user-mode...
+(p6)	cmp.ne pKStk,pUStk=r0,r0	// a successful execve() lands us in user-mode...
 	mov rp=loc0
 (p6)	mov ar.pfs=r0			// clear ar.pfs on success
 (p7)	br.ret.sptk.many rp
@@ -193,7 +193,7 @@
 	;;
 (p6)	srlz.d
 	ld8 sp=[r21]			// load kernel stack pointer of new task
-	mov IA64_KR(CURRENT)=r20	// update "current" application register
+	mov IA64_KR(CURRENT)=in0	// update "current" application register
 	mov r8=r13			// return pointer to previously running task
 	mov r13=in0			// set "current" pointer
 	;;
@@ -507,7 +507,14 @@
 
 GLOBAL_ENTRY(ia64_trace_syscall)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args
+}
 .ret6:	br.call.sptk.many rp=b6			// do the syscall
 strace_check_retval:
 	cmp.lt p6,p0=r8,r0			// syscall failed?
@@ -537,12 +544,19 @@
 
 GLOBAL_ENTRY(ia64_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to() after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret8:
 	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
@@ -569,11 +583,12 @@
 	// fall through
 GLOBAL_ENTRY(ia64_leave_kernel)
 	PT_REGS_UNWIND_INFO(0)
-	// work.need_resched etc. mustn't get changed by this CPU before it returns to userspace:
-(pUser)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUser
-(pUser)	rsm psr.i
+	// work.need_resched etc. mustn't get changed by this CPU before it returns to
+	// user- or fsys-mode:
+(pUStk)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUStk
+(pUStk)	rsm psr.i
 	;;
-(pUser)	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
+(pUStk)	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
 .work_processed:
 (p6)	ld4 r18=[r17]				// load current_thread_info()->flags
@@ -635,9 +650,9 @@
 	;;
 	srlz.i			// ensure interruption collection is off
 	mov b7=r15
+	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
 	;;
-	bsw.0			// switch back to bank 0
-	;;
+(pUStk)	mov r18=IA64_KR(CURRENT)	// Itanium 2: 12 cycle read latency
 	adds r16=16,r12
 	adds r17=24,r12
 	;;
@@ -665,16 +680,21 @@
 	;;
 	ld8.fill r12=[r16],16
 	ld8.fill r13=[r17],16
+(pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
 	;;
 	ld8.fill r14=[r16]
 	ld8.fill r15=[r17]
+(pUStk)	mov r17=1
+	;;
+(pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
 	shr.u r18=r19,16	// get byte size of existing "dirty" partition
 	;;
 	mov r16=ar.bsp		// get existing backing store pointer
 	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
 	;;
 	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
-(pKern)	br.cond.dpnt skip_rbs_switch
+(pKStk)	br.cond.dpnt skip_rbs_switch
+
 	/*
 	 * Restore user backing store.
 	 *
@@ -710,21 +730,9 @@
 	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
 	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
 	;;
-#if 1
-	.align 32		// see comment below about gas bug...
-#endif
 	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
 	shladd in0=loc1,3,r17
 	mov in1=0
-#if 0
-	// gas-2.12.90 is unable to generate a stop bit after .align, which is bad,
-	// because alloc must be at the beginning of an insn-group.
-	.align 32
-#else
-	nop 0
-	nop 0
-	nop 0
-#endif
 	;;
 rse_clear_invalid:
 #ifdef CONFIG_ITANIUM
@@ -788,12 +796,12 @@
 skip_rbs_switch:
 	mov b6=rB6
 	mov ar.pfs=rARPFS
-(pUser)	mov ar.bspstore=rARBSPSTORE
+(pUStk)	mov ar.bspstore=rARBSPSTORE
 (p9)	mov cr.ifs=rCRIFS
 	mov cr.ipsr=rCRIPSR
 	mov cr.iip=rCRIIP
 	;;
-(pUser)	mov ar.rnat=rARRNAT	// must happen with RSE in lazy mode
+(pUStk)	mov ar.rnat=rARRNAT	// must happen with RSE in lazy mode
 	mov ar.rsc=rARRSC
 	mov ar.unat=rARUNAT
 	mov pr=rARPR,-1
@@ -963,17 +971,16 @@
 END(sys_rt_sigreturn)
 
 GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
-	//
-	// r16 = fake ar.pfs, we simply need to make sure
-	// privilege is still 0
-	//
-	mov r16=r0
 	.prologue
+	/*
+	 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
+	 */
+	mov r16=r0
 	DO_SAVE_SWITCH_STACK
-	br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt
+	br.call.sptk.many rp=ia64_handle_unaligned	// stack frame setup in ivt
 .ret21:	.body
 	DO_LOAD_SWITCH_STACK
-	br.cond.sptk.many rp			  // goes to ia64_leave_kernel
+	br.cond.sptk.many rp				// goes to ia64_leave_kernel
 END(ia64_prepare_handle_unaligned)
 
 	//
@@ -1235,8 +1242,8 @@
 	data8 sys_sched_setaffinity
 	data8 sys_sched_getaffinity
 	data8 sys_set_tid_address
-	data8 ia64_ni_syscall 		// available. (was sys_alloc_hugepages)
-	data8 ia64_ni_syscall		// available (was sys_free_hugepages)
+	data8 ia64_ni_syscall
+	data8 ia64_ni_syscall 			// 1235
 	data8 sys_exit_group
 	data8 sys_lookup_dcookie
 	data8 sys_io_setup
diff -Nru a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
--- a/arch/ia64/kernel/entry.h	Mon Feb 10 10:39:25 2003
+++ b/arch/ia64/kernel/entry.h	Mon Feb 10 10:39:25 2003
@@ -4,8 +4,8 @@
  * Preserved registers that are shared between code in ivt.S and entry.S.  Be
  * careful not to step on these!
  */
-#define pKern		p2	/* will leave_kernel return to kernel-mode? */
-#define pUser		p3	/* will leave_kernel return to user-mode? */
+#define pKStk		p2	/* will leave_kernel return to kernel-stacks? */
+#define pUStk		p3	/* will leave_kernel return to user-stacks? */
 #define pSys		p4	/* are we processing a (synchronous) system call? */
 #define pNonSys		p5	/* complement of pSys */
 
diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/fsys.S	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,384 @@
+/*
+ * This file contains the light-weight system call handlers (fsyscall-handlers).
+ *
+ * Copyright (C) 2003 Hewlett-Packard Co
+ * 	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/errno.h>
+#include <asm/offsets.h>
+#include <asm/thread_info.h>
+
+/*
+ * See Documentation/ia64/fsys.txt for details on fsyscalls.
+ *
+ * On entry to an fsyscall handler:
+ *   r10	= 0 (i.e., defaults to "successful syscall return")
+ *   r11	= saved ar.pfs (a user-level value)
+ *   r15	= system call number
+ *   r16	= "current" task pointer (in normal kernel-mode, this is in r13)
+ *   r32-r39	= system call arguments
+ *   b6		= return address (a user-level value)
+ *   ar.pfs	= previous frame-state (a user-level value)
+ *   PSR.be	= cleared to zero (i.e., little-endian byte order is in effect)
+ *   all other registers may contain values passed in from user-mode
+ *
+ * On return from an fsyscall handler:
+ *   r11	= saved ar.pfs (as passed into the fsyscall handler)
+ *   r15	= system call number (as passed into the fsyscall handler)
+ *   r32-r39	= system call arguments (as passed into the fsyscall handler)
+ *   b6		= return address (as passed into the fsyscall handler)
+ *   ar.pfs	= previous frame-state (as passed into the fsyscall handler)
+ */
+
+ENTRY(fsys_ni_syscall)
+	mov r8=ENOSYS
+	mov r10=-1
+	MCKINLEY_E9_WORKAROUND
+	br.ret.sptk.many b6
+END(fsys_ni_syscall)
+
+ENTRY(fsys_getpid)
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
+	;;
+	ld4 r9=[r9]
+	add r8=IA64_TASK_TGID_OFFSET,r16
+	;;
+	and r9=TIF_ALLWORK_MASK,r9
+	ld4 r8=[r8]				// r8 = current->tgid
+	;;
+	cmp.ne p8,p0=0,r9
+(p8)	br.spnt.many fsys_fallback_syscall
+	MCKINLEY_E9_WORKAROUND
+	br.ret.sptk.many b6
+END(fsys_getpid)
+
+ENTRY(fsys_getppid)
+	add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
+	;;
+	ld8 r17=[r17]				// r17 = current->group_leader
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
+	;;
+
+	ld4 r9=[r9]
+	add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = &current->group_leader->real_parent
+	;;
+	and r9=TIF_ALLWORK_MASK,r9
+
+1:	ld8 r18=[r17]				// r18 = current->group_leader->real_parent
+	;;
+	cmp.ne p8,p0=0,r9
+	add r8=IA64_TASK_TGID_OFFSET,r18	// r8 = &current->group_leader->real_parent->tgid
+	;;
+
+	/*
+	 * The .acq is needed to ensure that the read of tgid has returned its data before
+	 * we re-check "real_parent".
+	 */
+	ld4.acq r8=[r8]				// r8 = current->group_leader->real_parent->tgid
+#ifdef CONFIG_SMP
+	/*
+	 * Re-read current->group_leader->real_parent.
+	 */
+	ld8 r19=[r17]				// r19 = current->group_leader->real_parent
+(p8)	br.spnt.many fsys_fallback_syscall
+	;;
+	cmp.ne p6,p0=r18,r19			// did real_parent change?
+	mov r19=0			// i must not leak kernel bits...
+(p6)	br.cond.spnt.few 1b			// yes -> redo the read of tgid and the check
+	;;
+	mov r17=0			// i must not leak kernel bits...
+	mov r18=0			// i must not leak kernel bits...
+#else
+	mov r17=0			// i must not leak kernel bits...
+	mov r18=0			// i must not leak kernel bits...
+	mov r19=0			// i must not leak kernel bits...
+#endif
+	MCKINLEY_E9_WORKAROUND
+	br.ret.sptk.many b6
+END(fsys_getppid)
+
+ENTRY(fsys_set_tid_address)
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
+	;;
+	ld4 r9=[r9]
+	tnat.z p6,p7=r32		// check argument register for being NaT
+	;;
+	and r9=TIF_ALLWORK_MASK,r9
+	add r8=IA64_TASK_PID_OFFSET,r16
+	add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16
+	;;
+	ld4 r8=[r8]
+	cmp.ne p8,p0=0,r9
+	mov r17=-1
+	;;
+(p6)	st8 [r18]=r32
+(p7)	st8 [r18]=r17
+(p8)	br.spnt.many fsys_fallback_syscall
+	;;
+	mov r17=0			// i must not leak kernel bits...
+	mov r18=0			// i must not leak kernel bits...
+	MCKINLEY_E9_WORKAROUND
+	br.ret.sptk.many b6
+END(fsys_set_tid_address)
+
+	.rodata
+	.align 8
+	.globl fsyscall_table
+fsyscall_table:
+	data8 fsys_ni_syscall
+	data8 fsys_fallback_syscall	// exit			// 1025
+	data8 fsys_fallback_syscall	// read
+	data8 fsys_fallback_syscall	// write
+	data8 fsys_fallback_syscall	// open
+	data8 fsys_fallback_syscall	// close
+	data8 fsys_fallback_syscall	// creat		// 1030
+	data8 fsys_fallback_syscall	// link
+	data8 fsys_fallback_syscall	// unlink
+	data8 fsys_fallback_syscall	// execve
+	data8 fsys_fallback_syscall	// chdir
+	data8 fsys_fallback_syscall	// fchdir		// 1035
+	data8 fsys_fallback_syscall	// utimes
+	data8 fsys_fallback_syscall	// mknod
+	data8 fsys_fallback_syscall	// chmod
+	data8 fsys_fallback_syscall	// chown
+	data8 fsys_fallback_syscall	// lseek		// 1040
+	data8 fsys_getpid
+	data8 fsys_getppid		// getppid
+	data8 fsys_fallback_syscall	// mount
+	data8 fsys_fallback_syscall	// umount
+	data8 fsys_fallback_syscall	// setuid		// 1045
+	data8 fsys_fallback_syscall	// getuid
+	data8 fsys_fallback_syscall	// geteuid
+	data8 fsys_fallback_syscall	// ptrace
+	data8 fsys_fallback_syscall	// access
+	data8 fsys_fallback_syscall	// sync			// 1050
+	data8 fsys_fallback_syscall	// fsync
+	data8 fsys_fallback_syscall	// fdatasync
+	data8 fsys_fallback_syscall	// kill
+	data8 fsys_fallback_syscall	// rename
+	data8 fsys_fallback_syscall	// mkdir		// 1055
+	data8 fsys_fallback_syscall	// rmdir
+	data8 fsys_fallback_syscall	// dup
+	data8 fsys_fallback_syscall	// pipe
+	data8 fsys_fallback_syscall	// times
+	data8 fsys_fallback_syscall	// brk			// 1060
+	data8 fsys_fallback_syscall	// setgid
+	data8 fsys_fallback_syscall	// getgid
+	data8 fsys_fallback_syscall	// getegid
+	data8 fsys_fallback_syscall	// acct
+	data8 fsys_fallback_syscall	// ioctl		// 1065
+	data8 fsys_fallback_syscall	// fcntl
+	data8 fsys_fallback_syscall	// umask
+	data8 fsys_fallback_syscall	// chroot
+	data8 fsys_fallback_syscall	// ustat
+	data8 fsys_fallback_syscall	// dup2			// 1070
+	data8 fsys_fallback_syscall	// setreuid
+	data8 fsys_fallback_syscall	// setregid
+	data8 fsys_fallback_syscall	// getresuid
+	data8 fsys_fallback_syscall	// setresuid
+	data8 fsys_fallback_syscall	// getresgid		// 1075
+	data8 fsys_fallback_syscall	// setresgid
+	data8 fsys_fallback_syscall	// getgroups
+	data8 fsys_fallback_syscall	// setgroups
+	data8 fsys_fallback_syscall	// getpgid
+	data8 fsys_fallback_syscall	// setpgid		// 1080
+	data8 fsys_fallback_syscall	// setsid
+	data8 fsys_fallback_syscall	// getsid
+	data8 fsys_fallback_syscall	// sethostname
+	data8 fsys_fallback_syscall	// setrlimit
+	data8 fsys_fallback_syscall	// getrlimit		// 1085
+	data8 fsys_fallback_syscall	// getrusage
+	data8 fsys_fallback_syscall	// gettimeofday
+	data8 fsys_fallback_syscall	// settimeofday
+	data8 fsys_fallback_syscall	// select
+	data8 fsys_fallback_syscall	// poll			// 1090
+	data8 fsys_fallback_syscall	// symlink
+	data8 fsys_fallback_syscall	// readlink
+	data8 fsys_fallback_syscall	// uselib
+	data8 fsys_fallback_syscall	// swapon
+	data8 fsys_fallback_syscall	// swapoff		// 1095
+	data8 fsys_fallback_syscall	// reboot
+	data8 fsys_fallback_syscall	// truncate
+	data8 fsys_fallback_syscall	// ftruncate
+	data8 fsys_fallback_syscall	// fchmod
+	data8 fsys_fallback_syscall	// fchown		// 1100
+	data8 fsys_fallback_syscall	// getpriority
+	data8 fsys_fallback_syscall	// setpriority
+	data8 fsys_fallback_syscall	// statfs
+	data8 fsys_fallback_syscall	// fstatfs
+	data8 fsys_fallback_syscall	// gettid		// 1105
+	data8 fsys_fallback_syscall	// semget
+	data8 fsys_fallback_syscall	// semop
+	data8 fsys_fallback_syscall	// semctl
+	data8 fsys_fallback_syscall	// msgget
+	data8 fsys_fallback_syscall	// msgsnd		// 1110
+	data8 fsys_fallback_syscall	// msgrcv
+	data8 fsys_fallback_syscall	// msgctl
+	data8 fsys_fallback_syscall	// shmget
+	data8 fsys_fallback_syscall	// shmat
+	data8 fsys_fallback_syscall	// shmdt		// 1115
+	data8 fsys_fallback_syscall	// shmctl
+	data8 fsys_fallback_syscall	// syslog
+	data8 fsys_fallback_syscall	// setitimer
+	data8 fsys_fallback_syscall	// getitimer
+	data8 fsys_fallback_syscall		 		// 1120
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall	// vhangup
+	data8 fsys_fallback_syscall	// lchown
+	data8 fsys_fallback_syscall	// remap_file_pages	// 1125
+	data8 fsys_fallback_syscall	// wait4
+	data8 fsys_fallback_syscall	// sysinfo
+	data8 fsys_fallback_syscall	// clone
+	data8 fsys_fallback_syscall	// setdomainname
+	data8 fsys_fallback_syscall	// newuname		// 1130
+	data8 fsys_fallback_syscall	// adjtimex
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall	// init_module
+	data8 fsys_fallback_syscall	// delete_module
+	data8 fsys_fallback_syscall				// 1135
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall	// quotactl
+	data8 fsys_fallback_syscall	// bdflush
+	data8 fsys_fallback_syscall	// sysfs
+	data8 fsys_fallback_syscall	// personality		// 1140
+	data8 fsys_fallback_syscall	// afs_syscall
+	data8 fsys_fallback_syscall	// setfsuid
+	data8 fsys_fallback_syscall	// setfsgid
+	data8 fsys_fallback_syscall	// getdents
+	data8 fsys_fallback_syscall	// flock		// 1145
+	data8 fsys_fallback_syscall	// readv
+	data8 fsys_fallback_syscall	// writev
+	data8 fsys_fallback_syscall	// pread64
+	data8 fsys_fallback_syscall	// pwrite64
+	data8 fsys_fallback_syscall	// sysctl		// 1150
+	data8 fsys_fallback_syscall	// mmap
+	data8 fsys_fallback_syscall	// munmap
+	data8 fsys_fallback_syscall	// mlock
+	data8 fsys_fallback_syscall	// mlockall
+	data8 fsys_fallback_syscall	// mprotect		// 1155
+	data8 fsys_fallback_syscall	// mremap
+	data8 fsys_fallback_syscall	// msync
+	data8 fsys_fallback_syscall	// munlock
+	data8 fsys_fallback_syscall	// munlockall
+	data8 fsys_fallback_syscall	// sched_getparam	// 1160
+	data8 fsys_fallback_syscall	// sched_setparam
+	data8 fsys_fallback_syscall	// sched_getscheduler
+	data8 fsys_fallback_syscall	// sched_setscheduler
+	data8 fsys_fallback_syscall	// sched_yield
+	data8 fsys_fallback_syscall	// sched_get_priority_max	// 1165
+	data8 fsys_fallback_syscall	// sched_get_priority_min
+	data8 fsys_fallback_syscall	// sched_rr_get_interval
+	data8 fsys_fallback_syscall	// nanosleep
+	data8 fsys_fallback_syscall	// nfsservctl
+	data8 fsys_fallback_syscall	// prctl		// 1170
+	data8 fsys_fallback_syscall	// getpagesize
+	data8 fsys_fallback_syscall	// mmap2
+	data8 fsys_fallback_syscall	// pciconfig_read
+	data8 fsys_fallback_syscall	// pciconfig_write
+	data8 fsys_fallback_syscall	// perfmonctl		// 1175
+	data8 fsys_fallback_syscall	// sigaltstack
+	data8 fsys_fallback_syscall	// rt_sigaction
+	data8 fsys_fallback_syscall	// rt_sigpending
+	data8 fsys_fallback_syscall	// rt_sigprocmask
+	data8 fsys_fallback_syscall	// rt_sigqueueinfo	// 1180
+	data8 fsys_fallback_syscall	// rt_sigreturn
+	data8 fsys_fallback_syscall	// rt_sigsuspend
+	data8 fsys_fallback_syscall	// rt_sigtimedwait
+	data8 fsys_fallback_syscall	// getcwd
+	data8 fsys_fallback_syscall	// capget		// 1185
+	data8 fsys_fallback_syscall	// capset
+	data8 fsys_fallback_syscall	// sendfile
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall	// socket		// 1190
+	data8 fsys_fallback_syscall	// bind
+	data8 fsys_fallback_syscall	// connect
+	data8 fsys_fallback_syscall	// listen
+	data8 fsys_fallback_syscall	// accept
+	data8 fsys_fallback_syscall	// getsockname		// 1195
+	data8 fsys_fallback_syscall	// getpeername
+	data8 fsys_fallback_syscall	// socketpair
+	data8 fsys_fallback_syscall	// send
+	data8 fsys_fallback_syscall	// sendto
+	data8 fsys_fallback_syscall	// recv			// 1200
+	data8 fsys_fallback_syscall	// recvfrom
+	data8 fsys_fallback_syscall	// shutdown
+	data8 fsys_fallback_syscall	// setsockopt
+	data8 fsys_fallback_syscall	// getsockopt
+	data8 fsys_fallback_syscall	// sendmsg		// 1205
+	data8 fsys_fallback_syscall	// recvmsg
+	data8 fsys_fallback_syscall	// pivot_root
+	data8 fsys_fallback_syscall	// mincore
+	data8 fsys_fallback_syscall	// madvise
+	data8 fsys_fallback_syscall	// newstat		// 1210
+	data8 fsys_fallback_syscall	// newlstat
+	data8 fsys_fallback_syscall	// newfstat
+	data8 fsys_fallback_syscall	// clone2
+	data8 fsys_fallback_syscall	// getdents64
+	data8 fsys_fallback_syscall	// getunwind		// 1215
+	data8 fsys_fallback_syscall	// readahead
+	data8 fsys_fallback_syscall	// setxattr
+	data8 fsys_fallback_syscall	// lsetxattr
+	data8 fsys_fallback_syscall	// fsetxattr
+	data8 fsys_fallback_syscall	// getxattr		// 1220
+	data8 fsys_fallback_syscall	// lgetxattr
+	data8 fsys_fallback_syscall	// fgetxattr
+	data8 fsys_fallback_syscall	// listxattr
+	data8 fsys_fallback_syscall	// llistxattr
+	data8 fsys_fallback_syscall	// flistxattr		// 1225
+	data8 fsys_fallback_syscall	// removexattr
+	data8 fsys_fallback_syscall	// lremovexattr
+	data8 fsys_fallback_syscall	// fremovexattr
+	data8 fsys_fallback_syscall	// tkill
+	data8 fsys_fallback_syscall	// futex		// 1230
+	data8 fsys_fallback_syscall	// sched_setaffinity
+	data8 fsys_fallback_syscall	// sched_getaffinity
+	data8 fsys_set_tid_address	// set_tid_address
+	data8 fsys_fallback_syscall	// unused
+	data8 fsys_fallback_syscall	// unused		// 1235
+	data8 fsys_fallback_syscall	// exit_group
+	data8 fsys_fallback_syscall	// lookup_dcookie
+	data8 fsys_fallback_syscall	// io_setup
+	data8 fsys_fallback_syscall	// io_destroy
+	data8 fsys_fallback_syscall	// io_getevents		// 1240
+	data8 fsys_fallback_syscall	// io_submit
+	data8 fsys_fallback_syscall	// io_cancel
+	data8 fsys_fallback_syscall	// epoll_create
+	data8 fsys_fallback_syscall	// epoll_ctl
+	data8 fsys_fallback_syscall	// epoll_wait		// 1245
+	data8 fsys_fallback_syscall	// restart_syscall
+	data8 fsys_fallback_syscall	// semtimedop
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1250
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1255
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1260
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1265
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1270
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall				// 1275
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
+	data8 fsys_fallback_syscall
diff -Nru a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
--- a/arch/ia64/kernel/gate.S	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/kernel/gate.S	Mon Feb 10 10:39:31 2003
@@ -2,7 +2,7 @@
  * This file contains the code that gets mapped at the upper end of each task's text
  * region.  For now, it contains the signal trampoline code only.
  *
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  * 	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -14,6 +14,87 @@
 #include <asm/page.h>
 
 	.section .text.gate, "ax"
+.start_gate:
+
+
+#if CONFIG_FSYS
+
+#include <asm/errno.h>
+
+/*
+ * On entry:
+ *	r11 = saved ar.pfs
+ *	r15 = system call #
+ *	b0  = saved return address
+ *	b6  = return address
+ * On exit:
+ *	r11 = saved ar.pfs
+ *	r15 = system call #
+ *	b0  = saved return address
+ *	all other "scratch" registers:	undefined
+ *	all "preserved" registers:	same as on entry
+ */
+GLOBAL_ENTRY(syscall_via_epc)
+	.prologue
+	.altrp b6
+	.body
+{
+	/*
+	 * Note: the kernel cannot assume that the first two instructions in this
+	 * bundle get executed.  The remaining code must be safe even if
+	 * they do not get executed.
+	 */
+	adds r17=-1024,r15
+	mov r10=0				// default to successful syscall execution
+	epc
+}
+	;;
+	rsm psr.be
+	movl r18=fsyscall_table
+
+	mov r16=IA64_KR(CURRENT)
+	mov r19=255
+	;;
+	shladd r18=r17,3,r18
+	cmp.geu p6,p0=r19,r17			// (syscall > 0 && syscall <= 1024+255)?
+	;;
+	srlz.d					// ensure little-endian byteorder is in effect
+(p6)	ld8 r18=[r18]
+	;;
+(p6)	mov b7=r18
+(p6)	br.sptk.many b7
+
+	mov r10=-1
+	mov r8=ENOSYS
+	MCKINLEY_E9_WORKAROUND
+	br.ret.sptk.many b6
+END(syscall_via_epc)
+
+GLOBAL_ENTRY(syscall_via_break)
+	.prologue
+	.altrp b6
+	.body
+	break 0x100000
+	br.ret.sptk.many b6
+END(syscall_via_break)
+
+GLOBAL_ENTRY(fsys_fallback_syscall)
+	/*
+	 * It would be better/fsyser to do the SAVE_MIN magic directly here, but for now
+	 * we simply fall back on doing a system-call via break.  Good enough
+	 * to get started.  (Note: we have to do this through the gate page again, since
+	 * the br.ret will switch us back to user-level privilege.)
+	 *
+	 * XXX Move this back to fsys.S after changing it over to avoid break 0x100000.
+	 */
+	movl r2=(syscall_via_break - .start_gate) + GATE_ADDR
+	;;
+	MCKINLEY_E9_WORKAROUND
+	mov b7=r2
+	br.ret.sptk.many b7
+END(fsys_fallback_syscall)
+
+#endif /* CONFIG_FSYS */
 
 #	define ARG0_OFF		(16 + IA64_SIGFRAME_ARG0_OFFSET)
 #	define ARG1_OFF		(16 + IA64_SIGFRAME_ARG1_OFFSET)
@@ -63,15 +144,18 @@
 	 * call stack.
 	 */
 
+#define SIGTRAMP_SAVES										\
+	.unwabi @svr4, 's'		// mark this as a sigtramp handler (saves scratch regs)	\
+	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF						\
+	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF						\
+	.savesp pr, PR_OFF+SIGCONTEXT_OFF							\
+	.savesp rp, RP_OFF+SIGCONTEXT_OFF							\
+	.vframesp SP_OFF+SIGCONTEXT_OFF
+
 GLOBAL_ENTRY(ia64_sigtramp)
 	// describe the state that is active when we get here:
 	.prologue
-	.unwabi @svr4, 's'		// mark this as a sigtramp handler (saves scratch regs)
-	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF
-	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF
-	.savesp pr, PR_OFF+SIGCONTEXT_OFF
-	.savesp rp, RP_OFF+SIGCONTEXT_OFF
-	.vframesp SP_OFF+SIGCONTEXT_OFF
+	SIGTRAMP_SAVES
 	.body
 
 	.label_state 1
@@ -156,10 +240,11 @@
 	ldf.fill f14=[base0],32
 	ldf.fill f15=[base1],32
 	mov r15=__NR_rt_sigreturn
+	.restore sp				// pop .prologue
 	break __BREAK_SYSCALL
 
-	.body
-	.copy_state 1
+	.prologue
+	SIGTRAMP_SAVES
 setup_rbs:
 	mov ar.rsc=0				// put RSE into enforced lazy mode
 	;;
@@ -171,6 +256,7 @@
 	;;
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	st8 [r14]=r16				// save sc_ar_rnat
+	.body
 	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
 
 	mov.m r16=ar.bsp			// sc_loadrs <- (new bsp - new bspstore) << 16
@@ -182,10 +268,11 @@
 	;;
 	st8 [r14]=r15				// save sc_loadrs
 	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
+	.restore sp				// pop .prologue
 	br.cond.sptk back_from_setup_rbs
 
 	.prologue
-	.copy_state 1
+	SIGTRAMP_SAVES
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	.body
 restore_rbs:
diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
--- a/arch/ia64/kernel/head.S	Mon Feb 10 10:39:29 2003
+++ b/arch/ia64/kernel/head.S	Mon Feb 10 10:39:29 2003
@@ -5,7 +5,7 @@
  * to set up the kernel's global pointer and jump to the kernel
  * entry point.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
@@ -143,17 +143,14 @@
 	movl r2=init_thread_union
 	cmp.eq isBP,isAP=r0,r0
 #endif
-	;;
-	extr r3=r2,0,61		// r3 == phys addr of task struct
 	mov r16=KERNEL_TR_PAGE_NUM
 	;;
 
 	// load the "current" pointer (r13) and ar.k6 with the current task
-	mov r13=r2
-	mov IA64_KR(CURRENT)=r3		// Physical address
-
+	mov IA64_KR(CURRENT)=r2		// virtual address
 	// initialize k4 to a safe value (64-128MB is mapped by TR_KERNEL)
 	mov IA64_KR(CURRENT_STACK)=r16
+	mov r13=r2
 	/*
 	 * Reserve space at the top of the stack for "struct pt_regs".  Kernel threads
 	 * don't store interesting values in that structure, but the space still needs
diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
--- a/arch/ia64/kernel/ia64_ksyms.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/ia64_ksyms.c	Mon Feb 10 10:39:27 2003
@@ -142,4 +142,8 @@
 EXPORT_SYMBOL(ia64_mv);
 #endif
 EXPORT_SYMBOL(machvec_noop);
-
+#ifdef CONFIG_PERFMON
+#include <asm/perfmon.h>
+EXPORT_SYMBOL(pfm_install_alternate_syswide_subsystem);
+EXPORT_SYMBOL(pfm_remove_alternate_syswide_subsystem);
+#endif
diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/iosapic.c	Mon Feb 10 10:39:27 2003
@@ -4,7 +4,7 @@
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
@@ -433,7 +433,7 @@
 	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
 	{
 		new_vector = ia64_alloc_vector();
-		printk("Reassigning vector %d to %d\n", vector, new_vector);
+		printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
 		memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
 		       sizeof(struct iosapic_intr_info));
 		memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
@@ -468,17 +468,17 @@
 #else
 	if (iosapic_address) {
 		if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address))
-			printk("WARN: register_intr: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n",
-			       gsi, vector);
+			printk(KERN_WARNING "warning: register_intr: diff IOSAPIC ADDRESS for "
+			       "GSI 0x%x, vector %d\n", gsi, vector);
 		iosapic_intr_info[vector].addr = iosapic_address;
 		if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) {
-			printk("WARN: register_intr: diff GSI base 0x%x for GSI 0x%x, vector %d\n",
-			       gsi_base, gsi, vector);
+			printk(KERN_WARNING "warning: register_intr: diff GSI base 0x%x for "
+			       "GSI 0x%x, vector %d\n", gsi_base, gsi, vector);
 		}
 		iosapic_intr_info[vector].gsi_base = gsi_base;
 	} else if (!iosapic_intr_info[vector].addr)
-		printk("WARN: register_intr: invalid override for GSI 0x%x, vector %d\n",
-		       gsi, vector);
+		printk(KERN_WARNING "warning: register_intr: invalid override for GSI 0x%x, "
+		       "vector %d\n", gsi, vector);
 #endif
 	if (edge_triggered) {
 		iosapic_intr_info[vector].trigger = IOSAPIC_EDGE;
@@ -491,9 +491,8 @@
 	idesc = irq_desc(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
-			printk("%s: changing vector %d from %s to %s\n",
-			       __FUNCTION__, vector, idesc->handler->typename,
-			       irq_type->typename);
+			printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
+			       __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
 		idesc->handler = irq_type;
 	}
 }
@@ -518,7 +517,7 @@
 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
 		      polarity, edge_triggered, gsi_base, iosapic_address);
 
-	printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
 	       gsi, (polarity ? "high" : "low"),
 	       (edge_triggered ? "edge" : "level"), dest, vector);
 
@@ -560,14 +559,14 @@
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
 	      default:
-		printk("iosapic_register_platform_irq(): invalid int type\n");
+		printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n");
 		return -1;
 	}
 
 	register_intr(gsi, vector, delivery, polarity,
 		      edge_triggered, gsi_base, iosapic_address);
 
-	printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
 	       int_type, gsi, (polarity ? "high" : "low"),
 	       (edge_triggered ? "edge" : "level"), dest, vector);
 
@@ -594,7 +593,7 @@
 	index = find_iosapic(gsi);
 
 	if (index < 0) {
-		printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n",
+		printk(KERN_ERR "ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n",
 		       isa_irq, gsi);
 		return;
 	}
@@ -634,7 +633,7 @@
 		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
 		 * enabled.
 		 */
-		printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
+		printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
 		outb(0xff, 0xA1);
 		outb(0xff, 0x21);
 	}
@@ -655,7 +654,7 @@
 	iosapic_lists[num_iosapic].num_rte = num_rte;
 	num_iosapic++;
 
-	printk(KERN_INFO"  IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
+	printk(KERN_INFO "  IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
 	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
 
 	if ((gsi_base == 0) && pcat_compat) {
@@ -692,7 +691,7 @@
 	idesc = irq_desc(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
-			printk("IOSAPIC: changing vector %d from %s to %s\n",
+			printk(KERN_INFO "IOSAPIC: changing vector %d from %s to %s\n",
 			       vector, idesc->handler->typename, irq_type->typename);
 		idesc->handler = irq_type;
 	}
@@ -723,7 +722,8 @@
 #endif
 	set_rte(vector, dest);
 
-	printk("IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n", pci_id, gsi, dest, vector);
+	printk(KERN_INFO "IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n",
+	       pci_id, gsi, dest, vector);
 }
 
 void __init
@@ -751,8 +751,8 @@
 			index = find_iosapic(gsi);
 
 			if (index < 0) {
-				printk(KERN_WARNING"IOSAPIC: GSI 0x%x has no IOSAPIC!\n", gsi);
-				return;
+				printk(KERN_WARNING "IOSAPIC: GSI 0x%x has no IOSAPIC!\n", gsi);
+				continue;
 			}
 			addr = iosapic_lists[index].addr;
 			gsi_base = iosapic_lists[index].gsi_base;
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/kernel/irq.c	Mon Feb 10 10:39:31 2003
@@ -108,7 +108,7 @@
  * a generic callback i think.
  */
 #if CONFIG_X86
-	printk("unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * Currently unexpected vectors happen only on SMP and APIC.
@@ -122,7 +122,7 @@
 #endif
 #endif
 #if CONFIG_IA64
-	printk("Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
 #endif
 }
 
@@ -317,7 +317,7 @@
 		desc->depth--;
 		break;
 	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n",
+		printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n",
 		       irq, (void *) __builtin_return_address(0));
 	}
 	spin_unlock_irqrestore(&desc->lock, flags);
@@ -466,7 +466,7 @@
 	 */
 	if (irqflags & SA_SHIRQ) {
 		if (!dev_id)
-			printk("Bad boy: %s called us without a dev_id!\n", devname);
+			printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname);
 	}
 #endif
 
@@ -547,7 +547,7 @@
 			kfree(action);
 			return;
 		}
-		printk("Trying to free free IRQ%d\n",irq);
+		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
 		spin_unlock_irqrestore(&desc->lock,flags);
 		return;
 	}
diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
--- a/arch/ia64/kernel/irq_ia64.c	Mon Feb 10 10:39:25 2003
+++ b/arch/ia64/kernel/irq_ia64.c	Mon Feb 10 10:39:25 2003
@@ -178,7 +178,7 @@
 	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
 #endif
 #ifdef CONFIG_PERFMON
-	perfmon_init_percpu();
+	pfm_init_percpu();
 #endif
 	platform_irq_init();
 }
diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
--- a/arch/ia64/kernel/ivt.S	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/kernel/ivt.S	Mon Feb 10 10:39:23 2003
@@ -192,7 +192,7 @@
 	rfi
 END(vhpt_miss)
 
-	.align 1024
+	.org ia64_ivt+0x400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0400 Entry 1 (size 64 bundles) ITLB (21)
 ENTRY(itlb_miss)
@@ -206,7 +206,7 @@
 	mov r16=cr.ifa				// get virtual address
 	mov r29=b0				// save b0
 	mov r31=pr				// save predicates
-itlb_fault:
+.itlb_fault:
 	mov r17=cr.iha				// get virtual address of L3 PTE
 	movl r30=1f				// load nested fault continuation point
 	;;
@@ -230,7 +230,7 @@
 	rfi
 END(itlb_miss)
 
-	.align 1024
+	.org ia64_ivt+0x0800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
 ENTRY(dtlb_miss)
@@ -268,7 +268,7 @@
 	rfi
 END(dtlb_miss)
 
-	.align 1024
+	.org ia64_ivt+0x0c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
 ENTRY(alt_itlb_miss)
@@ -288,7 +288,7 @@
 	;;
 (p8)	mov cr.iha=r17
 (p8)	mov r29=b0				// save b0
-(p8)	br.cond.dptk itlb_fault
+(p8)	br.cond.dptk .itlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
 	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
@@ -306,7 +306,7 @@
 	rfi
 END(alt_itlb_miss)
 
-	.align 1024
+	.org ia64_ivt+0x1000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 ENTRY(alt_dtlb_miss)
@@ -379,7 +379,7 @@
 	br.call.sptk.many b6=ia64_do_page_fault	// ignore return address
 END(page_fault)
 
-	.align 1024
+	.org ia64_ivt+0x1400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
 ENTRY(nested_dtlb_miss)
@@ -440,7 +440,7 @@
 	br.sptk.many b0				// return to continuation point
 END(nested_dtlb_miss)
 
-	.align 1024
+	.org ia64_ivt+0x1800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
 ENTRY(ikey_miss)
@@ -448,7 +448,7 @@
 	FAULT(6)
 END(ikey_miss)
 
-	.align 1024
+	.org ia64_ivt+0x1c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
 ENTRY(dkey_miss)
@@ -456,7 +456,7 @@
 	FAULT(7)
 END(dkey_miss)
 
-	.align 1024
+	.org ia64_ivt+0x2000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
 ENTRY(dirty_bit)
@@ -512,7 +512,7 @@
 	rfi
 END(idirty_bit)
 
-	.align 1024
+	.org ia64_ivt+0x2400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
 ENTRY(iaccess_bit)
@@ -571,7 +571,7 @@
 	rfi
 END(iaccess_bit)
 
-	.align 1024
+	.org ia64_ivt+0x2800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
 ENTRY(daccess_bit)
@@ -618,7 +618,7 @@
 	rfi
 END(daccess_bit)
 
-	.align 1024
+	.org ia64_ivt+0x2c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
 ENTRY(break_fault)
@@ -690,7 +690,7 @@
 	// NOT REACHED
 END(break_fault)
 
-ENTRY(demine_args)
+ENTRY_MIN_ALIGN(demine_args)
 	alloc r2=ar.pfs,8,0,0,0
 	tnat.nz p8,p0=in0
 	tnat.nz p9,p0=in1
@@ -719,7 +719,7 @@
 	br.ret.sptk.many rp
 END(demine_args)
 
-	.align 1024
+	.org ia64_ivt+0x3000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
 ENTRY(interrupt)
@@ -746,19 +746,19 @@
 	br.call.sptk.many b6=ia64_handle_irq
 END(interrupt)
 
-	.align 1024
+	.org ia64_ivt+0x3400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3400 Entry 13 (size 64 bundles) Reserved
 	DBG_FAULT(13)
 	FAULT(13)
 
-	.align 1024
+	.org ia64_ivt+0x3800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3800 Entry 14 (size 64 bundles) Reserved
 	DBG_FAULT(14)
 	FAULT(14)
 
-	.align 1024
+	.org ia64_ivt+0x3c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
 	DBG_FAULT(15)
@@ -803,7 +803,7 @@
 	br.sptk.many ia64_leave_kernel
 END(dispatch_illegal_op_fault)
 
-	.align 1024
+	.org ia64_ivt+0x4000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4000 Entry 16 (size 64 bundles) Reserved
 	DBG_FAULT(16)
@@ -893,7 +893,7 @@
 
 #endif /* CONFIG_IA32_SUPPORT */
 
-	.align 1024
+	.org ia64_ivt+0x4400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved
 	DBG_FAULT(17)
@@ -925,7 +925,7 @@
 	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
 END(non_syscall)
 
-	.align 1024
+	.org ia64_ivt+0x4800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4800 Entry 18 (size 64 bundles) Reserved
 	DBG_FAULT(18)
@@ -959,7 +959,7 @@
 	br.sptk.many ia64_prepare_handle_unaligned
 END(dispatch_unaligned_handler)
 
-	.align 1024
+	.org ia64_ivt+0x4c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4c00 Entry 19 (size 64 bundles) Reserved
 	DBG_FAULT(19)
@@ -1005,7 +1005,7 @@
 // --- End of long entries, Beginning of short entries
 //
 
-	.align 1024
+	.org ia64_ivt+0x5000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
 ENTRY(page_not_present)
@@ -1025,7 +1025,7 @@
 	br.sptk.many page_fault
 END(page_not_present)
 
-	.align 256
+	.org ia64_ivt+0x5100
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
 ENTRY(key_permission)
@@ -1038,7 +1038,7 @@
 	br.sptk.many page_fault
 END(key_permission)
 
-	.align 256
+	.org ia64_ivt+0x5200
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
 ENTRY(iaccess_rights)
@@ -1051,7 +1051,7 @@
 	br.sptk.many page_fault
 END(iaccess_rights)
 
-	.align 256
+	.org ia64_ivt+0x5300
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
 ENTRY(daccess_rights)
@@ -1064,7 +1064,7 @@
 	br.sptk.many page_fault
 END(daccess_rights)
 
-	.align 256
+	.org ia64_ivt+0x5400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
 ENTRY(general_exception)
@@ -1079,7 +1079,7 @@
 	br.sptk.many dispatch_to_fault_handler
 END(general_exception)
 
-	.align 256
+	.org ia64_ivt+0x5500
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
 ENTRY(disabled_fp_reg)
@@ -1092,7 +1092,7 @@
 	br.sptk.many dispatch_to_fault_handler
 END(disabled_fp_reg)
 
-	.align 256
+	.org ia64_ivt+0x5600
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 ENTRY(nat_consumption)
@@ -1100,7 +1100,7 @@
 	FAULT(26)
 END(nat_consumption)
 
-	.align 256
+	.org ia64_ivt+0x5700
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5700 Entry 27 (size 16 bundles) Speculation (40)
 ENTRY(speculation_vector)
@@ -1137,13 +1137,13 @@
 	rfi				// and go back
 END(speculation_vector)
 
-	.align 256
+	.org ia64_ivt+0x5800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5800 Entry 28 (size 16 bundles) Reserved
 	DBG_FAULT(28)
 	FAULT(28)
 
-	.align 256
+	.org ia64_ivt+0x5900
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
 ENTRY(debug_vector)
@@ -1151,7 +1151,7 @@
 	FAULT(29)
 END(debug_vector)
 
-	.align 256
+	.org ia64_ivt+0x5a00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
 ENTRY(unaligned_access)
@@ -1162,91 +1162,103 @@
 	br.sptk.many dispatch_unaligned_handler
 END(unaligned_access)
 
-	.align 256
+	.org ia64_ivt+0x5b00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
+ENTRY(unsupported_data_reference)
 	DBG_FAULT(31)
 	FAULT(31)
+END(unsupported_data_reference)
 
-	.align 256
+	.org ia64_ivt+0x5c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
+ENTRY(floating_point_fault)
 	DBG_FAULT(32)
 	FAULT(32)
+END(floating_point_fault)
 
-	.align 256
+	.org ia64_ivt+0x5d00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
+ENTRY(floating_point_trap)
 	DBG_FAULT(33)
 	FAULT(33)
+END(floating_point_trap)
 
-	.align 256
+	.org ia64_ivt+0x5e00
 /////////////////////////////////////////////////////////////////////////////////////////
-// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Tranfer Trap (66)
+// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
+ENTRY(lower_privilege_trap)
 	DBG_FAULT(34)
 	FAULT(34)
+END(lower_privilege_trap)
 
-	.align 256
+	.org ia64_ivt+0x5f00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
+ENTRY(taken_branch_trap)
 	DBG_FAULT(35)
 	FAULT(35)
+END(taken_branch_trap)
 
-	.align 256
+	.org ia64_ivt+0x6000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
+ENTRY(single_step_trap)
 	DBG_FAULT(36)
 	FAULT(36)
+END(single_step_trap)
 
-	.align 256
+	.org ia64_ivt+0x6100
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6100 Entry 37 (size 16 bundles) Reserved
 	DBG_FAULT(37)
 	FAULT(37)
 
-	.align 256
+	.org ia64_ivt+0x6200
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6200 Entry 38 (size 16 bundles) Reserved
 	DBG_FAULT(38)
 	FAULT(38)
 
-	.align 256
+	.org ia64_ivt+0x6300
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6300 Entry 39 (size 16 bundles) Reserved
 	DBG_FAULT(39)
 	FAULT(39)
 
-	.align 256
+	.org ia64_ivt+0x6400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6400 Entry 40 (size 16 bundles) Reserved
 	DBG_FAULT(40)
 	FAULT(40)
 
-	.align 256
+	.org ia64_ivt+0x6500
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6500 Entry 41 (size 16 bundles) Reserved
 	DBG_FAULT(41)
 	FAULT(41)
 
-	.align 256
+	.org ia64_ivt+0x6600
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6600 Entry 42 (size 16 bundles) Reserved
 	DBG_FAULT(42)
 	FAULT(42)
 
-	.align 256
+	.org ia64_ivt+0x6700
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6700 Entry 43 (size 16 bundles) Reserved
 	DBG_FAULT(43)
 	FAULT(43)
 
-	.align 256
+	.org ia64_ivt+0x6800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6800 Entry 44 (size 16 bundles) Reserved
 	DBG_FAULT(44)
 	FAULT(44)
 
-	.align 256
+	.org ia64_ivt+0x6900
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
 ENTRY(ia32_exception)
@@ -1254,7 +1266,7 @@
 	FAULT(45)
 END(ia32_exception)
 
-	.align 256
+	.org ia64_ivt+0x6a00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
 ENTRY(ia32_intercept)
@@ -1284,7 +1296,7 @@
 	FAULT(46)
 END(ia32_intercept)
 
-	.align 256
+	.org ia64_ivt+0x6b00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
 ENTRY(ia32_interrupt)
@@ -1297,121 +1309,121 @@
 #endif
 END(ia32_interrupt)
 
-	.align 256
+	.org ia64_ivt+0x6c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6c00 Entry 48 (size 16 bundles) Reserved
 	DBG_FAULT(48)
 	FAULT(48)
 
-	.align 256
+	.org ia64_ivt+0x6d00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6d00 Entry 49 (size 16 bundles) Reserved
 	DBG_FAULT(49)
 	FAULT(49)
 
-	.align 256
+	.org ia64_ivt+0x6e00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6e00 Entry 50 (size 16 bundles) Reserved
 	DBG_FAULT(50)
 	FAULT(50)
 
-	.align 256
+	.org ia64_ivt+0x6f00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6f00 Entry 51 (size 16 bundles) Reserved
 	DBG_FAULT(51)
 	FAULT(51)
 
-	.align 256
+	.org ia64_ivt+0x7000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7000 Entry 52 (size 16 bundles) Reserved
 	DBG_FAULT(52)
 	FAULT(52)
 
-	.align 256
+	.org ia64_ivt+0x7100
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7100 Entry 53 (size 16 bundles) Reserved
 	DBG_FAULT(53)
 	FAULT(53)
 
-	.align 256
+	.org ia64_ivt+0x7200
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7200 Entry 54 (size 16 bundles) Reserved
 	DBG_FAULT(54)
 	FAULT(54)
 
-	.align 256
+	.org ia64_ivt+0x7300
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7300 Entry 55 (size 16 bundles) Reserved
 	DBG_FAULT(55)
 	FAULT(55)
 
-	.align 256
+	.org ia64_ivt+0x7400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7400 Entry 56 (size 16 bundles) Reserved
 	DBG_FAULT(56)
 	FAULT(56)
 
-	.align 256
+	.org ia64_ivt+0x7500
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7500 Entry 57 (size 16 bundles) Reserved
 	DBG_FAULT(57)
 	FAULT(57)
 
-	.align 256
+	.org ia64_ivt+0x7600
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7600 Entry 58 (size 16 bundles) Reserved
 	DBG_FAULT(58)
 	FAULT(58)
 
-	.align 256
+	.org ia64_ivt+0x7700
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7700 Entry 59 (size 16 bundles) Reserved
 	DBG_FAULT(59)
 	FAULT(59)
 
-	.align 256
+	.org ia64_ivt+0x7800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7800 Entry 60 (size 16 bundles) Reserved
 	DBG_FAULT(60)
 	FAULT(60)
 
-	.align 256
+	.org ia64_ivt+0x7900
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7900 Entry 61 (size 16 bundles) Reserved
 	DBG_FAULT(61)
 	FAULT(61)
 
-	.align 256
+	.org ia64_ivt+0x7a00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7a00 Entry 62 (size 16 bundles) Reserved
 	DBG_FAULT(62)
 	FAULT(62)
 
-	.align 256
+	.org ia64_ivt+0x7b00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7b00 Entry 63 (size 16 bundles) Reserved
 	DBG_FAULT(63)
 	FAULT(63)
 
-	.align 256
+	.org ia64_ivt+0x7c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7c00 Entry 64 (size 16 bundles) Reserved
 	DBG_FAULT(64)
 	FAULT(64)
 
-	.align 256
+	.org ia64_ivt+0x7d00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7d00 Entry 65 (size 16 bundles) Reserved
 	DBG_FAULT(65)
 	FAULT(65)
 
-	.align 256
+	.org ia64_ivt+0x7e00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7e00 Entry 66 (size 16 bundles) Reserved
 	DBG_FAULT(66)
 	FAULT(66)
 
-	.align 256
+	.org ia64_ivt+0x7f00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7f00 Entry 67 (size 16 bundles) Reserved
 	DBG_FAULT(67)
diff -Nru a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c
--- a/arch/ia64/kernel/machvec.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/machvec.c	Mon Feb 10 10:39:27 2003
@@ -47,7 +47,7 @@
 		panic("generic kernel failed to find machine vector for platform %s!", name);
 	}
 	ia64_mv = *mv;
-	printk("booting generic kernel on platform %s\n", name);
+	printk(KERN_INFO "booting generic kernel on platform %s\n", name);
 }
 
 #endif /* CONFIG_IA64_GENERIC */
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/mca.c	Mon Feb 10 10:39:27 2003
@@ -231,7 +231,7 @@
 {
 	/* Register the CPE interrupt vector with SAL */
 	if (ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0)) {
-		printk("ia64_mca_platform_init: failed to register Corrected "
+		printk(KERN_ERR "ia64_mca_platform_init: failed to register Corrected "
 		       "Platform Error interrupt vector with SAL.\n");
 		return;
 	}
@@ -398,7 +398,7 @@
 					 IA64_MCA_RENDEZ_TIMEOUT,
 					 0)))
 	{
-		printk("ia64_mca_init: Failed to register rendezvous interrupt "
+		printk(KERN_ERR "ia64_mca_init: Failed to register rendezvous interrupt "
 		       "with SAL.  rc = %ld\n", rc);
 		return;
 	}
@@ -409,8 +409,8 @@
 					 IA64_MCA_WAKEUP_VECTOR,
 					 0, 0)))
 	{
-		printk("ia64_mca_init: Failed to register wakeup interrupt with SAL.  rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register wakeup interrupt with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -430,8 +430,8 @@
 				       ia64_mc_info.imi_mca_handler_size,
 				       0, 0, 0)))
 	{
-		printk("ia64_mca_init: Failed to register os mca handler with SAL.  rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register os mca handler with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -459,8 +459,8 @@
 				       __pa(ia64_get_gp()),
 				       ia64_mc_info.imi_slave_init_handler_size)))
 	{
-		printk("ia64_mca_init: Failed to register m/s init handlers with SAL. rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -495,7 +495,8 @@
 				}
 			ia64_mca_register_cpev(cpev);
 		} else
-			printk("ia64_mca_init: Failed to get routed CPEI vector from ACPI.\n");
+			printk(KERN_ERR
+			       "ia64_mca_init: Failed to get routed CPEI vector from ACPI.\n");
 	}
 
 	/* Initialize the areas set aside by the OS to buffer the
@@ -511,7 +512,7 @@
 	mca_test();
 #endif /* #if defined(MCA_TEST) */
 
-	printk("Mca related initialization done\n");
+	printk(KERN_INFO "Mca related initialization done\n");
 
 	/* commented out because this is done elsewhere */
 #if 0
@@ -807,7 +808,7 @@
 	sal_log_processor_info_t *proc_ptr;
 	ia64_err_rec_t *plog_ptr;
 
-	printk("Entered OS INIT handler\n");
+	printk(KERN_INFO "Entered OS INIT handler\n");
 
 	/* Get the INIT processor log */
 	if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk))
@@ -1736,8 +1737,7 @@
 		/*
 		 *  Now process processor device error record section
 		 */
-		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh,
-						 printk);
+		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, printk);
 	}
 
 	IA64_MCA_DEBUG("ia64_mca_log_print: "
diff -Nru a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
--- a/arch/ia64/kernel/minstate.h	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/kernel/minstate.h	Mon Feb 10 10:39:31 2003
@@ -30,25 +30,23 @@
  * on interrupts.
  */
 #define MINSTATE_START_SAVE_MIN_VIRT								\
-(pUser)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
-	dep r1=-1,r1,61,3;				/* r1 = current (virtual) */		\
+(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 	;;											\
-(pUser)	mov.m rARRNAT=ar.rnat;									\
-(pUser)	addl rKRBS=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
-(pKern) mov r1=sp;					/* get sp  */				\
-	;;											\
-(pUser) lfetch.fault.excl.nt1 [rKRBS];								\
-(pUser)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
-(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUStk)	mov.m rARRNAT=ar.rnat;									\
+(pUStk)	addl rKRBS=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
+(pKStk) mov r1=sp;					/* get sp  */				\
 	;;											\
-(pUser)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
-(pKern) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
+(pUStk) lfetch.fault.excl.nt1 [rKRBS];								\
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUStk)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
 	;;											\
-(pUser)	mov r18=ar.bsp;										\
-(pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+(pUStk)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
+	;;											\
+(pUStk)	mov r18=ar.bsp;										\
+(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
 
 #define MINSTATE_END_SAVE_MIN_VIRT								\
-	or r13=r13,r14;		/* make `current' a kernel virtual address */			\
 	bsw.1;			/* switch back to bank 1 (must be last in insn group) */	\
 	;;
 
@@ -57,21 +55,21 @@
  * go virtual and dont want to destroy the iip or ipsr.
  */
 #define MINSTATE_START_SAVE_MIN_PHYS								\
-(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
-(pUser)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
-(pUser)	addl rKRBS=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
-	;;											\
-(pUser)	mov rARRNAT=ar.rnat;									\
-(pKern) dep r1=0,sp,61,3;				/* compute physical addr of sp	*/	\
-(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
-(pUser)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
-(pUser)	dep rKRBS=-1,rKRBS,61,3;			/* compute kernel virtual addr of RBS */\
+(pKStk) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
+(pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
+(pUStk)	addl rKRBS=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
+	;;											\
+(pUStk)	mov rARRNAT=ar.rnat;									\
+(pKStk) dep r1=0,sp,61,3;				/* compute physical addr of sp	*/	\
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUStk)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
+(pUStk)	dep rKRBS=-1,rKRBS,61,3;			/* compute kernel virtual addr of RBS */\
 	;;											\
-(pKern) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
-(pUser)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
+(pUStk)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
 	;;											\
-(pUser)	mov r18=ar.bsp;										\
-(pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+(pUStk)	mov r18=ar.bsp;										\
+(pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
 
 #define MINSTATE_END_SAVE_MIN_PHYS								\
 	or r12=r12,r14;		/* make sp a kernel virtual address */				\
@@ -79,11 +77,13 @@
 	;;
 
 #ifdef MINSTATE_VIRT
+# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT)
 # define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_VIRT
 # define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_VIRT
 #endif
 
 #ifdef MINSTATE_PHYS
+# define MINSTATE_GET_CURRENT(reg)	mov reg=IA64_KR(CURRENT);; dep reg=0,reg,61,3
 # define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_PHYS
 # define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_PHYS
 #endif
@@ -110,23 +110,26 @@
  * we can pass interruption state as arguments to a handler.
  */
 #define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							  \
-	mov rARRSC=ar.rsc;									  \
-	mov rARPFS=ar.pfs;									  \
-	mov rR1=r1;										  \
-	mov rARUNAT=ar.unat;									  \
-	mov rCRIPSR=cr.ipsr;									  \
-	mov rB6=b6;				/* rB6 = branch reg 6 */			  \
-	mov rCRIIP=cr.iip;									  \
-	mov r1=IA64_KR(CURRENT);		/* r1 = current (physical) */			  \
-	COVER;											  \
+	mov rARRSC=ar.rsc;		/* M */							  \
+	mov rARUNAT=ar.unat;		/* M */							  \
+	mov rR1=r1;			/* A */							  \
+	MINSTATE_GET_CURRENT(r1);	/* M (or M;;I) */					  \
+	mov rCRIPSR=cr.ipsr;		/* M */							  \
+	mov rARPFS=ar.pfs;		/* I */							  \
+	mov rCRIIP=cr.iip;		/* M */							  \
+	mov rB6=b6;			/* I */	/* rB6 = branch reg 6 */			  \
+	COVER;				/* B;; (or nothing) */					  \
 	;;											  \
-	invala;											  \
-	extr.u r16=rCRIPSR,32,2;		/* extract psr.cpl */				  \
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r1;						  \
 	;;											  \
-	cmp.eq pKern,pUser=r0,r16;		/* are we in kernel mode already? (psr.cpl==0) */ \
+	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	  \
+	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	  \
 	/* switch from user to kernel RBS: */							  \
 	;;											  \
+	invala;				/* M */							  \
 	SAVE_IFS;										  \
+	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? (psr.cpl==0) */ \
+	;;											  \
 	MINSTATE_START_SAVE_MIN									  \
 	add r17=L1_CACHE_BYTES,r1			/* really: biggest cache-line size */	  \
 	;;											  \
@@ -138,23 +141,23 @@
 	;;											  \
 	lfetch.fault.excl.nt1 [r17];								  \
 	adds r17=8,r1;					/* initialize second base pointer */	  \
-(pKern)	mov r18=r0;		/* make sure r18 isn't NaT */					  \
+(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					  \
 	;;											  \
 	st8 [r17]=rCRIIP,16;	/* save cr.iip */						  \
 	st8 [r16]=rCRIFS,16;	/* save cr.ifs */						  \
-(pUser)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
+(pUStk)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
 	;;											  \
 	st8 [r17]=rARUNAT,16;	/* save ar.unat */						  \
 	st8 [r16]=rARPFS,16;	/* save ar.pfs */						  \
 	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			  \
 	;;											  \
 	st8 [r17]=rARRSC,16;	/* save ar.rsc */						  \
-(pUser)	st8 [r16]=rARRNAT,16;	/* save ar.rnat */						  \
-(pKern)	adds r16=16,r16;	/* skip over ar_rnat field */					  \
+(pUStk)	st8 [r16]=rARRNAT,16;	/* save ar.rnat */						  \
+(pKStk)	adds r16=16,r16;	/* skip over ar_rnat field */					  \
 	;;			/* avoid RAW on r16 & r17 */					  \
-(pUser)	st8 [r17]=rARBSPSTORE,16;	/* save ar.bspstore */					  \
+(pUStk)	st8 [r17]=rARBSPSTORE,16;	/* save ar.bspstore */					  \
 	st8 [r16]=rARPR,16;	/* save predicates */						  \
-(pKern)	adds r17=16,r17;	/* skip over ar_bspstore field */				  \
+(pKStk)	adds r17=16,r17;	/* skip over ar_bspstore field */				  \
 	;;											  \
 	st8 [r17]=rB6,16;	/* save b6 */							  \
 	st8 [r16]=r18,16;	/* save ar.rsc value for "loadrs" */				  \
diff -Nru a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
--- a/arch/ia64/kernel/pal.S	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/pal.S	Mon Feb 10 10:39:33 2003
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
  *	David Mosberger <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -114,7 +114,7 @@
 	;;
 	rsm psr.i
 	mov b7 = loc2
-	;; 
+	;;
 	br.call.sptk.many rp=b7		// now make the call
 .ret0:	mov psr.l  = loc3
 	mov ar.pfs = loc1
@@ -131,15 +131,15 @@
  * 	in0         Index of PAL service
  * 	in2 - in3   Remaning PAL arguments
  *
- * PSR_DB, PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
+ * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
  * So we don't need to clear them.
  */
-#define PAL_PSR_BITS_TO_CLEAR						\
-	(IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |		\
-	 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |	\
+#define PAL_PSR_BITS_TO_CLEAR							\
+	(IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT  | IA64_PSR_DB | IA64_PSR_RT |	\
+	 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |		\
 	 IA64_PSR_DFL | IA64_PSR_DFH)
 
-#define PAL_PSR_BITS_TO_SET						\
+#define PAL_PSR_BITS_TO_SET							\
 	(IA64_PSR_BN)
 
 
@@ -161,7 +161,7 @@
 	;;
 	mov loc3 = psr			// save psr
 	adds r8  = 1f-1b,r8		// calculate return address for call
-	;; 
+	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	dep.z r8=r8,0,61		// convert rp to physical
@@ -275,7 +275,6 @@
  * Inputs:
  *      in0	Address of stack storage for fp regs
  */
-
 GLOBAL_ENTRY(ia64_load_scratch_fpregs)
 	alloc r3=ar.pfs,1,0,0,0
 	add r2=16,in0
diff -Nru a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
--- a/arch/ia64/kernel/palinfo.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/kernel/palinfo.c	Mon Feb 10 10:39:23 2003
@@ -6,7 +6,7 @@
  * Intel IA-64 Architecture Software Developer's Manual v1.0.
  *
  *
- * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
  * 05/26/2000	S.Eranian	initial release
@@ -225,15 +225,12 @@
 	int i,j, k;
 	s64 status;
 
-	if ((status=ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
-			printk("ia64_pal_cache_summary=%ld\n", status);
-			return 0;
+	if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
+		printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
+		return 0;
 	}
 
-	p += sprintf(p, "Cache levels  : %ld\n" \
-			"Unique caches : %ld\n\n",
-			levels,
-			unique_caches);
+	p += sprintf(p, "Cache levels  : %ld\nUnique caches : %ld\n\n", levels, unique_caches);
 
 	for (i=0; i < levels; i++) {
 
@@ -308,8 +305,8 @@
 	int i, j;
 	s64 status;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 
@@ -339,8 +336,8 @@
 	}
 	p += sprintf(p, "\n");
 
-	if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
-		printk("ia64_pal_vm_page_size=%ld\n", status);
+	if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
 		return 0;
 	}
 
@@ -360,7 +357,7 @@
 	p = bitvector_process(p, vw_pages);
 
 	if ((status=ia64_get_ptce(&ptce)) != 0) {
-		printk("ia64_get_ptce=%ld\n",status);
+		printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
 		return 0;
 	}
 
@@ -710,8 +707,8 @@
 		u64 rv2:32;
 	} *rid_reg;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 	max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
@@ -722,7 +719,8 @@
 
 		status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
 		if (status != 0) {
-			printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status);
+			printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n",
+			       i, j, status);
 			continue;
 		}
 
@@ -841,7 +839,7 @@
 {
 	palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
 	if (data == NULL) {
-		printk("%s palinfo: data pointer is NULL\n", KERN_ERR);
+		printk(KERN_ERR "palinfo: data pointer is NULL\n");
 		data->ret = 0; /* no output */
 		return;
 	}
@@ -868,7 +866,8 @@
 
 	/* will send IPI to other CPU and wait for completion of remote call */
 	if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) {
-		printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
+		printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: "
+		       "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
 		return 0;
 	}
 	return ptr.ret;
@@ -877,7 +876,7 @@
 static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
-	printk("palinfo: should not be called with non SMP kernel\n");
+	printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n");
 	return 0;
 }
 #endif /* CONFIG_SMP */
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ia64/kernel/perfmon.c	Mon Feb 10 10:39:32 2003
@@ -28,7 +28,6 @@
 #include <asm/bitops.h>
 #include <asm/errno.h>
 #include <asm/page.h>
-#include <asm/pal.h>
 #include <asm/perfmon.h>
 #include <asm/processor.h>
 #include <asm/signal.h>
@@ -56,8 +55,8 @@
 /*
  * Reset register flags
  */
-#define PFM_RELOAD_LONG_RESET	1
-#define PFM_RELOAD_SHORT_RESET	2
+#define PFM_PMD_LONG_RESET	1
+#define PFM_PMD_SHORT_RESET	2
 
 /*
  * Misc macros and definitions
@@ -83,8 +82,10 @@
 #define	PFM_REG_CONFIG		(0x4<<4|PFM_REG_IMPL) /* refine configuration */
 #define PFM_REG_BUFFER	 	(0x5<<4|PFM_REG_IMPL) /* PMD used as buffer */
 
+#define PMC_IS_LAST(i)	(pmu_conf.pmc_desc[i].type & PFM_REG_END)
+#define PMD_IS_LAST(i)	(pmu_conf.pmd_desc[i].type & PFM_REG_END)
 
-#define PFM_IS_DISABLED() pmu_conf.pfm_is_disabled
+#define PFM_IS_DISABLED() pmu_conf.disabled
 
 #define PMC_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_soft_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
 #define PFM_FL_INHERIT_MASK	(PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)
@@ -102,7 +103,6 @@
 #define PMD_PMD_DEP(i)	   pmu_conf.pmd_desc[i].dep_pmd[0]
 #define PMC_PMD_DEP(i)	   pmu_conf.pmc_desc[i].dep_pmd[0]
 
-
 /* k assume unsigned */
 #define IBR_IS_IMPL(k)	  (k<pmu_conf.num_ibrs)
 #define DBR_IS_IMPL(k)	  (k<pmu_conf.num_dbrs)
@@ -131,6 +131,9 @@
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
+#define PFM_CPUINFO_CLEAR(v)	__get_cpu_var(pfm_syst_info) &= ~(v)
+#define PFM_CPUINFO_SET(v)	__get_cpu_var(pfm_syst_info) |= (v)
+
 #ifdef CONFIG_SMP
 #define cpu_is_online(i) (cpu_online_map & (1UL << i))
 #else
@@ -211,7 +214,7 @@
 	u64 reset_pmds[4]; /* which other pmds to reset when this counter overflows */
 	u64 seed;	/* seed for random-number generator */
 	u64 mask;	/* mask for random-number generator */
-	int flags;	/* notify/do not notify */
+	unsigned int flags; /* notify/do not notify */
 } pfm_counter_t;
 
 /*
@@ -226,7 +229,8 @@
 	unsigned int frozen:1;		/* pmu must be kept frozen on ctxsw in */
 	unsigned int protected:1;	/* allow access to creator of context only */
 	unsigned int using_dbreg:1;	/* using range restrictions (debug registers) */
-	unsigned int reserved:24;
+	unsigned int excl_idle:1;	/* exclude idle task in system wide session */
+	unsigned int reserved:23;
 } pfm_context_flags_t;
 
 /*
@@ -261,10 +265,8 @@
 
 	u64			ctx_saved_psr;		/* copy of psr used for lazy ctxsw */
 	unsigned long		ctx_saved_cpus_allowed;	/* copy of the task cpus_allowed (system wide) */
-	unsigned long		ctx_cpu;		/* cpu to which perfmon is applied (system wide) */
+	unsigned int		ctx_cpu;		/* CPU used by system wide session */
 
-	atomic_t		ctx_saving_in_progress;	/* flag indicating actual save in progress */
-	atomic_t		ctx_is_busy;		/* context accessed by overflow handler */
 	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
 } pfm_context_t;
 
@@ -274,6 +276,7 @@
 #define ctx_fl_frozen		ctx_flags.frozen
 #define ctx_fl_protected	ctx_flags.protected
 #define ctx_fl_using_dbreg	ctx_flags.using_dbreg
+#define ctx_fl_excl_idle	ctx_flags.excl_idle
 
 /*
  * global information about all sessions
@@ -282,10 +285,10 @@
 typedef struct {
 	spinlock_t		pfs_lock;		   /* lock the structure */
 
-	unsigned long		pfs_task_sessions;	   /* number of per task sessions */
-	unsigned long		pfs_sys_sessions;	   /* number of per system wide sessions */
-	unsigned long   	pfs_sys_use_dbregs;	   /* incremented when a system wide session uses debug regs */
-	unsigned long   	pfs_ptrace_use_dbregs;	   /* incremented when a process uses debug regs */
+	unsigned int 		pfs_task_sessions;	   /* number of per task sessions */
+	unsigned int		pfs_sys_sessions;	   /* number of per system wide sessions */
+	unsigned int		pfs_sys_use_dbregs;	   /* incremented when a system wide session uses debug regs */
+	unsigned int		pfs_ptrace_use_dbregs;	   /* incremented when a process uses debug regs */
 	struct task_struct	*pfs_sys_session[NR_CPUS]; /* point to task owning a system-wide session */
 } pfm_session_t;
 
@@ -313,23 +316,22 @@
 
 /*
  * This structure is initialized at boot time and contains
- * a description of the PMU main characteristic as indicated
- * by PAL along with a list of inter-registers dependencies and configurations.
+ * a description of the PMU main characteristics.
  */
 typedef struct {
-	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
-	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
-	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
-	unsigned long num_pmcs ;	/* highest PMC implemented (may have holes) */
-	unsigned long num_pmds;		/* highest PMD implemented (may have holes) */
-	unsigned long impl_regs[16];	/* buffer used to hold implememted PMC/PMD mask */
-	unsigned long num_ibrs;		/* number of instruction debug registers */
-	unsigned long num_dbrs;		/* number of data debug registers */
-	pfm_reg_desc_t *pmc_desc;	/* detailed PMC register descriptions */
-	pfm_reg_desc_t *pmd_desc;	/* detailed PMD register descriptions */
+	unsigned int  disabled;		/* indicates if perfmon is working properly */
+	unsigned long ovfl_val;		/* overflow value for generic counters   */
+	unsigned long impl_pmcs[4];	/* bitmask of implemented PMCS */
+	unsigned long impl_pmds[4];	/* bitmask of implemented PMDS */
+	unsigned int  num_pmcs;		/* number of implemented PMCS */
+	unsigned int  num_pmds;		/* number of implemented PMDS */
+	unsigned int  num_ibrs;		/* number of implemented IBRS */
+	unsigned int  num_dbrs;		/* number of implemented DBRS */
+	unsigned int  num_counters;	/* number of PMD/PMC counters */
+	pfm_reg_desc_t *pmc_desc;	/* detailed PMC register dependencies descriptions */
+	pfm_reg_desc_t *pmd_desc;	/* detailed PMD register dependencies descriptions */
 } pmu_config_t;
 
-
 /*
  * structure used to pass argument to/from remote CPU 
  * using IPI to check and possibly save the PMU context on SMP systems.
@@ -389,13 +391,12 @@
 /*
  * perfmon internal variables
  */
-static pmu_config_t	pmu_conf; 	/* PMU configuration */
 static pfm_session_t	pfm_sessions;	/* global sessions information */
 static struct proc_dir_entry *perfmon_dir; /* for debug only */
 static pfm_stats_t	pfm_stats[NR_CPUS];
+static pfm_intr_handler_desc_t	*pfm_alternate_intr_handler;
 
-DEFINE_PER_CPU(int, pfm_syst_wide);
-static DEFINE_PER_CPU(int, pfm_dcr_pp);
+DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 
 /* sysctl() controls */
 static pfm_sysctl_t pfm_sysctl;
@@ -436,9 +437,6 @@
  * forward declarations
  */
 static void pfm_reset_pmu(struct task_struct *);
-#ifdef CONFIG_SMP
-static void pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx);
-#endif
 static void pfm_lazy_save_regs (struct task_struct *ta);
 
 #if   defined(CONFIG_ITANIUM)
@@ -449,43 +447,76 @@
 #include "perfmon_generic.h"
 #endif
 
+static inline void
+pfm_clear_psr_pp(void)
+{
+	__asm__ __volatile__ ("rsm psr.pp;; srlz.i;;"::: "memory");
+}
+
+static inline void
+pfm_set_psr_pp(void)
+{
+	__asm__ __volatile__ ("ssm psr.pp;; srlz.i;;"::: "memory");
+}
+
+static inline void
+pfm_clear_psr_up(void)
+{
+	__asm__ __volatile__ ("rum psr.up;; srlz.i;;"::: "memory");
+}
+
+static inline void
+pfm_set_psr_up(void)
+{
+	__asm__ __volatile__ ("sum psr.up;; srlz.i;;"::: "memory");
+}
+
+static inline unsigned long
+pfm_get_psr(void)
+{
+	unsigned long tmp;
+	__asm__ __volatile__ ("mov %0=psr;;": "=r"(tmp) :: "memory");
+	return tmp;
+}
+
+static inline void
+pfm_set_psr_l(unsigned long val)
+{
+	__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(val): "memory");
+}
+
+static inline void
+pfm_freeze_pmu(void)
+{
+	ia64_set_pmc(0,1UL);
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_unfreeze_pmu(void)
+{
+	ia64_set_pmc(0,0UL);
+	ia64_srlz_d();
+}
+
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
 {
-	return ctx->ctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.perf_ovfl_val);
+	return ctx->ctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.ovfl_val);
 }
 
 static inline void
 pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val)
 {
-	ctx->ctx_soft_pmds[i].val = val  & ~pmu_conf.perf_ovfl_val;
+	ctx->ctx_soft_pmds[i].val = val  & ~pmu_conf.ovfl_val;
 	/*
 	 * writing to unimplemented part is ignore, so we do not need to
 	 * mask off top part
 	 */
-	ia64_set_pmd(i, val & pmu_conf.perf_ovfl_val);
+	ia64_set_pmd(i, val & pmu_conf.ovfl_val);
 }
 
 /*
- * finds the number of PM(C|D) registers given
- * the bitvector returned by PAL
- */
-static unsigned long __init
-find_num_pm_regs(long *buffer)
-{
-	int i=3; /* 4 words/per bitvector */
-
-	/* start from the most significant word */
-	while (i>=0 && buffer[i] == 0 ) i--;
-	if (i< 0) {
-		printk(KERN_ERR "perfmon: No bit set in pm_buffer\n");
-		return 0;
-	}
-	return 1+ ia64_fls(buffer[i]) + 64 * i;
-}
-
-
-/*
  * Generates a unique (per CPU) timestamp
  */
 static inline unsigned long
@@ -562,7 +593,7 @@
 	pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return;
 	}
 	/*
@@ -627,7 +658,7 @@
 	 * some sanity checks first
 	 */
 	if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) {
-		printk("perfmon: invalid context mm=%p\n", task->mm);
+		printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm);
 		return -1;
 	}
 	psb = ctx->ctx_psb;
@@ -638,11 +669,11 @@
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
-		printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", 
-				task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
+		printk(KERN_DEBUG "perfmon: pid %d unable to unmap sampling buffer "
+		       "@0x%lx size=%ld\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
 	}
 
-	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", 
+	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n",
 		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags));
 
 	return 0;
@@ -677,7 +708,7 @@
 		page = pfm_kvirt_to_pa(buf);
 
 		if (remap_page_range(vma, addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
-		
+
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
 		size  -= PAGE_SIZE;
@@ -834,7 +865,7 @@
 	vma->vm_end = vma->vm_start + size;
 
 	DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start));
-		
+
 	/* can only be applied to current, need to have the mm semaphore held when called */
 	if (pfm_remap_buffer(vma, (unsigned long)smpl_buf, vma->vm_start, size)) {
 		DBprintk(("Can't remap buffer\n"));
@@ -875,6 +906,121 @@
 	return -ENOMEM;
 }
 
+static int
+pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask)
+{
+	unsigned long m, undo_mask;
+	unsigned int n, i;
+
+	/*
+	 * validy checks on cpu_mask have been done upstream
+	 */
+	LOCK_PFS();
+
+	if (is_syswide) {
+		/* 
+		 * cannot mix system wide and per-task sessions
+		 */
+		if (pfm_sessions.pfs_task_sessions > 0UL) {
+			DBprintk(("system wide not possible, %u conflicting task_sessions\n", 
+			  	pfm_sessions.pfs_task_sessions));
+			goto abort;
+		}
+
+		m = cpu_mask; undo_mask = 0UL; n = 0;
+		DBprintk(("cpu_mask=0x%lx\n", cpu_mask));
+		for(i=0; m; i++, m>>=1) {
+
+			if ((m & 0x1) == 0UL) continue;
+
+			if (pfm_sessions.pfs_sys_session[i]) goto undo;
+
+			DBprintk(("reserving CPU%d currently on CPU%d\n", i, smp_processor_id()));
+
+			pfm_sessions.pfs_sys_session[i] = task;
+			undo_mask |= 1UL << i;
+			n++;
+		}
+		pfm_sessions.pfs_sys_sessions += n;
+	} else {
+		if (pfm_sessions.pfs_sys_sessions) goto abort;
+		pfm_sessions.pfs_task_sessions++;
+	}
+	DBprintk(("task_sessions=%u sys_session[%d]=%d", 
+		  pfm_sessions.pfs_task_sessions, 
+		  smp_processor_id(), pfm_sessions.pfs_sys_session[smp_processor_id()] ? 1 : 0));
+	UNLOCK_PFS();
+	return 0;
+undo:
+	DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n",
+  		pfm_sessions.pfs_sys_session[i]->pid, i));
+
+	for(i=0; undo_mask; i++, undo_mask >>=1) {
+		pfm_sessions.pfs_sys_session[i] = NULL;
+	}
+abort:
+	UNLOCK_PFS();
+
+	return -EBUSY;
+
+}
+
+static int
+pfm_unreserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask)
+{
+	pfm_context_t *ctx;
+	unsigned long m;
+	unsigned int n, i;
+
+	ctx = task ? task->thread.pfm_context : NULL;
+
+	/*
+	 * validy checks on cpu_mask have been done upstream
+	 */
+	LOCK_PFS();
+
+	DBprintk(("[%d] sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu_mask=0x%lx\n",
+		task->pid,
+		pfm_sessions.pfs_sys_sessions,
+		pfm_sessions.pfs_task_sessions,
+		pfm_sessions.pfs_sys_use_dbregs,
+		is_syswide,
+		cpu_mask));
+
+
+	if (is_syswide) {
+		m = cpu_mask; n = 0;
+		for(i=0; m; i++, m>>=1) {
+			if ((m & 0x1) == 0UL) continue;
+			pfm_sessions.pfs_sys_session[i] = NULL;
+			n++;
+		}
+		/* 
+		 * would not work with perfmon+more than one bit in cpu_mask
+		 */
+		if (ctx && ctx->ctx_fl_using_dbreg) {
+			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
+				printk(KERN_DEBUG "perfmon: invalid release for [%d] "
+				       "sys_use_dbregs=0\n", task->pid);
+			} else {
+				pfm_sessions.pfs_sys_use_dbregs--;
+			}
+		}
+		pfm_sessions.pfs_sys_sessions -= n;
+
+		DBprintk(("CPU%d sys_sessions=%u\n", 
+			smp_processor_id(), pfm_sessions.pfs_sys_sessions));
+	} else {
+		pfm_sessions.pfs_task_sessions--;
+		DBprintk(("[%d] task_sessions=%u\n", 
+			task->pid, pfm_sessions.pfs_task_sessions));
+	}
+
+	UNLOCK_PFS();
+
+	return 0;
+}
+
 /*
  * XXX: do something better here
  */
@@ -891,6 +1037,7 @@
 static int
 pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
 {
+	unsigned long smpl_pmds = pfx->ctx_smpl_regs[0];
 	int ctx_flags;
 	int cpu;
 
@@ -957,6 +1104,11 @@
 		}
 #endif
 	}
+	/* verify validity of smpl_regs */
+	if ((smpl_pmds & pmu_conf.impl_pmds[0]) != smpl_pmds) {
+		DBprintk(("invalid smpl_regs 0x%lx\n", smpl_pmds));
+		return -EINVAL;
+	}
 	/* probably more to add here */
 
 	return 0;
@@ -968,7 +1120,7 @@
 {
 	pfarg_context_t tmp;
 	void *uaddr = NULL;
-	int ret, cpu = 0;
+	int ret;
 	int ctx_flags;
 	pid_t notify_pid;
 
@@ -987,40 +1139,8 @@
 
 	ctx_flags = tmp.ctx_flags;
 
-	ret =  -EBUSY;
-
-	LOCK_PFS();
-
-	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
-
-		/* at this point, we know there is at least one bit set */
-		cpu = ffz(~tmp.ctx_cpu_mask);
-
-		DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id()));
-
-		if (pfm_sessions.pfs_task_sessions > 0) {
-			DBprintk(("system wide not possible, task_sessions=%ld\n", pfm_sessions.pfs_task_sessions));
-			goto abort;
-		}
-
-		if (pfm_sessions.pfs_sys_session[cpu]) {
-			DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n",pfm_sessions.pfs_sys_session[cpu]->pid, cpu));
-			goto abort;
-		}
-		pfm_sessions.pfs_sys_session[cpu] = task;
-		/*
-		 * count the number of system wide sessions
-		 */
-		pfm_sessions.pfs_sys_sessions++;
-
-	} else if (pfm_sessions.pfs_sys_sessions == 0) {
-		pfm_sessions.pfs_task_sessions++;
-	} else {
-		/* no per-process monitoring while there is a system wide session */
-		goto abort;
-	}
-
-	UNLOCK_PFS();
+	ret = pfm_reserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE, tmp.ctx_cpu_mask);
+	if (ret) goto abort;
 
 	ret = -ENOMEM;
 
@@ -1103,6 +1223,7 @@
 	ctx->ctx_fl_inherit   = ctx_flags & PFM_FL_INHERIT_MASK;
 	ctx->ctx_fl_block     = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
 	ctx->ctx_fl_system    = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
+	ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
 	ctx->ctx_fl_frozen    = 0;
 	/*
 	 * setting this flag to 0 here means, that the creator or the task that the
@@ -1113,14 +1234,10 @@
 	ctx->ctx_fl_protected = 0;
 
 	/* for system wide mode only (only 1 bit set) */
-	ctx->ctx_cpu         = cpu;
+	ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask);
 
 	atomic_set(&ctx->ctx_last_cpu,-1); /* SMP only, means no CPU */
 
-	/* may be redudant with memset() but at least it's easier to remember */
-	atomic_set(&ctx->ctx_saving_in_progress, 0); 
-	atomic_set(&ctx->ctx_is_busy, 0); 
-
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
 	if (__copy_to_user(req, &tmp, sizeof(tmp))) {
@@ -1131,9 +1248,9 @@
 	DBprintk(("context=%p, pid=%d notify_task=%p\n",
 			(void *)ctx, task->pid, ctx->ctx_notify_task));
 
-	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d\n", 
+	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d\n", 
 			(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, 
-			ctx->ctx_fl_block, ctx->ctx_fl_system));
+			ctx->ctx_fl_block, ctx->ctx_fl_system, ctx->ctx_fl_excl_idle));
 
 	/*
 	 * when no notification is required, we can make this visible at the last moment
@@ -1146,8 +1263,8 @@
 	 */
 	if (ctx->ctx_fl_system) {
 		ctx->ctx_saved_cpus_allowed = task->cpus_allowed;
-		set_cpus_allowed(task, 1UL << cpu);
-		DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid,task->cpus_allowed));
+		set_cpus_allowed(task, tmp.ctx_cpu_mask);
+		DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid, task->cpus_allowed));
 	}
 
 	return 0;
@@ -1155,20 +1272,8 @@
 buffer_error:
 	pfm_context_free(ctx);
 error:
-	/*
-	 * undo session reservation
-	 */
-	LOCK_PFS();
-
-	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
-		pfm_sessions.pfs_sys_session[cpu] = NULL;
-		pfm_sessions.pfs_sys_sessions--;
-	} else {
-		pfm_sessions.pfs_task_sessions--;
-	}
+	pfm_unreserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE , tmp.ctx_cpu_mask);
 abort:
-	UNLOCK_PFS();
-
 	/* make sure we don't leave anything behind */
 	task->thread.pfm_context = NULL;
 
@@ -1200,9 +1305,7 @@
 	unsigned long mask = ovfl_regs[0];
 	unsigned long reset_others = 0UL;
 	unsigned long val;
-	int i, is_long_reset = (flag & PFM_RELOAD_LONG_RESET);
-
-	DBprintk(("masks=0x%lx\n", mask));
+	int i, is_long_reset = (flag == PFM_PMD_LONG_RESET);
 
 	/*
 	 * now restore reset value on sampling overflowed counters
@@ -1213,7 +1316,7 @@
 			val = pfm_new_counter_value(ctx->ctx_soft_pmds + i, is_long_reset);
 			reset_others |= ctx->ctx_soft_pmds[i].reset_pmds[0];
 
-			DBprintk(("[%d] %s reset soft_pmd[%d]=%lx\n", current->pid,
+			DBprintk_ovfl(("[%d] %s reset soft_pmd[%d]=%lx\n", current->pid,
 				  is_long_reset ? "long" : "short", i, val));
 
 			/* upper part is ignored on rval */
@@ -1235,7 +1338,7 @@
 		} else {
 			ia64_set_pmd(i, val);
 		}
-		DBprintk(("[%d] %s reset_others pmd[%d]=%lx\n", current->pid,
+		DBprintk_ovfl(("[%d] %s reset_others pmd[%d]=%lx\n", current->pid,
 			  is_long_reset ? "long" : "short", i, val));
 	}
 	ia64_srlz_d();
@@ -1246,7 +1349,7 @@
 {
 	struct thread_struct *th = &task->thread;
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
-	unsigned long value;
+	unsigned long value, reset_pmds;
 	unsigned int cnum, reg_flags, flags;
 	int i;
 	int ret = -EINVAL;
@@ -1262,10 +1365,11 @@
 
 		if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		cnum      = tmp.reg_num;
-		reg_flags = tmp.reg_flags;
-		value     = tmp.reg_value;
-		flags     = 0;
+		cnum       = tmp.reg_num;
+		reg_flags  = tmp.reg_flags;
+		value      = tmp.reg_value;
+		reset_pmds = tmp.reg_reset_pmds[0];
+		flags      = 0;
 
 		/* 
 		 * we reject all non implemented PMC as well
@@ -1283,6 +1387,8 @@
 		 * any other configuration is rejected.
 		 */
 		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
+			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); 
+
 			if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) {
 				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system));
 				goto error;
@@ -1310,6 +1416,11 @@
 
 			if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM;
 
+			/* verify validity of reset_pmds */
+			if ((reset_pmds & pmu_conf.impl_pmds[0]) != reset_pmds) {
+				DBprintk(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum));
+				goto error;
+			}
 		} else if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) {
 				DBprintk(("cannot set ovfl_notify or random on pmc%u\n", cnum));
 				goto error;
@@ -1348,13 +1459,10 @@
 		ctx->ctx_soft_pmds[cnum].flags = flags;
 
 		if (PMC_IS_COUNTING(cnum)) {
-			/*
-			 * copy reset vector
-			 */
-			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = tmp.reg_reset_pmds[0];
-			ctx->ctx_soft_pmds[cnum].reset_pmds[1] = tmp.reg_reset_pmds[1];
-			ctx->ctx_soft_pmds[cnum].reset_pmds[2] = tmp.reg_reset_pmds[2];
-			ctx->ctx_soft_pmds[cnum].reset_pmds[3] = tmp.reg_reset_pmds[3];
+			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds;
+
+			/* mark all PMDS to be accessed as used */
+			CTX_USED_PMD(ctx, reset_pmds);
 		}
 
 		/*
@@ -1397,7 +1505,7 @@
 	unsigned long value, hw_value;
 	unsigned int cnum;
 	int i;
-	int ret;
+	int ret = 0;
 
 	/* we don't quite support this right now */
 	if (task != current) return -EINVAL;
@@ -1448,9 +1556,9 @@
 		/* update virtualized (64bits) counter */
 		if (PMD_IS_COUNTING(cnum)) {
 			ctx->ctx_soft_pmds[cnum].lval = value;
-			ctx->ctx_soft_pmds[cnum].val  = value & ~pmu_conf.perf_ovfl_val;
+			ctx->ctx_soft_pmds[cnum].val  = value & ~pmu_conf.ovfl_val;
 
-			hw_value = value & pmu_conf.perf_ovfl_val; 
+			hw_value = value & pmu_conf.ovfl_val;
 
 			ctx->ctx_soft_pmds[cnum].long_reset  = tmp.reg_long_reset;
 			ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset;
@@ -1478,7 +1586,7 @@
 				ctx->ctx_soft_pmds[cnum].val,
 				ctx->ctx_soft_pmds[cnum].short_reset,
 				ctx->ctx_soft_pmds[cnum].long_reset,
-				ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val,
+				ia64_get_pmd(cnum) & pmu_conf.ovfl_val,
 				PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
 				ctx->ctx_used_pmds[0],
 				ctx->ctx_soft_pmds[cnum].reset_pmds[0]));
@@ -1504,15 +1612,18 @@
 	return ret;
 }
 
-
 static int
 pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
 	struct thread_struct *th = &task->thread;
-	unsigned long val = 0UL;
+	unsigned long val, lval;
 	pfarg_reg_t *req = (pfarg_reg_t *)arg;
 	unsigned int cnum, reg_flags = 0;
-	int i, ret = -EINVAL;
+	int i, ret = 0;
+
+#if __GNUC__ < 3
+	int foo;
+#endif
 
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
@@ -1528,9 +1639,16 @@
 	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
 
 	for (i = 0; i < count; i++, req++) {
-
+#if __GNUC__ < 3
+		foo = __get_user(cnum, &req->reg_num);
+		if (foo) return -EFAULT;
+		foo = __get_user(reg_flags, &req->reg_flags);
+		if (foo) return -EFAULT;
+#else
 		if (__get_user(cnum, &req->reg_num)) return -EFAULT;
 		if (__get_user(reg_flags, &req->reg_flags)) return -EFAULT;
+#endif
+		lval = 0UL;
 
 		if (!PMD_IS_IMPL(cnum)) goto abort_mission;
 		/*
@@ -1553,34 +1671,16 @@
 			val = ia64_get_pmd(cnum);
 			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
-#ifdef CONFIG_SMP
-			int cpu;
-			/*
-			 * for SMP system, the context may still be live on another
-			 * CPU so we need to fetch it before proceeding with the read
-			 * This call we only be made once for the whole loop because
-			 * of ctx_last_cpu becoming == -1.
-			 *
-			 * We cannot reuse ctx_last_cpu as it may change before we get to the
-			 * actual IPI call. In this case, we will do the call for nothing but
-			 * there is no way around it. The receiving side will simply do nothing.
-			 */
-			cpu = atomic_read(&ctx->ctx_last_cpu);
-			if (cpu != -1) {
-				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid));
-				pfm_fetch_regs(cpu, task, ctx);
-			}
-#endif
-			/* context has been saved */
 			val = th->pmd[cnum];
 		}
 		if (PMD_IS_COUNTING(cnum)) {
 			/*
 			 * XXX: need to check for overflow
 			 */
-
-			val &= pmu_conf.perf_ovfl_val;
+			val &= pmu_conf.ovfl_val;
 			val += ctx->ctx_soft_pmds[cnum].val;
+
+			lval = ctx->ctx_soft_pmds[cnum].lval;
 		} 
 
 		/*
@@ -1592,10 +1692,11 @@
 			val = v;
 		}
 
-		PFM_REG_RETFLAG_SET(reg_flags, 0);
+		PFM_REG_RETFLAG_SET(reg_flags, ret);
 
 		DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n", 
-			cnum, ret, val, ia64_get_pmc(cnum)));
+					cnum, ret, val, ia64_get_pmc(cnum)));
+
 		/*
 		 * update register return value, abort all if problem during copy.
 		 * we only modify the reg_flags field. no check mode is fine because
@@ -1604,16 +1705,19 @@
 		if (__put_user(cnum, &req->reg_num)) return -EFAULT;
 		if (__put_user(val, &req->reg_value)) return -EFAULT;
 		if (__put_user(reg_flags, &req->reg_flags)) return -EFAULT;
+		if (__put_user(lval, &req->reg_last_reset_value)) return -EFAULT;
 	}
 
 	return 0;
 
 abort_mission:
 	PFM_REG_RETFLAG_SET(reg_flags, PFM_REG_RETFL_EINVAL);
+	/* 
+	 * XXX: if this fails, we stick with the original failure, flag not updated!
+	 */
+	__put_user(reg_flags, &req->reg_flags);
 
-	if (__put_user(reg_flags, &req->reg_flags)) ret = -EFAULT;
-
-	return ret;
+	return -EINVAL;
 }
 
 #ifdef PFM_PMU_USES_DBR
@@ -1655,7 +1759,7 @@
 	else
 		pfm_sessions.pfs_ptrace_use_dbregs++;
 
-	DBprintk(("ptrace_use_dbregs=%lu  sys_use_dbregs=%lu by [%d] ret = %d\n", 
+	DBprintk(("ptrace_use_dbregs=%u  sys_use_dbregs=%u by [%d] ret = %d\n", 
 		  pfm_sessions.pfs_ptrace_use_dbregs, 
 		  pfm_sessions.pfs_sys_use_dbregs, 
 		  task->pid, ret));
@@ -1673,7 +1777,6 @@
  * perfmormance monitoring, so we only decrement the number
  * of "ptraced" debug register users to keep the count up to date
  */
-
 int
 pfm_release_debug_registers(struct task_struct *task)
 {
@@ -1681,7 +1784,8 @@
 
 	LOCK_PFS();
 	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-		printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+		printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n",
+		       task->pid);
 		ret = -1;
 	}  else {
 		pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -1702,6 +1806,7 @@
 {
 	return 0;
 }
+
 int
 pfm_release_debug_registers(struct task_struct *task)
 {
@@ -1721,9 +1826,12 @@
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
 	if (task == current) {
-		DBprintk(("restarting self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen));
+		DBprintk(("restarting self %d frozen=%d ovfl_regs=0x%lx\n", 
+			task->pid, 
+			ctx->ctx_fl_frozen,
+			ctx->ctx_ovfl_regs[0]));
 
-		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET);
+		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
 
 		ctx->ctx_ovfl_regs[0] = 0UL;
 
@@ -1739,8 +1847,7 @@
 		}
 
 		/* simply unfreeze */
-		ia64_set_pmc(0, 0);
-		ia64_srlz_d();
+		pfm_unfreeze_pmu();
 
 		return 0;
 	} 
@@ -1806,18 +1913,18 @@
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
 		/* stop monitoring */
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+		pfm_clear_psr_pp();
 
 		ia64_srlz_i();
 
-		__get_cpu_var(pfm_dcr_pp)  = 0;
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
 
 		ia64_psr(regs)->pp = 0;
 
 	} else {
 
 		/* stop monitoring */
-		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+		pfm_clear_psr_up();
 
 		ia64_srlz_i();
 
@@ -1939,7 +2046,7 @@
 
 	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
+	printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
 
 	return 0;
 }
@@ -1979,14 +2086,9 @@
 	int i, ret = 0;
 
 	/*
-	 * for range restriction: psr.db must be cleared or the
-	 * the PMU will ignore the debug registers.
-	 *
-	 * XXX: may need more in system wide mode,
-	 * no task can have this bit set?
+	 * we do not need to check for ipsr.db because we do clear ibr.x, dbr.r, and dbr.w
+	 * ensuring that no real breakpoint can be installed via this call.
 	 */
-	if (ia64_psr(regs)->db == 1) return -EINVAL;
-
 
 	first_time = ctx->ctx_fl_using_dbreg == 0;
 
@@ -2055,7 +2157,6 @@
 	 * Now install the values into the registers
 	 */
 	for (i = 0; i < count; i++, req++) {
-
 		
 		if (__copy_from_user(&tmp, req, sizeof(tmp))) goto abort_mission;
 		
@@ -2145,7 +2246,7 @@
 		 * XXX: for now we can only come here on EINVAL
 		 */
 		PFM_REG_RETFLAG_SET(tmp.dbreg_flags, PFM_REG_RETFL_EINVAL);
-		__put_user(tmp.dbreg_flags, &req->dbreg_flags);
+		if (__put_user(tmp.dbreg_flags, &req->dbreg_flags)) ret = -EFAULT;
 	}
 	return ret;
 }
@@ -2209,19 +2310,19 @@
 				current));
 
 	if (PMU_OWNER() != task) {
-		printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
+		printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
 		return -EINVAL;
 	}
 
 	if (ctx->ctx_fl_system) {
 		
-		__get_cpu_var(pfm_dcr_pp)  = 1;
+		PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP);
 
 		/* set user level psr.pp */
 		ia64_psr(regs)->pp = 1;
 
 		/* start monitoring at kernel level */
-		__asm__ __volatile__ ("ssm psr.pp;;"::: "memory");
+		pfm_set_psr_pp();
 
 		/* enable dcr pp */
 		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
@@ -2230,14 +2331,15 @@
 
 	} else {
 		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
-			printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid);
+			printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n",
+			       task->pid);
 			return -EINVAL;
 		}
 		/* set user level psr.up */
 		ia64_psr(regs)->up = 1;
 
 		/* start monitoring at kernel level */
-		__asm__ __volatile__ ("sum psr.up;;"::: "memory");
+		pfm_set_psr_up();
 
 		ia64_srlz_i();
 	}
@@ -2264,11 +2366,12 @@
 		ia64_psr(regs)->up = 0; /* just to make sure! */
 
 		/* make sure monitoring is stopped */
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+		pfm_clear_psr_pp();
 		ia64_srlz_i();
 
-		__get_cpu_var(pfm_dcr_pp)    = 0;
-		__get_cpu_var(pfm_syst_wide) = 1;
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
+		PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE);
+		if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE);
 	} else {
 		/*
 		 * needed in case the task was a passive task during
@@ -2279,7 +2382,7 @@
 		ia64_psr(regs)->up = 0;
 
 		/* make sure monitoring is stopped */
-		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+		pfm_clear_psr_up();
 		ia64_srlz_i();
 
 		DBprintk(("clearing psr.sp for [%d]\n", current->pid));
@@ -2297,8 +2400,7 @@
 	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
 
 	/* simply unfreeze */
-	ia64_set_pmc(0, 0);
-	ia64_srlz_d();
+	pfm_unfreeze_pmu();
 
 	return 0;
 }
@@ -2331,6 +2433,7 @@
 abort_mission:
 	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
 	if (__copy_to_user(req, &tmp, sizeof(tmp))) ret = -EFAULT;
+
 	return ret;
 }
 
@@ -2400,7 +2503,7 @@
 	return ret;
 }
 
-asmlinkage int
+asmlinkage long
 sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, long arg7, 
 		long arg8, long stack)
 {
@@ -2503,7 +2606,7 @@
 	 * do some sanity checks first
 	 */
 	if (!ctx) {
-		printk("perfmon: [%d] has no PFM context\n", current->pid);
+		printk(KERN_DEBUG "perfmon: [%d] has no PFM context\n", current->pid);
 		return;
 	}
 
@@ -2532,7 +2635,7 @@
 		 * use the local reference
 		 */
 
-		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET);
+		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
 
 		ctx->ctx_ovfl_regs[0] = 0UL;
 
@@ -2545,8 +2648,7 @@
 			ctx->ctx_psb->psb_index = 0;
 		}
 
-		ia64_set_pmc(0, 0);
-		ia64_srlz_d();
+		pfm_unfreeze_pmu();
 
 		/* state restored, can go back to work (user mode) */
 	}
@@ -2591,19 +2693,11 @@
 	h->pid  = current->pid;
 	h->cpu  = smp_processor_id();
 	h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL;
-	/* 
-	 * where did the fault happen
-	 */
-	h->ip   = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL;	
-
-	/* 
-	 * which registers overflowed
-	 */
-	h->regs = ovfl_mask;
+	h->ip   = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL;
+	h->regs = ovfl_mask; 			/* which registers overflowed */
 
 	/* guaranteed to monotonically increase on each cpu */
 	h->stamp  = pfm_get_stamp();
-	h->period = 0UL; /* not yet used */
 
 	/* position for first pmd */
 	e = (unsigned long *)(h+1);
@@ -2683,16 +2777,16 @@
 	 * Don't think this could happen given upfront tests
 	 */
 	if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
-		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", 
-			task->pid);
+		printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not "
+		       "using perfmon\n", task->pid);
 		return 0x1;
 	}
 	/*
 	 * sanity test. Should never happen
 	 */
 	if ((pmc0 & 0x1) == 0) {
-		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", 
-			task->pid, pmc0);
+		printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n",
+		       task->pid, pmc0);
 		return 0x0;
 	}
 
@@ -2724,7 +2818,7 @@
 		 * pfm_read_pmds().
 		 */
 		old_val = ctx->ctx_soft_pmds[i].val;
-		ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
+		ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
 
 		/*
 		 * check for overflow condition
@@ -2739,9 +2833,7 @@
 		}
 		DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", 
 			  i, ctx->ctx_soft_pmds[i].val, old_val, 
-			  ia64_get_pmd(i) & pmu_conf.perf_ovfl_val, ovfl_pmds, ovfl_notify));
-
-
+			  ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify));
 	}
 
 	/*
@@ -2776,7 +2868,7 @@
 	 */
 	if (ovfl_notify == 0UL) {
 		if (ovfl_pmds) 
-			pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
+			pfm_reset_regs(ctx, &ovfl_pmds, PFM_PMD_SHORT_RESET);
 		return 0x0;
 	}
 
@@ -2859,8 +2951,8 @@
 		 * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock
 		 */
 		ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
-		if (ret != 0) 
-			printk("send_sig_info(process %d, SIGPROF)=%d\n",  
+		if (ret != 0)
+			printk(KERN_DEBUG "send_sig_info(process %d, SIGPROF)=%d\n",
 			       ctx->ctx_notify_task->pid, ret);
 		/*
 		 * now undo the protections in order
@@ -2924,7 +3016,7 @@
 }
 
 static void
-perfmon_interrupt (int irq, void *arg, struct pt_regs *regs)
+pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
 {
 	u64 pmc0;
 	struct task_struct *task;
@@ -2932,6 +3024,14 @@
 
 	pfm_stats[smp_processor_id()].pfm_ovfl_intr_count++;
 
+	/*
+	 * if an alternate handler is registered, just bypass the default one
+	 */
+	if (pfm_alternate_intr_handler) {
+		(*pfm_alternate_intr_handler->handler)(irq, arg, regs);
+		return;
+	}
+
 	/* 
 	 * srlz.d done before arriving here
 	 *
@@ -2951,23 +3051,10 @@
 
 		/* sanity check */
 		if (!ctx) {
-			printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
-				task->pid);
+			printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d has "
+			       "no PFM context\n", task->pid);
 			return;
 		}
-#ifdef CONFIG_SMP
-		/*
-		 * Because an IPI has higher priority than the PMU overflow interrupt, it is 
-		 * possible that the handler be interrupted by a request from another CPU to fetch 
-		 * the PMU state of the currently active context. The task may have just been 
-		 * migrated to another CPU which is trying to restore the context. If there was
-		 * a pending overflow interrupt when the task left this CPU, it is possible for
-		 * the handler to get interrupt by the IPI. In which case, we fetch request
-		 * MUST be postponed until the interrupt handler is done. The ctx_is_busy
-		 * flag indicates such a condition. The other CPU must busy wait until it's cleared.
-		 */
-		atomic_set(&ctx->ctx_is_busy, 1);
-#endif
 
 		/* 
 		 * assume PMC[0].fr = 1 at this point 
@@ -2981,12 +3068,6 @@
 		ia64_set_pmc(0, pmc0);
 		ia64_srlz_d();
 
-#ifdef CONFIG_SMP
-		/*
-		 * announce that we are doing with the context
-		 */
-		atomic_set(&ctx->ctx_is_busy, 0);
-#endif
 	} else {
 		pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++;
 	}
@@ -2994,14 +3075,13 @@
 
 /* for debug only */
 static int
-perfmon_proc_info(char *page)
+pfm_proc_info(char *page)
 {
 	char *p = page;
 	int i;
 
-	p += sprintf(p, "enabled                : %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes");
 	p += sprintf(p, "fastctxsw              : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
-	p += sprintf(p, "ovfl_mask              : 0x%lx\n", pmu_conf.perf_ovfl_val);
+	p += sprintf(p, "ovfl_mask              : 0x%lx\n", pmu_conf.ovfl_val);
 
 	for(i=0; i < NR_CPUS; i++) {
 		if (cpu_is_online(i) == 0) continue;
@@ -3009,16 +3089,18 @@
 		p += sprintf(p, "CPU%-2d spurious intrs   : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count);
 		p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count);
 		p += sprintf(p, "CPU%-2d smpl buffer full : %lu\n", i, pfm_stats[i].pfm_full_smpl_buffer_count);
+		p += sprintf(p, "CPU%-2d syst_wide        : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_SYST_WIDE ? 1 : 0);
+		p += sprintf(p, "CPU%-2d dcr_pp           : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_DCR_PP ? 1 : 0);
+		p += sprintf(p, "CPU%-2d exclude idle     : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0);
 		p += sprintf(p, "CPU%-2d owner            : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
-		p += sprintf(p, "CPU%-2d syst_wide        : %d\n", i, per_cpu(pfm_syst_wide, i));
-		p += sprintf(p, "CPU%-2d dcr_pp           : %d\n", i, per_cpu(pfm_dcr_pp, i));
 	}
 
 	LOCK_PFS();
-	p += sprintf(p, "proc_sessions          : %lu\n"
-			"sys_sessions           : %lu\n"
-			"sys_use_dbregs         : %lu\n"
-			"ptrace_use_dbregs      : %lu\n", 
+
+	p += sprintf(p, "proc_sessions          : %u\n"
+			"sys_sessions           : %u\n"
+			"sys_use_dbregs         : %u\n"
+			"ptrace_use_dbregs      : %u\n", 
 			pfm_sessions.pfs_task_sessions, 
 			pfm_sessions.pfs_sys_sessions,
 			pfm_sessions.pfs_sys_use_dbregs,
@@ -3033,7 +3115,7 @@
 static int
 perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	int len = perfmon_proc_info(page);
+	int len = pfm_proc_info(page);
 
 	if (len <= off+count) *eof = 1;
 
@@ -3046,24 +3128,66 @@
 	return len;
 }
 
+/*
+ * we come here as soon as PFM_CPUINFO_SYST_WIDE is set. This happens
+ * during pfm_enable() hence before pfm_start(). We cannot assume monitoring
+ * is active or inactive based on mode. We must rely on the value in 
+ * cpu_data(i)->pfm_syst_info
+ */
 void
-pfm_syst_wide_update_task(struct task_struct *task, int mode)
+pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
 {
-	struct pt_regs *regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET);
+	struct pt_regs *regs;
+	unsigned long dcr;
+	unsigned long dcr_pp;
 
-	regs--;
+	dcr_pp = info & PFM_CPUINFO_DCR_PP ? 1 : 0;
 
 	/*
-	 * propagate the value of the dcr_pp bit to the psr
+	 * pid 0 is guaranteed to be the idle task. There is one such task with pid 0 
+	 * on every CPU, so we can rely on the pid to identify the idle task.
+	 */
+	if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) {
+		regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET);
+		regs--;
+		ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0;
+		return;
+	}
+	/*
+	 * if monitoring has started
 	 */
-	ia64_psr(regs)->pp = mode ? __get_cpu_var(pfm_dcr_pp) : 0;
+	if (dcr_pp) {
+		dcr = ia64_get_dcr();
+		/* 
+		 * context switching in? 
+		 */
+		if (is_ctxswin) {
+			/* mask monitoring for the idle task */
+			ia64_set_dcr(dcr & ~IA64_DCR_PP);
+			pfm_clear_psr_pp();
+			ia64_srlz_i();
+			return;
+		}
+		/* 
+		 * context switching out
+		 * restore monitoring for next task 
+		 *
+		 * Due to inlining this odd if-then-else construction generates 
+		 * better code.
+		 */
+		ia64_set_dcr(dcr |IA64_DCR_PP);
+		pfm_set_psr_pp();
+		ia64_srlz_i();
+	}
 }
 
 void
 pfm_save_regs (struct task_struct *task)
 {
 	pfm_context_t *ctx;
+	unsigned long mask;
 	u64 psr;
+	int i;
 
 	ctx = task->thread.pfm_context;
 
@@ -3071,7 +3195,7 @@
 	/*
 	 * save current PSR: needed because we modify it
 	 */
-	__asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory");
+	psr = pfm_get_psr();
 
 	/*
 	 * stop monitoring:
@@ -3080,129 +3204,61 @@
 	 * We do not need to set psr.sp because, it is irrelevant in kernel.
 	 * It will be restored from ipsr when going back to user level
 	 */
-	__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+	pfm_clear_psr_up();
 	ia64_srlz_i();
 
 	ctx->ctx_saved_psr = psr;
 
-	//ctx->ctx_last_cpu  = smp_processor_id();
-
-}
-
-static void
-pfm_lazy_save_regs (struct task_struct *task)
-{
-	pfm_context_t *ctx;
-	struct thread_struct *t;
-	unsigned long mask;
-	int i;
-
-	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
-
-	t   = &task->thread;
-	ctx = task->thread.pfm_context;
-
 #ifdef CONFIG_SMP
-	/* 
-	 * announce we are saving this PMU state
-	 * This will cause other CPU, to wait until we're done
-	 * before using the context.h
+	/*
+	 * We do not use a lazy scheme in SMP because
+	 * of the new scheduler which masks interrupts
+	 * during low-level context switch. So we save
+	 * all the PMD register we use and restore on
+	 * ctxsw in.
 	 *
-	 * must be an atomic operation
+	 * release ownership of this PMU.
+	 * must be done before we save the registers.
 	 */
-	atomic_set(&ctx->ctx_saving_in_progress, 1);
-
-	 /*
-	  * if owner is NULL, it means that the other CPU won the race
-	  * and the IPI has caused the context to be saved in pfm_handle_fectch_regs()
-	  * instead of here. We have nothing to do
-	  *
-	  * note that this is safe, because the other CPU NEVER modifies saving_in_progress.
-	  */
-	if (PMU_OWNER() == NULL) goto do_nothing;
-#endif
+	SET_PMU_OWNER(NULL);
 
 	/*
-	 * do not own the PMU
+	 * save PMDs
 	 */
-	SET_PMU_OWNER(NULL);
-
 	ia64_srlz_d();
 
-	/*
-	 * XXX needs further optimization.
-	 * Also must take holes into account
-	 */
 	mask = ctx->ctx_used_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
+		if (mask & 0x1) task->thread.pmd[i] =ia64_get_pmd(i);
 	}
 
-	/* save pmc0 */
-	t->pmc[0] = ia64_get_pmc(0);
+	/* 
+	 * save pmc0 
+	 */
+	task->thread.pmc[0] = ia64_get_pmc(0);
 
-	/* not owned by this CPU */
+	/* 
+	 * force a full reload 
+	 */
 	atomic_set(&ctx->ctx_last_cpu, -1);
-
-#ifdef CONFIG_SMP
-do_nothing:
 #endif
-	/*
-	 * declare we are done saving this context
-	 *
-	 * must be an atomic operation
-	 */
-	atomic_set(&ctx->ctx_saving_in_progress,0);
-
 }
 
-#ifdef CONFIG_SMP
-/*
- * Handles request coming from other CPUs
- */
-static void 
-pfm_handle_fetch_regs(void *info)
+static void
+pfm_lazy_save_regs (struct task_struct *task)
 {
-	pfm_smp_ipi_arg_t *arg = info;
-	struct thread_struct *t;
 	pfm_context_t *ctx;
+	struct thread_struct *t;
 	unsigned long mask;
 	int i;
 
-	ctx = arg->task->thread.pfm_context;
-	t   = &arg->task->thread;
-
-	DBprintk(("task=%d owner=%d saving=%d\n", 
-		  arg->task->pid,
-		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
-		  atomic_read(&ctx->ctx_saving_in_progress)));
-
-	/* must wait until not busy before retrying whole request */
-	if (atomic_read(&ctx->ctx_is_busy)) {
-		arg->retval = 2;
-		return;
-	}
-
-	/* must wait if saving was interrupted */
-	if (atomic_read(&ctx->ctx_saving_in_progress)) {
-		arg->retval = 1;
-		return;
-	}
-
-	/* can proceed, done with context */
-	if (PMU_OWNER() != arg->task) {
-		arg->retval = 0;
-		return;
-	}
+	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
 
-	DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", 
-		arg->task->pid,
-		ctx->ctx_used_pmcs[0],
-		ctx->ctx_reload_pmcs[0],
-		ctx->ctx_used_pmds[0]));
+	t   = &task->thread;
+	ctx = task->thread.pfm_context;
 
 	/*
-	 * XXX: will be replaced with pure assembly call
+	 * do not own the PMU
 	 */
 	SET_PMU_OWNER(NULL);
 
@@ -3210,10 +3266,11 @@
 
 	/*
 	 * XXX needs further optimization.
+	 * Also must take holes into account
 	 */
 	mask = ctx->ctx_used_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i);
+		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
 	}
 
 	/* save pmc0 */
@@ -3221,66 +3278,7 @@
 
 	/* not owned by this CPU */
 	atomic_set(&ctx->ctx_last_cpu, -1);
-
-	/* can proceed */
-	arg->retval = 0;
-}
-
-/*
- * Function call to fetch PMU state from another CPU identified by 'cpu'.
- * If the context is being saved on the remote CPU, then we busy wait until
- * the saving is done and then we return. In this case, non IPI is sent.
- * Otherwise, we send an IPI to the remote CPU, potentially interrupting 
- * pfm_lazy_save_regs() over there.
- *
- * If the retval==1, then it means that we interrupted remote save and that we must
- * wait until the saving is over before proceeding.
- * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there.
- * in either case, we can proceed.
- */
-static void
-pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx)
-{
-	pfm_smp_ipi_arg_t  arg;
-	int ret;
-
-	arg.task   = task;
-	arg.retval = -1;
-
-	if (atomic_read(&ctx->ctx_is_busy)) {
-must_wait_busy:
-		while (atomic_read(&ctx->ctx_is_busy));
-	}
-
-	if (atomic_read(&ctx->ctx_saving_in_progress)) {
-		DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
-must_wait_saving:
-		/* busy wait */
-		while (atomic_read(&ctx->ctx_saving_in_progress));
-		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
-		return;
-	}
-	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
-
-	if (cpu == -1) {
-		printk("refusing to use -1 for [%d]\n", task->pid);
-		return;
-	}
-
-	/* will send IPI to other CPU and wait for completion of remote call */
-	if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) {
-		printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret);
-		return;
-	}
-	/*
-	 * we must wait until saving is over on the other CPU
-	 * This is the case, where we interrupted the saving which started just at the time we sent the
-	 * IPI.
-	 */
-	if (arg.retval == 1) goto must_wait_saving;
-	if (arg.retval == 2) goto must_wait_busy;
 }
-#endif /* CONFIG_SMP */
 
 void
 pfm_load_regs (struct task_struct *task)
@@ -3291,14 +3289,16 @@
 	unsigned long mask;
 	u64 psr;
 	int i;
-#ifdef CONFIG_SMP
-	int cpu;
-#endif
 
 	owner = PMU_OWNER();
 	ctx   = task->thread.pfm_context;
 	t     = &task->thread;
 
+	if (ctx == NULL) {
+		printk("perfmon: pfm_load_regs: null ctx for [%d]\n", task->pid);
+		return;
+	}
+
 	/*
 	 * we restore ALL the debug registers to avoid picking up 
 	 * stale state.
@@ -3324,6 +3324,7 @@
 
 	/*
 	 * if we were the last user, then nothing to do except restore psr
+	 * this path cannot be used in SMP
 	 */
 	if (owner == task) {
 		if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
@@ -3331,32 +3332,19 @@
 				atomic_read(&ctx->ctx_last_cpu), task->pid));
 
 		psr = ctx->ctx_saved_psr;
-		__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
+		pfm_set_psr_l(psr);
 
 		return;
 	}
-	DBprintk(("load_regs: must reload for [%d] owner=%d\n", 
-		task->pid, owner ? owner->pid : -1 ));
+
 	/*
 	 * someone else is still using the PMU, first push it out and
 	 * then we'll be able to install our stuff !
+	 *
+	 * not possible in SMP
 	 */
 	if (owner) pfm_lazy_save_regs(owner);
 
-#ifdef CONFIG_SMP
-	/* 
-	 * check if context on another CPU (-1 means saved)
-	 * We MUST use the variable, as last_cpu may change behind our 
-	 * back. If it changes to -1 (not on a CPU anymore), then in cpu
-	 * we have the last CPU the context was on. We may be sending the 
-	 * IPI for nothing, but we have no way of verifying this. 
-	 */
-	cpu = atomic_read(&ctx->ctx_last_cpu);
-	if (cpu != -1) {
-		pfm_fetch_regs(cpu, task, ctx);
-	}
-#endif
-
 	/*
 	 * To avoid leaking information to the user level when psr.sp=0,
 	 * we must reload ALL implemented pmds (even the ones we don't use).
@@ -3369,7 +3357,7 @@
 	 */
 	mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.perf_ovfl_val);
+		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.ovfl_val);
 	}
 
 	/* 
@@ -3393,8 +3381,7 @@
 	 * fl_frozen==1 when we are in blocking mode waiting for restart
 	 */
 	if (ctx->ctx_fl_frozen == 0) {
-		ia64_set_pmc(0, 0);
-		ia64_srlz_d();
+		pfm_unfreeze_pmu();
 	}
 	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
 
@@ -3404,8 +3391,7 @@
 	 * restore the psr we changed in pfm_save_regs()
 	 */
 	psr = ctx->ctx_saved_psr;
-	__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
-
+	pfm_set_psr_l(psr);
 }
 
 /*
@@ -3419,15 +3405,16 @@
 	int i;
 
 	if (task != current) {
-		printk("perfmon: invalid task in ia64_reset_pmu()\n");
+		printk("perfmon: invalid task in pfm_reset_pmu()\n");
 		return;
 	}
 
 	/* Let's make sure the PMU is frozen */
-	ia64_set_pmc(0,1);
+	pfm_freeze_pmu();
 
 	/*
 	 * install reset values for PMC. We skip PMC0 (done above)
+	 * XX: good up to 64 PMCS
 	 */
 	for (i=1; (pmu_conf.pmc_desc[i].type & PFM_REG_END) == 0; i++) {
 		if ((pmu_conf.pmc_desc[i].type & PFM_REG_IMPL) == 0) continue;
@@ -3444,7 +3431,7 @@
 
 	/*
 	 * clear reset values for PMD. 
-	 * XXX: good up to 64 PMDS. Suppose that zero is a valid value.
+	 * XXX: good up to 64 PMDS.
 	 */
 	for (i=0; (pmu_conf.pmd_desc[i].type & PFM_REG_END) == 0; i++) {
 		if ((pmu_conf.pmd_desc[i].type & PFM_REG_IMPL) == 0) continue;
@@ -3477,13 +3464,13 @@
 	  *
 	  * We never directly restore PMC0 so we do not include it in the mask.
 	  */
-	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0] & ~0x1;
+	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_pmcs[0] & ~0x1;
 	/*
 	 * We must include all the PMD in this mask to avoid picking
 	 * up stale value and leak information, especially directly
 	 * at the user level when psr.sp=0
 	 */
-	ctx->ctx_reload_pmds[0] = pmu_conf.impl_regs[4];
+	ctx->ctx_reload_pmds[0] = pmu_conf.impl_pmds[0];
 
 	/* 
 	 * Keep track of the pmds we want to sample
@@ -3493,7 +3480,7 @@
 	 *
 	 * We ignore the unimplemented pmds specified by the user
 	 */
-	ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
+	ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0];
 	ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[0] */
 
 	/*
@@ -3547,16 +3534,17 @@
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
 		/* stop monitoring */
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+		pfm_clear_psr_pp();
 
 		ia64_srlz_i();
 
-		__get_cpu_var(pfm_syst_wide) = 0;
-		__get_cpu_var(pfm_dcr_pp)    = 0;
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE);
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE);
 	} else  {
 
 		/* stop monitoring */
-		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+		pfm_clear_psr_up();
 
 		ia64_srlz_i();
 
@@ -3589,8 +3577,7 @@
 	 * This destroys the overflow information. This is required to make sure
 	 * next process does not start with monitoring on if not requested
 	 */
-	ia64_set_pmc(0, 1);
-	ia64_srlz_d();
+	pfm_freeze_pmu();
 
 	/*
 	 * We don't need to restore psr, because we are on our way out
@@ -3606,8 +3593,9 @@
 	 *
 	 */
 
-	if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) 
-		printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu));
+	if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
+		printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n",
+		       task->pid, atomic_read(&ctx->ctx_last_cpu));
 
 	/*
 	 * we save all the used pmds
@@ -3622,10 +3610,14 @@
 		val = ia64_get_pmd(i);
 
 		if (PMD_IS_COUNTING(i)) {
-			DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", task->pid, i, ctx->ctx_soft_pmds[i].val, val & pmu_conf.perf_ovfl_val));
+			DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", 
+				task->pid, 
+				i, 
+				ctx->ctx_soft_pmds[i].val, 
+				val & pmu_conf.ovfl_val));
 
 			/* collect latest results */
-			ctx->ctx_soft_pmds[i].val += val & pmu_conf.perf_ovfl_val;
+			ctx->ctx_soft_pmds[i].val += val & pmu_conf.ovfl_val;
 
 			/*
 			 * now everything is in ctx_soft_pmds[] and we need
@@ -3638,7 +3630,7 @@
 			 * take care of overflow inline
 			 */
 			if (pmc0 & (1UL << i)) {
-				ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
+				ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
 				DBprintk(("[%d] pmd[%d] overflowed soft_pmd=0x%lx\n",
 					task->pid, i, ctx->ctx_soft_pmds[i].val));
 			}
@@ -3771,8 +3763,8 @@
 	m = nctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
 	for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) {
 		if ((m & 0x1) && pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING) {
-			nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].lval & ~pmu_conf.perf_ovfl_val;
-			thread->pmd[i]	      	   = nctx->ctx_soft_pmds[i].lval & pmu_conf.perf_ovfl_val;
+			nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].lval & ~pmu_conf.ovfl_val;
+			thread->pmd[i]	      	   = nctx->ctx_soft_pmds[i].lval & pmu_conf.ovfl_val;
 		} else {
 			thread->pmd[i]	      	   = 0UL; /* reset to initial state */
 		}
@@ -3811,6 +3803,16 @@
 
 	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
 
+	/*
+	 * propagate kernel psr in new context (used for first ctxsw in
+	 */
+	nctx->ctx_saved_psr = pfm_get_psr();
+
+	/*
+	 * propagate kernel psr in new context (used for first ctxsw in
+	 */
+	nctx->ctx_saved_psr = pfm_get_psr();
+
 	/* link with new task */
 	thread->pfm_context = nctx;
 
@@ -3939,30 +3941,14 @@
 
 	UNLOCK_CTX(ctx);
 
-	LOCK_PFS();
+	pfm_unreserve_session(task, ctx->ctx_fl_system, 1UL << ctx->ctx_cpu);
 
 	if (ctx->ctx_fl_system) {
-
-		pfm_sessions.pfs_sys_session[ctx->ctx_cpu] = NULL;
-		pfm_sessions.pfs_sys_sessions--;
-		DBprintk(("freeing syswide session on CPU%ld\n", ctx->ctx_cpu));
-
-		/* update perfmon debug register usage counter */
-		if (ctx->ctx_fl_using_dbreg) {
-			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
-				printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid);
-			} else
-				pfm_sessions.pfs_sys_use_dbregs--;
-		}
-
 		/*
 	 	 * remove any CPU pinning
 	 	 */
 		set_cpus_allowed(task, ctx->ctx_saved_cpus_allowed);
-	} else {
-		pfm_sessions.pfs_task_sessions--;
-	}
-	UNLOCK_PFS();
+	} 
 
 	pfm_context_free(ctx);
 	/* 
@@ -3983,15 +3969,14 @@
 	pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return -1;
 	}
 	/*
 	 * Walk through the list and free the sampling buffer and psb
 	 */
 	while (psb) {
-		DBprintk(("[%d] freeing smpl @%p size %ld\n", 
-			current->pid, psb->psb_hdr, psb->psb_size));
+		DBprintk(("[%d] freeing smpl @%p size %ld\n", current->pid, psb->psb_hdr, psb->psb_size));
 
 		pfm_rvfree(psb->psb_hdr, psb->psb_size);
 		tmp = psb->psb_next;
@@ -4095,16 +4080,16 @@
 		if (ctx && ctx->ctx_notify_task == task) {
 			DBprintk(("trying for notifier [%d] in [%d]\n", task->pid, p->pid));
 			/*
-			 * the spinlock is required to take care of a race condition with
-			 * the send_sig_info() call. We must make sure that either the
-			 * send_sig_info() completes using a valid task, or the
-			 * notify_task is cleared before the send_sig_info() can pick up a
-			 * stale value. Note that by the time this function is executed
-			 * the 'task' is already detached from the tasklist. The problem
-			 * is that the notifiers have a direct pointer to it. It is okay
-			 * to send a signal to a task in this stage, it simply will have
-			 * no effect. But it is better than sending to a completely
-			 * destroyed task or worse to a new task using the same
+			 * the spinlock is required to take care of a race condition
+			 * with the send_sig_info() call. We must make sure that 
+			 * either the send_sig_info() completes using a valid task,
+			 * or the notify_task is cleared before the send_sig_info()
+			 * can pick up a stale value. Note that by the time this
+			 * function is executed the 'task' is already detached from the
+			 * tasklist. The problem is that the notifiers have a direct
+			 * pointer to it. It is okay to send a signal to a task in this
+			 * stage, it simply will have no effect. But it is better than sending
+			 * to a completely destroyed task or worse to a new task using the same
 			 * task_struct address.
 			 */
 			LOCK_CTX(ctx);
@@ -4123,87 +4108,130 @@
 }
 
 static struct irqaction perfmon_irqaction = {
-	.handler =	perfmon_interrupt,
-	.flags =	SA_INTERRUPT,
-	.name =		"perfmon"
+	.handler =	pfm_interrupt_handler,
+	.flags   =	SA_INTERRUPT,
+	.name    =	"perfmon"
 };
 
+int
+pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl)
+{
+	int ret;
+
+	/* some sanity checks */
+	if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
+
+	/* do the easy test first */
+	if (pfm_alternate_intr_handler) return -EBUSY;
+
+	/* reserve our session */
+	ret = pfm_reserve_session(NULL, 1, cpu_online_map);
+	if (ret) return ret;
+
+	if (pfm_alternate_intr_handler) {
+		printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL "
+		       "after reserve\n");
+		return -EINVAL;
+	}
+
+	pfm_alternate_intr_handler = hdl;
+
+	return 0;
+}
+
+int
+pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl)
+{
+	if (hdl == NULL) return -EINVAL;
+
+	/* cannot remove someone else's handler! */
+	if (pfm_alternate_intr_handler != hdl) return -EINVAL;
+
+	pfm_alternate_intr_handler = NULL;
+
+	/* 
+	 * XXX: assume cpu_online_map has not changed since reservation 
+	 */
+	pfm_unreserve_session(NULL, 1, cpu_online_map);
+
+	return 0;
+}
 
 /*
  * perfmon initialization routine, called from the initcall() table
  */
 int __init
-perfmon_init (void)
+pfm_init(void)
 {
-	pal_perf_mon_info_u_t pm_info;
-	s64 status;
+	unsigned int n, n_counters, i;
 
-	pmu_conf.pfm_is_disabled = 1;
+	pmu_conf.disabled = 1;
 
-	printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n", 
-		PFM_VERSION_MAJ, 
-		PFM_VERSION_MIN, 
-		PFM_SMPL_VERSION_MAJ, 
-		PFM_SMPL_VERSION_MIN, 
-		IA64_PERFMON_VECTOR);
+	printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN,
+	       IA64_PERFMON_VECTOR);
 
-	if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) {
-		printk("perfmon: PAL call failed (%ld), perfmon disabled\n", status);
-		return -1;
-	}
-
-	pmu_conf.perf_ovfl_val = (1UL << pm_info.pal_perf_mon_info_s.width) - 1;
 	/*
-	 * XXX: use the pfm_*_desc tables instead and simply verify with PAL
+	 * compute the number of implemented PMD/PMC from the
+	 * description tables
 	 */
-	pmu_conf.max_counters  = pm_info.pal_perf_mon_info_s.generic;
-	pmu_conf.num_pmcs      = find_num_pm_regs(pmu_conf.impl_regs);
-	pmu_conf.num_pmds      = find_num_pm_regs(&pmu_conf.impl_regs[4]);
+	n = 0;
+	for (i=0; PMC_IS_LAST(i) == 0;  i++) {
+		if (PMC_IS_IMPL(i) == 0) continue;
+		pmu_conf.impl_pmcs[i>>6] |= 1UL << (i&63);
+		n++;
+	}
+	pmu_conf.num_pmcs = n;
 
-	printk("perfmon: %u bits counters\n", pm_info.pal_perf_mon_info_s.width);
+	n = 0; n_counters = 0;
+	for (i=0; PMD_IS_LAST(i) == 0;  i++) {
+		if (PMD_IS_IMPL(i) == 0) continue;
+		pmu_conf.impl_pmds[i>>6] |= 1UL << (i&63);
+		n++;
+		if (PMD_IS_COUNTING(i)) n_counters++;
+	}
+	pmu_conf.num_pmds      = n;
+	pmu_conf.num_counters  = n_counters;
 
-	printk("perfmon: %lu PMC/PMD pairs, %lu PMCs, %lu PMDs\n", 
-	       pmu_conf.max_counters, pmu_conf.num_pmcs, pmu_conf.num_pmds);
+	printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n",
+	       pmu_conf.num_pmcs,
+	       pmu_conf.num_pmds,
+	       pmu_conf.num_counters,
+	       ffz(pmu_conf.ovfl_val));
 
 	/* sanity check */
 	if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) {
-		printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon is DISABLED\n");
-		return -1; /* no need to continue anyway */
-	}
-
-	if (ia64_pal_debug_info(&pmu_conf.num_ibrs, &pmu_conf.num_dbrs)) {
-		printk(KERN_WARNING "perfmon: unable to get number of debug registers\n");
-		pmu_conf.num_ibrs = pmu_conf.num_dbrs = 0;
+		printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n");
+		return -1;
 	}
-	/* PAL reports the number of pairs */
-	pmu_conf.num_ibrs <<=1;
-	pmu_conf.num_dbrs <<=1;
-
-	/*
-	 * setup the register configuration descriptions for the CPU
-	 */
-	pmu_conf.pmc_desc = pfm_pmc_desc;
-	pmu_conf.pmd_desc = pfm_pmd_desc;
-
-	/* we are all set */
-	pmu_conf.pfm_is_disabled = 0;
 
 	/*
 	 * for now here for debug purposes
 	 */
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
+	if (perfmon_dir == NULL) {
+		printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n");
+		return -1;
+	}
 
+	/*
+	 * create /proc/perfmon
+	 */
 	pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root, 0);
 
+	/*
+	 * initialize all our spinlocks
+	 */
 	spin_lock_init(&pfm_sessions.pfs_lock);
 
+	/* we are all set */
+	pmu_conf.disabled = 0;
+
 	return 0;
 }
-
-__initcall(perfmon_init);
+__initcall(pfm_init);
 
 void
-perfmon_init_percpu (void)
+pfm_init_percpu(void)
 {
 	int i;
 
@@ -4222,22 +4250,21 @@
 	 *
 	 * On McKinley, this code is ineffective until PMC4 is initialized.
 	 */
-	for (i=1; (pfm_pmc_desc[i].type & PFM_REG_END) == 0;  i++) {
-		if ((pfm_pmc_desc[i].type & PFM_REG_IMPL) == 0) continue;
-		ia64_set_pmc(i, pfm_pmc_desc[i].default_value);
+	for (i=1; PMC_IS_LAST(i) == 0;  i++) {
+		if (PMC_IS_IMPL(i) == 0) continue;
+		ia64_set_pmc(i, PMC_DFL_VAL(i));
 	}
-	for (i=0; (pfm_pmd_desc[i].type & PFM_REG_END) == 0; i++) {
-		if ((pfm_pmd_desc[i].type & PFM_REG_IMPL) == 0) continue;
+
+	for (i=0; PMD_IS_LAST(i); i++) {
+		if (PMD_IS_IMPL(i) == 0) continue;
 		ia64_set_pmd(i, 0UL);
 	}
-	ia64_set_pmc(0,1UL);
-	ia64_srlz_d();
-
+	pfm_freeze_pmu();
 }
 
 #else /* !CONFIG_PERFMON */
 
-asmlinkage int
+asmlinkage long
 sys_perfmonctl (int pid, int cmd, void *req, int count, long arg5, long arg6, 
 		long arg7, long arg8, long stack)
 {
diff -Nru a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h
--- a/arch/ia64/kernel/perfmon_generic.h	Mon Feb 10 10:39:25 2003
+++ b/arch/ia64/kernel/perfmon_generic.h	Mon Feb 10 10:39:25 2003
@@ -1,10 +1,17 @@
+/*
+ * This file contains the architected PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright (C) 2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ */
 #define RDEP(x)	(1UL<<(x))
 
-#if defined(CONFIG_ITANIUM) || defined(CONFIG_MCKINLEY)
-#error "This file should only be used when CONFIG_ITANIUM and CONFIG_MCKINLEY are not defined"
+#if defined(CONFIG_ITANIUM) || defined (CONFIG_MCKINLEY)
+#error "This file should not be used when CONFIG_ITANIUM or CONFIG_MCKINLEY is defined"
 #endif
 
-static pfm_reg_desc_t pmc_desc[PMU_MAX_PMCS]={
+static pfm_reg_desc_t pmc_gen_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -13,10 +20,10 @@
 /* pmc5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-	     { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
+	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
 
-static pfm_reg_desc_t pmd_desc[PMU_MAX_PMDS]={
+static pfm_reg_desc_t pmd_gen_desc[PMU_MAX_PMDS]={
 /* pmd0  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
 /* pmd1  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
 /* pmd2  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
@@ -25,5 +32,17 @@
 /* pmd5  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
 /* pmd6  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
 /* pmd7  */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
-	     { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
+	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+/*
+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
+ */
+static pmu_config_t pmu_conf={
+	.disabled = 1,
+	.ovfl_val = (1UL << 32) - 1,
+	.num_ibrs = 8,
+	.num_dbrs = 8,
+	.pmd_desc = pfm_gen_pmd_desc,
+	.pmc_desc = pfm_gen_pmc_desc
 };
diff -Nru a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h
--- a/arch/ia64/kernel/perfmon_itanium.h	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/perfmon_itanium.h	Mon Feb 10 10:39:33 2003
@@ -15,7 +15,7 @@
 static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
 static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
 
-static pfm_reg_desc_t pfm_pmc_desc[PMU_MAX_PMCS]={
+static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -33,7 +33,7 @@
 	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
 
-static pfm_reg_desc_t pfm_pmd_desc[PMU_MAX_PMDS]={
+static pfm_reg_desc_t pfm_ita_pmd_desc[PMU_MAX_PMDS]={
 /* pmd0  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
 /* pmd1  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
 /* pmd2  */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
@@ -54,6 +54,19 @@
 /* pmd17 */ { PFM_REG_BUFFER  , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
 	    { PFM_REG_END     , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
+
+/*
+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
+ */
+static pmu_config_t pmu_conf={
+	.disabled = 1,
+	.ovfl_val = (1UL << 32) - 1,
+	.num_ibrs = 8,
+	.num_dbrs = 8,
+	.pmd_desc = pfm_ita_pmd_desc,
+	.pmc_desc = pfm_ita_pmc_desc
+};
+
 
 static int
 pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
diff -Nru a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h
--- a/arch/ia64/kernel/perfmon_mckinley.h	Mon Feb 10 10:39:30 2003
+++ b/arch/ia64/kernel/perfmon_mckinley.h	Mon Feb 10 10:39:30 2003
@@ -16,7 +16,7 @@
 static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
 static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
 
-static pfm_reg_desc_t pfm_pmc_desc[PMU_MAX_PMCS]={
+static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -36,7 +36,7 @@
 	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
 
-static pfm_reg_desc_t pfm_pmd_desc[PMU_MAX_PMDS]={
+static pfm_reg_desc_t pfm_mck_pmd_desc[PMU_MAX_PMDS]={
 /* pmd0  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
 /* pmd1  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
 /* pmd2  */ { PFM_REG_BUFFER  , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
@@ -59,6 +59,19 @@
 };
 
 /*
+ * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
+ */
+static pmu_config_t pmu_conf={
+	.disabled = 1,
+	.ovfl_val = (1UL << 47) - 1,
+	.num_ibrs = 8,
+	.num_dbrs = 8,
+	.pmd_desc = pfm_mck_pmd_desc,
+	.pmc_desc = pfm_mck_pmc_desc
+};
+
+
+/*
  * PMC reserved fields must have their power-up values preserved
  */
 static int
@@ -150,12 +163,12 @@
 	 * i-side events in L1D and L2 caches
 	 */
 	if (check_case1) {
-		ret =   ((val13 >> 45) & 0xf) == 0 
+		ret =   ((val13 >> 45) & 0xf) == 0
 		   && ((val8 & 0x1) == 0)
 		   && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
 		       ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
 
-		if (ret) printk("perfmon: failure check_case1\n");
+		if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n");
 	}
 
 	return ret ? -EINVAL : 0;
diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
--- a/arch/ia64/kernel/process.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/kernel/process.c	Mon Feb 10 10:39:27 2003
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
@@ -96,7 +96,7 @@
 {
 	unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
-	printk("\nPid: %d, comm: %20s\n", current->pid, current->comm);
+	printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
 	printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
 	       regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
 	print_symbol("ip is at %s\n", ip);
@@ -144,6 +144,15 @@
 void
 do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
 {
+#ifdef CONFIG_FSYS
+	if (fsys_mode(current, &scr->pt)) {
+		/* defer signal-handling etc. until we return to privilege-level 0.  */
+		if (!ia64_psr(&scr->pt)->lp)
+			ia64_psr(&scr->pt)->lp = 1;
+		return;
+	}
+#endif
+
 #ifdef CONFIG_PERFMON
 	if (current->thread.pfm_ovfl_block_reset)
 		pfm_ovfl_block_reset();
@@ -198,6 +207,10 @@
 void
 ia64_save_extra (struct task_struct *task)
 {
+#ifdef CONFIG_PERFMON
+	unsigned long info;
+#endif
+
 	if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
 		ia64_save_debug_regs(&task->thread.dbr[0]);
 
@@ -205,8 +218,9 @@
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 		pfm_save_regs(task);
 
-	if (__get_cpu_var(pfm_syst_wide))
-		pfm_syst_wide_update_task(task, 0);
+	info = __get_cpu_var(pfm_syst_info);
+	if (info & PFM_CPUINFO_SYST_WIDE)
+		pfm_syst_wide_update_task(task, info, 0);
 #endif
 
 #ifdef CONFIG_IA32_SUPPORT
@@ -218,6 +232,10 @@
 void
 ia64_load_extra (struct task_struct *task)
 {
+#ifdef CONFIG_PERFMON
+	unsigned long info;
+#endif
+
 	if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
 		ia64_load_debug_regs(&task->thread.dbr[0]);
 
@@ -225,8 +243,9 @@
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
 		pfm_load_regs(task);
 
-	if (__get_cpu_var(pfm_syst_wide)) 
-		pfm_syst_wide_update_task(task, 1);
+	info = __get_cpu_var(pfm_syst_info);
+	if (info & PFM_CPUINFO_SYST_WIDE) 
+		pfm_syst_wide_update_task(task, info, 1);
 #endif
 
 #ifdef CONFIG_IA32_SUPPORT
diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/ptrace.c	Mon Feb 10 10:39:33 2003
@@ -833,21 +833,19 @@
 			return -1;
 		}
 #ifdef CONFIG_PERFMON
-		/* 
-		 * Check if debug registers are used 
-		 * by perfmon. This test must be done once we know that we can
-		 * do the operation, i.e. the arguments are all valid, but before
-		 * we start modifying the state.
+		/*
+		 * Check if debug registers are used by perfmon. This test must be done
+		 * once we know that we can do the operation, i.e. the arguments are all
+		 * valid, but before we start modifying the state.
 		 *
-		 * Perfmon needs to keep a count of how many processes are
-		 * trying to modify the debug registers for system wide monitoring
-		 * sessions.
+		 * Perfmon needs to keep a count of how many processes are trying to
+		 * modify the debug registers for system wide monitoring sessions.
 		 *
-		 * We also include read access here, because they may cause 
-		 * the PMU-installed debug register state (dbr[], ibr[]) to
-		 * be reset. The two arrays are also used by perfmon, but
-		 * we do not use IA64_THREAD_DBG_VALID. The registers are restored
-		 * by the PMU context switch code.
+		 * We also include read access here, because they may cause the
+		 * PMU-installed debug register state (dbr[], ibr[]) to be reset. The two
+		 * arrays are also used by perfmon, but we do not use
+		 * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context
+		 * switch code.
 		 */
 		if (pfm_use_debug_registers(child)) return -1;
 #endif
diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
--- a/arch/ia64/kernel/sal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/sal.c	Mon Feb 10 10:39:33 2003
@@ -1,7 +1,7 @@
 /*
  * System Abstraction Layer (SAL) interface routines.
  *
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -96,17 +96,17 @@
 	int i;
 
 	if (!systab) {
-		printk("Hmm, no SAL System Table.\n");
+		printk(KERN_WARNING "Hmm, no SAL System Table.\n");
 		return;
 	}
 
 	if (strncmp(systab->signature, "SST_", 4) != 0)
-		printk("bad signature in system table!");
+		printk(KERN_ERR "bad signature in system table!");
 
 	/*
 	 * revisions are coded in BCD, so %x does the job for us
 	 */
-	printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n",
+	printk(KERN_INFO "SAL v%x.%02x: oem=%.32s, product=%.32s\n",
 	       systab->sal_rev_major, systab->sal_rev_minor,
 	       systab->oem_id, systab->product_id);
 
@@ -121,7 +121,7 @@
 		switch (*p) {
 		      case SAL_DESC_ENTRY_POINT:
 			ep = (struct ia64_sal_desc_entry_point *) p;
-			printk("SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
+			printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
 			       ep->pal_proc, ep->sal_proc);
 			ia64_pal_handler_init(__va(ep->pal_proc));
 			ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
@@ -139,12 +139,12 @@
 			      switch (ap->mechanism) {
 				    case IA64_SAL_AP_EXTERNAL_INT:
 				      ap_wakeup_vector = ap->vector;
-				      printk("SAL: AP wakeup using external interrupt "
+				      printk(KERN_INFO "SAL: AP wakeup using external interrupt "
 					     "vector 0x%lx\n", ap_wakeup_vector);
 				      break;
 
 				    default:
-				      printk("SAL: AP wakeup mechanism unsupported!\n");
+				      printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n");
 				      break;
 			      }
 			      break;
@@ -154,7 +154,7 @@
 		      {
 			      struct ia64_sal_desc_platform_feature *pf = (void *) p;
 			      sal_platform_features = pf->feature_mask;
-			      printk("SAL: Platform features ");
+			      printk(KERN_INFO "SAL: Platform features ");
 
 			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
 				      printk("BusLock ");
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/kernel/setup.c	Mon Feb 10 10:39:23 2003
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
@@ -171,7 +171,7 @@
 
 #if IGNORE_PFN0
 	if (start == PAGE_OFFSET) {
-		printk("warning: skipping physical page 0\n");
+		printk(KERN_WARNING "warning: skipping physical page 0\n");
 		start += PAGE_SIZE;
 		if (start >= end) return 0;
 	}
@@ -341,7 +341,7 @@
 		initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
 		initrd_end   = initrd_start+ia64_boot_param->initrd_size;
 
-		printk("Initial ramdisk at: 0x%lx (%lu bytes)\n",
+		printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
 		       initrd_start, ia64_boot_param->initrd_size);
 	}
 #endif
@@ -409,8 +409,9 @@
 		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
 	else {
 		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
-		printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n");
-		printk("I/O port base = 0x%lx\n", phys_iobase);
+		printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
+		       "to AR.KR0\n");
+		printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
 	}
 	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
 
@@ -615,7 +616,7 @@
 		impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
 		phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
 	}
-	printk("CPU %d: %lu virtual and %lu physical address bits\n",
+	printk(KERN_INFO "CPU %d: %lu virtual and %lu physical address bits\n",
 	       smp_processor_id(), impl_va_msb + 1, phys_addr_size);
 	c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
 	c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
@@ -738,7 +739,7 @@
 	if (ia64_pal_vm_summary(NULL, &vmi) == 0)
 		max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
 	else {
-		printk("cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
+		printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
 		max_ctx = (1U << 15) - 1;	/* use architected minimum */
 	}
 	while (max_ctx < ia64_ctx.max_ctx) {
@@ -748,10 +749,39 @@
 	}
 
 	if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
-		printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n");
+		printk(KERN_WARNING "cpu_init: PAL RSE info failed; assuming 96 physical "
+		       "stacked regs\n");
 		num_phys_stacked = 96;
 	}
 	/* size of physical stacked register partition plus 8 bytes: */
 	__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
 	platform_cpu_init();
+}
+
+void
+check_bugs (void)
+{
+	extern int __start___mckinley_e9_bundles[];
+	extern int __end___mckinley_e9_bundles[];
+	u64 *bundle;
+	int *wp;
+
+	if (local_cpu_data->family == 0x1f && local_cpu_data->model == 0)
+		printk(KERN_INFO "check_bugs: leaving McKinley Errata 9 workaround enabled\n");
+	else {
+		printk(KERN_INFO "check_bugs: McKinley Errata 9 workaround not needed; "
+		       "disabling it\n");
+		for (wp = __start___mckinley_e9_bundles; wp < __end___mckinley_e9_bundles; ++wp) {
+			bundle = (u64 *) ((char *) wp + *wp);
+			/* install a bundle of NOPs: */
+			bundle[0] = 0x0000000100000000;
+			bundle[1] = 0x0004000000000200;
+			ia64_fc(bundle);
+		}
+		ia64_insn_group_barrier();
+		ia64_sync_i();
+		ia64_insn_group_barrier();
+		ia64_srlz_i();
+		ia64_insn_group_barrier();
+	}
 }
diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c	Mon Feb 10 10:39:28 2003
+++ b/arch/ia64/kernel/signal.c	Mon Feb 10 10:39:28 2003
@@ -68,13 +68,13 @@
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	{
 		oldset = current->blocked;
 		current->blocked = set;
 		recalc_sigpending();
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/*
 	 * The return below usually returns to the signal handler.  We need to
@@ -274,12 +274,12 @@
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	{
 		current->blocked = set;
 		recalc_sigpending();
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(sc, scr))
 		goto give_sigsegv;
@@ -465,13 +465,13 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		{
 			sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
 			sigaddset(&current->blocked, sig);
 			recalc_sigpending();
 		}
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return 1;
 }
diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/kernel/smpboot.c	Mon Feb 10 10:39:24 2003
@@ -1,7 +1,7 @@
 /*
  * SMP boot-related support
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 01/05/16 Rohit Seth <rohit.seth@intel.com>	Moved SMP booting functions from smp.c to here.
@@ -204,7 +204,7 @@
 	go[MASTER] = 1;
 
 	if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) {
-		printk("sync_itc: failed to get attention of CPU %u!\n", master);
+		printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master);
 		return;
 	}
 
@@ -244,8 +244,8 @@
 		       t[i].rt, t[i].master, t[i].diff, t[i].lat);
 #endif
 
-	printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)\n",
-	       smp_processor_id(), master, delta, rt);
+	printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, "
+	       "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt);
 }
 
 /*
@@ -265,14 +265,15 @@
 	extern void ia64_init_itm(void);
 
 #ifdef CONFIG_PERFMON
-	extern void perfmon_init_percpu(void);
+	extern void pfm_init_percpu(void);
 #endif
 
 	cpuid = smp_processor_id();
 	phys_id = hard_smp_processor_id();
 
 	if (test_and_set_bit(cpuid, &cpu_online_map)) {
-		printk("huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid);
+		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
+		       phys_id, cpuid);
 		BUG();
 	}
 
@@ -300,7 +301,7 @@
 #endif
 
 #ifdef CONFIG_PERFMON
-	perfmon_init_percpu();
+	pfm_init_percpu();
 #endif
 
 	local_irq_enable();
@@ -380,9 +381,7 @@
 
 	if (test_bit(cpu, &cpu_callin_map)) {
 		/* number CPUs logically, starting from 1 (BSP is 0) */
-		printk("CPU%d: ", cpu);
-		/*print_cpu_info(&cpu_data[cpu]); */
-		printk("CPU has booted.\n");
+		printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu);
 	} else {
 		printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
 		ia64_cpu_to_sapicid[cpu] = -1;
@@ -399,7 +398,7 @@
 {
 	cache_decay_ticks = 10;	/* XXX base this on PAL info and cache-bandwidth estimate */
 
-	printk("task migration cache decay timeout: %ld msecs.\n",
+	printk(KERN_INFO "task migration cache decay timeout: %ld msecs.\n",
 	       (cache_decay_ticks + 1) * 1000 / HZ);
 }
 
@@ -491,7 +490,7 @@
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
 
-	printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
+	printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
 
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
@@ -526,7 +525,7 @@
 		if (cpu_online(cpu))
 			bogosum += cpu_data(cpu)->loops_per_jiffy;
 
-	printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+	printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 	       num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
 }
 
@@ -552,7 +551,7 @@
 }
 
 /*
- * Assume that CPU's have been discovered by some platform-dependant interface.  For
+ * Assume that CPU's have been discovered by some platform-dependent interface.  For
  * SoftSDV/Lion, that would be ACPI.
  *
  * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
@@ -571,5 +570,6 @@
 	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
 				       __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
 	if (sal_ret < 0)
-		printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n", ia64_sal_strerror(sal_ret));
+		printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n",
+		       ia64_sal_strerror(sal_ret));
 }
diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
--- a/arch/ia64/kernel/sys_ia64.c	Mon Feb 10 10:39:28 2003
+++ b/arch/ia64/kernel/sys_ia64.c	Mon Feb 10 10:39:28 2003
@@ -16,11 +16,11 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
+#include <linux/hugetlb.h>
 
 #include <asm/shmparam.h>
 #include <asm/uaccess.h>
 
-
 unsigned long
 arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len,
 			unsigned long pgoff, unsigned long flags)
@@ -31,6 +31,20 @@
 
 	if (len > RGN_MAP_LIMIT)
 		return -ENOMEM;
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define COLOR_HALIGN(addr) ((addr + HPAGE_SIZE - 1) & ~(HPAGE_SIZE - 1))
+#define TASK_HPAGE_BASE ((REGION_HPAGE << REGION_SHIFT) | HPAGE_SIZE)
+	if (filp && is_file_hugepages(filp)) {
+		if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE -1)))
+			addr = TASK_HPAGE_BASE;
+		addr = COLOR_HALIGN(addr);
+	}
+	else {
+		if (REGION_NUMBER(addr) == REGION_HPAGE)
+			addr = 0;
+	}
+#endif
 	if (!addr)
 		addr = TASK_UNMAPPED_BASE;
 
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/kernel/time.c	Mon Feb 10 10:39:24 2003
@@ -1,7 +1,7 @@
 /*
  * linux/arch/ia64/kernel/time.c
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger <davidm@hpl.hp.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
@@ -24,7 +24,6 @@
 #include <asm/sal.h>
 #include <asm/system.h>
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 extern unsigned long last_time_offset;
 
@@ -76,10 +75,8 @@
 
 	now = ia64_get_itc();
 	if ((long) (now - last_tick) < 0) {
-# if 1
-		printk("CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
+		printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
 		       smp_processor_id(), now, last_tick);
-# endif
 		return last_time_offset;
 	}
 	elapsed_cycles = now - last_tick;
@@ -89,7 +86,7 @@
 void
 do_settimeofday (struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	{
 		/*
 		 * This is revolting. We need to set "xtime" correctly. However, the value
@@ -112,21 +109,21 @@
 		time_maxerror = NTP_PHASE_LIMIT;
 		time_esterror = NTP_PHASE_LIMIT;
 	}
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 void
 do_gettimeofday (struct timeval *tv)
 {
-	unsigned long flags, usec, sec, old;
+	unsigned long seq, usec, sec, old;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	{
+	do {
+		seq = read_seqbegin(&xtime_lock);
 		usec = gettimeoffset();
 
 		/*
-		 * Ensure time never goes backwards, even when ITC on different CPUs are
-		 * not perfectly synchronized.
+		 * Ensure time never goes backwards, even when ITC on 
+		 * different CPUs are not perfectly synchronized.
 		 */
 		do {
 			old = last_time_offset;
@@ -138,8 +135,8 @@
 
 		sec = xtime.tv_sec;
 		usec += xtime.tv_nsec / 1000;
-	}
-	read_unlock_irqrestore(&xtime_lock, flags);
+	} while (read_seqend(&xtime_lock, seq));
+
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -158,7 +155,7 @@
 	new_itm = local_cpu_data->itm_next;
 
 	if (!time_after(ia64_get_itc(), new_itm))
-		printk("Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
+		printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
 		       ia64_get_itc(), new_itm);
 
 	while (1) {
@@ -182,10 +179,10 @@
 			 * another CPU. We need to avoid to SMP race by acquiring the
 			 * xtime_lock.
 			 */
-			write_lock(&xtime_lock);
+			write_seqlock(&xtime_lock);
 			do_timer(regs);
 			local_cpu_data->itm_next = new_itm;
-			write_unlock(&xtime_lock);
+			write_sequnlock(&xtime_lock);
 		} else
 			local_cpu_data->itm_next = new_itm;
 
@@ -247,21 +244,22 @@
 	 */
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift);
 	if (status != 0) {
-		printk("SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
+		printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
 	} else {
 		status = ia64_pal_freq_ratios(&proc_ratio, 0, &itc_ratio);
 		if (status != 0)
-			printk("PAL_FREQ_RATIOS failed with status=%ld\n", status);
+			printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status);
 	}
 	if (status != 0) {
 		/* invent "random" values */
-		printk("SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
+		printk(KERN_ERR
+		       "SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
 		platform_base_freq = 100000000;
 		itc_ratio.num = 3;
 		itc_ratio.den = 1;
 	}
 	if (platform_base_freq < 40000000) {
-		printk("Platform base frequency %lu bogus---resetting to 75MHz!\n",
+		printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
 		       platform_base_freq);
 		platform_base_freq = 75000000;
 	}
@@ -272,8 +270,8 @@
 
 	itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
 	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
-	printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n",
-	       smp_processor_id(),
+	printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
+	       "ITC freq=%lu.%03luMHz\n", smp_processor_id(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
 	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
 
diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
--- a/arch/ia64/kernel/traps.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/traps.c	Mon Feb 10 10:39:33 2003
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific trap handling.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
@@ -57,7 +57,8 @@
 		major = fpswa_interface->revision >> 16;
 		minor = fpswa_interface->revision & 0xffff;
 	}
-	printk("fpswa interface at %lx (rev %d.%d)\n", ia64_boot_param->fpswa, major, minor);
+	printk(KERN_INFO "fpswa interface at %lx (rev %d.%d)\n",
+	       ia64_boot_param->fpswa, major, minor);
 }
 
 /*
@@ -142,7 +143,7 @@
 
 	switch (break_num) {
 	      case 0: /* unknown error (used by GCC for __builtin_abort()) */
-		die_if_kernel("bad break", regs, break_num);
+		die_if_kernel("bugcheck!", regs, break_num);
 		sig = SIGILL; code = ILL_ILLOPC;
 		break;
 
@@ -222,7 +223,7 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 
-	printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+	printk(KERN_DEBUG "%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
 	       regs->r15, arg0, arg1, arg2, arg3);
 	return -ENOSYS;
 }
@@ -346,7 +347,7 @@
 			/* emulation was successful */
 			ia64_increment_ip(regs);
 		} else if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else {
 			/* is next instruction a trap? */
@@ -369,7 +370,7 @@
 		}
 	} else {
 		if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else if (exception != 0) {
 			/* raise exception */
@@ -467,7 +468,9 @@
 				       ? " (RSE access)" : " (data access)") : "");
 		if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
-			printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr);
+			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
+			       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri,
+			       regs->pr);
 # endif
 			return;
 		}
@@ -524,6 +527,25 @@
 	      case 29: /* Debug */
 	      case 35: /* Taken Branch Trap */
 	      case 36: /* Single Step Trap */
+#ifdef CONFIG_FSYS
+		if (fsys_mode(current, regs)) {
+			extern char syscall_via_break[], __start_gate_section[];
+			/*
+			 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
+			 * need special handling; Debug trap is not supposed to happen.
+			 */
+			if (unlikely(vector == 29)) {
+				die("Got debug trap in fsys-mode---not supposed to happen!",
+				    regs, 0);
+				return;
+			}
+			/* re-do the system call via break 0x100000: */
+			regs->cr_iip = GATE_ADDR + (syscall_via_break - __start_gate_section);
+			ia64_psr(regs)->ri = 0;
+			ia64_psr(regs)->cpl = 3;
+			return;
+		}
+#endif
 		switch (vector) {
 		      case 29:
 			siginfo.si_code = TRAP_HWBKPT;
@@ -563,19 +585,31 @@
 		}
 		return;
 
-	      case 34:		/* Unimplemented Instruction Address Trap */
-		if (user_mode(regs)) {
-			siginfo.si_signo = SIGILL;
-			siginfo.si_code = ILL_BADIADDR;
-			siginfo.si_errno = 0;
-			siginfo.si_flags = 0;
-			siginfo.si_isr = 0;
-			siginfo.si_imm = 0;
-			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
-			force_sig_info(SIGILL, &siginfo, current);
+	      case 34:
+		if (isr & 0x2) {
+			/* Lower-Privilege Transfer Trap */
+			/*
+			 * Just clear PSR.lp and then return immediately: all the
+			 * interesting work (e.g., signal delivery is done in the kernel
+			 * exit path).
+			 */
+			ia64_psr(regs)->lp = 0;
 			return;
+		} else {
+			/* Unimplemented Instr. Address Trap */
+			if (user_mode(regs)) {
+				siginfo.si_signo = SIGILL;
+				siginfo.si_code = ILL_BADIADDR;
+				siginfo.si_errno = 0;
+				siginfo.si_flags = 0;
+				siginfo.si_isr = 0;
+				siginfo.si_imm = 0;
+				siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+				force_sig_info(SIGILL, &siginfo, current);
+				return;
+			}
+			sprintf(buf, "Unimplemented Instruction Address fault");
 		}
-		sprintf(buf, "Unimplemented Instruction Address fault");
 		break;
 
 	      case 45:
@@ -583,8 +617,9 @@
 		if (ia32_exception(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 exception (Trap 45)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);
+		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
+		       regs->cr_iip, ifa, isr);
 		force_sig(SIGSEGV, current);
 		break;
 
@@ -593,8 +628,8 @@
 		if (ia32_intercept(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 intercept trap (Trap 46)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
+		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
 		       regs->cr_iip, ifa, isr, iim);
 		force_sig(SIGSEGV, current);
 		return;
diff -Nru a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
--- a/arch/ia64/kernel/unaligned.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ia64/kernel/unaligned.c	Mon Feb 10 10:39:32 2003
@@ -331,12 +331,8 @@
 		return;
 	}
 
-	/*
-	 * Avoid using user_mode() here: with "epc", we cannot use the privilege level to
-	 * infer whether the interrupt task was running on the kernel backing store.
-	 */
-	if (regs->r12 >= TASK_SIZE) {
-		DPRINT("ignoring kernel write to r%lu; register isn't on the RBS!", r1);
+	if (!user_stack(current, regs)) {
+		DPRINT("ignoring kernel write to r%lu; register isn't on the kernel RBS!", r1);
 		return;
 	}
 
@@ -406,11 +402,7 @@
 		return;
 	}
 
-	/*
-	 * Avoid using user_mode() here: with "epc", we cannot use the privilege level to
-	 * infer whether the interrupt task was running on the kernel backing store.
-	 */
-	if (regs->r12 >= TASK_SIZE) {
+	if (!user_stack(current, regs)) {
 		DPRINT("ignoring kernel read of r%lu; register isn't on the RBS!", r1);
 		goto fail;
 	}
@@ -1302,12 +1294,12 @@
 void
 ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
 {
-	struct exception_fixup fix = { 0 };
 	struct ia64_psr *ipsr = ia64_psr(regs);
 	mm_segment_t old_fs = get_fs();
 	unsigned long bundle[2];
 	unsigned long opcode;
 	struct siginfo si;
+	const struct exception_table_entry *eh = NULL;
 	union {
 		unsigned long l;
 		load_store_t insn;
@@ -1325,10 +1317,9 @@
 	 * user-level unaligned accesses.  Otherwise, a clever program could trick this
 	 * handler into reading an arbitrary kernel addresses...
 	 */
-	if (!user_mode(regs)) {
-		fix = SEARCH_EXCEPTION_TABLE(regs);
-	}
-	if (user_mode(regs) || fix.cont) {
+	if (!user_mode(regs))
+		eh = SEARCH_EXCEPTION_TABLE(regs);
+	if (user_mode(regs) || eh) {
 		if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
 			goto force_sigbus;
 
@@ -1494,8 +1485,8 @@
   failure:
 	/* something went wrong... */
 	if (!user_mode(regs)) {
-		if (fix.cont) {
-			handle_exception(regs, fix);
+		if (eh) {
+			handle_exception(regs, eh);
 			goto done;
 		}
 		die_if_kernel("error during unaligned kernel access\n", regs, ret);
diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
--- a/arch/ia64/kernel/unwind.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/kernel/unwind.c	Mon Feb 10 10:39:33 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
@@ -532,7 +532,7 @@
 
 	rs = alloc_reg_state();
 	if (!rs) {
-		printk("unwind: cannot stack reg state!\n");
+		printk(KERN_ERR "unwind: cannot stack reg state!\n");
 		return;
 	}
 	memcpy(rs, &sr->curr, sizeof(*rs));
@@ -545,7 +545,7 @@
 	struct unw_reg_state *rs = sr->curr.next;
 
 	if (!rs) {
-		printk("unwind: stack underflow!\n");
+		printk(KERN_ERR "unwind: stack underflow!\n");
 		return;
 	}
 	memcpy(&sr->curr, rs, sizeof(*rs));
@@ -561,7 +561,7 @@
 	while (rs) {
 		copy = alloc_reg_state();
 		if (!copy) {
-			printk ("unwind.dup_state_stack: out of memory\n");
+			printk(KERN_ERR "unwind.dup_state_stack: out of memory\n");
 			return NULL;
 		}
 		memcpy(copy, rs, sizeof(*copy));
@@ -951,7 +951,7 @@
 			return;
 		}
 	}
-	printk("unwind: failed to find state labeled 0x%lx\n", label);
+	printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
 }
 
 static inline void
@@ -961,7 +961,7 @@
 
 	ls = alloc_labeled_state();
 	if (!ls) {
-		printk("unwind.desc_label_state(): out of memory\n");
+		printk(KERN_ERR "unwind.desc_label_state(): out of memory\n");
 		return;
 	}
 	ls->label = label;
@@ -1055,7 +1055,8 @@
 	r->val = 4*spoff;
 }
 
-#define UNW_DEC_BAD_CODE(code)			printk("unwind: unknown code 0x%02x\n", code);
+#define UNW_DEC_BAD_CODE(code)			printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
+						       code);
 
 /*
  * region headers:
@@ -1997,23 +1998,25 @@
 {
 	extern char __start_gate_section[], __stop_gate_section[];
 	unsigned long *lp, start, end, segbase = unw.kernel_table.segment_base;
-	const struct unw_table_entry *entry, *first;
+	const struct unw_table_entry *entry, *first, *unw_table_end;
+	extern int ia64_unw_end;
 	size_t info_size, size;
 	char *info;
 
 	start = (unsigned long) __start_gate_section - segbase;
 	end   = (unsigned long) __stop_gate_section - segbase;
+	unw_table_end = (struct unw_table_entry *) &ia64_unw_end;
 	size  = 0;
 	first = lookup(&unw.kernel_table, start);
 
-	for (entry = first; entry->start_offset < end; ++entry)
+	for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry)
 		size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
 	size += 8;	/* reserve space for "end of table" marker */
 
 	unw.gate_table = alloc_bootmem(size);
 	if (!unw.gate_table) {
 		unw.gate_table_size = 0;
-		printk("unwind: unable to create unwind data for gate page!\n");
+		printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n");
 		return;
 	}
 	unw.gate_table_size = size;
@@ -2021,7 +2024,7 @@
 	lp = unw.gate_table;
 	info = (char *) unw.gate_table + size;
 
-	for (entry = first; entry->start_offset < end; ++entry, lp += 3) {
+	for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry, lp += 3) {
 		info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
 		info -= info_size;
 		memcpy(info, (char *) segbase + entry->info_offset, info_size);
diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
--- a/arch/ia64/lib/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/lib/Makefile	Mon Feb 10 10:39:33 2003
@@ -4,8 +4,6 @@
 
 L_TARGET = lib.a
 
-export-objs := swiotlb.o
-
 obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o			\
 	__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o			\
 	checksum.o clear_page.o csum_partial_copy.o copy_page.o		\
diff -Nru a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
--- a/arch/ia64/lib/memcpy_mck.S	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/lib/memcpy_mck.S	Mon Feb 10 10:39:27 2003
@@ -159,7 +159,7 @@
 	mov	ar.ec=2
 (p10)	br.dpnt.few .aligned_src_tail
 	;;
-	.align 32
+//	.align 32
 1:
 EX(.ex_handler, (p16)	ld8	r34=[src0],16)
 EK(.ex_handler, (p16)	ld8	r38=[src1],16)
@@ -316,7 +316,7 @@
 (p7)	mov	ar.lc = r21
 (p8)	mov	ar.lc = r0
 	;;
-	.align 32
+//	.align 32
 1:	lfetch.fault	  [src_pre_mem], 128
 	lfetch.fault.excl [dst_pre_mem], 128
 	br.cloop.dptk.few 1b
@@ -522,7 +522,7 @@
 		 shrp	r21=r22,r38,shift;	/* speculative work */			\
 		 br.sptk.few .unaligned_src_tail /* branch out of jump table */		\
 		 ;;
-	.align 32
+//	.align 32
 .jump_table:
 	COPYU(8)	// unaligned cases
 .jmp1:
diff -Nru a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S
--- a/arch/ia64/lib/memset.S	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/lib/memset.S	Mon Feb 10 10:39:27 2003
@@ -125,7 +125,7 @@
 (p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
 ;; }
 
-	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
+//	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
 	mov	ptr9 = ptr1			// used for prefetching
@@ -194,7 +194,7 @@
 	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
 ;; }
 
-	.align 32
+//	.align 32
 .l1b:	// ------------------------------------ //  L1B: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
@@ -261,7 +261,7 @@
 	and	cnt = 0x1f, cnt			// compute the remaining cnt
 	mov.i   ar.lc = loopcnt
 ;; }
-	.align 32
+//	.align 32
 .l2:	// ------------------------------------ //  L2A:  store 32B in 2 cycles
 { .mmb
 	stf8	[ptr1] = fvalue, 8
diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
--- a/arch/ia64/lib/swiotlb.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ia64/lib/swiotlb.c	Mon Feb 10 10:39:30 2003
@@ -113,7 +113,7 @@
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
 
-	printk("Placing software IO TLB between 0x%p - 0x%p\n",
+	printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n",
 	       (void *) io_tlb_start, (void *) io_tlb_end);
 }
 
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/mm/discontig.c	Mon Feb 10 10:39:31 2003
@@ -215,7 +215,7 @@
 	int	node;
 
 	if (numnodes == 0) {
-		printk("node info missing!\n");
+		printk(KERN_ERR "node info missing!\n");
 		numnodes = 1;
 	}
 
diff -Nru a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c
--- a/arch/ia64/mm/extable.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/mm/extable.c	Mon Feb 10 10:39:24 2003
@@ -10,20 +10,19 @@
 #include <asm/uaccess.h>
 #include <asm/module.h>
 
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
-
-static inline const struct exception_table_entry *
-search_one_table (const struct exception_table_entry *first,
-		  const struct exception_table_entry *last,
-		  unsigned long ip, unsigned long gp)
+const struct exception_table_entry *
+search_extable (const struct exception_table_entry *first,
+		const struct exception_table_entry *last,
+		unsigned long ip)
 {
-        while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
+	const struct exception_table_entry *mid;
+	unsigned long mid_ip;
+	long diff;
 
+        while (first <= last) {
 		mid = &first[(last - first)/2];
-		diff = (mid->addr + gp) - ip;
+		mid_ip = (u64) &mid->addr + mid->addr;
+		diff = mid_ip - ip;
                 if (diff == 0)
                         return mid;
                 else if (diff < 0)
@@ -34,50 +33,14 @@
         return 0;
 }
 
-#ifndef CONFIG_MODULES
-register unsigned long main_gp __asm__("gp");
-#endif
-
-struct exception_fixup
-search_exception_table (unsigned long addr)
-{
-	const struct exception_table_entry *entry;
-	struct exception_fixup fix = { 0 };
-
-#ifndef CONFIG_MODULES
-	/* There is only the kernel to search.  */
-	entry = search_one_table(__start___ex_table, __stop___ex_table - 1, addr, main_gp);
-	if (entry)
-		fix.cont = entry->cont + main_gp;
-	return fix;
-#else
-	struct archdata *archdata;
-	struct module *mp;
-
-	/* The kernel is the last "module" -- no need to treat it special. */
-	for (mp = module_list; mp; mp = mp->next) {
-		if (!mp->ex_table_start)
-			continue;
-		archdata = (struct archdata *) mp->archdata_start;
-		if (!archdata)
-			continue;
-		entry = search_one_table(mp->ex_table_start, mp->ex_table_end - 1,
-					 addr, (unsigned long) archdata->gp);
-		if (entry) {
-			fix.cont = entry->cont + (unsigned long) archdata->gp;
-			return fix;
-		}
-	}
-#endif
-	return fix;
-}
-
 void
-handle_exception (struct pt_regs *regs, struct exception_fixup fix)
+handle_exception (struct pt_regs *regs, const struct exception_table_entry *e)
 {
+	long fix = (u64) &e->cont + e->cont;
+
 	regs->r8 = -EFAULT;
-	if (fix.cont & 4)
+	if (fix & 4)
 		regs->r9 = 0;
-	regs->cr_iip = (long) fix.cont & ~0xf;
-	ia64_psr(regs)->ri = fix.cont & 0x3;		/* set continuation slot number */
+	regs->cr_iip = fix & ~0xf;
+	ia64_psr(regs)->ri = fix & 0x3;		/* set continuation slot number */
 }
diff -Nru a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
--- a/arch/ia64/mm/fault.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/mm/fault.c	Mon Feb 10 10:39:33 2003
@@ -196,7 +196,7 @@
 		yield();
 		goto survive;
 	}
-	printk("VM: killing process %s\n", current->comm);
+	printk(KERN_CRIT "VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/mm/hugetlbpage.c	Mon Feb 10 10:39:27 2003
@@ -12,71 +12,41 @@
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
-
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
-static struct vm_operations_struct hugetlb_vm_ops;
-struct list_head htlbpage_freelist;
-spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
-extern long htlbpagemem;
+#include <linux/sysctl.h>
+
+static long    htlbpagemem;
+int     htlbpage_max;
+static long    htlbzone_pages;
 
-static void zap_hugetlb_resources (struct vm_area_struct *);
+static LIST_HEAD(htlbpage_freelist);
+static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 
-static struct page *
-alloc_hugetlb_page (void)
+static struct page *alloc_hugetlb_page(void)
 {
-	struct list_head *curr, *head;
+	int i;
 	struct page *page;
 
 	spin_lock(&htlbpage_lock);
-
-	head = &htlbpage_freelist;
-	curr = head->next;
-
-	if (curr == head) {
+	if (list_empty(&htlbpage_freelist)) {
 		spin_unlock(&htlbpage_lock);
 		return NULL;
 	}
-	page = list_entry(curr, struct page, list);
-	list_del(curr);
+
+	page = list_entry(htlbpage_freelist.next, struct page, list);
+	list_del(&page->list);
 	htlbpagemem--;
 	spin_unlock(&htlbpage_lock);
 	set_page_count(page, 1);
-	memset(page_address(page), 0, HPAGE_SIZE);
+	for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
+		clear_highpage(&page[i]);
 	return page;
 }
 
-static void
-free_hugetlb_page (struct page *page)
-{
-	spin_lock(&htlbpage_lock);
-	if ((page->mapping != NULL) && (page_count(page) == 2)) {
-		struct inode *inode = page->mapping->host;
-		int i;
-
-		ClearPageDirty(page);
-		remove_from_page_cache(page);
-		set_page_count(page, 1);
-		if ((inode->i_size -= HPAGE_SIZE) == 0) {
-			for (i = 0; i < MAX_ID; i++)
-				if (htlbpagek[i].key == inode->i_ino) {
-					htlbpagek[i].key = 0;
-					htlbpagek[i].in = NULL;
-					break;
-				}
-			kfree(inode);
-		}
-	}
-	if (put_page_testzero(page)) {
-		list_add(&page->list, &htlbpage_freelist);
-		htlbpagemem++;
-	}
-	spin_unlock(&htlbpage_lock);
-}
-
 static pte_t *
 huge_pte_alloc (struct mm_struct *mm, unsigned long addr)
 {
@@ -126,63 +96,8 @@
 	return;
 }
 
-static int
-anon_get_hugetlb_page (struct mm_struct *mm, struct vm_area_struct *vma,
-		       int write_access, pte_t * page_table)
-{
-	struct page *page;
-
-	page = alloc_hugetlb_page();
-	if (page == NULL)
-		return -1;
-	set_huge_pte(mm, vma, page, page_table, write_access);
-	return 1;
-}
-
-static int
-make_hugetlb_pages_present (unsigned long addr, unsigned long end, int flags)
-{
-	int write;
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	pte_t *pte;
-
-	vma = find_vma(mm, addr);
-	if (!vma)
-		goto out_error1;
-
-	write = (vma->vm_flags & VM_WRITE) != 0;
-	if ((vma->vm_end - vma->vm_start) & (HPAGE_SIZE - 1))
-		goto out_error1;
-	spin_lock(&mm->page_table_lock);
-	do {
-		pte = huge_pte_alloc(mm, addr);
-		if ((pte) && (pte_none(*pte))) {
-			if (anon_get_hugetlb_page(mm, vma, write ? VM_WRITE : VM_READ, pte) == -1)
-				goto out_error;
-		} else
-			goto out_error;
-		addr += HPAGE_SIZE;
-	} while (addr < end);
-	spin_unlock(&mm->page_table_lock);
-	vma->vm_flags |= (VM_HUGETLB | VM_RESERVED);
-	if (flags & MAP_PRIVATE)
-		vma->vm_flags |= VM_DONTCOPY;
-	vma->vm_ops = &hugetlb_vm_ops;
-	return 0;
-out_error:
-	if (addr > vma->vm_start) {
-		vma->vm_end = addr;
-		zap_hugetlb_resources(vma);
-		vma->vm_end = end;
-	}
-	spin_unlock(&mm->page_table_lock);
-out_error1:
-	return -1;
-}
-
-int
-copy_hugetlb_page_range (struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma)
+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;
@@ -202,15 +117,14 @@
 		addr += HPAGE_SIZE;
 	}
 	return 0;
-
-      nomem:
+nomem:
 	return -ENOMEM;
 }
 
 int
-follow_hugetlb_page (struct mm_struct *mm, struct vm_area_struct *vma,
-		     struct page **pages, struct vm_area_struct **vmas,
-		     unsigned long *st, int *length, int i)
+follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+		    struct page **pages, struct vm_area_struct **vmas,
+		    unsigned long *st, int *length, int i)
 {
 	pte_t *ptep, pte;
 	unsigned long start = *st;
@@ -227,6 +141,7 @@
 		page = pte_page(pte);
 		if (pages) {
 			page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
+			get_page(page);
 			pages[i] = page;
 		}
 		if (vmas)
@@ -234,8 +149,8 @@
 		i++;
 		len--;
 		start += PAGE_SIZE;
-		if (((start & HPAGE_MASK) == pstart) && len
-		    && (start < vma->vm_end))
+		if (((start & HPAGE_MASK) == pstart) && len &&
+				(start < vma->vm_end))
 			goto back1;
 	} while (len && start < vma->vm_end);
 	*length = len;
@@ -243,51 +158,149 @@
 	return i;
 }
 
-static void
-zap_hugetlb_resources (struct vm_area_struct *mpnt)
+void free_huge_page(struct page *page)
 {
-	struct mm_struct *mm = mpnt->vm_mm;
-	unsigned long len, addr, end;
-	pte_t *ptep;
+	BUG_ON(page_count(page));
+	BUG_ON(page->mapping);
+
+	INIT_LIST_HEAD(&page->list);
+
+	spin_lock(&htlbpage_lock);
+	list_add(&page->list, &htlbpage_freelist);
+	htlbpagemem++;
+	spin_unlock(&htlbpage_lock);
+}
+
+void huge_page_release(struct page *page)
+{
+	if (!put_page_testzero(page))
+		return;
+
+	free_huge_page(page);
+}
+
+void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long address;
+	pte_t *pte;
 	struct page *page;
 
-	addr = mpnt->vm_start;
-	end = mpnt->vm_end;
-	len = end - addr;
-	do {
-		ptep = huge_pte_offset(mm, addr);
-		page = pte_page(*ptep);
-		pte_clear(ptep);
-		free_hugetlb_page(page);
-		addr += HPAGE_SIZE;
-	} while (addr < end);
-	mm->rss -= (len >> PAGE_SHIFT);
-	mpnt->vm_ops = NULL;
-	flush_tlb_range(mpnt, end - len, end);
+	BUG_ON(start & (HPAGE_SIZE - 1));
+	BUG_ON(end & (HPAGE_SIZE - 1));
+
+	spin_lock(&htlbpage_lock);
+	spin_unlock(&htlbpage_lock);
+	for (address = start; address < end; address += HPAGE_SIZE) {
+		pte = huge_pte_offset(mm, address);
+		if (pte_none(*pte))
+			continue;
+		page = pte_page(*pte);
+		huge_page_release(page);
+		pte_clear(pte);
+	}
+	mm->rss -= (end - start) >> PAGE_SHIFT;
+	flush_tlb_range(vma, start, end);
 }
 
-static void
-unlink_vma (struct vm_area_struct *mpnt)
+void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	spin_lock(&mm->page_table_lock);
+	unmap_hugepage_range(vma, start, start + length);
+	spin_unlock(&mm->page_table_lock);
+}
+
+int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
+	unsigned long addr;
+	int ret = 0;
+
+	BUG_ON(vma->vm_start & ~HPAGE_MASK);
+	BUG_ON(vma->vm_end & ~HPAGE_MASK);
+
+	spin_lock(&mm->page_table_lock);
+	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+		unsigned long idx;
+		pte_t *pte = huge_pte_alloc(mm, addr);
+		struct page *page;
+
+		if (!pte) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		if (!pte_none(*pte))
+			continue;
 
-	vma = mm->mmap;
-	if (vma == mpnt) {
-		mm->mmap = vma->vm_next;
-	} else {
-		while (vma->vm_next != mpnt) {
-			vma = vma->vm_next;
+		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+		page = find_get_page(mapping, idx);
+		if (!page) {
+			page = alloc_hugetlb_page();
+			if (!page) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+			unlock_page(page);
 		}
-		vma->vm_next = mpnt->vm_next;
+		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
-	rb_erase(&mpnt->vm_rb, &mm->mm_rb);
-	mm->mmap_cache = NULL;
-	mm->map_count--;
+out:
+	spin_unlock(&mm->page_table_lock);
+	return ret;
 }
 
-int
-set_hugetlb_mem_size (int count)
+void update_and_free_page(struct page *page)
+{
+	int j;
+	struct page *map;
+
+	map = page;
+	htlbzone_pages--;
+	for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
+		map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
+				1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
+				1 << PG_private | 1<< PG_writeback);
+		set_page_count(map, 0);
+		map++;
+	}
+	set_page_count(page, 1);
+	__free_pages(page, HUGETLB_PAGE_ORDER);
+}
+
+int try_to_free_low(int count)
+{
+	struct list_head *p;
+	struct page *page, *map;
+
+	map = NULL;
+	spin_lock(&htlbpage_lock);
+	list_for_each(p, &htlbpage_freelist) {
+		if (map) {
+			list_del(&map->list);
+			update_and_free_page(map);
+			htlbpagemem--;
+			map = NULL;
+			if (++count == 0)
+				break;
+		}
+		page = list_entry(p, struct page, list);
+		if ((page_zone(page))->name[0] != 'H') // Look for non-Highmem
+				map = page;
+	}
+	if (map) {
+		list_del(&map->list);
+		update_and_free_page(map);
+		htlbpagemem--;
+		count++;
+	}
+	spin_unlock(&htlbpage_lock);
+	return count;
+}
+
+int set_hugetlb_mem_size(int count)
 {
 	int j, lcount;
 	struct page *page, *map;
@@ -298,16 +311,14 @@
 		lcount = count;
 	else
 		lcount = count - htlbzone_pages;
-	if (lcount > 0) {	/*Increase the mem size. */
+
+	if (lcount == 0)
+		return (int)htlbzone_pages;
+	if (lcount > 0) {	/* Increase the mem size. */
 		while (lcount--) {
 			page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
 			if (page == NULL)
 				break;
-			map = page;
-			for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-				SetPageReserved(map);
-				map++;
-			}
 			spin_lock(&htlbpage_lock);
 			list_add(&page->list, &htlbpage_freelist);
 			htlbpagemem++;
@@ -316,27 +327,80 @@
 		}
 		return (int) htlbzone_pages;
 	}
-	/*Shrink the memory size. */
+	/* Shrink the memory size. */
+	lcount = try_to_free_low(lcount);
 	while (lcount++) {
 		page = alloc_hugetlb_page();
 		if (page == NULL)
 			break;
 		spin_lock(&htlbpage_lock);
-		htlbzone_pages--;
+		update_and_free_page(page);
 		spin_unlock(&htlbpage_lock);
-		map = page;
-		for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-			map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
-					1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
-					1 << PG_private | 1<< PG_writeback);
-			map++;
-		}
-		set_page_count(page, 1);
-		__free_pages(page, HUGETLB_PAGE_ORDER);
 	}
 	return (int) htlbzone_pages;
 }
 
-static struct vm_operations_struct hugetlb_vm_ops = {
-	.close =	zap_hugetlb_resources
+int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length)
+{
+	proc_dointvec(table, write, file, buffer, length);
+	htlbpage_max = set_hugetlb_mem_size(htlbpage_max);
+	return 0;
+}
+
+static int __init hugetlb_setup(char *s)
+{
+	if (sscanf(s, "%d", &htlbpage_max) <= 0)
+		htlbpage_max = 0;
+	return 1;
+}
+__setup("hugepages=", hugetlb_setup);
+
+static int __init hugetlb_init(void)
+{
+	int i, j;
+	struct page *page;
+
+	for (i = 0; i < htlbpage_max; ++i) {
+		page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
+		if (!page)
+			break;
+		for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j)
+			SetPageReserved(&page[j]);
+		spin_lock(&htlbpage_lock);
+		list_add(&page->list, &htlbpage_freelist);
+		spin_unlock(&htlbpage_lock);
+	}
+	htlbpage_max = htlbpagemem = htlbzone_pages = i;
+	printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem);
+	return 0;
+}
+module_init(hugetlb_init);
+
+int hugetlb_report_meminfo(char *buf)
+{
+	return sprintf(buf,
+			"HugePages_Total: %5lu\n"
+			"HugePages_Free:  %5lu\n"
+			"Hugepagesize:    %5lu kB\n",
+			htlbzone_pages,
+			htlbpagemem,
+			HPAGE_SIZE/1024);
+}
+
+int is_hugepage_mem_enough(size_t size)
+{
+	if (size > (htlbpagemem << HPAGE_SHIFT))
+		return 0;
+	return 1;
+}
+
+static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+{
+	BUG();
+	return NULL;
+}
+
+struct vm_operations_struct hugetlb_vm_ops = {
+	.nopage =	hugetlb_nopage,
+	.close =	zap_hugetlb_resources,
 };
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c	Mon Feb 10 10:39:26 2003
+++ b/arch/ia64/mm/init.c	Mon Feb 10 10:39:26 2003
@@ -234,7 +234,7 @@
 	pte_t *pte;
 
 	if (!PageReserved(page))
-		printk("put_gate_page: gate page at 0x%p not in reserved memory\n",
+		printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n",
 		       page_address(page));
 
 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
@@ -342,13 +342,6 @@
  * Set up the page tables.
  */
 
-#ifdef CONFIG_HUGETLB_PAGE
-long htlbpagemem;
-int htlbpage_max;
-extern long htlbzone_pages;
-extern struct list_head htlbpage_freelist;
-#endif
-
 #ifdef CONFIG_DISCONTIGMEM
 void
 paging_init (void)
@@ -438,10 +431,10 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n",
-	       (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10),
-	       num_physpages << (PAGE_SHIFT - 10), codesize >> 10, reserved_pages << (PAGE_SHIFT - 10),
-	       datasize >> 10, initsize >> 10);
+	printk(KERN_INFO "Memory: %luk/%luk available (%luk code, %luk reserved, "
+	       "%luk data, %luk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10),
+	       num_physpages << (PAGE_SHIFT - 10), codesize >> 10,
+	       reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10);
 
 	/*
 	 * Allow for enough (cached) page table pages so that we can map the entire memory
@@ -461,30 +454,5 @@
 
 #ifdef CONFIG_IA32_SUPPORT
 	ia32_gdt_init();
-#endif
-#ifdef CONFIG_HUGETLB_PAGE
-	{
-		long i;
-		int j;
-		struct page *page, *map;
-
-		if ((htlbzone_pages << (HPAGE_SHIFT - PAGE_SHIFT)) >= max_low_pfn)
-			htlbzone_pages = (max_low_pfn >> ((HPAGE_SHIFT - PAGE_SHIFT) + 1));
-		INIT_LIST_HEAD(&htlbpage_freelist);
-		for (i = 0; i < htlbzone_pages; i++) {
-			page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
-			if (!page)
-				break;
-			map = page;
-			for (j = 0; j < (HPAGE_SIZE/PAGE_SIZE); j++) {
-				SetPageReserved(map);
-				map++;
-			}
-			list_add(&page->list, &htlbpage_freelist);
-		}
-		printk("Total Huge_TLB_Page memory pages allocated %ld \n", i);
-		htlbzone_pages = htlbpagemem = i;
-		htlbpage_max = (int)i;
-	}
 #endif
 }
diff -Nru a/arch/ia64/scripts/check-gas b/arch/ia64/scripts/check-gas
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/check-gas	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,11 @@
+#!/bin/sh
+dir=$(dirname $0)
+CC=$1
+$CC -c $dir/check-gas-asm.S
+res=$(objdump -r --section .data check-gas-asm.o | fgrep 00004 | tr -s ' ' |cut -f3 -d' ')
+if [ $res != ".text" ]; then
+	echo buggy
+else
+	echo good
+fi
+exit 0
diff -Nru a/arch/ia64/scripts/check-gas-asm.S b/arch/ia64/scripts/check-gas-asm.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/check-gas-asm.S	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,2 @@
+[1:]	nop 0
+	.xdata4 ".data", 0, 1b-.
diff -Nru a/arch/ia64/scripts/unwcheck.sh b/arch/ia64/scripts/unwcheck.sh
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/unwcheck.sh	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,109 @@
+#!/bin/sh
+#   Usage: unwcheck.sh <executable_file_name>
+#   Pre-requisite: readelf [from Gnu binutils package]
+#   Purpose: Check the following invariant
+#       For each code range in the input binary:
+#          Sum[ lengths of unwind regions] = Number of slots in code range.
+#   Author : Harish Patil
+#   First version: January 2002
+#   Modified : 2/13/2002
+#   Modified : 3/15/2002: duplicate detection
+readelf -u $1 | gawk '\
+ function todec(hexstr){
+    dec = 0;
+    l = length(hexstr);
+    for (i = 1; i <= l; i++)
+    {
+        c = substr(hexstr, i, 1);
+        if (c == "A")
+            dec = dec*16 + 10;
+        else if (c == "B")
+            dec = dec*16 + 11;
+        else if (c == "C")
+            dec = dec*16 + 12;
+        else if (c == "D")
+            dec = dec*16 + 13;
+        else if (c == "E")
+            dec = dec*16 + 14;
+        else if (c == "F")
+            dec = dec*16 + 15;
+        else
+            dec = dec*16 + c;
+    }
+    return dec;
+ }
+ BEGIN { first = 1; sum_rlen = 0; no_slots = 0; errors=0; no_code_ranges=0; }
+ {
+   if (NF==5 && $3=="info")
+   {
+      no_code_ranges += 1;
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print full_code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+         sum_rlen = 0;
+      }
+      full_code_range =  $0;
+      code_range =  $2;
+      gsub("..$", "", code_range);
+      gsub("^.", "", code_range);
+      split(code_range, addr, "-");
+      lo = toupper(addr[1]);
+
+      code_range_lo[no_code_ranges] = addr[1];
+      occurs[addr[1]] += 1;
+      full_range[addr[1]] = $0;
+
+      gsub("0X.[0]*", "", lo);
+      hi = toupper(addr[2]);
+      gsub("0X.[0]*", "", hi);
+      no_slots = (todec(hi) - todec(lo))/ 16*3
+      first = 0;
+   }
+   if (index($0,"rlen") > 0 )
+   {
+    rlen_str =  substr($0, index($0,"rlen"));
+    rlen = rlen_str;
+    gsub("rlen=", "", rlen);
+    gsub(")", "", rlen);
+    sum_rlen = sum_rlen +  rlen;
+   }
+  }
+  END {
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print "code_range=", code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+      }
+    no_duplicates = 0;
+    for (i=1; i<=no_code_ranges; i++)
+    {
+        cr = code_range_lo[i];
+        if (reported_cr[cr]==1) continue;
+        if ( occurs[cr] > 1)
+        {
+            reported_cr[cr] = 1;
+            print "Code range low ", code_range_lo[i], ":", full_range[cr], " occurs: ", occurs[cr], " times.";
+            print " ";
+            no_duplicates++;
+        }
+    }
+    print "======================================"
+    print "Total errors:", errors, "/", no_code_ranges, " duplicates:", no_duplicates;
+    print "======================================"
+  }
+  '
diff -Nru a/arch/ia64/sn/io/Makefile b/arch/ia64/sn/io/Makefile
--- a/arch/ia64/sn/io/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/ia64/sn/io/Makefile	Mon Feb 10 10:39:24 2003
@@ -13,8 +13,6 @@
 EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
 endif
 
-export-objs := hcl.o pci_dma.o
-
 obj-$(CONFIG_IA64_SGI_SN) += stubs.o sgi_if.o xswitch.o klgraph_hack.o \
 		hcl.o labelcl.o invent.o sgi_io_sim.o \
 		klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \
diff -Nru a/arch/ia64/sn/io/sn1/pcibr.c b/arch/ia64/sn/io/sn1/pcibr.c
--- a/arch/ia64/sn/io/sn1/pcibr.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ia64/sn/io/sn1/pcibr.c	Mon Feb 10 10:39:29 2003
@@ -4811,7 +4811,7 @@
 
 	    /* Device is capable of A64 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     */
 
@@ -4853,7 +4853,7 @@
 	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
 	    /* User desires DIRECT A32 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     * Mapping calls may fail if target
 	     * is outside the direct32 range.
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Mon Feb 10 10:39:33 2003
@@ -3216,7 +3216,7 @@
 
 	    /* Device is capable of A64 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     */
 
@@ -3266,7 +3266,7 @@
 	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
 	    /* User desires DIRECT A32 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     * Mapping calls may fail if target
 	     * is outside the direct32 range.
diff -Nru a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
--- a/arch/ia64/sn/kernel/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ia64/sn/kernel/Makefile	Mon Feb 10 10:39:23 2003
@@ -38,8 +38,6 @@
 .S.o:
 	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 
-export-objs = sn_ksyms.o iomv.o
-
 obj-y		= probe.o setup.o sn_asm.o sv.o bte.o iomv.o
 obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o
 obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o
diff -Nru a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
--- a/arch/ia64/tools/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/ia64/tools/Makefile	Mon Feb 10 10:39:27 2003
@@ -4,14 +4,7 @@
 
 src = $(obj)
 
-all:
-
-fastdep:
-
-mrproper: clean
-
-clean:
-	rm -f $(obj)/print_offsets.s $(obj)/print_offsets $(obj)/offsets.h
+clean-files := print_offsets.s print_offsets offsets.h
 
 $(TARGET): $(obj)/offsets.h
 	@if ! cmp -s $(obj)/offsets.h ${TARGET}; then	\
diff -Nru a/arch/ia64/tools/print_offsets.c b/arch/ia64/tools/print_offsets.c
--- a/arch/ia64/tools/print_offsets.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ia64/tools/print_offsets.c	Mon Feb 10 10:39:32 2003
@@ -1,7 +1,7 @@
 /*
  * Utility to generate asm-ia64/offsets.h.
  *
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Note that this file has dual use: when building the kernel
@@ -52,8 +52,13 @@
     { "SIGFRAME_SIZE",			sizeof (struct sigframe) },
     { "UNW_FRAME_INFO_SIZE",		sizeof (struct unw_frame_info) },
     { "", 0 },			/* spacer */
-    { "IA64_TASK_THREAD_KSP_OFFSET",	offsetof (struct task_struct, thread.ksp) },
+    { "IA64_TASK_CLEAR_CHILD_TID_OFFSET",offsetof (struct task_struct, clear_child_tid) },
+    { "IA64_TASK_GROUP_LEADER_OFFSET",	offsetof (struct task_struct, group_leader) },
     { "IA64_TASK_PID_OFFSET",		offsetof (struct task_struct, pid) },
+    { "IA64_TASK_REAL_PARENT_OFFSET",	offsetof (struct task_struct, real_parent) },
+    { "IA64_TASK_TGID_OFFSET",		offsetof (struct task_struct, tgid) },
+    { "IA64_TASK_THREAD_KSP_OFFSET",	offsetof (struct task_struct, thread.ksp) },
+    { "IA64_TASK_THREAD_ON_USTACK_OFFSET", offsetof (struct task_struct, thread.on_ustack) },
     { "IA64_PT_REGS_CR_IPSR_OFFSET",	offsetof (struct pt_regs, cr_ipsr) },
     { "IA64_PT_REGS_CR_IIP_OFFSET",	offsetof (struct pt_regs, cr_iip) },
     { "IA64_PT_REGS_CR_IFS_OFFSET",	offsetof (struct pt_regs, cr_ifs) },
diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
--- a/arch/ia64/vmlinux.lds.S	Mon Feb 10 10:39:31 2003
+++ b/arch/ia64/vmlinux.lds.S	Mon Feb 10 10:39:31 2003
@@ -6,7 +6,7 @@
 
 #define LOAD_OFFSET PAGE_OFFSET
 #include <asm-generic/vmlinux.lds.h>
-	
+
 OUTPUT_FORMAT("elf64-ia64-little")
 OUTPUT_ARCH(ia64)
 ENTRY(phys_start)
@@ -29,6 +29,7 @@
 
   _text = .;
   _stext = .;
+
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
 	*(.text.ivt)
@@ -44,33 +45,46 @@
 
   /* Read-only data */
 
-  /* Global data */
-  _data = .;
-
   /* Exception table */
   . = ALIGN(16);
-  __start___ex_table = .;
   __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET)
-	{ *(__ex_table) }
-  __stop___ex_table = .;
+	{
+	  __start___ex_table = .;
+	  *(__ex_table)
+	  __stop___ex_table = .;
+	}
+
+  __mckinley_e9_bundles : AT(ADDR(__mckinley_e9_bundles) - PAGE_OFFSET)
+	{
+	  __start___mckinley_e9_bundles = .;
+	  *(__mckinley_e9_bundles)
+	  __end___mckinley_e9_bundles = .;
+	}
+
+  /* Global data */
+  _data = .;
 
 #if defined(CONFIG_IA64_GENERIC)
   /* Machine Vector */
   . = ALIGN(16);
-  machvec_start = .;
   .machvec : AT(ADDR(.machvec) - PAGE_OFFSET)
-	{ *(.machvec) }
-  machvec_end = .;
+	{
+	  machvec_start = .;
+	  *(.machvec)
+	  machvec_end = .;
+	}
 #endif
 
   /* Unwind info & table: */
   . = ALIGN(8);
   .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
 	{ *(.IA_64.unwind_info*) }
-  ia64_unw_start = .;
   .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET)
-	{ *(.IA_64.unwind*) }
-  ia64_unw_end = .;
+	{
+	  ia64_unw_start = .;
+	  *(.IA_64.unwind*)
+	  ia64_unw_end = .;
+	}
 
   RODATA
 
@@ -87,32 +101,38 @@
   .init.data : AT(ADDR(.init.data) - PAGE_OFFSET)
 	{ *(.init.data) }
 
-  __initramfs_start = .;
   .init.ramfs : AT(ADDR(.init.ramfs) - PAGE_OFFSET)
-	{ *(.init.ramfs) }
-  __initramfs_end = .;
+	{
+	  __initramfs_start = .;
+	  *(.init.ramfs)
+	  __initramfs_end = .;
+	}
 
    . = ALIGN(16);
-  __setup_start = .;
   .init.setup : AT(ADDR(.init.setup) - PAGE_OFFSET)
-        { *(.init.setup) }
-  __setup_end = .;
-  __start___param = .;
+        {
+	  __setup_start = .;
+	  *(.init.setup)
+	  __setup_end = .;
+	}
   __param : AT(ADDR(__param) - PAGE_OFFSET)
-        { *(__param) }
-  __stop___param = .;
-  __initcall_start = .;
+        {
+	  __start___param = .;
+	  *(__param)
+	  __stop___param = .;
+	}
   .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET)
 	{
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
+	  __initcall_start = .;
+	  *(.initcall1.init)
+	  *(.initcall2.init)
+	  *(.initcall3.init)
+	  *(.initcall4.init)
+	  *(.initcall5.init)
+	  *(.initcall6.init)
+	  *(.initcall7.init)
+	  __initcall_end = .;
 	}
-  __initcall_end = .;
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
@@ -130,10 +150,6 @@
   . = ALIGN(SMP_CACHE_BYTES);
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET)
         { *(.data.cacheline_aligned) }
-
-  /* Kernel symbol names for modules: */
-  .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET)
-	{ *(.kstrtab) }
 
   /* Per-cpu data: */
   . = ALIGN(PERCPU_PAGE_SIZE);
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/arch/m68k/Kconfig	Mon Feb 10 10:39:29 2003
@@ -73,8 +73,8 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  When compiled this way, there will be modules called pcmcia_core.o
-	  and ds.o.  If you want to compile it as a module, say M here and
+	  When compiled this way, there will be modules called pcmcia_core
+	  and ds.  If you want to compile it as a module, say M here and
 	  read <file:Documentation/modules.txt>.
 
 config AMIGA
@@ -398,7 +398,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -428,7 +428,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -453,7 +453,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config ZORRO
@@ -541,7 +541,7 @@
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  parport.o.  If you have more than one parallel port and want to
+	  parport.  If you have more than one parallel port and want to
 	  specify which port and IRQ to be used by this driver at module load
 	  time, take a look at <file:Documentation/parport.txt>.
 
@@ -553,7 +553,7 @@
 	help
 	  Say Y here if you need support for the parallel port hardware on
 	  Amiga machines. This code is also available as a module (say M),
-	  called parport_amiga.o. If in doubt, saying N is the safe plan.
+	  called parport_amiga. If in doubt, saying N is the safe plan.
 
 config PARPORT_MFC3
 	tristate "Multiface III parallel port"
@@ -561,7 +561,7 @@
 	help
 	  Say Y here if you need parallel port support for the MFC3 card.
 	  This code is also available as a module (say M), called
-	  parport_mfc3.o. If in doubt, saying N is the safe plan.
+	  parport_mfc3. If in doubt, saying N is the safe plan.
 
 config PARPORT_PC
 	bool
@@ -576,7 +576,7 @@
 	  as a module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  parport_pc.o.
+	  parport_pc.
 
 	  If unsure, say Y.
 
@@ -586,7 +586,7 @@
 	help
 	  Say Y here if you need support for the parallel port hardware on
 	  Atari machines. This code is also available as a module (say M),
-	  called parport_atari.o. If in doubt, saying N is the safe plan.
+	  called parport_atari. If in doubt, saying N is the safe plan.
 
 config PRINTER
 	tristate "Parallel printer support"
@@ -604,7 +604,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -702,7 +702,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -729,7 +729,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -750,7 +750,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.o.  If you want to compile it as a
+	  The module will be called sd_mod.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
 	  module if your root file system (the one containing the directory /)
@@ -786,7 +786,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st.o. If you want to compile it as a
+	  The module will be called st. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -818,7 +818,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod.o. If you want to compile it as a
+	  The module will be called sr_mod. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -871,7 +871,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.o.
+	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
 	  If unsure, say N.
 
 comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
@@ -934,7 +934,7 @@
 	  built-in SCSI controller, say Y. Otherwise, say N. This driver is
 	  also available as a module ( = code which can be inserted in and
 	  removed from the running kernel whenever you want). The module is
-	  called wd33c93.o. If you want to compile it as a module, say M here
+	  called wd33c93. If you want to compile it as a module, say M here
 	  and read <file:Documentation/modules.txt>.
 
 config A4000T_SCSI
@@ -950,7 +950,7 @@
 	  If you have a Commodore A2091 SCSI controller, say Y. Otherwise,
 	  say N. This driver is also available as a module ( = code which can
 	  be inserted in and removed from the running kernel whenever you
-	  want). The module is called wd33c93.o. If you want to compile it as
+	  want). The module is called wd33c93. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config GVP11_SCSI
@@ -965,7 +965,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module will be called gvp11.o. If you want to compile it
+	  want). The module will be called gvp11. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config CYBERSTORM_SCSI
@@ -1050,7 +1050,7 @@
 	  a compatible SCSI controller (e.g. for Medusa).  This driver is also
 	  available as a module ( = code which can be inserted in and removed
 	  from the running kernel whenever you want).  The module is called
-	  atari_scsi.o.  If you want to compile it as a module, say M here and
+	  atari_scsi.  If you want to compile it as a module, say M here and
 	  read <file:Documentation/modules.txt>.  This driver supports both
 	  styles of NCR integration into the system: the TT style (separate
 	  DMA), and the Falcon style (via ST-DMA, replacing ACSI).  It does
@@ -1101,7 +1101,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mac_esp.o.  If you want to compile it as
+	  The module will be called mac_esp.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 #   dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
@@ -1169,7 +1169,7 @@
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  serial.o.
+	  serial.
 	  [WARNING: Do not compile this driver as a module if you are using
 	  non-standard serial ports, since the configuration information will
 	  be lost when the driver is unloaded.  This limitation may be lifted
@@ -1315,7 +1315,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called nvram.o. If you want to compile it as a
+	  The module will be called nvram. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ATARI_MFPSER
@@ -1426,9 +1426,9 @@
 	  for which 8 pin to DB25 adapters were supplied. The card also had
 	  jumpers internally to toggle various pinning configurations.
 
-	  This driver can be built as a module; but then "generic_serial.o"
+	  This driver can be built as a module; but then "generic_serial"
 	  will also be built as a module. This has to be loaded before
-	  "ser_a2232.o". If you want to do this, answer M here and read
+	  "ser_a2232". If you want to do this, answer M here and read
 	  "<file:Documentation/modules.txt>".
 
 config GVPIOEXT
@@ -1686,7 +1686,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  softdog.o.
+	  softdog.
 
 config RTC
 	bool "Enhanced Real Time Clock Support"
@@ -1713,7 +1713,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called rtc.o. If you want to compile it as a module,
+	  The module is called rtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 config GEN_RTC
@@ -1734,7 +1734,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called genrtc.o. If you want to compile it as a module,
+	  The module is called genrtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>. To load the
 	  module automatically add 'alias char-major-10-135 genrtc' to your
 	  /etc/modules.conf
diff -Nru a/arch/m68k/Makefile b/arch/m68k/Makefile
--- a/arch/m68k/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/m68k/Makefile	Mon Feb 10 10:39:32 2003
@@ -54,9 +54,9 @@
 endif
 
 ifndef CONFIG_SUN3
-HEAD := arch/m68k/kernel/head.o
+head-y := arch/m68k/kernel/head.o
 else
-HEAD := arch/m68k/kernel/sun3-head.o
+head-y := arch/m68k/kernel/sun3-head.o
 endif 
 
 core-y				+= arch/m68k/kernel/	arch/m68k/mm/
@@ -113,5 +113,3 @@
 archclean:
 	rm -f vmlinux.gz vmlinux.bz2
 	rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d
-
-archmrproper:
diff -Nru a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile
--- a/arch/m68k/amiga/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/m68k/amiga/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for Linux arch/m68k/amiga source directory
 #
 
-export-objs	:= amiga_ksyms.o
-
 obj-y		:= config.o amiints.o cia.o chipram.o amisound.o amiga_ksyms.o
 
 obj-$(CONFIG_AMIGA_PCMCIA)	+= pcmcia.o
diff -Nru a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
--- a/arch/m68k/atari/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/m68k/atari/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for Linux arch/m68k/atari source directory
 #
 
-export-objs	:= atari_ksyms.o
-
 obj-y		:= config.o time.o debug.o ataints.o stdma.o \
 			atasound.o stram.o atari_ksyms.o
 
diff -Nru a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
--- a/arch/m68k/atari/hades-pci.c	Mon Feb 10 10:39:27 2003
+++ b/arch/m68k/atari/hades-pci.c	Mon Feb 10 10:39:27 2003
@@ -375,7 +375,7 @@
 	memset(bus, 0, sizeof(struct pci_bus_info));
 
 	/*
-	 * Claim resources. The m68k has no seperate I/O space, both
+	 * Claim resources. The m68k has no separate I/O space, both
 	 * PCI memory space and PCI I/O space are in memory space. Therefore
 	 * the I/O resources are requested in memory space as well.
 	 */
diff -Nru a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
--- a/arch/m68k/kernel/Makefile	Mon Feb 10 10:39:30 2003
+++ b/arch/m68k/kernel/Makefile	Mon Feb 10 10:39:30 2003
@@ -8,8 +8,6 @@
   EXTRA_TARGETS := sun3-head.o
 endif 
 
-export-objs	:= setup.o m68k_ksyms.o
-
 obj-y		:= entry.o process.o traps.o ints.o signal.o ptrace.o \
 			sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o
 
diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
--- a/arch/m68k/kernel/time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/m68k/kernel/time.c	Mon Feb 10 10:39:24 2003
@@ -22,6 +22,7 @@
 #include <asm/machdep.h>
 #include <asm/io.h>
 
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/profile.h>
 
@@ -129,25 +130,27 @@
 	mach_sched_init(timer_interrupt);
 }
 
-extern rwlock_t xtime_lock;
-
 /*
  * This version of gettimeofday has near microsecond resolution.
  */
 void do_gettimeofday(struct timeval *tv)
 {
-	extern unsigned long wall_jiffies;
 	unsigned long flags;
+	extern unsigned long wall_jiffies;
+	unsigned long seq;
 	unsigned long usec, sec, lost;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = mach_gettimeoffset();
-	lost = jiffies - wall_jiffies;
-	if (lost)
-		usec += lost * (1000000/HZ);
-	sec = xtime.tv_sec;
-	usec += xtime.tv_nsec/1000;
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+		usec = mach_gettimeoffset();
+		lost = jiffies - wall_jiffies;
+		if (lost)
+			usec += lost * (1000000/HZ);
+		sec = xtime.tv_sec;
+		usec += xtime.tv_nsec/1000;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -162,7 +165,7 @@
 {
 	extern unsigned long wall_jiffies;
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/* This is revolting. We need to set the xtime.tv_nsec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
@@ -183,5 +186,5 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
diff -Nru a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile
--- a/arch/m68k/mac/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/m68k/mac/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,7 +2,5 @@
 # Makefile for Linux arch/m68k/mac source directory
 #
 
-export-objs	:= mac_ksyms.o
-
 obj-y		:= config.o bootparse.o macints.o iop.o via.o oss.o psc.o \
 			baboon.o macboing.o debug.o misc.o mac_ksyms.o
diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
--- a/arch/m68k/mac/macints.c	Mon Feb 10 10:39:31 2003
+++ b/arch/m68k/mac/macints.c	Mon Feb 10 10:39:31 2003
@@ -749,7 +749,7 @@
 	/*                                              */
 	/* Note that we're ignoring scc_mask for now.   */
 	/* If we actually mask the ints then we tend to */
-	/* get hammered by very persistant SCC irqs,    */
+	/* get hammered by very persistent SCC irqs,    */
 	/* and since they're autovector interrupts they */
 	/* pretty much kill the system.                 */
 
diff -Nru a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
--- a/arch/m68k/mac/via.c	Mon Feb 10 10:39:25 2003
+++ b/arch/m68k/mac/via.c	Mon Feb 10 10:39:25 2003
@@ -48,7 +48,7 @@
  * just hit the combined register (ie, vIER|rIER) but that seems to
  * break on AV Macs...probably because they actually decode more than
  * eight address bits. Why can't Apple engineers at least be
- * _consistantly_ lazy?                          - 1999-05-21 (jmt)
+ * _consistently_ lazy?                          - 1999-05-21 (jmt)
  */
 
 static int gIER,gIFR,gBufA,gBufB;
diff -Nru a/arch/m68k/math-emu/fp_decode.h b/arch/m68k/math-emu/fp_decode.h
--- a/arch/m68k/math-emu/fp_decode.h	Mon Feb 10 10:39:23 2003
+++ b/arch/m68k/math-emu/fp_decode.h	Mon Feb 10 10:39:23 2003
@@ -68,7 +68,7 @@
 do_fscc=0
 
 | first decoding of the instr type
-| this seperates the conditional instr
+| this separates the conditional instr
 .macro	fp_decode_cond_instr_type
 	bfextu	%d2{#8,#2},%d0
 	jmp	([0f:w,%pc,%d0*4])
@@ -80,7 +80,7 @@
 .endm
 
 | second decoding of the instr type
-| this seperates most move instr
+| this separates most move instr
 .macro	fp_decode_move_instr_type
 	bfextu	%d2{#16,#3},%d0
 	jmp	([0f:w,%pc,%d0*4])
diff -Nru a/arch/m68k/math-emu/fp_scan.S b/arch/m68k/math-emu/fp_scan.S
--- a/arch/m68k/math-emu/fp_scan.S	Mon Feb 10 10:39:27 2003
+++ b/arch/m68k/math-emu/fp_scan.S	Mon Feb 10 10:39:27 2003
@@ -74,13 +74,13 @@
 | first two instruction words are kept in %d2
 	getuser.l (%a0)+,%d2,fp_err_ua1,%a0
 	fp_put_pc %a0
-fp_decode_cond:				| seperate conditional instr
+fp_decode_cond:				| separate conditional instr
 	fp_decode_cond_instr_type
 
 	.long	fp_decode_move, fp_fscc
 	.long	fp_fbccw, fp_fbccl
 
-fp_decode_move:				| seperate move instr
+fp_decode_move:				| separate move instr
 	fp_decode_move_instr_type
 
 	.long	fp_fgen_fp, fp_ill
diff -Nru a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile
--- a/arch/m68k/mvme16x/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/m68k/mvme16x/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,6 +2,4 @@
 # Makefile for Linux arch/m68k/mvme16x source directory
 #
 
-export-objs	:= mvme16x_ksyms.o
-
 obj-y		:= config.o 16xints.o rtc.o mvme16x_ksyms.o
diff -Nru a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile
--- a/arch/m68k/sun3/Makefile	Mon Feb 10 10:39:22 2003
+++ b/arch/m68k/sun3/Makefile	Mon Feb 10 10:39:22 2003
@@ -2,8 +2,6 @@
 # Makefile for Linux arch/m68k/sun3 source directory
 #
 
-export-objs	:= sun3_ksyms.o
-
 obj-y	:= sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o
 
 obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o \
diff -Nru a/arch/m68k/sun3x/Makefile b/arch/m68k/sun3x/Makefile
--- a/arch/m68k/sun3x/Makefile	Mon Feb 10 10:39:25 2003
+++ b/arch/m68k/sun3x/Makefile	Mon Feb 10 10:39:25 2003
@@ -2,6 +2,4 @@
 # Makefile for Linux arch/m68k/sun3x source directory
 #
 
-export-objs	:= sun3x_ksyms.o
-
 obj-y		:= config.o time.o dvma.o prom.o
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/arch/m68knommu/Kconfig	Mon Feb 10 10:39:29 2003
@@ -658,7 +658,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
--- a/arch/m68knommu/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/m68knommu/Makefile	Mon Feb 10 10:39:29 2003
@@ -84,7 +84,7 @@
 
 LDFLAGS_BLOB	:= --format binary --oformat elf32-m68k
 
-HEAD := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
+head-y := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
 
 CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h.tmp \
 	       include/asm-$(ARCH)/asm-offsets.h \
@@ -97,8 +97,6 @@
 libs-y	+= arch/m68knommu/lib/
 
 prepare: include/asm-$(ARCH)/asm-offsets.h
-
-archmrproper:
 
 archclean:
 	$(call descend arch/$(ARCH)/boot, subdirclean)
diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile
--- a/arch/m68knommu/kernel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/m68knommu/kernel/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for arch/m68knommu/kernel.
 #
 
-export-objs := m68k_ksyms.o
-
 obj-y += entry.o init_task.o ints.o m68k_ksyms.o process.o ptrace.o \
 	 semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o \
 	 traps.o
diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
--- a/arch/m68knommu/kernel/signal.c	Mon Feb 10 10:39:29 2003
+++ b/arch/m68knommu/kernel/signal.c	Mon Feb 10 10:39:29 2003
@@ -63,11 +63,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->d0 = -EINTR;
 	while (1) {
@@ -93,11 +93,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->d0 = -EINTR;
 	while (1) {
@@ -370,10 +370,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
 		goto badframe;
@@ -399,10 +399,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
 		goto badframe;
@@ -738,11 +738,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
--- a/arch/m68knommu/kernel/time.c	Mon Feb 10 10:39:29 2003
+++ b/arch/m68knommu/kernel/time.c	Mon Feb 10 10:39:29 2003
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/profile.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 
 #include <asm/machdep.h>
@@ -126,21 +127,23 @@
 	mach_sched_init(timer_interrupt);
 }
 
-extern rwlock_t xtime_lock;
-
 /*
  * This version of gettimeofday has near microsecond resolution.
  */
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
-	sec = xtime.tv_sec;
-	usec += (xtime.tv_nsec / 1000);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+		usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -153,7 +156,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/* This is revolting. We need to set the xtime.tv_usec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
@@ -174,5 +177,5 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S
--- a/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S	Mon Feb 10 10:39:33 2003
+++ b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S	Mon Feb 10 10:39:33 2003
@@ -358,7 +358,7 @@
     .long   0           /* (Unassigned, Reserved)                       - 62. */
     .long   0           /* (Unassigned, Reserved)                       - 63. */
     /*                  The assignment of these vectors to the CPM is         */
-    /*                  dependant on the configuration of the CPM vba         */
+    /*                  dependent on the configuration of the CPM vba         */
     /*                          fields.                                       */
     .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
     .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S
--- a/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S	Mon Feb 10 10:39:33 2003
+++ b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S	Mon Feb 10 10:39:33 2003
@@ -367,7 +367,7 @@
     .long   0           /* (Unassigned, Reserved)                       - 62. */
     .long   0           /* (Unassigned, Reserved)                       - 63. */
     /*                  The assignment of these vectors to the CPM is         */
-    /*                  dependant on the configuration of the CPM vba         */
+    /*                  dependent on the configuration of the CPM vba         */
     /*                          fields.                                       */
     .long   0           /* (User-Defined Vectors 1) CPM Error           - 64. */
     .long   0           /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/arch/mips/Kconfig	Mon Feb 10 10:39:27 2003
@@ -724,7 +724,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -755,7 +755,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -780,7 +780,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 source "drivers/pci/Kconfig"
@@ -875,7 +875,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -902,7 +902,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -994,7 +994,7 @@
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  serial.o.
+	  serial.
 	  [WARNING: Do not compile this driver as a module if you are using
 	  non-standard serial ports, since the configuration information will
 	  be lost when the driver is unloaded.  This limitation may be lifted
@@ -1157,7 +1157,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile
--- a/arch/mips/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/mips/Makefile	Mon Feb 10 10:39:23 2003
@@ -256,7 +256,7 @@
 
 AFLAGS_vmlinux.lds.o := -DLOADADDR=$(LOADADDR)
 
-HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
+head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
 
 SUBDIRS := arch/mips/tools
 
diff -Nru a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
--- a/arch/mips/au1000/common/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/mips/au1000/common/Makefile	Mon Feb 10 10:39:33 2003
@@ -6,8 +6,6 @@
 # Makefile for the Alchemy Au1000 CPU, generic files.
 #
 
-export-objs := serial.o
-
 obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o
 
 obj-$(CONFIG_AU1000_UART) += serial.o             
diff -Nru a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
--- a/arch/mips/au1000/common/time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/mips/au1000/common/time.c	Mon Feb 10 10:39:24 2003
@@ -27,6 +27,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
+#include <linux/time.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 
@@ -44,7 +45,6 @@
 
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern rwlock_t xtime_lock;
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
@@ -150,10 +150,10 @@
 	set_cp0_status(ALLINTS);
 
 	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
+	write_seqlock_irqsave (&xtime_lock, flags);
 	xtime.tv_sec = get_mips_time();
 	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* This is for machines which generate the exact clock. */
@@ -229,20 +229,24 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned int flags;
+	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		*tv = xtime;
+		tv->tv_usec += do_fast_gettimeoffset();
+
+		/*
+		 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
+
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-	read_unlock_irqrestore (&xtime_lock, flags);
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -252,7 +256,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec correctly.
 	 * However, the value in this location is is value at the last tick.
@@ -272,7 +276,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
 
 /*
diff -Nru a/arch/mips/baget/Makefile b/arch/mips/baget/Makefile
--- a/arch/mips/baget/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/mips/baget/Makefile	Mon Feb 10 10:39:33 2003
@@ -3,7 +3,6 @@
 # under Linux.
 #
 
-export-objs		:= vacserial.o
 obj-y			:= baget.o print.o setup.o time.o irq.o bagetIRQ.o \
 			   reset.o wbflush.o
 obj-$(CONFIG_SERIAL)	+= vacserial.o
diff -Nru a/arch/mips/baget/time.c b/arch/mips/baget/time.c
--- a/arch/mips/baget/time.c	Mon Feb 10 10:39:23 2003
+++ b/arch/mips/baget/time.c	Mon Feb 10 10:39:23 2003
@@ -11,6 +11,7 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/spinlock.h>
@@ -23,8 +24,6 @@
 
 #include <asm/baget/baget.h>
 
-extern rwlock_t xtime_lock;
-
 /* 
  *  To have precision clock, we need to fix available clock frequency
  */
@@ -79,20 +78,21 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	read_unlock_irqrestore (&xtime_lock, flags);
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		*tv = xtime;
+	} while (read_seqretry(&xtime_lock, seq));
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 	xtime = *tv;
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
diff -Nru a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
--- a/arch/mips/dec/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/mips/dec/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the DECstation family specific parts of the kernel
 #
 
-export-objs := wbflush.o
-
 obj-y	 := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o
 
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
diff -Nru a/arch/mips/dec/time.c b/arch/mips/dec/time.c
--- a/arch/mips/dec/time.c	Mon Feb 10 10:39:31 2003
+++ b/arch/mips/dec/time.c	Mon Feb 10 10:39:31 2003
@@ -15,6 +15,7 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/bcd.h>
 
@@ -35,7 +36,6 @@
 extern void (*board_time_init)(struct irqaction *irq);
 
 extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
 
 /*
  * Change this if you have some constant time drift
@@ -211,19 +211,22 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_gettimeoffset();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		*tv = xtime;
+		tv->tv_usec += do_gettimeoffset();
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		/*
+		 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
+
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-	read_unlock_irqrestore(&xtime_lock, flags);
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -233,7 +236,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec
 	 * correctly. However, the value in this location is
@@ -254,7 +257,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /*
@@ -330,6 +333,7 @@
 timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	volatile unsigned char dummy;
+	unsigned long seq;
 
 	dummy = CMOS_READ(RTC_REG_C);	/* ACK RTC Interrupt */
 
@@ -357,23 +361,27 @@
 	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
-	read_lock(&xtime_lock);
-	if ((time_status & STA_UNSYNC) == 0
-	    && xtime.tv_sec > last_rtc_update + 660
-	    && xtime.tv_usec >= 500000 - tick / 2
-	    && xtime.tv_usec <= 500000 + tick / 2) {
-		if (set_rtc_mmss(xtime.tv_sec) == 0)
-			last_rtc_update = xtime.tv_sec;
-		else
-			/* do it again in 60 s */
-			last_rtc_update = xtime.tv_sec - 600;
-	}
+	do {
+		seq = read_seqbegin(&xtime_lock);
+
+		if ((time_status & STA_UNSYNC) == 0
+		    && xtime.tv_sec > last_rtc_update + 660
+		    && xtime.tv_usec >= 500000 - tick / 2
+		    && xtime.tv_usec <= 500000 + tick / 2) {
+			if (set_rtc_mmss(xtime.tv_sec) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else
+				/* do it again in 60 s */
+				last_rtc_update = xtime.tv_sec - 600;
+		}
+	} while (read_seqretry(&xtime_lock, seq));
+
 	/* As we return to user mode fire off the other CPU schedulers.. this is
 	   basically because we don't yet share IRQ's around. This message is
 	   rigged to be safe on the 386 - basically it's a hack, so don't look
 	   closely for now.. */
 	/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
-	read_unlock(&xtime_lock);
+
 }
 
 static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -470,10 +478,10 @@
 	real_year = CMOS_READ(RTC_DEC_YEAR);
 	year += real_year - 72 + 2000;
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
 	xtime.tv_usec = 0;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 
 	if (mips_cpu.options & MIPS_CPU_COUNTER) {
 		write_32bit_cp0_register(CP0_COUNT, 0);
diff -Nru a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
--- a/arch/mips/ite-boards/generic/time.c	Mon Feb 10 10:39:26 2003
+++ b/arch/mips/ite-boards/generic/time.c	Mon Feb 10 10:39:26 2003
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/spinlock.h>
 
 #include <asm/mipsregs.h>
@@ -38,7 +39,6 @@
 
 extern void enable_cpu_timer(void);
 extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
 
 unsigned long missed_heart_beats = 0;
 static long last_rtc_update = 0;
@@ -119,6 +119,8 @@
  */
 void mips_timer_interrupt(struct pt_regs *regs)
 {
+	unsigned long seq;
+
 	if (r4k_offset == 0)
 		goto null;
 
@@ -133,18 +135,22 @@
  		 * within 500ms before the * next second starts, 
  		 * thus the following code.
  		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else {
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-			}
-		read_unlock(&xtime_lock);
+		do {
+			seq = read_seqbegin(&xtime_lock);
+
+
+			if ((time_status & STA_UNSYNC) == 0 
+			    && xtime.tv_sec > last_rtc_update + 660 
+			    && xtime.tv_usec >= 500000 - (tick >> 1) 
+			    && xtime.tv_usec <= 500000 + (tick >> 1))
+				if (set_rtc_mmss(xtime.tv_sec) == 0)
+					last_rtc_update = xtime.tv_sec;
+				else {
+					/* do it again in 60 s */
+					last_rtc_update = xtime.tv_sec - 600; 
+				}
+			
+		} while (read_seqretry(&xtime_lock, seq));
 
 		r4k_cur += r4k_offset;
 		ack_r4ktimer(r4k_cur);
@@ -247,10 +253,10 @@
 	enable_cpu_timer();
 
 	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
+	write_seqlock_irqsave (&xtime_lock, flags);
 	xtime.tv_sec = get_mips_time();
 	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* This is for machines which generate the exact clock. */
@@ -332,20 +338,24 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned int flags;
+	unsigned long flags;
+	unsigned int seq;
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		*tv = xtime;
+		tv->tv_usec += do_fast_gettimeoffset();
+
+		/*
+		 * xtime is atomically updated in timer_bh. 
+		 * jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
 
-	read_unlock_irqrestore (&xtime_lock, flags);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -355,7 +365,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec correctly.
 	 * However, the value in this location is is value at the last tick.
@@ -375,5 +385,5 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
--- a/arch/mips/kernel/Makefile	Mon Feb 10 10:39:26 2003
+++ b/arch/mips/kernel/Makefile	Mon Feb 10 10:39:26 2003
@@ -5,8 +5,6 @@
 # EXTRA_AFLAGS = -mips3 -mcpu=r4000 # not used?
 
 EXTRA_TARGETS	:= head.o init_task.o
-export-objs	:= mips_ksyms.o
-
 obj-y				+= branch.o process.o signal.o entry.o \
 				   traps.o ptrace.o vm86.o ioport.o reset.o \
 				   semaphore.o setup.o syscall.o sysmips.o \
diff -Nru a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
--- a/arch/mips/kernel/sysirix.c	Mon Feb 10 10:39:32 2003
+++ b/arch/mips/kernel/sysirix.c	Mon Feb 10 10:39:32 2003
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/errno.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/times.h>
 #include <linux/elf.h>
@@ -615,19 +616,17 @@
 	return current->gid;
 }
 
-extern rwlock_t xtime_lock;
-
 asmlinkage int irix_stime(int value)
 {
 	if (!capable(CAP_SYS_TIME))
 		return -EPERM;
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime.tv_sec = value;
 	xtime.tv_usec = 0;
 	time_maxerror = MAXPHASE;
 	time_esterror = MAXPHASE;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 
 	return 0;
 }
diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
--- a/arch/mips/kernel/time.c	Mon Feb 10 10:39:26 2003
+++ b/arch/mips/kernel/time.c	Mon Feb 10 10:39:26 2003
@@ -37,7 +37,6 @@
 /*
  * forward reference
  */
-extern rwlock_t xtime_lock;
 extern volatile unsigned long wall_jiffies;
 
 /*
@@ -63,19 +62,23 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_gettimeoffset();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		*tv = xtime;
+		tv->tv_usec += do_gettimeoffset();
+
+		/*
+		 * xtime is atomically updated in timer_bh. 
+		 * jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-	read_unlock_irqrestore (&xtime_lock, flags);
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -85,7 +88,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec
 	 * correctly. However, the value in this location is
@@ -105,7 +108,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
 
 
@@ -291,6 +294,8 @@
  */
 void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	unsigned long seq;
+
 	if (mips_cpu.options & MIPS_CPU_COUNTER) {
 		unsigned int count;
 
@@ -340,19 +345,21 @@
 	 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
-	read_lock (&xtime_lock);
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
-	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
-		if (rtc_set_time(xtime.tv_sec) == 0) {
-			last_rtc_update = xtime.tv_sec;
-		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
-			/* do it again in 60 s */
+	do {
+		seq = read_seqbegin(&xtime_lock);
+	
+		if ((time_status & STA_UNSYNC) == 0 &&
+		    xtime.tv_sec > last_rtc_update + 660 &&
+		    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+		    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
+			if (rtc_set_time(xtime.tv_sec) == 0) {
+				last_rtc_update = xtime.tv_sec;
+			} else {
+				last_rtc_update = xtime.tv_sec - 600; 
+				/* do it again in 60 s */
+			}
 		}
-	}
-	read_unlock (&xtime_lock);
+	} while (read_seqretry(&xtime_lock, seq));
 
 	/*
 	 * If jiffies has overflowed in this timer_interrupt we must
diff -Nru a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
--- a/arch/mips/mips-boards/generic/time.c	Mon Feb 10 10:39:29 2003
+++ b/arch/mips/mips-boards/generic/time.c	Mon Feb 10 10:39:29 2003
@@ -34,6 +34,7 @@
 #include <asm/div64.h>
 
 #include <linux/mc146818rtc.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 
 #include <asm/mips-boards/generic.h>
@@ -45,7 +46,6 @@
 
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern rwlock_t xtime_lock;
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
@@ -133,7 +133,9 @@
  */
 void mips_timer_interrupt(struct pt_regs *regs)
 {
+	unsigned long flags;
 	int irq = 7;
+	unsigned long seq;
 
 	if (r4k_offset == 0)
 		goto null;
@@ -149,18 +151,21 @@
  		 * within 500ms before the * next second starts, 
  		 * thus the following code.
  		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-		read_unlock(&xtime_lock);
 
+		do {
+			seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+			if ((time_status & STA_UNSYNC) == 0 
+			    && xtime.tv_sec > last_rtc_update + 660 
+			    && xtime.tv_usec >= 500000 - (tick >> 1) 
+			    && xtime.tv_usec <= 500000 + (tick >> 1))
+				if (set_rtc_mmss(xtime.tv_sec) == 0)
+					last_rtc_update = xtime.tv_sec;
+				else
+					/* do it again in 60 s */
+					last_rtc_update = xtime.tv_sec - 600; 
+		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+		
 		if ((timer_tick_count++ % HZ) == 0) {
 		    mips_display_message(&display_string[display_count++]);
 		    if (display_count == MAX_DISPLAY_COUNT)
@@ -267,10 +272,10 @@
 	change_cp0_status(ST0_IM, ALLINTS);
 
 	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
+	write_seqlock_irqsave (&xtime_lock, flags);
 	xtime.tv_sec = get_mips_time();
 	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* This is for machines which generate the exact clock. */
@@ -363,20 +368,24 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned int flags;
+	unsigned long flags;
+	unsigned long seq;
+
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
+		*tv = xtime;
+		tv->tv_usec += do_fast_gettimeoffset();
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		/*
+		 * xtime is atomically updated in timer_bh. 
+		 * jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
 
-	read_unlock_irqrestore (&xtime_lock, flags);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -386,7 +395,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec correctly.
 	 * However, the value in this location is is value at the last tick.
@@ -406,5 +415,5 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
--- a/arch/mips/mm/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/mips/mm/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,7 +2,6 @@
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
-export-objs			+= ioremap.o umap.o
 obj-y				+= extable.o init.o ioremap.o fault.o loadmmu.o
 
 obj-$(CONFIG_CPU_R3000)		+= r2300.o
diff -Nru a/arch/mips/philips/nino/time.c b/arch/mips/philips/nino/time.c
--- a/arch/mips/philips/nino/time.c	Mon Feb 10 10:39:23 2003
+++ b/arch/mips/philips/nino/time.c	Mon Feb 10 10:39:23 2003
@@ -19,12 +19,12 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/delay.h>
 #include <asm/tx3912.h>
 
 extern volatile unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
 
 static struct timeval xbase;
 
@@ -62,29 +62,31 @@
 void do_gettimeofday(struct timeval *tv)
 {
     unsigned long flags;
+    unsigned long seq;
     unsigned long high, low;
 
-    read_lock_irqsave(&xtime_lock, flags);
-    // 40 bit RTC, driven by 32khz source:
-    // +-----------+-----------------------------------------+
-    // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM |
-    // +-----------+-----------------------------------------+
-    readRTC(&high,&low);
-    tv->tv_sec  = (high << 17) | (low >> 15);
-    tv->tv_usec = (low % 32768) * 1953 / 64;
-    tv->tv_sec += xbase.tv_sec;
-    tv->tv_usec += xbase.tv_usec;
+    do {
+	    seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-    tv->tv_usec += do_gettimeoffset();
-
-    /*
-     * xtime is atomically updated in timer_bh. lost_ticks is
-     * nonzero if the timer bottom half hasnt executed yet.
-     */
-    if (jiffies - wall_jiffies)
-	tv->tv_usec += USECS_PER_JIFFY;
-
-    read_unlock_irqrestore(&xtime_lock, flags);
+	    // 40 bit RTC, driven by 32khz source:
+	    // +-----------+-----------------------------------------+
+	    // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM |
+	    // +-----------+-----------------------------------------+
+	    readRTC(&high,&low);
+	    tv->tv_sec  = (high << 17) | (low >> 15);
+	    tv->tv_usec = (low % 32768) * 1953 / 64;
+	    tv->tv_sec += xbase.tv_sec;
+	    tv->tv_usec += xbase.tv_usec;
+
+	    tv->tv_usec += do_gettimeoffset();
+
+	    /*
+	     * xtime is atomically updated in timer_bh. lost_ticks is
+	     * nonzero if the timer bottom half hasnt executed yet.
+	     */
+	    if (jiffies - wall_jiffies)
+		    tv->tv_usec += USECS_PER_JIFFY;
+    } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
     if (tv->tv_usec >= 1000000) {
 	tv->tv_usec -= 1000000;
@@ -94,7 +96,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-    write_lock_irq(&xtime_lock);
+    write_seqlock_irq(&xtime_lock);
     /* This is revolting. We need to set the xtime.tv_usec
      * correctly. However, the value in this location is
      * is value at the last tick.
@@ -118,7 +120,7 @@
     time_state = TIME_BAD;
     time_maxerror = MAXPHASE;
     time_esterror = MAXPHASE;
-    write_unlock_irq(&xtime_lock);
+    write_sequnlock_irq(&xtime_lock);
 }
 
 static int set_rtc_mmss(unsigned long nowtime)
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/arch/mips64/Kconfig	Mon Feb 10 10:39:24 2003
@@ -361,7 +361,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config MIPS32_COMPAT
@@ -406,7 +406,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 endmenu
@@ -464,7 +464,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -491,7 +491,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -608,7 +608,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/mips64/Makefile b/arch/mips64/Makefile
--- a/arch/mips64/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/mips64/Makefile	Mon Feb 10 10:39:24 2003
@@ -128,7 +128,7 @@
 
 LDFLAGS_vmlinux += -Ttext $(LOADADDR)
 
-HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
+head-y := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
 
 SUBDIRS		:= arch/mips64/tools $(SUBDIRS)
 core-y		+= arch/mips64/kernel/ arch/mips64/mm/
diff -Nru a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile
--- a/arch/mips64/kernel/Makefile	Mon Feb 10 10:39:25 2003
+++ b/arch/mips64/kernel/Makefile	Mon Feb 10 10:39:25 2003
@@ -4,8 +4,6 @@
 
 EXTRA_TARGETS	:= head.o init_task.o
 
-export-objs	:= mips64_ksyms.o
-
 obj-y	:= branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
 	   r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \
 	   scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \
diff -Nru a/arch/mips64/mips-boards/generic/time.c b/arch/mips64/mips-boards/generic/time.c
--- a/arch/mips64/mips-boards/generic/time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/mips64/mips-boards/generic/time.c	Mon Feb 10 10:39:24 2003
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/kernel_stat.h>
 #include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/spinlock.h>
 
 #include <asm/mipsregs.h>
@@ -44,7 +45,6 @@
 
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-extern rwlock_t xtime_lock;
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
 
@@ -132,6 +132,8 @@
  */
 void mips_timer_interrupt(struct pt_regs *regs)
 {
+	unsigned long flags;
+	unsigned long seq;
 	int irq = 7;
 
 	if (r4k_offset == 0)
@@ -148,17 +150,20 @@
  		 * within 500ms before the * next second starts, 
  		 * thus the following code.
  		 */
-		read_lock(&xtime_lock);
-		if ((time_status & STA_UNSYNC) == 0 
-		    && xtime.tv_sec > last_rtc_update + 660 
-		    && xtime.tv_usec >= 500000 - (tick >> 1) 
-		    && xtime.tv_usec <= 500000 + (tick >> 1))
-			if (set_rtc_mmss(xtime.tv_sec) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else
-				/* do it again in 60 s */
-	    			last_rtc_update = xtime.tv_sec - 600; 
-		read_unlock(&xtime_lock);
+		do {
+			seq = read_seqbegin_irqsave(&xtime_lock, flags);
+			
+			if ((time_status & STA_UNSYNC) == 0 
+			    && xtime.tv_sec > last_rtc_update + 660 
+			    && xtime.tv_usec >= 500000 - (tick >> 1) 
+			    && xtime.tv_usec <= 500000 + (tick >> 1))
+				if (set_rtc_mmss(xtime.tv_sec) == 0)
+					last_rtc_update = xtime.tv_sec;
+				else
+					/* do it again in 60 s */
+					last_rtc_update = xtime.tv_sec - 600; 
+		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
 
 		if ((timer_tick_count++ % HZ) == 0) {
 		    mips_display_message(&display_string[display_count++]);
@@ -266,10 +271,10 @@
 	set_cp0_status(ST0_IM, ALLINTS);
 
 	/* Read time from the RTC chipset. */
-	write_lock_irqsave (&xtime_lock, flags);
+	write_seqlock_irqsave (&xtime_lock, flags);
 	xtime.tv_sec = get_mips_time();
 	xtime.tv_usec = 0;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* This is for machines which generate the exact clock. */
@@ -352,20 +357,25 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned int flags;
+	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_fast_gettimeoffset();
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
+		*tv = xtime;
+		tv->tv_usec += do_fast_gettimeoffset();
+
+		/*
+		 * xtime is atomically updated in timer_bh. 
+		 * jiffies - wall_jiffies
+		 * is nonzero if the timer bottom half hasnt executed yet.
+		 */
+		if (jiffies - wall_jiffies)
+			tv->tv_usec += USECS_PER_JIFFY;
+
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
-	read_unlock_irqrestore (&xtime_lock, flags);
 
 	if (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
@@ -375,7 +385,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_usec correctly.
 	 * However, the value in this location is is value at the last tick.
@@ -395,5 +405,5 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
diff -Nru a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile
--- a/arch/mips64/mm/Makefile	Mon Feb 10 10:39:22 2003
+++ b/arch/mips64/mm/Makefile	Mon Feb 10 10:39:22 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
-export-objs			+= umap.o
-
 obj-y				:= extable.o init.o fault.o loadmmu.o
 
 obj-$(CONFIG_CPU_R4300)		+= r4xx0.o
diff -Nru a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c
--- a/arch/mips64/sgi-ip22/ip22-timer.c	Mon Feb 10 10:39:27 2003
+++ b/arch/mips64/sgi-ip22/ip22-timer.c	Mon Feb 10 10:39:27 2003
@@ -11,6 +11,7 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/kernel_stat.h>
@@ -32,8 +33,6 @@
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 
-extern rwlock_t xtime_lock;
-
 static inline void ack_r4ktimer(unsigned long newval)
 {
 	write_32bit_cp0_register(CP0_COMPARE, newval);
@@ -86,7 +85,7 @@
 	unsigned long count;
 	int irq = 7;
 
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	/* Ack timer and compute new compare. */
 	count = read_32bit_cp0_register(CP0_COUNT);
 	/* This has races.  */
@@ -116,7 +115,7 @@
 			/* do it again in 60s  */
 			last_rtc_update = xtime.tv_sec - 600;
 	}
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 static unsigned long dosample(volatile unsigned char *tcwp,
@@ -224,10 +223,10 @@
 	set_cp0_status(ST0_IM, ALLINTS);
 	sti();
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime.tv_sec = get_indy_time();		/* Read time from RTC. */
 	xtime.tv_usec = 0;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 void indy_8254timer_irq(void)
@@ -243,20 +242,21 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags;
+	unsigned long seq;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	*tv = xtime;
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		*tv = xtime;
+	} while (read_seqretry(&xtime_lock, seq));
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime = *tv;
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
diff -Nru a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
--- a/arch/mips64/sgi-ip27/ip27-timer.c	Mon Feb 10 10:39:25 2003
+++ b/arch/mips64/sgi-ip27/ip27-timer.c	Mon Feb 10 10:39:25 2003
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/param.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/mm.h>		
 #include <linux/bcd.h>		
@@ -40,7 +41,6 @@
 static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
 static long last_rtc_update;		/* Last time the rtc clock got updated */
 
-extern rwlock_t xtime_lock;
 extern volatile unsigned long wall_jiffies;
 
 
@@ -94,7 +94,7 @@
 	int cpuA = ((cputoslice(cpu)) == 0);
 	int irq = 7;				/* XXX Assign number */
 
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 
 again:
 	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
@@ -145,7 +145,7 @@
 		}
         }
 
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 
 	if (softirq_pending(cpu))
 		do_softirq();
@@ -162,17 +162,20 @@
 {
 	unsigned long flags;
 	unsigned long usec, sec;
+	unsigned long seq;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += xtime.tv_usec;
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+		usec = do_gettimeoffset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += xtime.tv_usec;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -185,7 +188,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	tv->tv_usec -= do_gettimeoffset();
 	tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
 
@@ -199,7 +202,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /* Includes for ioc3_init().  */
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/arch/parisc/Kconfig	Mon Feb 10 10:39:29 2003
@@ -199,7 +199,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -224,7 +224,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 endmenu
@@ -260,7 +260,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -327,7 +327,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/parisc/Makefile	Mon Feb 10 10:39:32 2003
@@ -33,10 +33,10 @@
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
 
-cflags-y	:= -D__linux__ -pipe -fno-strength-reduce
+cflags-y	:= -pipe
 
-# These should be on for older toolchains or SOM toolchains that don't
-# enable them by default.
+# These flags should be implied by an hppa-linux configuration, but they
+# are not in gcc 3.2.
 cflags-y	+= -mno-space-regs -mfast-indirect-calls
 
 # No fixed-point multiply
@@ -56,7 +56,6 @@
 head-$(CONFIG_PARISC64)	:= arch/parisc/kernel/head64.o
 
 CFLAGS	+= $(cflags-y)
-HEAD	:= $(head-y)
 
 core-y	+= $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o   \
 		mm/ kernel/ hpux/ math-emu/ kernel/init_task.o )
@@ -95,9 +94,6 @@
 	@echo -n '  Generating $@'
 	@$(generate-asm-offsets.h) < $< > $@.tmp
 	@$(update-if-changed)
-
-archclean:
-archmrproper:
 
 CLEAN_FILES	+= palo.conf lifimage include/asm-parisc/offsets.h \
 		include/asm-parisc/offsets.h.tmp
diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/parisc/kernel/Makefile	Mon Feb 10 10:39:24 2003
@@ -9,8 +9,6 @@
 AFLAGS_entry.o	:= -traditional
 AFLAGS_pacache.o := -traditional
 
-export-objs	:= parisc_ksyms.o
-
 obj-y	     	:= cache.o pacache.o setup.o traps.o time.o irq.o \
 		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
 		   ptrace.o hardware.o inventory.o drivers.o semaphore.o \
diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
--- a/arch/parisc/kernel/entry.S	Mon Feb 10 10:39:24 2003
+++ b/arch/parisc/kernel/entry.S	Mon Feb 10 10:39:24 2003
@@ -689,7 +689,7 @@
 	 * (we don't store them in the sigcontext), so set them
 	 * to "proper" values now (otherwise we'll wind up restoring
 	 * whatever was last stored in the task structure, which might
-	 * be inconsistant if an interrupt occured while on the gateway
+	 * be inconsistent if an interrupt occured while on the gateway
 	 * page) Note that we may be "trashing" values the user put in
 	 * them, but we don't support the the user changing them.
 	 */
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	Mon Feb 10 10:39:25 2003
+++ b/arch/parisc/kernel/irq.c	Mon Feb 10 10:39:25 2003
@@ -243,7 +243,7 @@
 	    for (i = 0; i <= MAX_CPU_IRQ; i++) {
 		struct irqaction *action = &region->action[i];
 		unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
-		int j=0;
+		int j = 0;
 		if (!action->handler)
 			continue;
 
@@ -251,7 +251,7 @@
 #ifdef CONFIG_SMP
 		for (; j < NR_CPUS; j++)
 #endif
-		    seq_printf(p, "%10u ", kstat_cpu(j).irqs[regnr][irq_no]);
+		  seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]);
 
 		seq_printf(p, " %14s",
 			    region->data.name ? region->data.name : "N/A");
@@ -373,7 +373,7 @@
 	/* XXX FIXME : bits_wide indicates how wide the transaction
 	** data is allowed to be...we may need a different virt_irq
 	** if this one won't work. Another reason to index virtual
-	** irq's into a table which can manage CPU/IRQ bit seperately.
+	** irq's into a table which can manage CPU/IRQ bit separately.
 	*/
 	if (IRQ_OFFSET(virt_irq) > (1 << (bits_wide -1)))
 	{
@@ -388,7 +388,7 @@
 	int cpu = smp_processor_id();
 
 	irq_enter();
-	++kstat_cpu(cpu).irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)];
+	++kstat_cpu(cpu).irqs[irq];
 
 	DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)));
 
diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
--- a/arch/parisc/kernel/module.c	Mon Feb 10 10:39:33 2003
+++ b/arch/parisc/kernel/module.c	Mon Feb 10 10:39:33 2003
@@ -13,6 +13,12 @@
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    (c) 2003 Randolph Chung <tausq@debian.org>
+
+    The best reference for this stuff is probably the Processor-
+    Specific ELF Supplement for PA-RISC:
+	http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf
 */
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
@@ -21,19 +27,92 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-#if 0
+#if 1
 #define DEBUGP printk
 #else
 #define DEBUGP(fmt...)
 #endif
 
-enum parisc_fsel {
-	e_fsel,
-	e_lsel,
-	e_rsel,
-	e_lrsel,
-	e_rrsel
+
+#ifndef __LP64__
+struct got_entry {
+	Elf32_Addr addr;
+};
+
+struct fdesc_entry {
+	Elf32_Addr gp;
+	Elf32_Addr addr;
+};
+
+struct stub_entry {
+	Elf32_Word insns[2]; /* each stub entry has two insns */
+};
+#else
+struct got_entry {
+	Elf64_Addr addr;
+};
+
+struct fdesc_entry {
+	Elf64_Addr dummy[2];
+	Elf64_Addr gp;
+	Elf64_Addr addr;
+};
+
+struct stub_entry {
+	Elf64_Word insns[4]; /* each stub entry has four insns */
 };
+#endif
+
+/* Field selection types defined by hppa */
+#define rnd(x)			(((x)+0x1000)&~0x1fff)
+/* fsel: full 32 bits */
+#define fsel(v,a)		((v)+(a))
+/* lsel: select left 21 bits */
+#define lsel(v,a)		(((v)+(a))>>11)
+/* rsel: select right 11 bits */
+#define rsel(v,a)		(((v)+(a))&0x7ff)
+/* lrsel with rounding of addend to nearest 8k */
+#define lrsel(v,a)		(((v)+rnd(a))>>11)
+/* rrsel with rounding of addend to nearest 8k */
+#define rrsel(v,a)		((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
+
+#define mask(x,sz)		((x) & ~((1<<(sz))-1))
+
+
+/* The reassemble_* functions prepare an immediate value for
+   insertion into an opcode. pa-risc uses all sorts of weird bitfields
+   in the instruction to hold the value.  */
+static inline int reassemble_14(int as14)
+{
+	return (((as14 & 0x1fff) << 1) |
+		((as14 & 0x2000) >> 13));
+}
+
+static inline int reassemble_17(int as17)
+{
+	return (((as17 & 0x10000) >> 16) |
+		((as17 & 0x0f800) << 5) |
+		((as17 & 0x00400) >> 8) |
+		((as17 & 0x003ff) << 3));
+}
+
+static inline int reassemble_21(int as21)
+{
+	return (((as21 & 0x100000) >> 20) |
+		((as21 & 0x0ffe00) >> 8) |
+		((as21 & 0x000180) << 7) |
+		((as21 & 0x00007c) << 14) |
+		((as21 & 0x000003) << 12));
+}
+
+static inline int reassemble_22(int as22)
+{
+	return (((as22 & 0x200000) >> 21) |
+		((as22 & 0x1f0000) << 5) |
+		((as22 & 0x00f800) << 5) |
+		((as22 & 0x000400) >> 8) |
+		((as22 & 0x0003ff) << 3));
+}
 
 void *module_alloc(unsigned long size)
 {
@@ -42,6 +121,81 @@
 	return vmalloc(size);
 }
 
+#ifndef __LP64__
+static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
+{
+	return 0;
+}
+
+static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
+{
+	return 0;
+}
+
+static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF32_R_TYPE(rela->r_info)) {
+			case R_PARISC_PCREL17F:
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+#else
+static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_LTOFF21L:
+			case R_PARISC_LTOFF14R:
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+
+static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 3; /* 3 for finalize */
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_FPTR64:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+
+static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
+{
+	unsigned long cnt = 0;
+
+	for (; n > 0; n--, rela++)
+	{
+		switch (ELF64_R_TYPE(rela->r_info)) {
+			case R_PARISC_PCREL22F:
+				cnt++;
+		}
+	}
+
+	return cnt;
+}
+#endif
+
 
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
@@ -51,35 +205,145 @@
            table entries. */
 }
 
-/* We don't need anything special. */
-long module_core_size(const Elf_Ehdr *hdr,
-		      const Elf_Shdr *sechdrs,
-		      const char *secstrings,
-		      struct module *module)
+#define CONST 
+int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
+			      CONST Elf_Shdr *sechdrs,
+			      CONST char *secstrings,
+			      struct module *me)
 {
-	return module->core_size;
+	unsigned long gots = 0, fdescs = 0, stubs = 0;
+	unsigned int i;
+
+	for (i = 1; i < hdr->e_shnum; i++) {
+		const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
+		unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
+
+		if (sechdrs[i].sh_type != SHT_RELA)
+			continue;
+
+		/* some of these are not relevant for 32-bit/64-bit
+		 * we leave them here to make the code common. the
+		 * compiler will do its thing and optimize out the
+		 * stuff we don't need
+		 */
+		gots += count_gots(rels, nrels);
+		fdescs += count_fdescs(rels, nrels);
+		stubs += count_stubs(rels, nrels);
+	}
+
+	/* align things a bit */
+	me->core_size = ALIGN(me->core_size, 16);
+	me->arch.got_offset = me->core_size;
+	me->core_size += gots * sizeof(struct got_entry);
+
+	me->core_size = ALIGN(me->core_size, 16);
+	me->arch.fdesc_offset = me->core_size;
+	me->core_size += stubs * sizeof(struct fdesc_entry);
+
+	me->core_size = ALIGN(me->core_size, 16);
+	me->arch.stub_offset = me->core_size;
+	me->core_size += stubs * sizeof(struct stub_entry);
+
+	return 0;
 }
 
-long module_init_size(const Elf_Ehdr *hdr,
-		      const Elf_Shdr *sechdrs,
-		      const char *secstrings,
-		      struct module *module)
+static Elf_Addr get_got(struct module *me, unsigned long value, long addend)
 {
-	return module->init_size;
+	unsigned int i;
+	struct got_entry *got;
+
+	value += addend;
+
+	BUG_ON(value == 0);
+
+	got = me->module_core + me->arch.got_offset;
+	for (i = 0; got[i].addr; i++)
+		if (got[i].addr == value)
+			return i * sizeof(struct got_entry);
+
+	got[i].addr = value;
+	return i * sizeof(struct got_entry);
 }
 
-int module_frob_arch_sections(Elf_Ehdr *hdr,
-			      Elf_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *mod)
+static Elf_Addr get_fdesc(struct module *me, unsigned long value)
 {
-	/* parisc should not need this ... */
-	printk(KERN_ERR "module %s: %s not yet implemented.\n",
-	       mod->name, __FUNCTION__);
-	return 0;
+	struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset;
+
+	if (!value) {
+		printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+		return 0;
+	}
+
+	/* Look for existing fdesc entry. */
+	while (fdesc->addr) {
+		if (fdesc->addr == value)
+			return (Elf_Addr)fdesc;
+		fdesc++;
+	}
+
+	/* Create new one */
+	fdesc->addr = value;
+	fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
+	return (Elf_Addr)fdesc;
 }
 
+static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
+	int millicode)
+{
+	unsigned long i;
+	struct stub_entry *stub;
 
+	i = me->arch.stub_count++;
+	stub = me->module_core + me->arch.stub_offset + 
+	       i * sizeof(struct stub_entry);
+
+#ifndef __LP64__
+/* for 32-bit the stub looks like this:
+ * 	ldil L'XXX,%r1
+ * 	be,n R'XXX(%sr4,%r1)
+ */
+	stub->insns[0] = 0x20200000;	/* ldil L'XXX,%r1	*/
+	stub->insns[1] = 0xe0202002;	/* be,n R'XXX(%sr4,%r1)	*/
+
+	stub->insns[0] |= reassemble_21(lrsel(value, addend));
+	stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
+#else
+/* for 64-bit we have two kinds of stubs:
+ * for normal function calls:
+ * 	ldd 0(%dp),%dp
+ * 	ldd 10(%dp), %r1
+ * 	bve (%r1)
+ * 	ldd 18(%dp), %dp
+ *
+ * for millicode:
+ * 	ldil 0, %r1
+ * 	ldo 0(%r1), %r1
+ * 	ldd 10(%r1), %r1
+ * 	bve,n (%r1)
+ */
+	if (!millicode)
+	{
+		stub->insns[0] = 0x537b0000;	/* ldd 0(%dp),%dp	*/
+		stub->insns[1] = 0x53610020;	/* ldd 10(%dp),%r1	*/
+		stub->insns[2] = 0xe820d000;	/* bve (%r1)		*/
+		stub->insns[3] = 0x537b0030;	/* ldd 18(%dp),%dp	*/
+
+		stub->insns[0] |= reassemble_21(get_got(me, value, addend));
+	}
+	else
+	{
+		stub->insns[0] = 0x20200000;	/* ldil 0,%r1		*/
+		stub->insns[1] = 0x34210000;	/* ldo 0(%r1), %r1	*/
+		stub->insns[2] = 0x50210020;	/* ldd 10(%r1),%r1	*/
+		stub->insns[3] = 0xe820d002;	/* bve,n (%r1)		*/
+
+		stub->insns[0] |= reassemble_21(lrsel(value, addend));
+		stub->insns[1] |= reassemble_14(rrsel(value, addend));
+	}
+#endif
+
+	return (Elf_Addr)stub;
+}
 
 int apply_relocate(Elf_Shdr *sechdrs,
 		   const char *strtab,
@@ -104,7 +368,10 @@
 	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
 	Elf32_Sym *sym;
 	Elf32_Word *loc;
-	Elf32_Addr value;
+	Elf32_Addr val;
+	Elf32_Sword addend;
+	Elf32_Addr dot;
+	register unsigned long dp asm ("r27");
 
 	DEBUGP("Applying relocate section %u to %u\n", relsec,
 	       sechdrs[relsec].sh_info);
@@ -120,59 +387,81 @@
 			       me->name, strtab + sym->st_name);
 			return -ENOENT;
 		}
+		dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
 
-		value = sym->st_value + rel[i].r_addend;
+		val = sym->st_value;
+		addend = rel[i].r_addend;
 
-		DEBUGP("Symbol %s loc 0x%lx value 0x%lx: ",
+#if 0
+#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
+		DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
 			strtab + sym->st_name,
-			(uint32_t)loc, value);
+			(uint32_t)loc, val, addend,
+			r(R_PARISC_PLABEL32)
+			r(R_PARISC_DIR32)
+			r(R_PARISC_DIR21L)
+			r(R_PARISC_DIR14R)
+			r(R_PARISC_SEGREL32)
+			r(R_PARISC_DPREL21L)
+			r(R_PARISC_DPREL14R)
+			r(R_PARISC_PCREL17F)
+			r(R_PARISC_PCREL22F)
+			"UNKNOWN");
+#undef r
+#endif
 
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
 		case R_PARISC_PLABEL32:
 			/* 32-bit function address */
-			DEBUGP("R_PARISC_PLABEL32\n");
+			/* no function descriptors... */
+			*loc = fsel(val, addend);
 			break;
 		case R_PARISC_DIR32:
 			/* direct 32-bit ref */
-			DEBUGP("R_PARISC_DIR32\n");
+			*loc = fsel(val, addend);
 			break;
 		case R_PARISC_DIR21L:
 			/* left 21 bits of effective address */
-			DEBUGP("R_PARISC_DIR21L\n");
+			*loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend));
 			break;
 		case R_PARISC_DIR14R:
 			/* right 14 bits of effective address */
-			DEBUGP("R_PARISC_DIR14R\n");
+			*loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend));
 			break;
 		case R_PARISC_SEGREL32:
 			/* 32-bit segment relative address */
-			DEBUGP("R_PARISC_SEGREL32\n");
+			val -= (uint32_t)me->module_core;
+			*loc = fsel(val, addend); 
 			break;
 		case R_PARISC_DPREL21L:
 			/* left 21 bit of relative address */
-			DEBUGP("R_PARISC_DPREL21L\n");
+			val -= dp;
+			*loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend) - dp);
 			break;
 		case R_PARISC_DPREL14R:
 			/* right 14 bit of relative address */
-			DEBUGP("R_PARISC_DPREL14R\n");
+			val -= dp;
+			*loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend) - dp);
 			break;
 		case R_PARISC_PCREL17F:
 			/* 17-bit PC relative address */
-			DEBUGP("R_PARISC_PCREL17F\n");
+			val = get_stub(me, val, addend, 0) - dot - 8;
+			*loc = (*loc&0x1f1ffd) | reassemble_17(val);
 			break;
 		case R_PARISC_PCREL22F:
-			/* 22-bit PC relative address */
-			DEBUGP("R_PARISC_PCREL22F\n");
+			/* 22-bit PC relative address; only defined for pa20 */
+			val = get_stub(me, val, addend, 0) - dot - 8;
+			*loc = (*loc&0x3ff1ffd) | reassemble_22(val);
 			break;
 
 		default:
-			printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
 			       me->name, ELF32_R_TYPE(rel[i].r_info));
 			return -ENOEXEC;
 		}
 	}
 
-	return -ENOEXEC;
+	return 0;
 }
 
 #else
@@ -186,7 +475,9 @@
 	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
 	Elf64_Sym *sym;
 	Elf64_Word *loc;
-	Elf64_Addr value;
+	Elf64_Addr val;
+	Elf64_Sxword addend;
+	Elf64_Addr dot;
 
 	DEBUGP("Applying relocate section %u to %u\n", relsec,
 	       sechdrs[relsec].sh_info);
@@ -202,38 +493,56 @@
 			       me->name, strtab + sym->st_name);
 			return -ENOENT;
 		}
+		dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
 
-		value = sym->st_value + rel[i].r_addend;
+		val = sym->st_value;
+		addend = rel[i].r_addend;
 
-		DEBUGP("Symbol %s loc 0x%Lx value 0x%Lx: ",
+#if 1
+#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t :
+		DEBUGP("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n",
 			strtab + sym->st_name,
-			(uint64_t)loc, value);
+			loc, val, addend,
+			r(R_PARISC_LTOFF14R)
+			r(R_PARISC_LTOFF21L)
+			r(R_PARISC_PCREL22F)
+			r(R_PARISC_DIR64)
+			r(R_PARISC_SEGREL32)
+			r(R_PARISC_FPTR64)
+			"UNKNOWN");
+#undef r
+#endif
 
 		switch (ELF64_R_TYPE(rel[i].r_info)) {
-		case R_PARISC_LTOFF14R:
-			/* LT-relative; right 14 bits */
-			DEBUGP("R_PARISC_LTOFF14R\n");
-			break;
 		case R_PARISC_LTOFF21L:
 			/* LT-relative; left 21 bits */
-			DEBUGP("R_PARISC_LTOFF21L\n");
+			*loc = mask(*loc, 21) | reassemble_21(get_got(me, val, addend));
+			break;
+		case R_PARISC_LTOFF14R:
+			/* L(ltoff(val+addend)) */
+			/* LT-relative; right 14 bits */
+			*loc = mask(*loc, 14) | reassemble_14(get_got(me, val, addend));
 			break;
 		case R_PARISC_PCREL22F:
 			/* PC-relative; 22 bits */
-			DEBUGP("R_PARISC_PCREL22F\n");
+			if (strncmp(strtab + sym->st_name, "$$", 2) == 0)
+				val = get_stub(me, val, addend, 1) - dot - 8;
+			else
+				val = get_stub(me, val, addend, 0) - dot - 8;
+			*loc = (*loc&0x3ff1ffd) | reassemble_22(val);
 			break;
 		case R_PARISC_DIR64:
 			/* 64-bit effective address */
-			DEBUGP("R_PARISC_DIR64\n");
-			*loc = value;
+			*loc = fsel(val, addend);
 			break;
 		case R_PARISC_SEGREL32:
 			/* 32-bit segment relative address */
-			DEBUGP("R_PARISC_SEGREL32\n");
+			val -= (uint64_t)me->module_core;
+			*loc = fsel(val, addend); 
 			break;
 		case R_PARISC_FPTR64:
 			/* 64-bit function address */
-			DEBUGP("R_PARISC_FPTR64\n");
+			*loc = get_fdesc(me, val+addend);
 			break;
 
 		default:
@@ -242,7 +551,7 @@
 			return -ENOEXEC;
 		}
 	}
-	return -ENOEXEC;
+	return 0;
 }
 #endif
 
@@ -250,5 +559,14 @@
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
+#ifdef __LP64__
+	me->init = (void *)get_fdesc(me, (Elf_Addr)me->init);
+#ifdef CONFIG_MODULE_UNLOAD
+	if (me->cleanup)
+		me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup);
+	if (me->destroy)
+		me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy);
+#endif
+#endif
 	return 0;
 }
diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
--- a/arch/parisc/kernel/parisc_ksyms.c	Mon Feb 10 10:39:33 2003
+++ b/arch/parisc/kernel/parisc_ksyms.c	Mon Feb 10 10:39:33 2003
@@ -31,10 +31,6 @@
 EXPORT_SYMBOL(get_pci_node_path);
 #endif
 
-#ifdef CONFIG_IOMMU_CCIO
-EXPORT_SYMBOL(ccio_get_fake);
-#endif
-
 #include <linux/sched.h>
 #include <asm/irq.h>
 EXPORT_SYMBOL(enable_irq);
diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
--- a/arch/parisc/kernel/signal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/parisc/kernel/signal.c	Mon Feb 10 10:39:33 2003
@@ -118,11 +118,11 @@
 #endif
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->gr[28] = -EINTR;
 	while (1) {
@@ -177,10 +177,10 @@
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* Good thing we saved the old gr[30], eh? */
 	if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
@@ -407,11 +407,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return 1;
 }
diff -Nru a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
--- a/arch/parisc/kernel/signal32.c	Mon Feb 10 10:39:24 2003
+++ b/arch/parisc/kernel/signal32.c	Mon Feb 10 10:39:24 2003
@@ -17,59 +17,6 @@
 	struct sigaction32 sa;
 };
 
-typedef unsigned int old_sigset_t32;
-
-static int
-put_old_sigset32(old_sigset_t32 *up, old_sigset_t *set)
-{
-	old_sigset_t32 set32 = *set;
-	return put_user(set32, up);
-}
-
-static int
-get_old_segset32(old_sigset_t32 *up, old_sigset_t *set)
-{
-	old_sigset_t32 set32;
-	int r;
-
-	if ((r = get_user(set32, up)) == 0)
-		*set = set32;
-
-	return r;
-}
-
-long
-sys32_sigpending(old_sigset_t32 *set)
-{
-	extern long sys_sigpending(old_sigset_t *set);
-	old_sigset_t pending;
-	int ret;
-
-	KERNEL_SYSCALL(ret, sys_sigpending, &pending);
-
-	/* can't put_user an old_sigset_t -- it is too big */
-	if (put_old_sigset32(set, &pending))
-		return -EFAULT;
-
-	return ret;
-}
-
-int sys32_sigprocmask(int how, old_sigset_t32 *set, 
-				 old_sigset_t32 *oset)
-{
-	extern int sys_sigprocmask(int how, old_sigset_t *set, 
-				 old_sigset_t *oset);
-	old_sigset_t s;
-	int ret;
-
-	if (set && get_old_segset32 (set, &s))
-		return -EFAULT;
-	KERNEL_SYSCALL(ret, sys_sigprocmask, how, set ? &s : NULL, oset ? &s : NULL);
-	if (!ret && oset && put_old_sigset32(oset, &s))
-		return -EFAULT;
-	return ret;
-}
-
 static inline void
 sigset_32to64(sigset_t *s64, sigset_t32 *s32)
 {
diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c	Mon Feb 10 10:39:24 2003
+++ b/arch/parisc/kernel/sys_parisc32.c	Mon Feb 10 10:39:24 2003
@@ -20,6 +20,7 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -314,74 +315,6 @@
     return -ENOSYS;
 }
 
-/* 32-bit user apps use struct statfs which uses 'long's */
-struct statfs32 {
-	__s32 f_type;
-	__s32 f_bsize;
-	__s32 f_blocks;
-	__s32 f_bfree;
-	__s32 f_bavail;
-	__s32 f_files;
-	__s32 f_ffree;
-	__kernel_fsid_t f_fsid;
-	__s32 f_namelen;
-	__s32 f_spare[6];
-};
-
-/* convert statfs struct to statfs32 struct and copy result to user */
-static unsigned long statfs32_to_user(struct statfs32 *ust32, struct statfs *st)
-{
-    struct statfs32 st32;
-#undef CP
-#define CP(a) st32.a = st->a
-    CP(f_type);
-    CP(f_bsize);
-    CP(f_blocks);
-    CP(f_bfree);
-    CP(f_bavail);
-    CP(f_files);
-    CP(f_ffree);
-    CP(f_fsid);
-    CP(f_namelen);
-    return copy_to_user(ust32, &st32, sizeof st32);
-}
-
-/* The following statfs calls are copies of code from linux/fs/open.c and
- * should be checked against those from time to time */
-asmlinkage long sys32_statfs(const char * path, struct statfs32 * buf)
-{
-	struct nameidata nd;
-	int error;
-
-	error = user_path_walk(path, &nd);
-	if (!error) {
-		struct statfs tmp;
-		error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
-		if (!error && statfs32_to_user(buf, &tmp))
-			error = -EFAULT;
-		path_release(&nd);
-	}
-	return error;
-}
-
-asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 * buf)
-{
-	struct file * file;
-	struct statfs tmp;
-	int error;
-
-	error = -EBADF;
-	file = fget(fd);
-	if (!file)
-		goto out;
-	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
-	if (!error && statfs32_to_user(buf, &tmp))
-		error = -EFAULT;
-	fput(file);
-out:
-	return error;
-}
-
 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2429,21 +2362,23 @@
 {
 	struct sysinfo val;
 	int err;
-	extern rwlock_t xtime_lock;
+	unsigned long seq;
 
 	/* We don't need a memset here because we copy the
 	 * struct to userspace once element at a time.
 	 */
 
-	read_lock_irq(&xtime_lock);
-	val.uptime = jiffies / HZ;
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		val.uptime = jiffies / HZ;
+
+		val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
+		val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
+		val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
 
-	val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
-	val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
-	val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
+		val.procs = nr_threads;
+	} while (read_seqretry(&xtime_lock, seq));
 
-	val.procs = nr_threads;
-	read_unlock_irq(&xtime_lock);
 
 	si_meminfo(&val);
 	si_swapinfo(&val);
diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
--- a/arch/parisc/kernel/syscall.S	Mon Feb 10 10:39:33 2003
+++ b/arch/parisc/kernel/syscall.S	Mon Feb 10 10:39:33 2003
@@ -425,30 +425,27 @@
 	/* I don't like this */
 	ENTRY_UHOH(sgetmask)
 	ENTRY_UHOH(ssetmask)
-	ENTRY_SAME(setreuid)	/* 70 */
+	ENTRY_SAME(setreuid)		/* 70 */
 	ENTRY_SAME(setregid)
 	ENTRY_SAME(mincore)
-	ENTRY_DIFF(sigpending)
+	ENTRY_COMP(sigpending)
 	ENTRY_SAME(sethostname)
 	/* Following 3 have linux-common-code structs containing longs -( */
-	ENTRY_DIFF(setrlimit)	/* 75 */
+	ENTRY_DIFF(setrlimit)		/* 75 */
 	ENTRY_DIFF(getrlimit)
 	ENTRY_DIFF(getrusage)
 	/* struct timeval and timezone are maybe?? consistent wide and narrow */
 	ENTRY_DIFF(gettimeofday)
 	ENTRY_DIFF(settimeofday)
-	ENTRY_SAME(getgroups)	/* 80 */
+	ENTRY_SAME(getgroups)		/* 80 */
 	ENTRY_SAME(setgroups)
 	/* struct socketaddr... */
 	ENTRY_SAME(sendto)
 	ENTRY_SAME(symlink)
 	/* see stat comment */
 	ENTRY_COMP(newlstat)
-	ENTRY_SAME(readlink)	/* 85 */
-	/* suspect we'll need some work for narrow shlibs on wide kernel */
-	/* NOTE this doesn't get used when I boot 32-bit userspace */
-	/* containing working shlib apps -- can this be nuked? */
-	ENTRY_UHOH(uselib)
+	ENTRY_SAME(readlink)		/* 85 */
+	ENTRY_SAME(ni_syscall)	/* was uselib */
 	ENTRY_SAME(swapon)
 	ENTRY_SAME(reboot)
 	ENTRY_SAME(mmap2)
@@ -461,17 +458,15 @@
 	ENTRY_SAME(getpriority)
 	ENTRY_SAME(setpriority)
 	ENTRY_SAME(recv)
-	ENTRY_DIFF(statfs)
-	ENTRY_DIFF(fstatfs)		/* 100 */
+	ENTRY_COMP(statfs)
+	ENTRY_COMP(fstatfs)		/* 100 */
 	ENTRY_SAME(stat64)
-	/* don't think hppa glibc even provides an entry pt for this
-	 * so disable for now */
-	ENTRY_UHOH(socketcall)
+	ENTRY_SAME(ni_syscall)	/* was socketcall */
 	ENTRY_SAME(syslog)
 	/* even though manpage says struct timeval contains longs, ours has
 	 * time_t and suseconds_t -- both of which are safe wide/narrow */
 	ENTRY_COMP(setitimer)
-	ENTRY_COMP(getitimer)	/* 105 */
+	ENTRY_COMP(getitimer)		/* 105 */
 	ENTRY_SAME(capget)
 	ENTRY_SAME(capset)
 	ENTRY_OURS(pread64)
@@ -494,10 +489,10 @@
 	ENTRY_SAME(recvfrom)
 	/* struct timex contains longs */
 	ENTRY_DIFF(adjtimex)
-	ENTRY_SAME(mprotect)	/* 125 */
+	ENTRY_SAME(mprotect)		/* 125 */
 	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
-	ENTRY_DIFF(sigprocmask)
-	ENTRY_SAME(ni_syscall)		/* create_module */
+	ENTRY_COMP(sigprocmask)
+	ENTRY_SAME(ni_syscall)	/* create_module */
 	ENTRY_SAME(init_module)
 	ENTRY_SAME(delete_module)
 	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
@@ -547,13 +542,13 @@
 	ENTRY_COMP(nanosleep)
 	ENTRY_SAME(mremap)
 	ENTRY_SAME(setresuid)
-	ENTRY_SAME(getresuid)	/* 165 */
+	ENTRY_SAME(getresuid)		/* 165 */
 	ENTRY_DIFF(sigaltstack_wrapper)
 	ENTRY_SAME(ni_syscall)		/* query_module */
 	ENTRY_SAME(poll)
 	/* structs contain pointers and an in_addr... */
 	ENTRY_DIFF(nfsservctl)
-	ENTRY_SAME(setresgid)	/* 170 */
+	ENTRY_SAME(setresgid)		/* 170 */
 	ENTRY_SAME(getresgid)
 	ENTRY_SAME(prctl)
 	/* signals need a careful review */
@@ -594,15 +589,9 @@
 	ENTRY_OURS(ftruncate64)		/* 200 */
 	ENTRY_SAME(getdents64)
 	ENTRY_DIFF(fcntl64)
-#ifdef CONFIG_XFS_FS
-	ENTRY_SAME(attrctl)
-	ENTRY_SAME(acl_get)
-	ENTRY_SAME(acl_set)		/* 205 */
-#else
 	ENTRY_SAME(ni_syscall)
 	ENTRY_SAME(ni_syscall)
 	ENTRY_SAME(ni_syscall)		/* 205 */
-#endif
 	ENTRY_SAME(gettid)             
 	ENTRY_SAME(readahead)          
 	ENTRY_SAME(ni_syscall)		/* tkill */
diff -Nru a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
--- a/arch/parisc/kernel/time.c	Mon Feb 10 10:39:25 2003
+++ b/arch/parisc/kernel/time.c	Mon Feb 10 10:39:25 2003
@@ -36,7 +36,6 @@
 
 /* xtime and wall_jiffies keep wall-clock time */
 extern unsigned long wall_jiffies;
-extern rwlock_t xtime_lock;
 
 static long clocktick;	/* timer cycles per tick */
 static long halftick;
@@ -115,9 +114,9 @@
 		smp_do_timer(regs);
 #endif
 		if (cpu == 0) {
-			write_lock(&xtime_lock);
+			write_seqlock(&xtime_lock);
 			do_timer(regs);
-			write_unlock(&xtime_lock);
+			write_sequnlock(&xtime_lock);
 		}
 	}
     
@@ -172,16 +171,14 @@
 void
 do_gettimeofday (struct timeval *tv)
 {
-	unsigned long flags, usec, sec;
+	unsigned long flags, seq, usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	{
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 		usec = gettimeoffset();
-	
 		sec = xtime.tv_sec;
 		usec += (xtime.tv_nsec / 1000);
-	}
-	read_unlock_irqrestore(&xtime_lock, flags);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -195,7 +192,7 @@
 void
 do_settimeofday (struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	{
 		/*
 		 * This is revolting. We need to set "xtime"
@@ -219,7 +216,7 @@
 		time_maxerror = NTP_PHASE_LIMIT;
 		time_esterror = NTP_PHASE_LIMIT;
 	}
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 
@@ -241,10 +238,10 @@
 	mtctl(next_tick, 16);
 
 	if(pdc_tod_read(&tod_data) == 0) {
-		write_lock_irq(&xtime_lock);
+		write_seqlock_irq(&xtime_lock);
 		xtime.tv_sec = tod_data.tod_sec;
 		xtime.tv_nsec = tod_data.tod_usec * 1000;
-		write_unlock_irq(&xtime_lock);
+		write_sequnlock_irq(&xtime_lock);
 	} else {
 		printk(KERN_ERR "Error reading tod clock\n");
 	        xtime.tv_sec = 0;
diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
--- a/arch/parisc/kernel/traps.c	Mon Feb 10 10:39:33 2003
+++ b/arch/parisc/kernel/traps.c	Mon Feb 10 10:39:33 2003
@@ -123,7 +123,11 @@
 }
 
 
-static int kstack_depth_to_print = 48;
+#ifndef __LP64__
+static int kstack_depth_to_print = 64 * 4;
+#else
+static int kstack_depth_to_print = 128 * 4;
+#endif
 
 void show_stack(unsigned long *sp)
 {
diff -Nru a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile
--- a/arch/ppc/8xx_io/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc/8xx_io/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
 #
 
-export-objs		:= fec.o
-
 obj-y			:= commproc.o uart.o
 
 obj-$(CONFIG_FEC_ENET)	+= fec.o
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc/Kconfig	Mon Feb 10 10:39:33 2003
@@ -776,7 +776,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 source "drivers/pci/Kconfig"
@@ -989,9 +989,9 @@
 	  for which 8 pin to DB25 adapters were supplied. The card also had
 	  jumpers internally to toggle various pinning configurations.
 
-	  This driver can be built as a module; but then "generic_serial.o"
+	  This driver can be built as a module; but then "generic_serial"
 	  will also be built as a module. This has to be loaded before
-	  "ser_a2232.o". If you want to do this, answer M here and read
+	  "ser_a2232". If you want to do this, answer M here and read
 	  "<file:Documentation/modules.txt>".
 
 config WHIPPET_SERIAL
@@ -1010,7 +1010,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module is called apne.o. If you want to compile it as a
+	  want). The module is called apne. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIAL_CONSOLE
@@ -1192,7 +1192,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -1219,7 +1219,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -1428,7 +1428,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc/Makefile	Mon Feb 10 10:39:23 2003
@@ -36,15 +36,12 @@
   CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
 endif
 
-head-y				:= head.o
-head-$(CONFIG_8xx)		:= head_8xx.o
-head-$(CONFIG_4xx)		:= head_4xx.o
-head-$(CONFIG_440)		:= head_44x.o
-
-HEAD := arch/ppc/kernel/$(head-y)
-ifdef CONFIG_6xx
-  HEAD += arch/ppc/kernel/idle_6xx.o
-endif
+head-y				:= arch/ppc/kernel/head.o
+head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
+head-$(CONFIG_4xx)		:= arch/ppc/kernel/head_4xx.o
+head-$(CONFIG_440)		:= arch/ppc/kernel/head_44x.o
+
+head-$(CONFIG_6xx)		+= arch/ppc/kernel/idle_6xx.o
 
 core-y				+= arch/ppc/kernel/ arch/ppc/platforms/ \
 				   arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
@@ -59,7 +56,7 @@
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm
 
-.PHONY: $(BOOT_TARGETS) clean archclean archmrproper
+.PHONY: $(BOOT_TARGETS)
 
 all: zImage
 
@@ -77,8 +74,6 @@
 
 archclean:
 	$(Q)$(MAKE) $(clean)=arch/ppc/boot
-
-archmrproper:
 
 prepare: include/asm-$(ARCH)/offsets.h checkbin
 
diff -Nru a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile
--- a/arch/ppc/amiga/Makefile	Mon Feb 10 10:39:26 2003
+++ b/arch/ppc/amiga/Makefile	Mon Feb 10 10:39:26 2003
@@ -2,8 +2,6 @@
 # Makefile for Linux arch/m68k/amiga source directory
 #
 
-export-objs	:= amiga_ksyms.o
-
 obj-y		:= config.o amiints.o cia.o time.o bootinfo.o amisound.o \
 			chipram.o amiga_ksyms.o
 
diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
--- a/arch/ppc/boot/simple/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc/boot/simple/Makefile	Mon Feb 10 10:39:23 2003
@@ -19,7 +19,7 @@
 # ENTRYPOINT which the image should be loaded at.  The optimal setting
 # for ENTRYPOINT is the link address.
 # (4) It is advisable to pass in the memory size using BI_MEMSIZE and
-# get_mem_size(), which is memory controller dependant.  Add in the correct
+# get_mem_size(), which is memory controller dependent.  Add in the correct
 # XXX_memory.o file for this to work, as well as editing the $(MISC) file.
 
 boot: zImage
diff -Nru a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
--- a/arch/ppc/boot/simple/misc.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ppc/boot/simple/misc.c	Mon Feb 10 10:39:30 2003
@@ -82,7 +82,7 @@
 
 #if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4)
 	/*
-	 * Call get_mem_size(), which is memory controller dependant,
+	 * Call get_mem_size(), which is memory controller dependent,
 	 * and we must have the correct file linked in here.
 	 */
 	TotalMemory = get_mem_size();
diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile	Mon Feb 10 10:39:32 2003
+++ b/arch/ppc/kernel/Makefile	Mon Feb 10 10:39:32 2003
@@ -17,8 +17,6 @@
 
 EXTRA_TARGETS	:= $(HEAD-y)
 
-export-objs			:= ppc_ksyms.o time.o
-
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o ptrace.o align.o \
 					semaphore.o syscalls.o setup.o \
diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
--- a/arch/ppc/kernel/pci.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ppc/kernel/pci.c	Mon Feb 10 10:39:27 2003
@@ -1069,7 +1069,7 @@
 	if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
 		pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
 
-	/* Call machine dependant fixup */
+	/* Call machine dependent fixup */
 	if (ppc_md.pcibios_fixup)
 		ppc_md.pcibios_fixup();
 
diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
--- a/arch/ppc/kernel/signal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc/kernel/signal.c	Mon Feb 10 10:39:33 2003
@@ -65,11 +65,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->result = -EINTR;
 	regs->ccr |= 0x10000000;
@@ -96,11 +96,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->result = -EINTR;
 	regs->ccr |= 0x10000000;
@@ -208,10 +208,10 @@
 	    || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
 		goto badframe;
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
@@ -311,10 +311,10 @@
 	set.sig[1] = sigctx._unused[3];
 #endif
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	if (regs->msr & MSR_FP )
 		giveup_fpu(current);
 
@@ -450,11 +450,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return;
 
diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
--- a/arch/ppc/kernel/time.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ppc/kernel/time.c	Mon Feb 10 10:39:30 2003
@@ -76,7 +76,6 @@
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
-extern rwlock_t xtime_lock;
 
 /* The decrementer counts down by 128 every 128ns on a 601. */
 #define DECREMENTER_COUNT_601	(1000000000 / HZ)
@@ -161,7 +160,7 @@
 			continue;
 
 		/* We are in an interrupt, no need to save/restore flags */
-		write_lock(&xtime_lock);
+		write_seqlock(&xtime_lock);
 		tb_last_stamp = jiffy_stamp;
 		do_timer(regs);
 
@@ -191,7 +190,7 @@
 				/* Try again one minute later */
 				last_rtc_update += 60;
 		}
-		write_unlock(&xtime_lock);
+		write_sequnlock(&xtime_lock);
 	}
 	if ( !disarm_decr[smp_processor_id()] )
 		set_dec(next_dec);
@@ -213,21 +212,23 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned delta, lost_ticks, usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	sec = xtime.tv_sec;
-	usec = (xtime.tv_nsec / 1000);
-	delta = tb_ticks_since(tb_last_stamp);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		sec = xtime.tv_sec;
+		usec = (xtime.tv_nsec / 1000);
+		delta = tb_ticks_since(tb_last_stamp);
 #ifdef CONFIG_SMP
-	/* As long as timebases are not in sync, gettimeofday can only
-	 * have jiffy resolution on SMP.
-	 */
-	if (!smp_tb_synchronized)
-		delta = 0;
+		/* As long as timebases are not in sync, gettimeofday can only
+		 * have jiffy resolution on SMP.
+		 */
+		if (!smp_tb_synchronized)
+			delta = 0;
 #endif /* CONFIG_SMP */
-	lost_ticks = jiffies - wall_jiffies;
-	read_unlock_irqrestore(&xtime_lock, flags);
+		lost_ticks = jiffies - wall_jiffies;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
 	while (usec >= 1000000) {
@@ -243,7 +244,7 @@
 	unsigned long flags;
 	int tb_delta, new_usec, new_sec;
 
-	write_lock_irqsave(&xtime_lock, flags);
+	write_seqlock_irqsave(&xtime_lock, flags);
 	/* Updating the RTC is not the job of this code. If the time is
 	 * stepped under NTP, the RTC will be update after STA_UNSYNC
 	 * is cleared. Tool like clock/hwclock either copy the RTC
@@ -283,7 +284,7 @@
 	time_state = TIME_ERROR;        /* p. 24, (a) */
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* This function is only called on the boot processor */
diff -Nru a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
--- a/arch/ppc/lib/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc/lib/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for ppc-specific library files..
 #
 
-export-objs		:= dec_and_lock.o
-
 obj-y			:= checksum.o string.o strcase.o dec_and_lock.o div64.o
 
 obj-$(CONFIG_SMP)	+= locks.o
diff -Nru a/arch/ppc/ocp/Makefile b/arch/ppc/ocp/Makefile
--- a/arch/ppc/ocp/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/ppc/ocp/Makefile	Mon Feb 10 10:39:24 2003
@@ -9,6 +9,5 @@
 #
 # NB: cribbed from the drivers/sbus/Makefile -- PMM
 
-export-objs := ocp.o ocp-driver.o ocp-probe.o
 obj-y   	+= ocp.o ocp-driver.o ocp-probe.o
 
diff -Nru a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
--- a/arch/ppc/platforms/4xx/Makefile	Mon Feb 10 10:39:31 2003
+++ b/arch/ppc/platforms/4xx/Makefile	Mon Feb 10 10:39:31 2003
@@ -1,8 +1,6 @@
 #
 # Makefile for the PowerPC 4xx linux kernel.
 
-export-objs			:= ibm405lp.o
-
 obj-$(CONFIG_ASH)		+= ash.o
 obj-$(CONFIG_BEECH)		+= beech.o 
 obj-$(CONFIG_CEDAR)		+= cedar.o
diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
--- a/arch/ppc/platforms/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc/platforms/Makefile	Mon Feb 10 10:39:33 2003
@@ -12,8 +12,6 @@
 # Extra CFLAGS so we don't have to do relative includes
 CFLAGS_pmac_setup.o	+= -I$(TOPDIR)/arch/$(ARCH)/mm
 
-export-objs			:= prep_setup.o
-
 obj-$(CONFIG_APUS)		+= apus_setup.o
 ifeq ($(CONFIG_APUS),y)
 obj-$(CONFIG_PCI)		+= apus_pci.o
diff -Nru a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
--- a/arch/ppc/platforms/pmac_time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ppc/platforms/pmac_time.c	Mon Feb 10 10:39:24 2003
@@ -15,6 +15,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/time.h>
 #include <linux/adb.h>
 #include <linux/cuda.h>
 #include <linux/pmu.h>
@@ -29,8 +30,6 @@
 #include <asm/time.h>
 #include <asm/nvram.h>
 
-extern rwlock_t xtime_lock;
-
 /* Apparently the RTC stores seconds since 1 Jan 1904 */
 #define RTC_OFFSET	2082844800
 
@@ -215,19 +214,21 @@
 {
 	static unsigned long time_diff;
 	unsigned long flags;
+	unsigned long seq;
 
 	switch (when) {
 	case PBOOK_SLEEP_NOW:
-		read_lock_irqsave(&xtime_lock, flags);
-		time_diff = xtime.tv_sec - pmac_get_rtc_time();
-		read_unlock_irqrestore(&xtime_lock, flags);
+		do {
+			seq = read_seqbegin_irqsave(&xtime_lock, flags);
+			time_diff = xtime.tv_sec - pmac_get_rtc_time();
+		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 		break;
 	case PBOOK_WAKE:
-		write_lock_irqsave(&xtime_lock, flags);
+		write_seqlock_irqsave(&xtime_lock, flags);
 		xtime.tv_sec = pmac_get_rtc_time() + time_diff;
 		xtime.tv_nsec = 0;
 		last_rtc_update = xtime.tv_sec;
-		write_unlock_irqrestore(&xtime_lock, flags);
+		write_sequnlock_irqrestore(&xtime_lock, flags);
 		break;
 	}
 	return PBOOK_SLEEP_OK;
diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc/syslib/Makefile	Mon Feb 10 10:39:23 2003
@@ -12,8 +12,6 @@
 CFLAGS_prom_init.o      += -mrelocatable-lib
 CFLAGS_btext.o          += -mrelocatable-lib
 
-export-objs			:=  ppc4xx_dma.o ppc4xx_pm.o
-
 obj-$(CONFIG_PPCBUG_NVRAM)	+= prep_nvram.o
 ifeq ($(CONFIG_4xx),y)
 obj-$(CONFIG_4xx)		+= ppc4xx_pic.o
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/arch/ppc64/Kconfig	Mon Feb 10 10:39:27 2003
@@ -128,6 +128,10 @@
 	tristate "Firmware flash interface"
 	depends on !PPC_ISERIES
 
+config PPC_RTAS
+	bool "Proc interface to RTAS"
+	depends on !PPC_ISERIES
+
 endmenu
 
 
@@ -208,7 +212,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 source "drivers/pci/Kconfig"
@@ -307,7 +311,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -334,7 +338,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -400,7 +404,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc64/Makefile	Mon Feb 10 10:39:23 2003
@@ -22,7 +22,7 @@
 		-Wno-uninitialized -mminimal-toc -mtraceback=full \
 		-finline-limit-2000 -mcpu=power4
 
-HEAD := arch/ppc64/kernel/head.o
+head-y := arch/ppc64/kernel/head.o
 
 libs-y				+= arch/ppc64/lib/
 core-y				+= arch/ppc64/kernel/
diff -Nru a/arch/ppc64/defconfig b/arch/ppc64/defconfig
--- a/arch/ppc64/defconfig	Mon Feb 10 10:39:24 2003
+++ b/arch/ppc64/defconfig	Mon Feb 10 10:39:24 2003
@@ -18,10 +18,10 @@
 #
 # General setup
 #
-CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=15
 
 #
 # Loadable module support
@@ -41,6 +41,7 @@
 # CONFIG_HMT is not set
 # CONFIG_DISCONTIGMEM is not set
 # CONFIG_RTAS_FLASH is not set
+CONFIG_PPC_RTAS=y
 
 #
 # General setup
@@ -50,6 +51,7 @@
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
 CONFIG_PROC_DEVICETREE=y
@@ -182,6 +184,11 @@
 # CONFIG_I2O is not set
 
 #
+# Networking support
+#
+CONFIG_NET=y
+
+#
 # Networking options
 #
 CONFIG_PACKET=y
@@ -233,10 +240,6 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 
 #
@@ -258,8 +261,6 @@
 # CONFIG_SUNGEM is not set
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=y
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
@@ -268,6 +269,7 @@
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_DGRS is not set
@@ -283,7 +285,6 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -429,6 +430,11 @@
 # CONFIG_QIC02_TAPE is not set
 
 #
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
@@ -516,6 +522,7 @@
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
@@ -580,6 +587,7 @@
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
 # CONFIG_FB_CT65550 is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S3TRIO is not set
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc64/kernel/Makefile	Mon Feb 10 10:39:33 2003
@@ -4,8 +4,6 @@
 
 EXTRA_CFLAGS	+= -mno-minimal-toc
 EXTRA_TARGETS	:= head.o
-export-objs	:= ppc_ksyms.o
-
 obj-y               :=	setup.o entry.o traps.o irq.o idle.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
 			align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
@@ -25,9 +23,10 @@
 
 # Change this to pSeries only once we've got iSeries up to date
 obj-y			  += open_pic.o xics.o pSeries_htab.o rtas.o \
-			     rtas-proc.o chrp_setup.o i8259.o ras.o prom.o 
+			     chrp_setup.o i8259.o ras.o prom.o 
 
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PROFILING)		+= profile.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
+obj-$(CONFIG_PPC_RTAS)		+= rtas-proc.o
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc64/kernel/entry.S	Mon Feb 10 10:39:23 2003
@@ -57,6 +57,7 @@
  * Handle a system call.
  */
 _GLOBAL(DoSyscall)
+	std	r3,ORIG_GPR3(r1)
 	ld	r11,_CCR(r1)	/* Clear SO bit in CR */
 	lis	r10,0x1000
 	andc	r11,r11,r10
@@ -226,6 +227,10 @@
 
 _GLOBAL(ppc32_rt_sigreturn)
 	bl	.sys32_rt_sigreturn
+	b	80f
+
+_GLOBAL(ppc64_sigreturn)
+	bl	.sys_sigreturn
 	b	80f
 
 _GLOBAL(ppc64_rt_sigreturn)
diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S	Mon Feb 10 10:39:27 2003
+++ b/arch/ppc64/kernel/head.S	Mon Feb 10 10:39:27 2003
@@ -31,6 +31,7 @@
 #include <asm/mmu.h>
 #include <asm/ppc_asm.h>
 #include <asm/offsets.h>
+#include <asm/bug.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -789,7 +790,6 @@
 	beq+	HardwareInterrupt_entry
 1:
 #endif
-	std	r3,ORIG_GPR3(r1)
 #ifdef DO_SOFT_DISABLE
 	ld	r20,SOFTE(r1)
 #else
@@ -1141,9 +1141,9 @@
 	 * If from user state, update THREAD.regs
 	 */
 	beq	2f			/* Modify THREAD.regs if from user */
-	addi	r24,r1,STACK_FRAME_OVERHEAD
+	addi	r23,r1,STACK_FRAME_OVERHEAD
 	ld	r22, PACACURRENT(r13)
-	std	r24,THREAD+PT_REGS(r22)
+	std	r23,THREAD+PT_REGS(r22)
 2:
 	SET_REG_TO_CONST(r22, MSR_KERNEL)
 
diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c
--- a/arch/ppc64/kernel/htab.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ppc64/kernel/htab.c	Mon Feb 10 10:39:29 2003
@@ -333,7 +333,7 @@
 					  hpteflags, 0, large);
 
 		/* Primary is full, try the secondary */
-		if (slot == -1) {
+		if (unlikely(slot == -1)) {
 			pte_val(new_pte) |= 1 << 15;
 			hpte_group = ((~hash & htab_data.htab_hash_mask) *
 				      HPTES_PER_GROUP) & ~0x7UL; 
@@ -393,6 +393,7 @@
 		mm = &init_mm;
 		vsid = get_kernel_vsid(ea);
 		break;
+#if 0
 	case EEH_REGION_ID:
 		/*
 		 * Should only be hit if there is an access to MMIO space
@@ -404,6 +405,7 @@
 		 * Should never get here - entire 0xC0... region is bolted.
 		 * Send the problem up to do_page_fault 
 		 */
+#endif
 	default:
 		/* Not a valid range
 		 * Send the problem up to do_page_fault 
diff -Nru a/arch/ppc64/kernel/init_task.c b/arch/ppc64/kernel/init_task.c
--- a/arch/ppc64/kernel/init_task.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ppc64/kernel/init_task.c	Mon Feb 10 10:39:24 2003
@@ -8,6 +8,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /*
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Mon Feb 10 10:39:31 2003
+++ b/arch/ppc64/kernel/misc.S	Mon Feb 10 10:39:31 2003
@@ -443,26 +443,61 @@
  *   kernel_thread(fn, arg, flags)
  */
 _GLOBAL(kernel_thread)
-	/* XXX fix this when we optimise syscall entry to not save volatiles */
-	mr	r6,r3		/* function */
-	mr	r7,r4		/* arg */
+	std	r29,-24(r1)
+	std	r30,-16(r1)
+	stdu	r1,-STACK_FRAME_OVERHEAD(r1)
+	mr	r29,r3
+	mr	r30,r4
 	ori	r3,r5,CLONE_VM	/* flags */
 	oris	r3,r3,(CLONE_UNTRACED>>16)
 	li	r4,0		/* new sp (unused) */
 	li	r0,__NR_clone
 	sc
 	cmpi	0,r3,0		/* parent or child? */
-	bnelr			/* return if parent */
+	bne	1f		/* return if parent */
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-	ld	r2,8(r6)
-	ld	r6,0(r6)
-	mtlr	r6              /* fn addr in lr */
-	mr	r3,r7	        /* load arg and call fn */
+	ld	r2,8(r29)
+	ld	r29,0(r29)
+	mtlr	r29              /* fn addr in lr */
+	mr	r3,r30	        /* load arg and call fn */
 	blrl
 	li	r0,__NR_exit	/* exit after child exits */
         li	r3,0
 	sc
+1:	addi	r1,r1,STACK_FRAME_OVERHEAD	
+	ld	r29,-24(r1)
+	ld	r30,-16(r1)
+	blr
+
+	.section	".toc","aw"
+.SYSCALL_ERRNO:
+	.tc errno[TC],errno
+
+	.section	".text"
+	.align 3
+	
+#define SYSCALL(name) \
+_GLOBAL(name) \
+	li	r0,__NR_##name; \
+	sc; \
+	bnslr; \
+	ld	r4,.SYSCALL_ERRNO@toc(2); \
+	std	r3,0(r4); \
+	li	r3,-1; \
+	blr
+
+#define __NR__exit __NR_exit
+
+SYSCALL(setsid)
+SYSCALL(open)
+SYSCALL(read)
+SYSCALL(write)
+SYSCALL(lseek)
+SYSCALL(close)
+SYSCALL(dup)
+SYSCALL(execve)
+SYSCALL(waitpid)
 
 #ifdef CONFIG_BINFMT_ELF32
 /* Why isn't this a) automatic, b) written in 'C'? */	
@@ -540,8 +575,8 @@
 	.llong .sys32_ssetmask
 	.llong .sys_setreuid	        /* 70 */
 	.llong .sys_setregid
-	.llong .sys32_sigsuspend
-	.llong .sys32_sigpending
+	.llong .sys_sigsuspend
+	.llong .compat_sys_sigpending
 	.llong .sys32_sethostname
 	.llong .sys32_setrlimit	        /* 75 */
 	.llong .sys32_old_getrlimit
@@ -594,7 +629,7 @@
 	.llong .sys_ni_syscall		/* old modify_ldt syscall */
 	.llong .sys32_adjtimex
 	.llong .sys_mprotect		/* 125 */
-	.llong .sys32_sigprocmask
+	.llong .compat_sys_sigprocmask
 	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys32_init_module
 	.llong .sys32_delete_module
@@ -783,13 +818,13 @@
 	.llong .sys_getppid
 	.llong .sys_getpgrp		/* 65 */
 	.llong .sys_setsid
-	.llong .sys_ni_syscall		/* 32 bit only sigaction */
+	.llong .sys_sigaction
 	.llong .sys_sgetmask
 	.llong .sys_ssetmask
 	.llong .sys_setreuid		/* 70 */
 	.llong .sys_setregid
-	.llong .sys_ni_syscall		/* 32bit only sigsuspend */
-	.llong .sys_ni_syscall		/* 32bit only sigpending */
+	.llong .sys_sigsuspend
+	.llong .sys_sigpending
 	.llong .sys_sethostname
 	.llong .sys_setrlimit		/* 75 */
 	.llong .sys_ni_syscall		/* old getrlimit syscall */
@@ -835,14 +870,14 @@
 	.llong .sys_sysinfo
 	.llong .sys_ipc
 	.llong .sys_fsync
-	.llong .sys_ni_syscall		/* 32bit only sigreturn */
+	.llong .ppc64_sigreturn
 	.llong .sys_clone		/* 120 */
 	.llong .sys_setdomainname
 	.llong .ppc64_newuname
 	.llong .sys_ni_syscall		/* old modify_ldt syscall */
 	.llong .sys_adjtimex
 	.llong .sys_mprotect		/* 125 */
-	.llong .sys_ni_syscall		/* 32bit only sigprocmask */
+	.llong .sys_sigprocmask
 	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys_init_module
 	.llong .sys_delete_module
diff -Nru a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
--- a/arch/ppc64/kernel/module.c	Mon Feb 10 10:39:33 2003
+++ b/arch/ppc64/kernel/module.c	Mon Feb 10 10:39:33 2003
@@ -136,6 +136,20 @@
 	return relocs * sizeof(struct ppc64_stub_entry);
 }
 
+/* Undefined symbols which refer to .funcname, hack to funcname */
+static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
+{
+	unsigned int i;
+
+	for (i = 1; i < numsyms; i++) {
+		if (syms[i].st_shndx == SHN_UNDEF) {
+			char *name = strtab + syms[i].st_name;
+			if (name[0] == '.')
+				memmove(name, name+1, strlen(name));
+		}
+	}
+}
+
 int module_frob_arch_sections(Elf64_Ehdr *hdr,
 			      Elf64_Shdr *sechdrs,
 			      char *secstrings,
@@ -143,7 +157,7 @@
 {
 	unsigned int i;
 
-	/* Find .toc and .stubs sections */
+	/* Find .toc and .stubs sections, symtab and strtab */
 	for (i = 1; i < hdr->e_shnum; i++) {
 		char *p;
 		if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
@@ -154,6 +168,12 @@
 		/* We don't handle .init for the moment: rename to _init */
 		while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
 			p[0] = '_';
+
+		if (sechdrs[i].sh_type == SHT_SYMTAB)
+			dedotify((void *)hdr + sechdrs[i].sh_offset,
+				 sechdrs[i].sh_size / sizeof(Elf64_Sym),
+				 (void *)hdr
+				 + sechdrs[sechdrs[i].sh_link].sh_offset);
 	}
 	if (!me->arch.stubs_section || !me->arch.toc_section) {
 		printk("%s: doesn't contain .toc or .stubs.\n", me->name);
@@ -175,6 +195,14 @@
 	return -ENOEXEC;
 }
 
+/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
+   gives the value maximum span in an instruction which uses a signed
+   offset) */
+static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
+{
+	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
+}
+
 /* Both low and high 16 bits are added as SIGNED additions, so if low
    16 bits has high bit set, high 16 bits must be adjusted.  These
    macros do that (stolen from binutils). */
@@ -183,10 +211,10 @@
 #define PPC_HA(v) PPC_HI ((v) + 0x8000)
 
 /* Patch stub to reference function and correct r2 value. */
-static inline int create_stub(struct ppc64_stub_entry *entry,
-			      unsigned long my_r2,
-			      unsigned long func,
-			      unsigned long r2)
+static inline int create_stub(Elf64_Shdr *sechdrs,
+			      struct ppc64_stub_entry *entry,
+			      struct ppc64_opd_entry *opd,
+			      struct module *me)
 {
 	Elf64_Half *loc1, *loc2;
 	long reladdr;
@@ -196,72 +224,32 @@
 	loc1 = (Elf64_Half *)&entry->jump[2];
 	loc2 = (Elf64_Half *)&entry->jump[6];
 
-	/* Stub uses address relative to r2, which is set to the TOC +
-           0x8000. */
-	reladdr = (unsigned long)entry - my_r2;
+	/* Stub uses address relative to r2. */
+	reladdr = (unsigned long)entry - my_r2(sechdrs, me);
 	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
-		printk("Address %p of stub out of range of %p.\n",
-		       (void *)reladdr, (void *)my_r2);
+		printk("%s: Address %p of stub out of range of %p.\n",
+		       me->name, (void *)reladdr, (void *)my_r2);
 		return 0;
 	}
 	DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr);
 
 	*loc1 = PPC_HA(reladdr);
 	*loc2 = PPC_LO(reladdr);
-	entry->opd.funcaddr = func;
-	entry->opd.r2 = r2;
-
-	DEBUGP("Stub: %08X %08X %08X %08X %08X %08X %08X: %p %p\n",
-	       ((unsigned int *)entry->jump)[0],
-	       ((unsigned int *)entry->jump)[1],
-	       ((unsigned int *)entry->jump)[2],
-	       ((unsigned int *)entry->jump)[3],
-	       ((unsigned int *)entry->jump)[4],
-	       ((unsigned int *)entry->jump)[5],
-	       ((unsigned int *)entry->jump)[6],
-	       (void *)entry->opd.funcaddr,
-	       (void *)entry->opd.r2);
+	entry->opd.funcaddr = opd->funcaddr;
+	entry->opd.r2 = opd->r2;
 	return 1;
 }
 
-/* Given ".function" reference, return address of "function" opd entry */
-static struct ppc64_opd_entry *find_function(const char *name,
-					     Elf64_Shdr *sechdrs,
-					     unsigned int symindex,
-					     const char *strtab,
-					     struct module *me,
-					     struct kernel_symbol_group **ksg)
-{
-	unsigned long val;
-
-	if (name[0] != '.')
-		return 0;
-
-	val = find_symbol_internal(sechdrs, symindex, strtab, name+1, me, ksg);
-
-	DEBUGP("Function %s is at %p\n", name+1, (void *)val);
-	return (void *)val;
-}
-
-/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
-   gives the value maximum span in an instruction which uses a signed
-   offset) */
-static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
-{
-	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
-}
-
-/* Create stub for this OPD address */
+/* Create stub to jump to function described in this OPD: we need the
+   stub to set up the TOC ptr (r2) for the function. */
 static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
-				   unsigned long addr,
-				   unsigned long r2,
+				   unsigned long opdaddr,
 				   struct module *me)
 {
 	struct ppc64_stub_entry *stubs;
+	struct ppc64_opd_entry *opd = (void *)opdaddr;
 	unsigned int i, num_stubs;
 
-	DEBUGP("Looking for stub for %p\n", (void *)addr);
-
 	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
 
 	/* Find this stub, or if that fails, the next avail. entry */
@@ -269,50 +257,23 @@
 	for (i = 0; stubs[i].opd.funcaddr; i++) {
 		BUG_ON(i >= num_stubs);
 
-		if (stubs[i].opd.funcaddr == addr) {
-			DEBUGP("Reusing stub %u (%p) for %p\n",
-			       i, &stubs[i], (void *)addr);
+		if (stubs[i].opd.funcaddr == opd->funcaddr)
 			return (unsigned long)&stubs[i];
-		}
 	}
-	DEBUGP("Here for %p\n", (void *)addr);
-
-	if (!create_stub(&stubs[i], my_r2(sechdrs, me), addr, r2))
-		return (unsigned long)-EINVAL;
 
-	DEBUGP("CREATED stub %u for %p\n", i, (void *)addr);
+	if (!create_stub(sechdrs, &stubs[i], opd, me))
+		return 0;
 
 	return (unsigned long)&stubs[i];
 }
 
-/* We need a stub to set the toc ptr when we make external calls. */
-static unsigned long do_stub_call(Elf64_Shdr *sechdrs,
-				  const char *strtab,
-				  unsigned int symindex,
-				  void *location,
-				  const char *funcname,
-				  struct module *me)
-{
-	struct ppc64_opd_entry *opd;
-	struct kernel_symbol_group *ksg;
-
-	DEBUGP("Doing stub for %lu (%s)\n",
-	       (unsigned long)location, funcname);
-	opd = find_function(funcname, sechdrs, symindex, strtab, me, &ksg);
-	if (!opd) {
-		printk("%s: Can't find function `%s'\n", me->name, funcname);
-		return (unsigned long)-ENOENT;
-	}
-
-	return stub_for_addr(sechdrs, opd->funcaddr, opd->r2, me);
-}
-
 /* We expect a noop next: if it is, replace it with instruction to
    restore r2. */
-static int restore_r2(u32 *instruction)
+static int restore_r2(u32 *instruction, struct module *me)
 {
 	if (*instruction != 0x60000000) {
-		printk("Expect noop after relocate, got %08x\n", *instruction);
+		printk("%s: Expect noop after relocate, got %08x\n",
+		       me->name, *instruction);
 		return 0;
 	}
 	*instruction = 0xe8410028;	/* ld r2,40(r1) */
@@ -346,31 +307,18 @@
 		       strtab + sym->st_name, (unsigned long)sym->st_value,
 		       (long)rela[i].r_addend);
 
-		/* REL24 references to (external) .function won't
-                   resolve; deal with that below */
-		if (!sym->st_value
-		    && ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) {
-			printk("%s: Unknown symbol %s (index %u)\n",
-			       me->name, strtab + sym->st_name,
-			       sym->st_shndx);
-			return -ENOENT;
-		}
 		/* `Everything is relative'. */
 		value = sym->st_value + rela[i].r_addend;
 
 		switch (ELF64_R_TYPE(rela[i].r_info)) {
 		case R_PPC64_ADDR32:
 			/* Simply set it */
-			DEBUGP("Setting location %p to 32-bit value %u\n",
-			       location, (unsigned int)value);
 			*(u32 *)location = value;
 			break;
 			
 		case R_PPC64_ADDR64:
 			/* Simply set it */
 			*(unsigned long *)location = value;
-			DEBUGP("Setting location %p to 64-bit value %p\n",
-			       location, (void *)value);
 			break;
 
 		case R_PPC64_TOC:
@@ -381,37 +329,31 @@
 			/* Subtact TOC pointer */
 			value -= my_r2(sechdrs, me);
 			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
-				DEBUGP("%s: bad TOC16_DS relocation (%lu)\n",
+				printk("%s: bad TOC16_DS relocation (%lu)\n",
 				       me->name, value);
 				return -ENOEXEC;
 			}
 			*((uint16_t *) location)
 				= (*((uint16_t *) location) & ~0xfffc)
 				| (value & 0xfffc);
-			DEBUGP("Modifying location %p by TOC (%p) => %i\n",
-			       location, 
-			       (void *)my_r2(sechdrs, me),
-			       *(uint16_t *)location);
 			break;
 
 		case R_PPC_REL24:
 			/* FIXME: Handle weak symbols here --RR */
 			if (sym->st_shndx == SHN_UNDEF) {
-				value = do_stub_call(sechdrs, strtab,
-						     symindex, location,
-						     strtab+sym->st_name, me);
-				if (IS_ERR((void *)value))
-					return value;
-				value += rela[i].r_addend;
-				if (!restore_r2((u32 *)location + 1))
+				/* External: go via stub */
+				value = stub_for_addr(sechdrs, value, me);
+				if (!value)
+					return -ENOENT;
+				if (!restore_r2((u32 *)location + 1, me))
 					return -ENOEXEC;
 			}
 
 			/* Convert value to relative */
 			value -= (unsigned long)location;
 			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
-				printk("REL24 relocation %li out of range!\n",
-				       (long int)value);
+				printk("%s: REL24 %li out of range!\n",
+				       me->name, (long int)value);
 				return -ENOEXEC;
 			}
 
@@ -422,7 +364,8 @@
 			break;
 
 		default:
-			printk("Unknown ADD relocation: %lu\n",
+			printk("%s: Unknown ADD relocation: %lu\n",
+			       me->name,
 			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
 			return -ENOEXEC;
 		}
@@ -439,25 +382,6 @@
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 {
-	struct ppc64_stub_entry *stubs;
-	unsigned int i;
-
-	/* Here is where we copy the OPD entry into the stub: we don't
-           do it ealier in case it's actually in the same module, and
-           hasn't been relocated yet. */
-	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
-	for (i = 0; stubs[i].opd.funcaddr; i++) {
-		struct ppc64_opd_entry *opd;
-
-		/* We mark opd pointers by setting r2 to 0: otherwise
-                   it's a function pointer already. */
-		if (stubs[i].opd.r2 == 0) {
-			/* We put the opd entry ptr in the funcaddr member. */
-			opd = (void *)stubs[i].opd.funcaddr;
-			stubs[i].opd = *opd;
-		}
-	}
-
 	sort_ex_table(me->extable.entry,
 		      me->extable.entry + me->extable.num_entries);
 	return 0;
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c	Mon Feb 10 10:39:31 2003
+++ b/arch/ppc64/kernel/pci.c	Mon Feb 10 10:39:31 2003
@@ -413,7 +413,7 @@
 			next_busno = hose->last_busno+1;
 	}
 
-	/* Call machine dependant fixup */
+	/* Call machine dependent fixup */
 	if (ppc_md.pcibios_fixup) {
 		ppc_md.pcibios_fixup();
 	}
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ppc64/kernel/process.c	Mon Feb 10 10:39:29 2003
@@ -163,6 +163,11 @@
 
 void flush_thread(void)
 {
+	struct thread_info *t = current_thread_info();
+
+	if (t->flags & _TIF_ABI_PENDING)
+		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
 }
diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
--- a/arch/ppc64/kernel/rtas-proc.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ppc64/kernel/rtas-proc.c	Mon Feb 10 10:39:27 2003
@@ -115,9 +115,10 @@
 
 
 /* Globals */
-static struct proc_dir_entry *proc_rtas;
+extern struct proc_dir_entry *proc_rtas;
+
 static struct rtas_sensors sensors;
-static struct device_node *rtas_node;
+static struct device_node *rtas_node = NULL;
 static unsigned long power_on_time = 0; /* Save the time the user set */
 static char progress_led[MAX_LINELENGTH];
 
@@ -200,13 +201,18 @@
 	struct proc_dir_entry *entry;
 
 	rtas_node = find_devices("rtas");
-	if ((rtas_node == 0) || (naca->platform == PLATFORM_ISERIES_LPAR)) {
+	if ((rtas_node == NULL) || (naca->platform == PLATFORM_ISERIES_LPAR)) {
 		return;
 	}
 	
-	proc_rtas = proc_mkdir("rtas", 0);
-	if (proc_rtas == 0)
+	if (proc_rtas == NULL) {
+		proc_rtas = proc_mkdir("rtas", 0);
+	}
+
+	if (proc_rtas == NULL) {
+		printk(KERN_ERR "Failed to create /proc/rtas in proc_rtas_init\n");
 		return;
+	}
 
 	/* /proc/rtas entries */
 
@@ -405,10 +411,14 @@
 		j = sensors.sensor[i].quant;
 		/* A sensor may have multiple instances */
 		while (j >= 0) {
+
 			error =	rtas_call(get_sensor_state, 2, 2, &ret, 
-				  sensors.sensor[i].token, sensors.sensor[i].quant-j);
+				  	  sensors.sensor[i].token, 
+				  	  sensors.sensor[i].quant - j);
+
 			state = (int) ret;
-			n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
+			n += ppc_rtas_process_sensor(sensors.sensor[i], state, 
+					     	     error, buffer+n );
 			n += sprintf (buffer+n, "\n");
 			j--;
 		} /* while */
@@ -426,6 +436,7 @@
 		n = count;
 	else
 		*eof = 1;
+
 	memcpy(buf, buffer + off, n);
 	*start = buf;
 	kfree(buffer);
@@ -436,10 +447,10 @@
 
 int ppc_rtas_find_all_sensors (void)
 {
-	unsigned long *utmp;
-	int len, i, j;
+	unsigned int *utmp;
+	int len, i;
 
-	utmp = (unsigned long *) get_property(rtas_node, "rtas-sensors", &len);
+	utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
 	if (utmp == NULL) {
 		printk (KERN_ERR "error: could not get rtas-sensors\n");
 		return 1;
@@ -447,9 +458,9 @@
 
 	sensors.quant = len / 8;      /* int + int */
 
-	for (i=0, j=0; j<sensors.quant; i+=2, j++) {
-		sensors.sensor[j].token = utmp[i];
-		sensors.sensor[j].quant = utmp[i+1];
+	for (i=0; i<sensors.quant; i++) {
+		sensors.sensor[i].token = *utmp++;
+		sensors.sensor[i].quant = *utmp++;
 	}
 	return 0;
 }
@@ -515,6 +526,7 @@
 	int n = 0;
 
 	/* What kind of sensor do we have here? */
+	
 	switch (s.token) {
 		case KEY_SWITCH:
 			n += sprintf(buf+n, "Key switch:\t");
@@ -698,9 +710,9 @@
 	ret = (char *) get_property(rtas_node, rstr, &llen);
 
 	n=0;
-	if (ret[0] == '\0')
+	if (ret == NULL || ret[0] == '\0') {
 		n += sprintf ( buffer+n, "--- ");/* does not have a location */
-	else {
+	} else {
 		char t[50];
 		ret += pos;
 
diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
--- a/arch/ppc64/kernel/rtasd.c	Mon Feb 10 10:39:24 2003
+++ b/arch/ppc64/kernel/rtasd.c	Mon Feb 10 10:39:24 2003
@@ -49,6 +49,8 @@
 #define SURVEILLANCE_TIMEOUT	1
 #define SURVEILLANCE_SCANRATE	1
 
+struct proc_dir_entry *proc_rtas;
+
 /*
  * Since we use 32 bit RTAS, the physical address of this must be below
  * 4G or else bad things happen. Allocate this in the kernel data and
@@ -270,13 +272,16 @@
 
 static int __init rtas_init(void)
 {
-	struct proc_dir_entry *rtas_dir, *entry;
+	struct proc_dir_entry *entry;
+
+	if (proc_rtas == NULL) {
+		proc_rtas = proc_mkdir("rtas", 0);
+	}
 
-	rtas_dir = proc_mkdir("rtas", 0);
-	if (!rtas_dir) {
-		printk(KERN_ERR "Failed to create rtas proc directory\n");
+	if (proc_rtas == NULL) {
+		printk(KERN_ERR "Failed to create /proc/rtas in rtas_init\n");
 	} else {
-		entry = create_proc_entry("error_log", S_IRUSR, rtas_dir);
+		entry = create_proc_entry("error_log", S_IRUSR, proc_rtas);
 		if (entry)
 			entry->proc_fops = &proc_rtas_log_operations;
 		else
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Mon Feb 10 10:39:22 2003
+++ b/arch/ppc64/kernel/signal.c	Mon Feb 10 10:39:22 2003
@@ -99,6 +99,40 @@
 
 extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
+	       struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->result = -EINTR;
+	regs->gpr[3] = EINTR;
+	regs->ccr |= 0x10000000;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			/*
+			 * If a signal handler needs to be called,
+			 * do_signal() has set R3 to the signal number (the
+			 * first argument of the signal handler), so don't
+			 * overwrite that with EINTR !
+			 * In the other cases, do_signal() doesn't touch 
+			 * R3, so it's still set to -EINTR (see above).
+			 */
+			return regs->gpr[3];
+	}
+}
+
 long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
 		  int p7, struct pt_regs *regs)
 {
@@ -112,11 +146,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->result = -EINTR;
 	regs->gpr[3] = EINTR;
@@ -136,6 +170,37 @@
 	return do_sigaltstack(uss, uoss, regs->gpr[1]);
 }
 
+long sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
 /*
  *  When we have rt signals to deliver, we set up on the
  *  user stack, going down from the original stack pointer:
@@ -164,10 +229,10 @@
 	    || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
 		goto badframe;
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
@@ -264,6 +329,116 @@
 }
 
 /*
+ * Do a signal return; undo the signal stack.
+ */
+long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
+		   unsigned long r6, unsigned long r7, unsigned long r8,
+		   struct pt_regs *regs)
+{
+	struct sigcontext *sc, sigctx;
+	struct sigregs *sr;
+	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
+	sigset_t set;
+
+	sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
+		goto badframe;
+
+	set.sig[0] = sigctx.oldmask;
+#if _NSIG_WORDS > 1
+	set.sig[1] = sigctx._unused[3];
+#endif
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+
+	/* restore registers */
+	sr = (struct sigregs *)sigctx.regs;
+	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
+		goto badframe;
+	saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+		| (saved_regs[PT_MSR] & MSR_USERCHANGE);
+	saved_regs[PT_SOFTE] = regs->softe;
+	memcpy(regs, saved_regs, GP_REGS_SIZE);
+
+	if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+			   sizeof(sr->fp_regs)))
+		goto badframe;
+
+	return regs->result;
+
+badframe:
+	do_exit(SIGSEGV);
+}	
+
+/*
+ * Set up a signal frame.
+ */
+static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
+	    unsigned long newsp)
+{
+
+	/* Handler is *really* a pointer to the function descriptor for
+	 * the signal routine.  The first entry in the function
+	 * descriptor is the entry address of signal and the second
+	 * entry is the TOC value we need to use.
+	 */
+	struct funct_descr_entry {
+		unsigned long entry;
+		unsigned long toc;
+	};
+  
+	struct funct_descr_entry * funct_desc_ptr;
+	unsigned long temp_ptr;
+
+	struct sigcontext *sc = (struct sigcontext *)newsp;
+  
+	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto badframe;
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+			      ELF_NFPREG * sizeof(double))
+	    /* li r0, __NR_sigreturn */
+	    || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
+	    /* sc */
+	    || __put_user(0x44000002UL, &frame->tramp[1]))
+		goto badframe;
+	flush_icache_range((unsigned long)&frame->tramp[0],
+			   (unsigned long)&frame->tramp[2]);
+	current->thread.fpscr = 0;	/* turn off all fp exceptions */
+
+	newsp -= __SIGNAL_FRAMESIZE;
+	if (get_user(temp_ptr, &sc->handler))
+		goto badframe;
+  
+	funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
+
+	if (put_user(regs->gpr[1], (unsigned long *)newsp)
+	    || get_user(regs->nip, &funct_desc_ptr ->entry)
+	    || get_user(regs->gpr[2],&funct_desc_ptr->toc)
+	    || get_user(regs->gpr[3], &sc->signal))
+		goto badframe;
+	regs->gpr[1] = newsp;
+	regs->gpr[4] = (unsigned long)sc;
+	regs->link = (unsigned long)frame->tramp;
+
+	return;
+
+badframe:
+#if DEBUG_SIG
+	printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
+	       regs, frame, newsp);
+#endif
+	do_exit(SIGSEGV);
+}
+
+/*
  * OK, we're invoking a handler
  */
 static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
@@ -271,7 +446,7 @@
 {
 	struct sigcontext *sc;
 	struct rt_sigframe *rt_sf;
-	struct k_sigaction *ka = &current->sig->action[sig-1];
+	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
 	if (regs->trap == 0x0C00 /* System Call! */
 	    && ((int)regs->result == -ERESTARTNOHAND ||
@@ -333,11 +508,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return;
 
@@ -378,7 +553,7 @@
 
 	signr = get_signal_to_deliver(&info, regs);
 	if (signr > 0) {
-		ka = &current->sig->action[signr-1];
+		ka = &current->sighand->action[signr-1];
 		if ((ka->sa.sa_flags & SA_ONSTACK)
 		     && (!on_sig_stack(regs->gpr[1])))
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
@@ -407,7 +582,10 @@
 	if (newsp == frame)
 		return 0;		/* no signals delivered */
 
-	setup_rt_frame(regs, (struct sigregs *)frame, newsp);
-
+	/* Invoke correct stack setup routine */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(regs, (struct sigregs *)frame, newsp);
+	else
+		setup_frame(regs, (struct sigregs *)frame, newsp);
 	return 1;
 }
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ppc64/kernel/signal32.c	Mon Feb 10 10:39:32 2003
@@ -104,8 +104,6 @@
  *
  *  System Calls
  *       sigaction                sys32_sigaction
- *       sigpending               sys32_sigpending
- *       sigprocmask              sys32_sigprocmask
  *       sigreturn                sys32_sigreturn
  *
  *  Note sigsuspend has no special 32 bit routine - uses the 64 bit routine
@@ -114,43 +112,6 @@
  *        setup_frame32
  */
 
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
-long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6,
-		      int p7, struct pt_regs *regs)
-{
-	sigset_t saveset;
-
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
-	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
-
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs))
-			/*
-			 * If a signal handler needs to be called,
-			 * do_signal() has set R3 to the signal number (the
-			 * first argument of the signal handler), so don't
-			 * overwrite that with EINTR !
-			 * In the other cases, do_signal() doesn't touch 
-			 * R3, so it's still set to -EINTR (see above).
-			 */
-			return regs->gpr[3];
-	}
-}
-
 long sys32_sigaction(int sig, struct old_sigaction32 *act,
 		struct old_sigaction32 *oact)
 {
@@ -161,7 +122,7 @@
 		sig = -sig;
 
 	if (act) {
-		old_sigset_t32 mask;
+		compat_old_sigset_t mask;
 
 		if (get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
 		    __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
@@ -184,54 +145,6 @@
 }
 
 
-extern long sys_sigpending(old_sigset_t *set);
-
-long sys32_sigpending(old_sigset_t32 *set)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_sigpending(&s);
-	set_fs(old_fs);
-	if (put_user(s, set))
-		return -EFAULT;
-	return ret;
-}
-
-
-extern long sys_sigprocmask(int how, old_sigset_t *set,
-		old_sigset_t *oset);
-
-/*
- * Note: it is necessary to treat how as an unsigned int, with the
- * corresponding cast to a signed int to insure that the proper
- * conversion (sign extension) between the register representation
- * of a signed int (msr in 32-bit mode) and the register representation
- * of a signed int (msr in 64-bit mode) is performed.
- */
-long sys32_sigprocmask(u32 how, old_sigset_t32 *set,
-		old_sigset_t32 *oset)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	if (set && get_user(s, set))
-		return -EFAULT;
-	set_fs(KERNEL_DS);
-	ret = sys_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL);
-	set_fs(old_fs);
-	if (ret)
-		return ret;
-	if (oset && put_user (s, oset))
-		return -EFAULT;
-	return 0;
-}
-
-
-
 /*
  * When we have signals to deliver, we set up on the
  * user stack, going down from the original stack pointer:
@@ -268,10 +181,10 @@
 	 */
 	set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32);
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	if (regs->msr & MSR_FP )
 		giveup_fpu(current);
 	/* Last stacked signal - restore registers */
@@ -487,10 +400,10 @@
 	 */
 	sigdelsetmask(&set, ~_BLOCKABLE); 
 	/* update the current based on the sigmask found in the rt_stackframe */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* If currently owning the floating point - give them up */
 	if (regs->msr & MSR_FP)
@@ -565,16 +478,16 @@
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
-	sigset32_t set32;
+	compat_sigset_t set32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset32_t))
+	if (sigsetsize != sizeof(compat_sigset_t))
 		return -EINVAL;
 
 	if (act) {
 		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
 		ret |= __copy_from_user(&set32, &act->sa_mask,
-					sizeof(sigset32_t));
+					sizeof(compat_sigset_t));
 		switch (_NSIG_WORDS) {
 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
 				| (((long)set32.sig[7]) << 32);
@@ -608,7 +521,7 @@
 		}
 		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
 		ret |= __copy_to_user(&oact->sa_mask, &set32,
-				      sizeof(sigset32_t));
+				      sizeof(compat_sigset_t));
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 	}
 	return ret;
@@ -625,16 +538,16 @@
  * of a signed int (msr in 32-bit mode) and the register representation
  * of a signed int (msr in 64-bit mode) is performed.
  */
-long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
-		sigset32_t *oset, size_t sigsetsize)
+long sys32_rt_sigprocmask(u32 how, compat_sigset_t *set,
+		compat_sigset_t *oset, size_t sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 
 	if (set) {
-		if (copy_from_user (&s32, set, sizeof(sigset32_t)))
+		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
 			return -EFAULT;
     
 		switch (_NSIG_WORDS) {
@@ -658,7 +571,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
+		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return 0;
@@ -668,10 +581,10 @@
 extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 
-long sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize)
+long sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 
@@ -685,7 +598,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (set, &s32, sizeof(sigset32_t)))
+		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return ret;
@@ -739,17 +652,17 @@
 		siginfo_t *uinfo, const struct timespec *uts,
 		size_t sigsetsize);
 
-long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
+long sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
 		struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	siginfo_t info;
 
-	if (copy_from_user(&s32, uthese, sizeof(sigset32_t)))
+	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
 		return -EFAULT;
 	switch (_NSIG_WORDS) {
 	case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -837,11 +750,11 @@
 	return ret;
 }
 
-int sys32_rt_sigsuspend(sigset32_t* unewset, size_t sigsetsize, int p3,
+int sys32_rt_sigsuspend(compat_sigset_t* unewset, size_t sigsetsize, int p3,
 		int p4, int p6, int p7, struct pt_regs *regs)
 {
 	sigset_t saveset, newset;
-	sigset32_t s32;
+	compat_sigset_t s32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
 	if (sigsetsize != sizeof(sigset_t))
@@ -863,11 +776,11 @@
 
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->result = -EINTR;
 	regs->gpr[3] = EINTR;
@@ -991,7 +904,7 @@
 {
 	struct sigcontext32 *sc;
 	struct rt_sigframe_32 *rt_sf;
-	struct k_sigaction *ka = &current->sig->action[sig-1];
+	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
 	if (regs->trap == 0x0C00 /* System Call! */
 	    && ((int)regs->result == -ERESTARTNOHAND ||
@@ -1055,11 +968,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	return;
 
@@ -1152,7 +1065,7 @@
 
 	signr = get_signal_to_deliver(&info, regs);
 	if (signr > 0) {
-		ka = &current->sig->action[signr-1];
+		ka = &current->sighand->action[signr-1];
 		if ((ka->sa.sa_flags & SA_ONSTACK)
 		     && (!on_sig_stack(regs->gpr[1])))
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c	Mon Feb 10 10:39:30 2003
+++ b/arch/ppc64/kernel/smp.c	Mon Feb 10 10:39:30 2003
@@ -494,8 +494,10 @@
 	while (atomic_read(&data.started) != cpus) {
 		HMT_low();
 		if (--timeout == 0) {
+#ifdef CONFIG_DEBUG_KERNEL
 			if (debugger)
 				debugger(0);
+#endif
 			printk("smp_call_function on cpu %d: other cpus not "
 			       "responding (%d)\n", smp_processor_id(),
 			       atomic_read(&data.started));
@@ -508,8 +510,10 @@
 		while (atomic_read(&data.finished) != cpus) {
 			HMT_low();
 			if (--timeout == 0) {
+#ifdef CONFIG_DEBUG_KERNEL
 				if (debugger)
 					debugger(0);
+#endif
 				printk("smp_call_function on cpu %d: other "
 				       "cpus not finishing (%d/%d)\n",
 				       smp_processor_id(),
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	Mon Feb 10 10:39:29 2003
+++ b/arch/ppc64/kernel/sys_ppc32.c	Mon Feb 10 10:39:29 2003
@@ -2756,10 +2756,27 @@
 		__get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
 
 		clen64 = kcmsg32->cmsg_len;
-		copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
-			       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
-		clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
-			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+		if (kcmsg32->cmsg_level == SOL_SOCKET &&
+		    kcmsg32->cmsg_type == SO_TIMESTAMP) {
+			struct timeval tv;
+			struct compat_timeval *tv32;
+
+			if (clen64 != CMSG_LEN(sizeof(struct timeval))) {
+				kfree(workbuf);
+				goto fail;
+			}
+			copy_from_user(&tv, CMSG_DATA(ucmsg), sizeof(tv));
+			tv32 = (struct compat_timeval *) CMSG32_DATA(kcmsg32);
+			tv32->tv_sec = tv.tv_sec;
+			tv32->tv_usec = tv.tv_usec;
+			clen32 = sizeof(*tv32) +
+				CMSG32_ALIGN(sizeof(struct cmsghdr32));
+		} else {
+			copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
+				       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
+			clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
+				  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+		}
 		kcmsg32->cmsg_len = clen32;
 
 		switch (kcmsg32->cmsg_type) {
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c	Mon Feb 10 10:39:32 2003
+++ b/arch/ppc64/kernel/time.c	Mon Feb 10 10:39:32 2003
@@ -69,7 +69,6 @@
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
-extern rwlock_t xtime_lock;
 extern int piranha_simulator;
 #ifdef CONFIG_PPC_ISERIES
 unsigned long iSeries_recal_titan = 0;
@@ -284,12 +283,12 @@
 		smp_local_timer_interrupt(regs);
 #endif
 		if (cpu == boot_cpuid) {
-			write_lock(&xtime_lock);
+			write_seqlock(&xtime_lock);
 			tb_last_stamp = lpaca->next_jiffy_update_tb;
 			do_timer(regs);
 			timer_sync_xtime( cur_tb );
 			timer_check_rtc();
-			write_unlock(&xtime_lock);
+			write_sequnlock(&xtime_lock);
 			if ( adjusting_time && (time_adjust == 0) )
 				ppc_adjtimex();
 		}
@@ -348,7 +347,7 @@
 	long int tb_delta, new_usec, new_sec;
 	unsigned long new_xsec;
 
-	write_lock_irqsave(&xtime_lock, flags);
+	write_seqlock_irqsave(&xtime_lock, flags);
 	/* Updating the RTC is not the job of this code. If the time is
 	 * stepped under NTP, the RTC will be update after STA_UNSYNC
 	 * is cleared. Tool like clock/hwclock either copy the RTC
@@ -399,7 +398,7 @@
 		do_gtod.tb_orig_stamp = tb_last_stamp;
 	}
 
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /*
@@ -465,7 +464,7 @@
 #endif
 		ppc_md.get_boot_time(&tm);
 
-	write_lock_irqsave(&xtime_lock, flags);
+	write_seqlock_irqsave(&xtime_lock, flags);
 	xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
 			      tm.tm_hour, tm.tm_min, tm.tm_sec);
 	tb_last_stamp = get_tb();
@@ -484,7 +483,7 @@
 
 	xtime.tv_nsec = 0;
 	last_rtc_update = xtime.tv_sec;
-	write_unlock_irqrestore(&xtime_lock, flags);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
 
 	/* Not exact, but the timer interrupt takes care of this */
 	set_dec(tb_ticks_per_jiffy);
@@ -587,7 +586,7 @@
 	new_tb_to_xs = divres.result_low;
 	new_xsec = mulhdu( tb_ticks, new_tb_to_xs );
 
-	write_lock_irqsave( &xtime_lock, flags );
+	write_seqlock_irqsave( &xtime_lock, flags );
 	old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
 	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
 
@@ -609,7 +608,7 @@
 	do_gtod.varp = temp_varp;
 	do_gtod.var_idx = temp_idx;
 
-	write_unlock_irqrestore( &xtime_lock, flags );
+	write_sequnlock_irqrestore( &xtime_lock, flags );
 
 }
 
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	Mon Feb 10 10:39:27 2003
+++ b/arch/ppc64/kernel/traps.c	Mon Feb 10 10:39:27 2003
@@ -81,8 +81,10 @@
 _exception(int signr, siginfo_t *info, struct pt_regs *regs)
 {
 	if (!user_mode(regs)) {
+#ifdef CONFIG_DEBUG_KERNEL
 		if (debugger)
 			debugger(regs);
+#endif
 		die("Exception in kernel mode\n", regs, signr);
 	}
 
@@ -133,8 +135,10 @@
 		FWNMI_release_errinfo();
 	}
 
+#ifdef CONFIG_DEBUG_KERNEL
 	if (debugger)
 		debugger(regs);
+#endif
 
 #ifdef PANIC_ON_ERROR
 	panic("System Reset");
@@ -174,13 +178,14 @@
 				return;
 		}
 
+#ifdef CONFIG_DEBUG_KERNEL
 		if (debugger_fault_handler) {
 			debugger_fault_handler(regs);
 			return;
 		}
 		if (debugger)
 			debugger(regs);
-
+#endif
 		console_verbose();
 		spin_lock_irq(&die_lock);
 		bust_spinlocks(1);
@@ -223,9 +228,10 @@
 {
 	siginfo_t info;
 
+#ifdef CONFIG_DEBUG_KERNEL
 	if (debugger_iabr_match && debugger_iabr_match(regs))
 		return;
-
+#endif
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
@@ -292,9 +298,10 @@
 	} else if (regs->msr & 0x20000) {
 		/* trap exception */
 
+#ifdef CONFIG_DEBUG_KERNEL
 		if (debugger_bpt && debugger_bpt(regs))
 			return;
-
+#endif
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code = TRAP_BRKPT;
@@ -318,9 +325,10 @@
 
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 
+#ifdef CONFIG_DEBUG_KERNEL
 	if (debugger_sstep && debugger_sstep(regs))
 		return;
-
+#endif
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_TRACE;
diff -Nru a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
--- a/arch/ppc64/lib/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/ppc64/lib/Makefile	Mon Feb 10 10:39:23 2003
@@ -4,7 +4,5 @@
 
 L_TARGET = lib.a
 
-export-objs := dec_and_lock.o
-
 obj-y := checksum.o dec_and_lock.o string.o strcase.o
 obj-y += copypage.o memcpy.o copyuser.o
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	Mon Feb 10 10:39:25 2003
+++ b/arch/s390/Kconfig	Mon Feb 10 10:39:25 2003
@@ -110,7 +110,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qdio.o. If you want to compile it as a
+	  The module will be called qdio. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say Y.
@@ -210,7 +210,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -235,7 +235,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config PROCESS_DEBUG
diff -Nru a/arch/s390/Makefile b/arch/s390/Makefile
--- a/arch/s390/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/s390/Makefile	Mon Feb 10 10:39:24 2003
@@ -20,7 +20,7 @@
 
 CFLAGS += -pipe -fno-strength-reduce
 
-HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
+head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
 
 core-y		+= arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/
 libs-y		+= arch/$(ARCH)/lib/
@@ -38,7 +38,6 @@
 install: vmlinux
 	$(call makeboot, $@)
 
-archmrproper:
 archclean:
 	$(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot
 
diff -Nru a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
--- a/arch/s390/kernel/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/s390/kernel/Makefile	Mon Feb 10 10:39:33 2003
@@ -5,7 +5,6 @@
 EXTRA_TARGETS	:= head.o init_task.o
 EXTRA_AFLAGS	:= -traditional
 
-export-objs	:= debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o
 obj-y	:= entry.o bitmap.o traps.o time.o process.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o reipl.o s390_ext.o debug.o
diff -Nru a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
--- a/arch/s390/kernel/signal.c	Mon Feb 10 10:39:30 2003
+++ b/arch/s390/kernel/signal.c	Mon Feb 10 10:39:30 2003
@@ -61,11 +61,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->gprs[2] = -EINTR;
 
 	while (1) {
@@ -89,11 +89,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->gprs[2] = -EINTR;
 
 	while (1) {
@@ -194,10 +194,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs(regs, &frame->sregs))
 		goto badframe;
@@ -220,10 +220,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -427,11 +427,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
--- a/arch/s390/kernel/time.c	Mon Feb 10 10:39:23 2003
+++ b/arch/s390/kernel/time.c	Mon Feb 10 10:39:23 2003
@@ -52,7 +52,6 @@
 static uint64_t xtime_cc;
 static uint64_t init_timer_cc;
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
 void tod_to_timeval(__u64 todval, struct timespec *xtime)
@@ -83,12 +82,15 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	sec = xtime.tv_sec;
-	usec = xtime.tv_nsec / 1000 + do_gettimeoffset();
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+		sec = xtime.tv_sec;
+		usec = xtime.tv_nsec / 1000 + do_gettimeoffset();
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -102,7 +104,7 @@
 void do_settimeofday(struct timeval *tv)
 {
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/* This is revolting. We need to set the xtime.tv_nsec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
@@ -122,7 +124,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 static inline __u32 div64_32(__u64 dividend, __u32 divisor)
@@ -166,7 +168,7 @@
 	 * Do not rely on the boot cpu to do the calls to do_timer.
 	 * Spread it over all cpus instead.
 	 */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	if (S390_lowcore.jiffy_timer > xtime_cc) {
 		__u32 xticks;
 
@@ -181,7 +183,7 @@
 		while (xticks--)
 			do_timer(regs);
 	}
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 	while (ticks--)
 		update_process_times(user_mode(regs));
 #else
diff -Nru a/arch/s390x/Kconfig b/arch/s390x/Kconfig
--- a/arch/s390x/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/arch/s390x/Kconfig	Mon Feb 10 10:39:27 2003
@@ -124,7 +124,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qdio.o. If you want to compile it as a
+	  The module will be called qdio. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say Y.
@@ -224,7 +224,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -249,7 +249,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config PROCESS_DEBUG
diff -Nru a/arch/s390x/Makefile b/arch/s390x/Makefile
--- a/arch/s390x/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/s390x/Makefile	Mon Feb 10 10:39:27 2003
@@ -21,7 +21,7 @@
 
 CFLAGS += -pipe -fno-strength-reduce
 
-HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
+head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
 
 core-y		+= arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/
 libs-y		+= arch/$(ARCH)/lib/
@@ -38,7 +38,6 @@
 install: vmlinux
 	$(call makeboot, $@)
 
-archmrproper:
 archclean:
 	$(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot
 
diff -Nru a/arch/s390x/kernel/Makefile b/arch/s390x/kernel/Makefile
--- a/arch/s390x/kernel/Makefile	Mon Feb 10 10:39:25 2003
+++ b/arch/s390x/kernel/Makefile	Mon Feb 10 10:39:25 2003
@@ -5,9 +5,6 @@
 EXTRA_TARGETS	:= head.o init_task.o
 EXTRA_AFLAGS	:= -traditional
 
-export-objs	:= debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o \
-		   exec32.o
-
 obj-y		:= entry.o bitmap.o traps.o time.o process.o \
 		   setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
 		   semaphore.o reipl.o s390_ext.o debug.o
diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c
--- a/arch/s390x/kernel/linux32.c	Mon Feb 10 10:39:30 2003
+++ b/arch/s390x/kernel/linux32.c	Mon Feb 10 10:39:30 2003
@@ -1725,7 +1725,7 @@
 			return -EINVAL;
 	}
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sig = dequeue_signal(&these, &info);
 	if (!sig) {
 		/* None ready -- temporarily unblock those we're interested
@@ -1733,7 +1733,7 @@
 		current->real_blocked = current->blocked;
 		sigandsets(&current->blocked, &current->blocked, &these);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 		timeout = MAX_SCHEDULE_TIMEOUT;
 		if (uts)
@@ -1743,13 +1743,13 @@
 		current->state = TASK_INTERRUPTIBLE;
 		timeout = schedule_timeout(timeout);
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sig = dequeue_signal(&these, &info);
 		current->blocked = current->real_blocked;
 		siginitset(&current->real_blocked, 0);
 		recalc_sigpending();
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (sig) {
 		ret = sig;
diff -Nru a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c
--- a/arch/s390x/kernel/signal.c	Mon Feb 10 10:39:29 2003
+++ b/arch/s390x/kernel/signal.c	Mon Feb 10 10:39:29 2003
@@ -60,11 +60,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->gprs[2] = -EINTR;
 
 	while (1) {
@@ -88,11 +88,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->gprs[2] = -EINTR;
 
 	while (1) {
@@ -188,10 +188,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs(regs, &frame->sregs))
 		goto badframe;
@@ -214,10 +214,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -421,11 +421,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c
--- a/arch/s390x/kernel/signal32.c	Mon Feb 10 10:39:26 2003
+++ b/arch/s390x/kernel/signal32.c	Mon Feb 10 10:39:26 2003
@@ -112,11 +112,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->gprs[2] = -EINTR;
 
 	while (1) {
@@ -147,11 +147,11 @@
 	}
         sigdelsetmask(&newset, ~_BLOCKABLE);
 
-        spin_lock_irq(&current->sig->siglock);
+        spin_lock_irq(&current->sighand->siglock);
         saveset = current->blocked;
         current->blocked = newset;
         recalc_sigpending();
-        spin_unlock_irq(&current->sig->siglock);
+        spin_unlock_irq(&current->sighand->siglock);
         regs->gprs[2] = -EINTR;
 
         while (1) {
@@ -345,10 +345,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs32(regs, &frame->sregs))
 		goto badframe;
@@ -375,10 +375,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -588,11 +588,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/s390x/kernel/time.c b/arch/s390x/kernel/time.c
--- a/arch/s390x/kernel/time.c	Mon Feb 10 10:39:31 2003
+++ b/arch/s390x/kernel/time.c	Mon Feb 10 10:39:31 2003
@@ -51,7 +51,6 @@
 static uint64_t xtime_cc;
 static uint64_t init_timer_cc;
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 
 void tod_to_timeval(__u64 todval, struct timespec *xtime)
@@ -78,12 +77,14 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	sec = xtime.tv_sec;
-	usec = xtime.tv_nsec + do_gettimeoffset();
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		sec = xtime.tv_sec;
+		usec = xtime.tv_nsec + do_gettimeoffset();
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -97,7 +98,7 @@
 void do_settimeofday(struct timeval *tv)
 {
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/* This is revolting. We need to set the xtime.tv_usec
 	 * correctly. However, the value in this location is
 	 * is value at the last tick.
@@ -117,7 +118,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /*
@@ -152,7 +153,7 @@
 	 * Do not rely on the boot cpu to do the calls to do_timer.
 	 * Spread it over all cpus instead.
 	 */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	if (S390_lowcore.jiffy_timer > xtime_cc) {
 		__u32 xticks;
 
@@ -167,7 +168,7 @@
 		while (xticks--)
 			do_timer(regs);
 	}
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 	while (ticks--)
 		update_process_times(user_mode(regs));
 #else
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/arch/sh/Kconfig	Mon Feb 10 10:39:33 2003
@@ -623,7 +623,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -648,7 +648,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 source "drivers/parport/Kconfig"
@@ -704,7 +704,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -731,7 +731,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -855,7 +855,7 @@
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  serial.o.
+	  serial.
 	  [WARNING: Do not compile this driver as a module if you are using
 	  non-standard serial ports, since the configuration information will
 	  be lost when the driver is unloaded.  This limitation may be lifted
@@ -992,7 +992,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -1036,7 +1036,7 @@
 	  This support is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  ppdev.o.
+	  ppdev.
 
 	  If unsure, say N.
 
@@ -1108,7 +1108,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called shwdt.o. If you want to compile it as a module,
+	  The module is called shwdt. If you want to compile it as a module,
 	  say M here and read Documentation/modules.txt.
 
 endmenu
@@ -1137,7 +1137,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called rtc.o. If you want to compile it as a module,
+	  The module is called rtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/char/pcmcia/Kconfig"
@@ -1175,7 +1175,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/sh/Makefile b/arch/sh/Makefile
--- a/arch/sh/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/sh/Makefile	Mon Feb 10 10:39:29 2003
@@ -53,7 +53,7 @@
 #
 CFLAGS		+= -pipe
 
-HEAD := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
+head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
 
 LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
 
@@ -80,6 +80,4 @@
 	$(MAKE) -C arch/$(ARCH)/kernel clean
 	$(MAKE) -C arch/$(ARCH)/stboards clean
 #	$(MAKE) -C arch/$(ARCH)/tools clean
-
-archmrproper:
 
diff -Nru a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
--- a/arch/sh/kernel/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/sh/kernel/Makefile	Mon Feb 10 10:39:29 2003
@@ -4,9 +4,6 @@
 
 EXTRA_TARGETS	:= head.o init_task.o
 
-export-objs	:= io.o io_generic.o io_hd64465.o setup_hd64465.o sh_ksyms.o \
-		   io_adx.o io_bigsur.o io_cat68701.o hd64465_gpio.o
-
 obj-y	:= process.o signal.o entry.o traps.o irq.o irq_ipr.o \
 	ptrace.o setup.o time.o sys_sh.o semaphore.o \
 	irq_imask.o io.o io_generic.o sh_ksyms.o
diff -Nru a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
--- a/arch/sh/kernel/io.c	Mon Feb 10 10:39:25 2003
+++ b/arch/sh/kernel/io.c	Mon Feb 10 10:39:25 2003
@@ -4,7 +4,7 @@
  * Copyright (C) 2000  Stuart Menefy
  *
  * Provide real functions which expand to whatever the header file defined.
- * Also definitions of machine independant IO functions.
+ * Also definitions of machine independent IO functions.
  */
 
 #include <asm/io.h>
diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
--- a/arch/sh/kernel/time.c	Mon Feb 10 10:39:23 2003
+++ b/arch/sh/kernel/time.c	Mon Feb 10 10:39:23 2003
@@ -72,7 +72,6 @@
 
 u64 jiffies_64;
 
-extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
 #define TICK_SIZE tick
 
@@ -128,18 +127,20 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += xtime.tv_usec;
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = do_gettimeoffset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += xtime.tv_usec;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -152,7 +153,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
@@ -172,7 +173,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /* last time the RTC clock got updated */
@@ -231,9 +232,9 @@
 	 * the irq version of write_lock because as just said we have irq
 	 * locally disabled. -arca
 	 */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	do_timer_interrupt(irq, NULL, regs);
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 static unsigned int __init get_timer_frequency(void)
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Mon Feb 10 10:39:22 2003
+++ b/arch/sparc/Kconfig	Mon Feb 10 10:39:22 2003
@@ -182,8 +182,8 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  When compiled this way, there will be modules called pcmcia_core.o
-	  and ds.o.  If you want to compile it as a module, say M here and
+	  When compiled this way, there will be modules called pcmcia_core
+	  and ds.  If you want to compile it as a module, say M here and
 	  read <file:Documentation/modules.txt>.
 
 config SBUS
@@ -276,7 +276,7 @@
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called openpromfs.o.  If unsure, say M.
+	  The module will be called openpromfs.  If unsure, say M.
 
 config KCORE_ELF
 	bool
@@ -319,7 +319,7 @@
 	  QMAGIC support" then you'll have to say Y here. You may answer M to
 	  compile a.out support as a module and later load the module when you
 	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout.o. Saying M or N here is dangerous though,
+	  called binfmt_aout. Saying M or N here is dangerous though,
 	  because some crucial programs on your system might still be in A.OUT
 	  format.
 
@@ -349,7 +349,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -374,7 +374,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config SUNOS_EMUL
@@ -404,7 +404,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -442,7 +442,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called floppy.o. If you want to compile it as a
+	  The module will be called floppy. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config BLK_DEV_LOOP
@@ -492,7 +492,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called loop.o.
+	  will be called loop.
 
 	  Most users will answer N here.
 
@@ -521,7 +521,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called nbd.o.
+	  will be called nbd.
 
 	  If unsure, say N.
 
@@ -543,7 +543,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M and read <file:Documentation/modules.txt>. The module will be
-	  called rd.o.
+	  called rd.
 
 	  Most normal users won't need the RAM disk functionality, and can
 	  thus say N here.
@@ -613,7 +613,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -644,7 +644,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -665,7 +665,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.o.  If you want to compile it as a
+	  The module will be called sd_mod.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
 	  module if your root file system (the one containing the directory /)
@@ -701,7 +701,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st.o. If you want to compile it as a
+	  The module will be called st. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -726,7 +726,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called osst.o. If you want to compile it as a
+	  The module will be called osst. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -741,7 +741,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod.o. If you want to compile it as a
+	  The module will be called sr_mod. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -794,7 +794,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.o.
+	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
 	  If unsure, say N.
 
 comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
@@ -856,7 +856,7 @@
 	  This is the driver for the Sun ESP SCSI host adapter. The ESP
 	  chipset is present in most SPARC SBUS-based computers.
 
-	  This support is also available as a module called esp.o ( = code
+	  This support is also available as a module called esp ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -870,7 +870,7 @@
 	  PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are
 	  driven by a different driver.
 
-	  This support is also available as a module called qlogicpti.o ( =
+	  This support is also available as a module called qlogicpti ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -963,7 +963,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
@@ -992,7 +992,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  softdog.o.
+	  softdog.
 
 endmenu
 
diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile
--- a/arch/sparc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/sparc/Makefile	Mon Feb 10 10:39:23 2003
@@ -37,7 +37,8 @@
 #  Actual linking is done with "make image".
 LDFLAGS_vmlinux = -r
 
-HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o
+head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o
+HEAD := $(head-y)
 
 core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/
 libs-y += arch/sparc/prom/ arch/sparc/lib/
@@ -60,8 +61,6 @@
 
 archclean:
 	$(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot
-
-archmrproper:
 
 prepare: include/asm-$(ARCH)/asm_offsets.h
 
diff -Nru a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
--- a/arch/sparc/kernel/Makefile	Mon Feb 10 10:39:31 2003
+++ b/arch/sparc/kernel/Makefile	Mon Feb 10 10:39:31 2003
@@ -6,7 +6,6 @@
 
 EXTRA_AFLAGS	:= -ansi
 
-export-objs := sparc_ksyms.o
 IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o
 obj-y    := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
 	    process.o signal.o ioport.o setup.o idprom.o \
diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S	Mon Feb 10 10:39:27 2003
+++ b/arch/sparc/kernel/entry.S	Mon Feb 10 10:39:27 2003
@@ -1808,6 +1808,15 @@
 	retl
 	 nop
 
+	.globl	C_LABEL(ndelay)
+C_LABEL(ndelay):
+	save	%sp, -REGWIN_SZ, %sp
+	mov	%i0, %o0
+	call	.umul
+	 mov	5, %o1
+	ba	delay_continue
+	 nop
+
 	.globl	C_LABEL(udelay)
 C_LABEL(udelay):
 	save	%sp, -REGWIN_SZ, %sp
@@ -1815,6 +1824,7 @@
 	sethi	%hi(0x10c6), %o1
 	call	.umul
 	 or	%o1, %lo(0x10c6), %o1
+delay_continue:
 #ifndef CONFIG_SMP
 	sethi	%hi(C_LABEL(loops_per_jiffy)), %o3
 	call	.umul
@@ -1879,7 +1889,7 @@
 	wr	%o4, 0x0, %psr			! the uwinmask state
 	WRITE_PAUSE				! burn them cycles
 1:
-	ld	[%g6 + TI_UWINMASK], %o0	! get consistant state
+	ld	[%g6 + TI_UWINMASK], %o0	! get consistent state
 	orcc	%g0, %o0, %g0			! did an interrupt come in?
 	be	4f				! yep, we are done
 	 rd	%wim, %o3			! get current wim
diff -Nru a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
--- a/arch/sparc/kernel/pcic.c	Mon Feb 10 10:39:27 2003
+++ b/arch/sparc/kernel/pcic.c	Mon Feb 10 10:39:27 2003
@@ -25,6 +25,7 @@
 
 #include <linux/ctype.h>
 #include <linux/pci.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/interrupt.h>
 
@@ -34,8 +35,6 @@
 #include <asm/timer.h>
 #include <asm/uaccess.h>
 
-extern rwlock_t xtime_lock;
-
 #ifndef CONFIG_PCI
 
 asmlinkage int sys_pciconfig_read(unsigned long bus,
@@ -739,10 +738,10 @@
 
 static void pcic_timer_handler (int irq, void *h, struct pt_regs *regs)
 {
-	write_lock(&xtime_lock);	/* Dummy, to show that we remember */
+	write_seqlock(&xtime_lock);	/* Dummy, to show that we remember */
 	pcic_clear_clock_irq();
 	do_timer(regs);
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 #define USECS_PER_JIFFY  10000  /* We have 100HZ "standard" timer for sparc */
@@ -795,18 +794,20 @@
 static void pci_do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += (xtime.tv_nsec / 1000);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = do_gettimeoffset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
--- a/arch/sparc/kernel/signal.c	Mon Feb 10 10:39:29 2003
+++ b/arch/sparc/kernel/signal.c	Mon Feb 10 10:39:29 2003
@@ -104,11 +104,11 @@
 	sigset_t saveset;
 
 	set &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, set);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->pc = regs->npc;
 	regs->npc += 4;
@@ -161,11 +161,11 @@
 	}
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	oldset = current->blocked;
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->pc = regs->npc;
 	regs->npc += 4;
@@ -267,10 +267,10 @@
 		goto segv_and_exit;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return;
 
 segv_and_exit:
@@ -314,10 +314,10 @@
 		goto segv_and_exit;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->pc = pc;
 	regs->npc = npc;
@@ -384,10 +384,10 @@
 	do_sigaltstack(&st, NULL, (unsigned long)sf);
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return;
 segv:
 	send_sig(SIGSEGV, current, 1);
@@ -967,10 +967,10 @@
 		set.sig[3] = setv.sigbits[3];
 	}
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->pc = pc;
 	regs->npc = npc | 1;
 	err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
@@ -1007,11 +1007,11 @@
 	if(ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
 	if(!(ka->sa.sa_flags & SA_NOMASK)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked, signr);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
@@ -1066,9 +1066,9 @@
 		sigset_t *mask = &current->blocked;
 		unsigned long signr = 0;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 		if (!signr)
 			break;
diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	Mon Feb 10 10:39:23 2003
+++ b/arch/sparc/kernel/sparc_ksyms.c	Mon Feb 10 10:39:23 2003
@@ -151,6 +151,7 @@
 #endif
 
 EXPORT_SYMBOL(udelay);
+EXPORT_SYMBOL(ndelay);
 EXPORT_SYMBOL(mostek_lock);
 EXPORT_SYMBOL(mstk48t02_regs);
 #if CONFIG_SUN_AUXIO
diff -Nru a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
--- a/arch/sparc/kernel/sys_sparc.c	Mon Feb 10 10:39:25 2003
+++ b/arch/sparc/kernel/sys_sparc.c	Mon Feb 10 10:39:25 2003
@@ -409,7 +409,7 @@
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		/* In the clone() case we could copy half consistant
+		/* In the clone() case we could copy half consistent
 		 * state to the user, however this could sleep and
 		 * deadlock us if we held the signal lock on SMP.  So for
 		 * now I take the easy way out and do no locking.
diff -Nru a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
--- a/arch/sparc/kernel/sys_sunos.c	Mon Feb 10 10:39:26 2003
+++ b/arch/sparc/kernel/sys_sunos.c	Mon Feb 10 10:39:26 2003
@@ -281,11 +281,11 @@
 {
 	unsigned long old;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	old = current->blocked.sig[0];
 	current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return old;
 }
 
@@ -293,11 +293,11 @@
 {
 	unsigned long retval;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	retval = current->blocked.sig[0];
 	current->blocked.sig[0] = (newmask & _BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return retval;
 }
 
@@ -1168,7 +1168,7 @@
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		/* In the clone() case we could copy half consistant
+		/* In the clone() case we could copy half consistent
 		 * state to the user, however this could sleep and
 		 * deadlock us if we held the signal lock on SMP.  So for
 		 * now I take the easy way out and do no locking.
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	Mon Feb 10 10:39:28 2003
+++ b/arch/sparc/kernel/time.c	Mon Feb 10 10:39:28 2003
@@ -23,6 +23,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -42,8 +43,6 @@
 #include <asm/page.h>
 #include <asm/pcic.h>
 
-extern rwlock_t xtime_lock;
-
 extern unsigned long wall_jiffies;
 
 u64 jiffies_64;
@@ -131,7 +130,7 @@
 #endif
 
 	/* Protect counter clear so that do_gettimeoffset works */
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 #ifdef CONFIG_SUN4
 	if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) ||
 	   (idprom->id_machtype == (SM_SUN4 | SM_4_110))) {
@@ -155,7 +154,7 @@
 	  else
 	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 	}
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
@@ -470,18 +469,20 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += (xtime.tv_nsec / 1000);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = do_gettimeoffset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -494,9 +495,9 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	bus_do_settimeofday(tv);
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 static void sbus_do_settimeofday(struct timeval *tv)
diff -Nru a/arch/sparc/math-emu/math.c b/arch/sparc/math-emu/math.c
--- a/arch/sparc/math-emu/math.c	Mon Feb 10 10:39:26 2003
+++ b/arch/sparc/math-emu/math.c	Mon Feb 10 10:39:26 2003
@@ -203,7 +203,7 @@
 }
 
 /* All routines returning an exception to raise should detect
- * such exceptions _before_ rounding to be consistant with
+ * such exceptions _before_ rounding to be consistent with
  * the behavior of the hardware in the implemented cases
  * (and thus with the recommendations in the V9 architecture
  * manual).
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	Mon Feb 10 10:39:30 2003
+++ b/arch/sparc/mm/sun4c.c	Mon Feb 10 10:39:30 2003
@@ -1042,7 +1042,7 @@
 		get_locked_segment(addr);
 
 	/* We are changing the virtual color of the page(s)
-	 * so we must flush the cache to guarentee consistancy.
+	 * so we must flush the cache to guarentee consistency.
 	 */
 	sun4c_flush_page(pages);
 #ifndef CONFIG_SUN4	
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/arch/sparc64/Kconfig	Mon Feb 10 10:39:31 2003
@@ -232,7 +232,7 @@
 	  Say Y here if you would like support for ISA Plug and Play devices.
 	  Some information is in <file:Documentation/isapnp.txt>.
 
-	  This support is also available as a module called isapnp.o ( =
+	  This support is also available as a module called isapnp ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -279,8 +279,8 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  When compiled this way, there will be modules called pcmcia_core.o
-	  and ds.o.  If you want to compile it as a module, say M here and
+	  When compiled this way, there will be modules called pcmcia_core
+	  and ds.  If you want to compile it as a module, say M here and
 	  read <file:Documentation/modules.txt>.
 
 config SBUS
@@ -338,7 +338,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called rtc.o. If you want to compile it as a module,
+	  The module is called rtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/pci/Kconfig"
@@ -354,7 +354,7 @@
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called openpromfs.o.  If unsure, say M.
+	  The module will be called openpromfs.  If unsure, say M.
 
 config KCORE_ELF
 	bool
@@ -431,7 +431,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -456,7 +456,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config SUNOS_EMUL
@@ -477,7 +477,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called solaris.o. If you want to compile it as a
+	  The module will be called solaris. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/parport/Kconfig"
@@ -498,7 +498,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -518,7 +518,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called envctrl.o. If you want to compile it as a
+	  The module will be called envctrl. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config DISPLAY7SEG
@@ -530,7 +530,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called display7seg.o. If you want to compile it
+	  The module will be called display7seg. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you do not have a CompactPCI model CP1400 or CP1500, or
@@ -546,7 +546,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpwatchdog.o. If you want to compile it
+	  The module will be called cpwatchdog. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you do not have a CompactPCI model CP1400 or CP1500, or
@@ -586,7 +586,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called floppy.o. If you want to compile it as a
+	  The module will be called floppy. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config BLK_DEV_LOOP
@@ -636,7 +636,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called loop.o.
+	  will be called loop.
 
 	  Most users will answer N here.
 
@@ -665,7 +665,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called nbd.o.
+	  will be called nbd.
 
 	  If unsure, say N.
 
@@ -687,7 +687,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M and read <file:Documentation/modules.txt>. The module will be
-	  called rd.o.
+	  called rd.
 
 	  Most normal users won't need the RAM disk functionality, and can
 	  thus say N here.
@@ -755,7 +755,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -782,7 +782,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -803,7 +803,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.o.  If you want to compile it as a
+	  The module will be called sd_mod.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
 	  module if your root file system (the one containing the directory /)
@@ -839,7 +839,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st.o. If you want to compile it as a
+	  The module will be called st. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -864,7 +864,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called osst.o. If you want to compile it as a
+	  The module will be called osst. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -879,7 +879,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod.o. If you want to compile it as a
+	  The module will be called sr_mod. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -932,7 +932,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.o.
+	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
 	  If unsure, say N.
 
 comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
@@ -994,7 +994,7 @@
 	  This is the driver for the Sun ESP SCSI host adapter. The ESP
 	  chipset is present in most SPARC SBUS-based computers.
 
-	  This support is also available as a module called esp.o ( = code
+	  This support is also available as a module called esp ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1008,7 +1008,7 @@
 	  PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are
 	  driven by a different driver.
 
-	  This support is also available as a module called qlogicpti.o ( =
+	  This support is also available as a module called qlogicpti ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1060,7 +1060,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called aic7xxx_old.o.
+	  will be called aic7xxx_old.
 
 config AIC7XXX_OLD_TCQ_ON_BY_DEFAULT
 	bool "Enable Tagged Command Queueing (TCQ) by default"
@@ -1404,7 +1404,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicisp.o.  If you want to compile it as
+	  The module will be called qlogicisp.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_QLOGIC_FC
@@ -1415,7 +1415,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicfc.o.  If you want to compile it as
+	  The module will be called qlogicfc.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_QLOGIC_FC_FIRMWARE
@@ -1502,7 +1502,7 @@
 	  device or user software interacting with such a driver, please read
 	  the file <file:Documentation/video4linux/API.html>.
 
-	  This driver is also available as a module called videodev.o ( = code
+	  This driver is also available as a module called videodev ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1518,7 +1518,7 @@
 	  If you say Y or M here, you need to say Y or M to "I2C support" and
 	  "I2C bit-banging interfaces" in the character device section.
 
-	  This driver is available as a module called bttv.o ( = code
+	  This driver is available as a module called bttv ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1552,14 +1552,14 @@
 	depends on DRM
 	help
 	  Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
-	  graphics card.  If M is selected, the module will be called tdfx.o.
+	  graphics card.  If M is selected, the module will be called tdfx.
 
 config DRM_R128
 	tristate "ATI Rage 128"
 	depends on DRM
 	help
 	  Choose this option if you have an ATI Rage 128 graphics card.  If M
-	  is selected, the module will be called r128.o.  AGP support for
+	  is selected, the module will be called r128.  AGP support for
 	  this card is strongly suggested (unless you have a PCI version).
 
 endmenu
@@ -1594,7 +1594,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
@@ -1623,7 +1623,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  softdog.o.
+	  softdog.
 
 endmenu
 
diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile
--- a/arch/sparc64/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/sparc64/Makefile	Mon Feb 10 10:39:33 2003
@@ -61,7 +61,7 @@
   CFLAGS := $(CFLAGS) -pg
 endif
 
-HEAD := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
+head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
 
 core-y				+= arch/sparc64/kernel/ arch/sparc64/mm/
 core-$(CONFIG_SOLARIS_EMUL)	+= arch/sparc64/solaris/
@@ -73,10 +73,6 @@
 
 tftpboot.img vmlinux.aout:
 	$(Q)$(MAKE) $(build)=arch/sparc64/boot arch/sparc64/boot/$@
-
-archclean:
-
-archmrproper:
 
 define archhelp
   echo  '* vmlinux       - Standard sparc64 kernel'
diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/sparc64/kernel/Makefile	Mon Feb 10 10:39:24 2003
@@ -6,7 +6,6 @@
 
 EXTRA_TARGETS	:= head.o init_task.o
 
-export-objs	:= sparc64_ksyms.o ebus.o
 obj-y		:= process.o setup.o cpu.o idprom.o \
 		   traps.o devices.o auxio.o \
 		   irq.o ptrace.o time.o sys_sparc.o signal.o \
diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
--- a/arch/sparc64/kernel/power.c	Mon Feb 10 10:39:31 2003
+++ b/arch/sparc64/kernel/power.c	Mon Feb 10 10:39:31 2003
@@ -70,9 +70,9 @@
 
 again:
 	while (button_pressed == 0) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		flush_signals(current);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		interruptible_sleep_on(&powerd_wait);
 	}
 
diff -Nru a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
--- a/arch/sparc64/kernel/sbus.c	Mon Feb 10 10:39:33 2003
+++ b/arch/sparc64/kernel/sbus.c	Mon Feb 10 10:39:33 2003
@@ -767,7 +767,7 @@
 	}
 	imap += reg_base;
 
-	/* SYSIO inconsistancy.  For external SLOTS, we have to select
+	/* SYSIO inconsistency.  For external SLOTS, we have to select
 	 * the right ICLR register based upon the lower SBUS irq level
 	 * bits.
 	 */
diff -Nru a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
--- a/arch/sparc64/kernel/signal.c	Mon Feb 10 10:39:28 2003
+++ b/arch/sparc64/kernel/signal.c	Mon Feb 10 10:39:28 2003
@@ -9,6 +9,9 @@
  */
 
 #include <linux/config.h>
+#ifdef CONFIG_SPARC32_COMPAT
+#include <linux/compat.h>	/* for compat_old_sigset_t */
+#endif
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
@@ -67,10 +70,10 @@
 				goto do_sigsegv;
 		}
 		sigdelsetmask(&set, ~_BLOCKABLE);
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		current->blocked = set;
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
@@ -247,18 +250,18 @@
 
 #ifdef CONFIG_SPARC32_COMPAT
 	if (test_thread_flag(TIF_32BIT)) {
-		extern asmlinkage void _sigpause32_common(old_sigset_t32,
+		extern asmlinkage void _sigpause32_common(compat_old_sigset_t,
 							  struct pt_regs *);
 		_sigpause32_common(set, regs);
 		return;
 	}
 #endif
 	set &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, set);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc = (regs->tnpc & 0xffffffff);
@@ -314,11 +317,11 @@
 	}
                                                                 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	oldset = current->blocked;
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc = (regs->tnpc & 0xffffffff);
@@ -425,10 +428,10 @@
 	set_fs(old_fs);
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return;
 segv:
 	send_sig(SIGSEGV, current, 1);
@@ -561,11 +564,11 @@
 	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
 	if (!(ka->sa.sa_flags & SA_NOMASK)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,signr);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
@@ -616,9 +619,9 @@
 		sigset_t *mask = &current->blocked;
 		unsigned long signr = 0;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		
 		if (!signr)
 			break;
diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c	Mon Feb 10 10:39:22 2003
+++ b/arch/sparc64/kernel/signal32.c	Mon Feb 10 10:39:23 2003
@@ -56,7 +56,7 @@
 	/* struct sigcontext32 * */ u32 sig_scptr;
 	int sig_address;
 	struct sigcontext32 sig_context;
-	unsigned extramask[_NSIG_WORDS32 - 1];
+	unsigned extramask[_COMPAT_NSIG_WORDS - 1];
 };
 
 /* 
@@ -69,7 +69,7 @@
 	__siginfo32_t		info;
 	/* __siginfo_fpu32_t * */ u32 fpu_save;
 	unsigned int		insns [2];
-	unsigned		extramask[_NSIG_WORDS32 - 1];
+	unsigned		extramask[_COMPAT_NSIG_WORDS - 1];
 	unsigned		extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
 	/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
 	siginfo_extra_v8plus_t	v8plus;
@@ -80,7 +80,7 @@
 	struct sparc_stackf32	ss;
 	siginfo_t32		info;
 	struct pt_regs32	regs;
-	sigset_t32		mask;
+	compat_sigset_t		mask;
 	/* __siginfo_fpu32_t * */ u32 fpu_save;
 	unsigned int		insns [2];
 	stack_t32		stack;
@@ -139,16 +139,16 @@
  * atomically swap in the new signal mask, and wait for a signal.
  * This is really tricky on the Sparc, watch out...
  */
-asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs)
+asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
 {
 	sigset_t saveset;
 
 	set &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, set);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
@@ -179,7 +179,7 @@
 asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
 {
 	sigset_t oldset, set;
-	sigset_t32 set32;
+	compat_sigset_t set32;
         
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
 	if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
@@ -199,11 +199,11 @@
 	case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
 	}
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	oldset = current->blocked;
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
@@ -256,7 +256,7 @@
 	unsigned int psr;
 	unsigned pc, npc, fpu_save;
 	sigset_t set;
-	unsigned seta[_NSIG_WORDS32];
+	unsigned seta[_COMPAT_NSIG_WORDS];
 	int err, i;
 	
 	regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
@@ -302,7 +302,7 @@
 	if (fpu_save)
 		err |= restore_fpu_state32(regs, &sf->fpu_state);
 	err |= __get_user(seta[0], &sf->info.si_mask);
-	err |= copy_from_user(seta+1, &sf->extramask, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+	err |= copy_from_user(seta+1, &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
 	if (err)
 	    	goto segv;
 	switch (_NSIG_WORDS) {
@@ -312,10 +312,10 @@
 		case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
 	}
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return;
 
 segv:
@@ -327,7 +327,7 @@
 	struct sigcontext32 *scptr;
 	unsigned pc, npc, psr;
 	sigset_t set;
-	unsigned seta[_NSIG_WORDS32];
+	unsigned seta[_COMPAT_NSIG_WORDS];
 	int err;
 
 	synchronize_user_stack();
@@ -349,7 +349,7 @@
 
 	err |= __get_user(seta[0], &scptr->sigc_mask);
 	/* Note that scptr + 1 points to extramask */
-	err |= copy_from_user(seta+1, scptr + 1, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+	err |= copy_from_user(seta+1, scptr + 1, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
 	if (err)
 	    	goto segv;
 	switch (_NSIG_WORDS) {
@@ -359,10 +359,10 @@
 		case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
 	}
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (test_thread_flag(TIF_32BIT)) {
 		pc &= 0xffffffff;
@@ -393,7 +393,7 @@
 	unsigned pc, npc, fpu_save;
 	mm_segment_t old_fs;
 	sigset_t set;
-	sigset_t32 seta;
+	compat_sigset_t seta;
 	stack_t st;
 	int err, i;
 	
@@ -440,7 +440,7 @@
 	err |= __get_user(fpu_save, &sf->fpu_save);
 	if (fpu_save)
 		err |= restore_fpu_state32(regs, &sf->fpu_state);
-	err |= copy_from_user(&seta, &sf->mask, sizeof(sigset_t32));
+	err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
 	err |= __get_user((long)st.ss_sp, &sf->stack.ss_sp);
 	err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
 	err |= __get_user(st.ss_size, &sf->stack.ss_size);
@@ -461,10 +461,10 @@
 		case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
 	}
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return;
 segv:
 	do_exit(SIGSEGV);
@@ -498,7 +498,7 @@
 {
 	struct signal_sframe32 *sframep;
 	struct sigcontext32 *sc;
-	unsigned seta[_NSIG_WORDS32];
+	unsigned seta[_COMPAT_NSIG_WORDS];
 	int err = 0;
 	void *sig_address;
 	int sig_code;
@@ -544,7 +544,7 @@
 	}
 	err |= __put_user(seta[0], &sc->sigc_mask);
 	err |= __copy_to_user(sframep->extramask, seta + 1,
-			      (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
 	err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
 	err |= __put_user(pc, &sc->sigc_pc);
 	err |= __put_user(npc, &sc->sigc_npc);
@@ -673,7 +673,7 @@
 	int sigframe_size;
 	u32 psr;
 	int i, err;
-	unsigned seta[_NSIG_WORDS32];
+	unsigned seta[_COMPAT_NSIG_WORDS];
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
@@ -729,7 +729,7 @@
 	}
 	err |= __put_user(seta[0], &sf->info.si_mask);
 	err |= __copy_to_user(sf->extramask, seta + 1,
-			      (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+			      (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
 
 	err |= copy_in_user((u32 *)sf,
 			    (u32 *)(regs->u_regs[UREG_FP]),
@@ -1059,10 +1059,10 @@
 	set_fs(old_fs);
 	
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	regs->tpc = pc;
 	regs->tnpc = npc | 1;
 	if (test_thread_flag(TIF_32BIT)) {
@@ -1098,7 +1098,7 @@
 	int sigframe_size;
 	u32 psr;
 	int i, err;
-	sigset_t32 seta;
+	compat_sigset_t seta;
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
@@ -1160,7 +1160,7 @@
 	case 1: seta.sig[1] = (oldset->sig[0] >> 32);
 		seta.sig[0] = oldset->sig[0];
 	}
-	err |= __copy_to_user(&sf->mask, &seta, sizeof(sigset_t32));
+	err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
 
 	err |= copy_in_user((u32 *)sf,
 			    (u32 *)(regs->u_regs[UREG_FP]),
@@ -1241,11 +1241,11 @@
 	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
 	if (!(ka->sa.sa_flags & SA_NOMASK)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,signr);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
@@ -1288,9 +1288,9 @@
 		sigset_t *mask = &current->blocked;
 		unsigned long signr = 0;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		
 		if (!signr)
 			break;
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Mon Feb 10 10:39:29 2003
+++ b/arch/sparc64/kernel/sys_sparc32.c	Mon Feb 10 10:39:29 2003
@@ -1681,7 +1681,7 @@
 
 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
 
-asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
+asmlinkage int sys32_sigprocmask(int how, compat_old_sigset_t *set, compat_old_sigset_t *oset)
 {
 	old_sigset_t s;
 	int ret;
@@ -1698,15 +1698,15 @@
 
 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, compat_size_t sigsetsize)
+asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset_t32 s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
 	if (set) {
-		if (copy_from_user (&s32, set, sizeof(sigset_t32)))
+		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
 			return -EFAULT;
 		switch (_NSIG_WORDS) {
 		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -1726,7 +1726,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
+		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return 0;
@@ -1734,7 +1734,7 @@
 
 extern asmlinkage int sys_sigpending(old_sigset_t *set);
 
-asmlinkage int sys32_sigpending(old_sigset_t32 *set)
+asmlinkage int sys32_sigpending(compat_old_sigset_t *set)
 {
 	old_sigset_t s;
 	int ret;
@@ -1749,10 +1749,10 @@
 
 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigpending(sigset_t32 *set, compat_size_t sigsetsize)
+asmlinkage int sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset_t32 s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 		
@@ -1766,19 +1766,19 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (set, &s32, sizeof(sigset_t32)))
+		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return ret;
 }
 
 asmlinkage int
-sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
+sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
 		      struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	int ret, sig;
 	sigset_t these;
-	sigset_t32 these32;
+	compat_sigset_t these32;
 	struct timespec ts;
 	siginfo_t info;
 	long timeout = 0;
@@ -1787,7 +1787,7 @@
 	if (sigsetsize != sizeof(sigset_t))
 		return -EINVAL;
 
-	if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
+	if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
 		return -EFAULT;
 
 	switch (_NSIG_WORDS) {
@@ -1812,7 +1812,7 @@
 			return -EINVAL;
 	}
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sig = dequeue_signal(&these, &info);
 	if (!sig) {
 		timeout = MAX_SCHEDULE_TIMEOUT;
@@ -1827,19 +1827,19 @@
 			current->real_blocked = current->blocked;
 			sigandsets(&current->blocked, &current->blocked, &these);
 			recalc_sigpending();
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 
 			current->state = TASK_INTERRUPTIBLE;
 			timeout = schedule_timeout(timeout);
 
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			sig = dequeue_signal(&these, &info);
 			current->blocked = current->real_blocked;
 			siginitset(&current->real_blocked, 0);
 			recalc_sigpending();
 		}
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (sig) {
 		ret = sig;
@@ -2718,7 +2718,7 @@
 	}
 
         if (act) {
-		old_sigset_t32 mask;
+		compat_old_sigset_t mask;
 		
 		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
 		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
@@ -2748,10 +2748,10 @@
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
-	sigset_t32 set32;
+	compat_sigset_t set32;
 
         /* XXX: Don't preclude handling different sized sigset_t's.  */
-        if (sigsetsize != sizeof(sigset_t32))
+        if (sigsetsize != sizeof(compat_sigset_t))
                 return -EINVAL;
 
 	/* All tasks which use RT signals (effectively) use
@@ -2762,7 +2762,7 @@
         if (act) {
 		new_ka.ka_restorer = restorer;
 		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
-		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
+		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
 		switch (_NSIG_WORDS) {
 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
 		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
@@ -2785,7 +2785,7 @@
 		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
 		}
 		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
-		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
+		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
 		if (ret)
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	Mon Feb 10 10:39:29 2003
+++ b/arch/sparc64/kernel/sys_sunos32.c	Mon Feb 10 10:39:29 2003
@@ -238,11 +238,11 @@
 {
 	u32 old;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	old = (u32) current->blocked.sig[0];
 	current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return old;
 }
 
@@ -250,11 +250,11 @@
 {
 	u32 retval;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	retval = (u32) current->blocked.sig[0];
 	current->blocked.sig[0] = (newmask & _BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return retval;
 }
 
@@ -1297,7 +1297,7 @@
 	int ret;
 
 	if (act) {
-		old_sigset_t32 mask;
+		compat_old_sigset_t mask;
 
 		if (get_user((long)new_ka.sa.sa_handler, &((struct old_sigaction32 *)A(act))->sa_handler) ||
 		    __get_user(new_ka.sa.sa_flags, &((struct old_sigaction32 *)A(act))->sa_flags))
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	Mon Feb 10 10:39:26 2003
+++ b/arch/sparc64/kernel/systbls.S	Mon Feb 10 10:39:26 2003
@@ -65,9 +65,6 @@
 	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
 /*220*/	.word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
-
-	/* 234 and 235 were for the hugetlb syscalls.  They can be reused */
-
 /*230*/	.word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall
 	.word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Mon Feb 10 10:39:27 2003
+++ b/arch/sparc64/kernel/time.c	Mon Feb 10 10:39:27 2003
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -37,8 +38,6 @@
 #include <asm/isa.h>
 #include <asm/starfire.h>
 
-extern rwlock_t xtime_lock;
-
 spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 unsigned long mstk48t02_regs = 0UL;
@@ -134,7 +133,7 @@
 {
 	unsigned long ticks, pstate;
 
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 
 	do {
 #ifndef CONFIG_SMP
@@ -196,13 +195,13 @@
 
 	timer_check_rtc();
 
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 #ifdef CONFIG_SMP
 void timer_tick_interrupt(struct pt_regs *regs)
 {
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 
 	do_timer(regs);
 
@@ -225,7 +224,7 @@
 
 	timer_check_rtc();
 
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 #endif
 
@@ -665,7 +664,7 @@
 	if (this_is_starfire)
 		return;
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
@@ -686,7 +685,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /* Ok, my cute asm atomicity trick doesn't work anymore.
@@ -696,18 +695,20 @@
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
+	unsigned long seq;
 	unsigned long usec, sec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	usec = do_gettimeoffset();
-	{
-		unsigned long lost = jiffies - wall_jiffies;
-		if (lost)
-			usec += lost * (1000000 / HZ);
-	}
-	sec = xtime.tv_sec;
-	usec += (xtime.tv_nsec / 1000);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = do_gettimeoffset();
+		{
+			unsigned long lost = jiffies - wall_jiffies;
+			if (lost)
+				usec += lost * (1000000 / HZ);
+		}
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
diff -Nru a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
--- a/arch/sparc64/kernel/winfixup.S	Mon Feb 10 10:39:27 2003
+++ b/arch/sparc64/kernel/winfixup.S	Mon Feb 10 10:39:27 2003
@@ -60,7 +60,7 @@
 	sll		%g2, 3, %g2			! NORMAL-->OTHER
 
 	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.
-	wrpr		%g2, 0x0, %wstate		! This must be consistant.
+	wrpr		%g2, 0x0, %wstate		! This must be consistent.
 	wrpr		%g0, 0x0, %otherwin		! We know this.
 	mov		PRIMARY_CONTEXT, %g1		! Change contexts...
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
@@ -181,7 +181,7 @@
 	sll		%g2, 3, %g2			! NORMAL-->OTHER
 	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.
 
-	wrpr		%g2, 0x0, %wstate		! This must be consistant.
+	wrpr		%g2, 0x0, %wstate		! This must be consistent.
 	wrpr		%g0, 0x0, %otherwin		! We know this.
 	mov		PRIMARY_CONTEXT, %g1		! Change contexts...
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
@@ -287,7 +287,7 @@
 	sll		%g2, 3, %g2			! NORMAL-->OTHER
 	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.
 
-	wrpr		%g2, 0x0, %wstate		! This must be consistant.
+	wrpr		%g2, 0x0, %wstate		! This must be consistent.
 	wrpr		%g0, 0x0, %otherwin		! We know this.
 	mov		PRIMARY_CONTEXT, %g1		! Change contexts...
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
diff -Nru a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c
--- a/arch/sparc64/math-emu/math.c	Mon Feb 10 10:39:29 2003
+++ b/arch/sparc64/math-emu/math.c	Mon Feb 10 10:39:29 2003
@@ -88,7 +88,7 @@
 #define FSR_CEXC_MASK	(0x1fUL << FSR_CEXC_SHIFT)
 
 /* All routines returning an exception to raise should detect
- * such exceptions _before_ rounding to be consistant with
+ * such exceptions _before_ rounding to be consistent with
  * the behavior of the hardware in the implemented cases
  * (and thus with the recommendations in the V9 architecture
  * manual).
diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c	Mon Feb 10 10:39:29 2003
+++ b/arch/sparc64/mm/hugetlbpage.c	Mon Feb 10 10:39:29 2003
@@ -288,6 +288,7 @@
 		page = pte_page(pte);
 		if (pages) {
 			page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
+			get_page(page);
 			pages[i] = page;
 		}
 		if (vmas)
@@ -584,11 +585,6 @@
 			page = alloc_pages(GFP_ATOMIC, HUGETLB_PAGE_ORDER);
 			if (page == NULL)
 				break;
-			map = page;
-			for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-				SetPageReserved(map);
-				map++;
-			}
 			spin_lock(&htlbpage_lock);
 			list_add(&page->list, &htlbpage_freelist);
 			htlbpagemem++;
@@ -613,7 +609,6 @@
 			map->flags &= ~(1UL << PG_locked | 1UL << PG_error |
 					1UL << PG_referenced |
 					1UL << PG_dirty | 1UL << PG_active |
-					1UL << PG_reserved |
 					1UL << PG_private | 1UL << PG_writeback);
 			set_page_count(page, 0);
 			map++;
@@ -624,6 +619,14 @@
 	return (int) htlbzone_pages;
 }
 
+static struct page *
+hugetlb_nopage(struct vm_area_struct *vma, unsigned long address, int unused)
+{
+	BUG();
+	return NULL;
+}
+
 static struct vm_operations_struct hugetlb_vm_ops = {
+	.nopage = hugetlb_nopage,
 	.close	= zap_hugetlb_resources,
 };
diff -Nru a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
--- a/arch/sparc64/solaris/signal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/sparc64/solaris/signal.c	Mon Feb 10 10:39:33 2003
@@ -99,16 +99,16 @@
 static long solaris_sigset(int sig, u32 arg)
 {
 	if (arg != 2) /* HOLD */ {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigdelsetmask(&current->blocked, _S(sig));
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		return sig_handler (sig, arg, 0);
 	} else {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigaddsetmask(&current->blocked, (_S(sig) & ~_BLOCKABLE));
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		return 0;
 	}
 }
@@ -120,10 +120,10 @@
 
 static inline long solaris_sigrelse(int sig)
 {
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigdelsetmask(&current->blocked, _S(sig));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return 0;
 }
 
@@ -311,10 +311,10 @@
 	u32 tmp[4];
 	switch (which) {
 	case 1: /* sigpending */
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigandsets(&s, &current->blocked, &current->pending.signal);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		break;
 	case 2: /* sigfillset - I just set signals which have linux equivalents */
 		sigfillset(&s);
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/arch/um/Kconfig	Mon Feb 10 10:39:27 2003
@@ -30,36 +30,42 @@
 	bool
 	default y
 
+menu "UML-specific options"
+
 config MODE_TT
-	bool
+	bool "Tracing thread support"
 	default y
+	help
+	This option controls whether tracing thread support is compiled
+	into UML.  Normally, this should be set to Y.  If you intend to
+	use only skas mode (and the host has the skas patch applied to it), 
+	then it is OK to say N here.
+
+config STATIC_LINK
+	bool "Force a static link"
+	default n
+	depends on !MODE_TT
+	help
+	If CONFIG_MODE_TT is disabled, then this option gives you the ability
+	to force a static link of UML.  Normally, if only skas mode is built
+	in to UML, it will be linked as a shared binary.  This is inconvenient
+	for use in a chroot jail.  So, if you intend to run UML inside a 
+	chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
+	here.
 
 config MODE_SKAS
-	bool
+	bool "Separate Kernel Address Space support"
 	default y
-
-menu "Code maturity level options"
-
-config EXPERIMENTAL
-	bool "Prompt for development and/or incomplete code/drivers"
-
-endmenu
-
-
-menu "General Setup"
+	help
+	This option controls whether skas (separate kernel address space)
+	support is compiled in.  If you have applied the skas patch to the
+	host, then you certainly want to say Y here (and consider saying N
+	to CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
+	option will shrink the UML binary slightly.
 
 config NET
 	bool "Networking support"
 
-config SYSVIPC
-	bool "System V IPC"
-
-config BSD_PROCESS_ACCT
-	bool "BSD Process Accounting"
-
-config SYSCTL
-	bool "Sysctl support"
-
 config BINFMT_AOUT
 	tristate "Kernel support for a.out binaries"
 
@@ -164,22 +170,18 @@
 config HIGHMEM
 	bool "Highmem support"
 
-endmenu
-
-
-menu "Loadable module support"
-
-config MODULES
-	bool "Enable loadable module support"
-
-# MODVERSIONS does not yet work in this architecture
-#   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-config KMOD
-	bool "Kernel module loader"
-	depends on MODULES
+config KERNEL_STACK_ORDER
+	int "Kernel stack size order"
+	default 2
+	help
+	This option determines the size of UML kernel stacks.  They will
+	be 1 << order pages.  The default is OK unless you're running Valgrind
+	on UML, in which case, set this to 3.
 
 endmenu
 
+source "init/Kconfig"
+
 source "arch/um/Kconfig_char"
 
 source "arch/um/Kconfig_block"
@@ -194,6 +196,10 @@
 
 source "fs/Kconfig"
 
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
 source "lib/Kconfig"
 
 menu "SCSI support"
@@ -221,6 +227,9 @@
 config DEBUG_SLAB
 	bool "Debug memory allocations"
 
+config DEBUG_SPINLOCK
+	bool "Debug spinlocks usage"
+
 config DEBUGSYM
 	bool "Enable kernel debugging symbols"
 	help
@@ -231,6 +240,10 @@
 
         If you're truly short on disk space or don't expect to report any
         bugs back to the UML developers, say N, otherwise say Y.
+
+config FRAME_POINTER
+	bool
+	default y if DEBUGSYM
 
 config PT_PROXY
 	bool "Enable ptrace proxy"
diff -Nru a/arch/um/Makefile b/arch/um/Makefile
--- a/arch/um/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/um/Makefile	Mon Feb 10 10:39:29 2003
@@ -6,9 +6,6 @@
 ARCH_DIR = arch/um
 OS := $(shell uname -s)
 
-EXTRAVERSION := $(EXTRAVERSION)-1um
-include/linux/version.h: arch/$(ARCH)/Makefile
-
 # Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
 # The way the toplevel Makefile is written EXTRAVERSION is not supposed
 # to be changed outside the toplevel Makefile, but recalculating MODLIB is
@@ -21,17 +18,34 @@
 endif
 
 CFLAGS-$(CONFIG_DEBUGSYM) += -g
-CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
-CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
-LINK-$(CONFIG_GPROF) += $(PROFILE) -Wl,--wrap,__monstartup
 
 core-y			+= $(ARCH_DIR)/kernel/		 \
 			   $(ARCH_DIR)/drivers/          \
 			   $(ARCH_DIR)/sys-$(SUBARCH)/
 
+# Have to precede the include because the included Makefiles reference them.
+SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
+	include/asm-um/sigcontext.h include/asm-um/processor.h \
+	include/asm-um/ptrace.h include/asm-um/arch-signal.h
+
+ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
+	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
+
+GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
+
+include $(ARCH_DIR)/Makefile-$(SUBARCH)
+include $(ARCH_DIR)/Makefile-os-$(OS)
+
+MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
+MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+
+ifneq ($(MAKEFILE-y),)
+  include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
+endif
+
+EXTRAVERSION := $(EXTRAVERSION)-1um
+
 ARCH_INCLUDE = -I$(ARCH_DIR)/include
-MODE_INCLUDE = -I$(ARCH_DIR)/kernel/tt/include \
-	-I$(ARCH_DIR)/kernel/skas/include
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
@@ -46,23 +60,11 @@
 
 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
 
-SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
-	include/asm-um/sigcontext.h include/asm-um/processor.h \
-	include/asm-um/ptrace.h include/asm-um/arch-signal.h
-
-ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
-	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
-
 ifeq ($(CONFIG_MODE_SKAS), y)
-GEN_HEADERS = $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
-
 $(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
 endif
 
-GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
-
-include $(ARCH_DIR)/Makefile-$(SUBARCH)
-include $(ARCH_DIR)/Makefile-os-$(OS)
+include/linux/version.h: arch/$(ARCH)/Makefile
 
 $(ARCH_DIR)/vmlinux.lds.S :
 	touch $@
@@ -73,16 +75,46 @@
 
 vmlinux: $(ARCH_DIR)/main.o 
 
-$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S scripts FORCE
-	$(call if_changed_dep,as_s_S)
+# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
+# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
 
-AFLAGS_uml.lds.o = -U$(SUBARCH) -DSTART=$$(($(TOP_ADDR) - $(SIZE))) \
-	-DELF_ARCH=$(ELF_ARCH) -DELF_FORMAT=\"$(ELF_FORMAT)\" -P -C -Uum
+LINK_TT = -static
+LD_SCRIPT_TT := uml.lds.s
 
-linux: $(ARCH_DIR)/uml.lds.s vmlinux
-	$(CC) -Wl,-T,$(ARCH_DIR)/uml.lds.s -static $(LINK-y) $(LINK_WRAPS) \
-		-o linux $(ARCH_DIR)/main.o vmlinux -L/usr/lib -lutil
+ifeq ($(CONFIG_STATIC_LINK),y)
+  LINK-y += $(LINK_TT)
+  LD_SCRIPT-y := $(LD_SCRIPT_TT)
+else
+ifeq ($(CONFIG_MODE_TT),y)
+  LINK-y += $(LINK_TT)
+  LD_SCRIPT-y := $(LD_SCRIPT_TT)
+else
+ifeq ($(CONFIG_MODE_SKAS),y)
+  LINK-y += $(LINK_SKAS)
+  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
+endif
+endif
+endif
+
+CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
+CONFIG_KERNEL_STACK_ORDER ?= 2
+STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
+
+AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
+	-DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
+	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+	-DKERNEL_STACK_SIZE=$(STACK_SIZE)
+
+AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
 
+LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
+
+$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
+	$(call if_changed_dep,as_s_S)
+
+linux: vmlinux $(LD_SCRIPT-y)
+	$(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
+		-o linux $(ARCH_DIR)/main.o vmlinux -L/usr/lib -lutil
 
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
 USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
@@ -92,7 +124,8 @@
 # To get a definition of F_SETSIG
 USER_CFLAGS += -D_GNU_SOURCE
 
-CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS)
+CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
+	$(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
 
 $(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
 	$(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
@@ -102,8 +135,7 @@
 	do \
 		$(MAKE) -C $$d archmrproper; \
 	done
-	rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
-		$(ARCH_DIR)/link.ld \
+	rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
 		$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
 
 archclean: sysclean
@@ -132,7 +164,7 @@
 	cd $(ARCH_DIR) && ln -sf os-$(OS) os
 
 $(ARCH_DIR)/include/uml-config.h :
-	ln -sf $(TOPDIR)/include/linux/autoconf.h $@
+	sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
 
 $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
 	$< > $@
@@ -145,8 +177,5 @@
 
 $(ARCH_DIR)/util: FORCE
 	@$(call descend,$@,)
-
-$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
-	$(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
 
 export SUBARCH USER_CFLAGS OS
diff -Nru a/arch/um/Makefile-skas b/arch/um/Makefile-skas
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/Makefile-skas	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,20 @@
+# 
+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+PROFILE += -pg
+
+CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
+CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
+LINK-$(CONFIG_GPROF) += $(PROFILE)
+
+MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
+
+LINK_SKAS = -Wl,-rpath,/lib 
+LD_SCRIPT_SKAS = dyn.lds.s
+
+GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
+
+$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
+	$(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
diff -Nru a/arch/um/Makefile-tt b/arch/um/Makefile-tt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/Makefile-tt	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,7 @@
+# 
+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
+
diff -Nru a/arch/um/defconfig b/arch/um/defconfig
--- a/arch/um/defconfig	Mon Feb 10 10:39:29 2003
+++ b/arch/um/defconfig	Mon Feb 10 10:39:29 2003
@@ -2,11 +2,11 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_USERMODE=y
-# CONFIG_ISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_PCI is not set
+CONFIG_MMU=y
+CONFIG_SWAP=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_CONFIG_LOG_BUF_SHIFT=14
 
 #
 # Code maturity level options
@@ -16,6 +16,8 @@
 #
 # General Setup
 #
+CONFIG_MODE_TT=y
+CONFIG_MODE_SKAS=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -32,6 +34,8 @@
 CONFIG_NEST_LEVEL=0
 CONFIG_KERNEL_HALF_GIGS=1
 # CONFIG_HIGHMEM is not set
+CONFIG_PROC_MM=y
+CONFIG_KERNEL_STACK_ORDER=2
 
 #
 # Loadable module support
@@ -56,13 +60,9 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_UML_WATCHDOG is not set
 CONFIG_UML_SOUND=y
 CONFIG_SOUND=y
 CONFIG_HOSTAUDIO=y
-# CONFIG_TTY_LOG is not set
 
 #
 # Block Devices
@@ -87,13 +87,14 @@
 CONFIG_UML_NET_DAEMON=y
 CONFIG_UML_NET_MCAST=y
 # CONFIG_UML_NET_PCAP is not set
+CONFIG_UML_NET_SLIRP=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=y
+# CONFIG_ETHERTAP is not set
 CONFIG_PPP=y
 # CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
 # CONFIG_PPP_ASYNC is not set
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
@@ -105,6 +106,10 @@
 # CONFIG_SLIP_MODE_SLIP6 is not set
 
 #
+# Networking support
+#
+
+#
 # Networking options
 #
 CONFIG_PACKET=y
@@ -113,6 +118,7 @@
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER 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
@@ -122,19 +128,19 @@
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_XFRM_USER is not set
 # CONFIG_IPV6 is not set
 
 #
-#    SCTP Configuration (EXPERIMENTAL)
+# SCTP Configuration (EXPERIMENTAL)
 #
 CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_LLC is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -151,6 +157,35 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices (depends on LLC=y)
+#
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
 # File systems
 #
 CONFIG_QUOTA=y
@@ -163,16 +198,14 @@
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=m
 CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 CONFIG_JFFS_FS=y
@@ -186,13 +219,9 @@
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
 CONFIG_MINIX_FS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 CONFIG_DEVFS_FS=y
@@ -200,17 +229,13 @@
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
 # CONFIG_XFS_FS is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
 
 #
 # Network File Systems
@@ -218,36 +243,18 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 # CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
 # CONFIG_EXPORTFS is not set
 # CONFIG_CIFS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
 #
@@ -293,6 +300,21 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+
+#
 # SCSI support
 #
 CONFIG_SCSI=y
@@ -322,13 +344,6 @@
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -337,8 +352,6 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_PARTITIONS is not set
 # CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -353,28 +366,18 @@
 #
 # CONFIG_MTD_CFI is not set
 # CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
 
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_MTDRAM is not set
 CONFIG_MTD_BLKMTD=m
@@ -385,7 +388,6 @@
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
 
 #
 # NAND Flash Device Drivers
@@ -396,7 +398,9 @@
 # Kernel hacking
 #
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUGSYM=y
+CONFIG_FRAME_POINTER=y
 CONFIG_PT_PROXY=y
 # CONFIG_GPROF is not set
 # CONFIG_GCOV is not set
diff -Nru a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
--- a/arch/um/drivers/Makefile	Mon Feb 10 10:39:28 2003
+++ b/arch/um/drivers/Makefile	Mon Feb 10 10:39:28 2003
@@ -20,8 +20,6 @@
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
 
-export-objs := mconsole_kern.o
-
 obj-y = 
 obj-$(CONFIG_SSL) += ssl.o 
 obj-$(CONFIG_UML_NET_SLIP) += slip.o
diff -Nru a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
--- a/arch/um/drivers/chan_kern.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/drivers/chan_kern.c	Mon Feb 10 10:39:33 2003
@@ -75,15 +75,15 @@
 }
 
 static struct chan_ops not_configged_ops = {
-	init:		not_configged_init,
-	open:		not_configged_open,
-	close:		not_configged_close,
-	read:		not_configged_read,
-	write:		not_configged_write,
-	console_write:	not_configged_console_write,
-	window_size:	not_configged_window_size,
-	free:		not_configged_free,
-	winch:		0,
+	.init		= not_configged_init,
+	.open		= not_configged_open,
+	.close		= not_configged_close,
+	.read		= not_configged_read,
+	.write		= not_configged_write,
+	.console_write	= not_configged_console_write,
+	.window_size	= not_configged_window_size,
+	.free		= not_configged_free,
+	.winch		= 0,
 };
 
 static void tty_receive_char(struct tty_struct *tty, char ch)
@@ -395,15 +395,15 @@
 
 	chan = kmalloc(sizeof(*chan), GFP_KERNEL);
 	if(chan == NULL) return(NULL);
-	*chan = ((struct chan) { list :	 	LIST_HEAD_INIT(chan->list),
-				 primary :	1,
-				 input :	0,
-				 output :	0,
-				 opened : 	0,
-				 fd :		-1,
-				 pri :		pri,
-				 ops :		ops,
-				 data :		data });
+	*chan = ((struct chan) { .list	 	= LIST_HEAD_INIT(chan->list),
+				 .primary	= 1,
+				 .input		= 0,
+				 .output 	= 0,
+				 .opened  	= 0,
+				 .fd 		= -1,
+				 .pri 		= pri,
+				 .ops 		= ops,
+				 .data 		= data });
 	return(chan);
 }
 
diff -Nru a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
--- a/arch/um/drivers/chan_user.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/chan_user.c	Mon Feb 10 10:39:23 2003
@@ -159,9 +159,9 @@
 		return(err);
 	}
 
-	data = ((struct winch_data) { pty_fd :		fd,
-				      pipe_fd :		fds[1],
-				      close_me :	fds[0] } );
+	data = ((struct winch_data) { .pty_fd 		= fd,
+				      .pipe_fd 		= fds[1],
+				      .close_me 	= fds[0] } );
 	pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
 	if(pid < 0){
 		printk("fork of winch_thread failed - errno = %d\n", errno);
diff -Nru a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
--- a/arch/um/drivers/daemon_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/daemon_kern.c	Mon Feb 10 10:39:23 2003
@@ -28,14 +28,14 @@
 	pri = dev->priv;
 	dpri = (struct daemon_data *) pri->user;
 	*dpri = ((struct daemon_data)
-		{ sock_type :		init->sock_type,
-		  ctl_sock :		init->ctl_sock,
-		  ctl_addr :		NULL,
-		  data_addr :		NULL,
-		  local_addr :		NULL,
-		  fd :			-1,
-		  control :		-1,
-		  dev :			dev });
+		{ .sock_type 		= init->sock_type,
+		  .ctl_sock 		= init->ctl_sock,
+		  .ctl_addr 		= NULL,
+		  .data_addr 		= NULL,
+		  .local_addr 		= NULL,
+		  .fd 			= -1,
+		  .control 		= -1,
+		  .dev 			= dev });
 
 	printk("daemon backend (uml_switch version %d) - %s:%s", 
 	       SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
@@ -59,10 +59,10 @@
 }
 
 static struct net_kern_info daemon_kern_info = {
-	init:			daemon_init,
-	protocol:		eth_protocol,
-	read:			daemon_read,
-	write:			daemon_write,
+	.init			= daemon_init,
+	.protocol		= eth_protocol,
+	.read			= daemon_read,
+	.write			= daemon_write,
 };
 
 int daemon_setup(char *str, char **mac_out, void *data)
@@ -71,8 +71,8 @@
 	char *remain;
 
 	*init = ((struct daemon_init)
-		{ sock_type :		"unix",
-		  ctl_sock :		"/tmp/uml.ctl" });
+		{ .sock_type 		= "unix",
+		  .ctl_sock 		= "/tmp/uml.ctl" });
 	
 	remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
 			       NULL);
@@ -84,13 +84,13 @@
 }
 
 static struct transport daemon_transport = {
-	list :		LIST_HEAD_INIT(daemon_transport.list),
-	name :		"daemon",
-	setup : 	daemon_setup,
-	user :		&daemon_user_info,
-	kern :		&daemon_kern_info,
-	private_size :	sizeof(struct daemon_data),
-	setup_size :	sizeof(struct daemon_init),
+	.list 		= LIST_HEAD_INIT(daemon_transport.list),
+	.name 		= "daemon",
+	.setup  	= daemon_setup,
+	.user 		= &daemon_user_info,
+	.kern 		= &daemon_kern_info,
+	.private_size 	= sizeof(struct daemon_data),
+	.setup_size 	= sizeof(struct daemon_init),
 };
 
 static int register_daemon(void)
diff -Nru a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
--- a/arch/um/drivers/daemon_user.c	Mon Feb 10 10:39:25 2003
+++ b/arch/um/drivers/daemon_user.c	Mon Feb 10 10:39:25 2003
@@ -7,6 +7,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/time.h>
@@ -24,8 +25,8 @@
 #define SWITCH_MAGIC 0xfeedface
 
 struct request_v3 {
-	unsigned long magic;
-	int version;
+	uint32_t magic;
+	uint32_t version;
 	enum request_type type;
 	struct sockaddr_un sock;
 };
@@ -172,14 +173,14 @@
 }
 
 struct net_user_info daemon_user_info = {
-	init:		daemon_user_init,
-	open:		daemon_open,
-	close:	 	NULL,
-	remove:	 	daemon_remove,
-	set_mtu:	daemon_set_mtu,
-	add_address:	NULL,
-	delete_address: NULL,
-	max_packet:	MAX_PACKET - ETH_HEADER_OTHER
+	.init		= daemon_user_init,
+	.open		= daemon_open,
+	.close	 	= NULL,
+	.remove	 	= daemon_remove,
+	.set_mtu	= daemon_set_mtu,
+	.add_address	= NULL,
+	.delete_address = NULL,
+	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER
 };
 
 /*
diff -Nru a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
--- a/arch/um/drivers/fd.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/drivers/fd.c	Mon Feb 10 10:39:33 2003
@@ -36,8 +36,8 @@
 		return(NULL);
 	}
 	if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
-	*data = ((struct fd_chan) { fd : 	n,
-				    raw : 	opts->raw });
+	*data = ((struct fd_chan) { .fd  	= n,
+				    .raw  	= opts->raw });
 	return(data);
 }
 
@@ -72,16 +72,16 @@
 }
 
 struct chan_ops fd_ops = {
-	type:		"fd",
-	init:		fd_init,
-	open:		fd_open,
-	close:		fd_close,
-	read:		generic_read,
-	write:		generic_write,
-	console_write:	fd_console_write,
-	window_size:	generic_window_size,
-	free:		generic_free,
-	winch:		1,
+	.type		= "fd",
+	.init		= fd_init,
+	.open		= fd_open,
+	.close		= fd_close,
+	.read		= generic_read,
+	.write		= generic_write,
+	.console_write	= fd_console_write,
+	.window_size	= generic_window_size,
+	.free		= generic_free,
+	.winch		= 1,
 };
 
 /*
diff -Nru a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
--- a/arch/um/drivers/harddog_kern.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/drivers/harddog_kern.c	Mon Feb 10 10:39:29 2003
@@ -145,17 +145,17 @@
 }
 
 static struct file_operations harddog_fops = {
-	owner:		THIS_MODULE,
-	write:		harddog_write,
-	ioctl:		harddog_ioctl,
-	open:		harddog_open,
-	release:	harddog_release,
+	.owner		= THIS_MODULE,
+	.write		= harddog_write,
+	.ioctl		= harddog_ioctl,
+	.open		= harddog_open,
+	.release	= harddog_release,
 };
 
 static struct miscdevice harddog_miscdev = {
-	minor:		WATCHDOG_MINOR,
-	name:		"watchdog",
-	fops:		&harddog_fops,
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &harddog_fops,
 };
 
 static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
diff -Nru a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
--- a/arch/um/drivers/harddog_user.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/drivers/harddog_user.c	Mon Feb 10 10:39:24 2003
@@ -11,6 +11,8 @@
 #include "helper.h"
 #include "mconsole.h"
 #include "os.h"
+#include "choose-mode.h"
+#include "mode.h"
 
 struct dog_data {
 	int stdin;
@@ -63,7 +65,8 @@
 		args = mconsole_args;
 	}
 	else {
-		sprintf(pid_buf, "%d", tracing_pid);
+		/* XXX The os_getpid() is not SMP correct */
+		sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
 		args = pid_args;
 	}
 
diff -Nru a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
--- a/arch/um/drivers/hostaudio_kern.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/drivers/hostaudio_kern.c	Mon Feb 10 10:39:33 2003
@@ -195,23 +195,23 @@
 /* kernel module operations */
 
 static struct file_operations hostaudio_fops = {
-        owner:          THIS_MODULE,
-        llseek:         no_llseek,
-        read:           hostaudio_read,
-        write:          hostaudio_write,
-        poll:           hostaudio_poll,
-        ioctl:          hostaudio_ioctl,
-        mmap:           NULL,
-        open:           hostaudio_open,
-        release:        hostaudio_release,
+        .owner          = THIS_MODULE,
+        .llseek         = no_llseek,
+        .read           = hostaudio_read,
+        .write          = hostaudio_write,
+        .poll           = hostaudio_poll,
+        .ioctl          = hostaudio_ioctl,
+        .mmap           = NULL,
+        .open           = hostaudio_open,
+        .release        = hostaudio_release,
 };
 
 static struct file_operations hostmixer_fops = {
-        owner:          THIS_MODULE,
-        llseek:         no_llseek,
-        ioctl:          hostmixer_ioctl_mixdev,
-        open:           hostmixer_open_mixdev,
-        release:        hostmixer_release,
+        .owner          = THIS_MODULE,
+        .llseek         = no_llseek,
+        .ioctl          = hostmixer_ioctl_mixdev,
+        .open           = hostmixer_open_mixdev,
+        .release        = hostmixer_release,
 };
 
 struct {
diff -Nru a/arch/um/drivers/line.c b/arch/um/drivers/line.c
--- a/arch/um/drivers/line.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/drivers/line.c	Mon Feb 10 10:39:31 2003
@@ -35,7 +35,7 @@
 	line_interrupt(dev->driver->read_irq, dev, NULL);
 }
 
-void buffer_data(struct line *line, const char *buf, int len)
+static void buffer_data(struct line *line, const char *buf, int len)
 {
 	int end;
 
@@ -452,11 +452,19 @@
 
 void lines_init(struct line *lines, int nlines)
 {
+	struct line *line;
 	int i;
 
 	for(i = 0; i < nlines; i++){
-		INIT_LIST_HEAD(&lines[i].chan_list);
-		sema_init(&lines[i].sem, 1);
+		line = &lines[i];
+		INIT_LIST_HEAD(&line->chan_list);
+		sema_init(&line->sem, 1);
+		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");
+		}
 	}
 }
 
@@ -511,11 +519,11 @@
 		printk("register_winch_irq - kmalloc failed\n");
 		goto out;
 	}
-	*winch = ((struct winch) { list : 	LIST_HEAD_INIT(winch->list),
-				   fd : 	fd,
-				   tty_fd :	tty_fd,
-				   pid : 	pid,
-				   line :	line });
+	*winch = ((struct winch) { .list  	= LIST_HEAD_INIT(winch->list),
+				   .fd  	= fd,
+				   .tty_fd 	= tty_fd,
+				   .pid  	= pid,
+				   .line 	= line });
 	list_add(&winch->list, &winch_handlers);
 	if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
 			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
@@ -533,7 +541,8 @@
 	list_for_each(ele, &winch_handlers){
 		winch = list_entry(ele, struct winch, list);
 		close(winch->fd);
-		if(winch->pid != -1) os_kill_process(winch->pid, 0);
+		if(winch->pid != -1) 
+			os_kill_process(winch->pid, 1);
 	}
 }
 
diff -Nru a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
--- a/arch/um/drivers/mcast_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/mcast_kern.c	Mon Feb 10 10:39:23 2003
@@ -36,11 +36,11 @@
 	pri = dev->priv;
 	dpri = (struct mcast_data *) pri->user;
 	*dpri = ((struct mcast_data)
-		{ addr :	init->addr,
-		  port :	init->port,
-		  ttl :		init->ttl,
-		  mcast_addr :	NULL,
-		  dev :		dev });
+		{ .addr 	= init->addr,
+		  .port 	= init->port,
+		  .ttl 		= init->ttl,
+		  .mcast_addr 	= NULL,
+		  .dev 		= dev });
 	printk("mcast backend ");
 	printk("multicast adddress: %s:%u, TTL:%u ",
 	       dpri->addr, dpri->port, dpri->ttl);
@@ -64,10 +64,10 @@
 }
 
 static struct net_kern_info mcast_kern_info = {
-	init:			mcast_init,
-	protocol:		eth_protocol,
-	read:			mcast_read,
-	write:			mcast_write,
+	.init			= mcast_init,
+	.protocol		= eth_protocol,
+	.read			= mcast_read,
+	.write			= mcast_write,
 };
 
 int mcast_setup(char *str, char **mac_out, void *data)
@@ -78,9 +78,9 @@
 	int n;
 
 	*init = ((struct mcast_init)
-		{ addr :	"239.192.168.1",
-		  port :	1102,
-		  ttl :		1 });
+		{ .addr 	= "239.192.168.1",
+		  .port 	= 1102,
+		  .ttl 		= 1 });
 
 	remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
 			       NULL);
@@ -116,13 +116,13 @@
 }
 
 static struct transport mcast_transport = {
-	list :		LIST_HEAD_INIT(mcast_transport.list),
-	name :		"mcast",
-	setup : 	mcast_setup,
-	user :		&mcast_user_info,
-	kern :		&mcast_kern_info,
-	private_size :	sizeof(struct mcast_data),
-	setup_size :	sizeof(struct mcast_init),
+	.list 		= LIST_HEAD_INIT(mcast_transport.list),
+	.name 		= "mcast",
+	.setup  	= mcast_setup,
+	.user 		= &mcast_user_info,
+	.kern 		= &mcast_kern_info,
+	.private_size 	= sizeof(struct mcast_data),
+	.setup_size 	= sizeof(struct mcast_init),
 };
 
 static int register_mcast(void)
diff -Nru a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
--- a/arch/um/drivers/mcast_user.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/drivers/mcast_user.c	Mon Feb 10 10:39:27 2003
@@ -153,14 +153,14 @@
 }
 
 struct net_user_info mcast_user_info = {
-	init:		mcast_user_init,
-	open:		mcast_open,
-	close:	 	mcast_close,
-	remove:	 	NULL,
-	set_mtu:	mcast_set_mtu,
-	add_address:	NULL,
-	delete_address: NULL,
-	max_packet:	MAX_PACKET - ETH_HEADER_OTHER
+	.init		= mcast_user_init,
+	.open		= mcast_open,
+	.close	 	= mcast_close,
+	.remove	 	= NULL,
+	.set_mtu	= mcast_set_mtu,
+	.add_address	= NULL,
+	.delete_address = NULL,
+	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER
 };
 
 /*
diff -Nru a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
--- a/arch/um/drivers/mconsole_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/mconsole_kern.c	Mon Feb 10 10:39:23 2003
@@ -36,8 +36,8 @@
 
 
 static struct notifier_block reboot_notifier = {
-	notifier_call:		do_unlink_socket,
-	priority:		0,
+	.notifier_call		= do_unlink_socket,
+	.priority		= 0,
 };
 
 /* Safe without explicit locking for now.  Tasklets provide their own 
@@ -418,9 +418,9 @@
 }
 
 static struct notifier_block panic_exit_notifier = {
-	notifier_call :		notify_panic,
-	next :			NULL,
-	priority :		1
+	.notifier_call 		= notify_panic,
+	.next 			= NULL,
+	.priority 		= 1
 };
 
 static int add_notifier(void)
diff -Nru a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
--- a/arch/um/drivers/mmapper_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/mmapper_kern.c	Mon Feb 10 10:39:23 2003
@@ -106,13 +106,13 @@
 }
 
 static struct file_operations mmapper_fops = {
-	owner:		THIS_MODULE,
-	read:		mmapper_read,
-	write:		mmapper_write,
-	ioctl:		mmapper_ioctl,
-	mmap:		mmapper_mmap,
-	open:		mmapper_open,
-	release:	mmapper_release,
+	.owner		= THIS_MODULE,
+	.read		= mmapper_read,
+	.write		= mmapper_write,
+	.ioctl		= mmapper_ioctl,
+	.mmap		= mmapper_mmap,
+	.open		= mmapper_open,
+	.release	= mmapper_release,
 };
 
 static int __init mmapper_init(void)
diff -Nru a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
--- a/arch/um/drivers/net_kern.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/drivers/net_kern.c	Mon Feb 10 10:39:27 2003
@@ -368,22 +368,22 @@
 	 */
 	save = lp->user[0];
 	*lp = ((struct uml_net_private) 
-		{ list : 		LIST_HEAD_INIT(lp->list),
-		  lock :		SPIN_LOCK_UNLOCKED,
-		  dev :			dev,
-		  fd :			-1,
-		  mac :			{ 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
-		  have_mac :		device->have_mac,
-		  protocol :		transport->kern->protocol,
-		  open :		transport->user->open,
-		  close :		transport->user->close,
-		  remove :		transport->user->remove,
-		  read :		transport->kern->read,
-		  write :		transport->kern->write,
-		  add_address :		transport->user->add_address,
-		  delete_address : 	transport->user->delete_address,
-		  set_mtu :		transport->user->set_mtu,
-		  user : 		{ save } });
+		{ .list  		= LIST_HEAD_INIT(lp->list),
+		  .lock 		= SPIN_LOCK_UNLOCKED,
+		  .dev 			= dev,
+		  .fd 			= -1,
+		  .mac 			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
+		  .have_mac 		= device->have_mac,
+		  .protocol 		= transport->kern->protocol,
+		  .open 		= transport->user->open,
+		  .close 		= transport->user->close,
+		  .remove 		= transport->user->remove,
+		  .read 		= transport->kern->read,
+		  .write 		= transport->kern->write,
+		  .add_address 		= transport->user->add_address,
+		  .delete_address  	= transport->user->delete_address,
+		  .set_mtu 		= transport->user->set_mtu,
+		  .user  		= { save } });
 	init_timer(&lp->tl);
 	lp->tl.function = uml_net_user_timer_expire;
 	memset(&lp->stats, 0, sizeof(lp->stats));
@@ -542,9 +542,9 @@
 		printk("eth_init : alloc_bootmem failed\n");
 		return(1);
 	}
-	*new = ((struct eth_init) { list : 	LIST_HEAD_INIT(new->list),
-				    index : 	n,
-				    init :	str });
+	*new = ((struct eth_init) { .list  	= LIST_HEAD_INIT(new->list),
+				    .index  	= n,
+				    .init 	= str });
 	list_add_tail(&new->list, &eth_cmd_line);
 	return(1);
 }
@@ -618,9 +618,10 @@
 }
 
 static struct mc_device net_mc = {
-	name:		"eth",
-	config:		net_config,
-	remove:		net_remove,
+	.name		= "eth",
+	.config		= net_config,
+	.get_config	= NULL,
+	.remove		= net_remove,
 };
 
 static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
@@ -662,7 +663,7 @@
 }
 
 struct notifier_block uml_inetaddr_notifier = {
-	notifier_call:		uml_inetaddr_event,
+	.notifier_call		= uml_inetaddr_event,
 };
 
 static int uml_net_init(void)
diff -Nru a/arch/um/drivers/null.c b/arch/um/drivers/null.c
--- a/arch/um/drivers/null.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/null.c	Mon Feb 10 10:39:23 2003
@@ -32,16 +32,16 @@
 }
 
 struct chan_ops null_ops = {
-	type:		"null",
-	init:		null_init,
-	open:		null_open,
-	close:		generic_close,
-	read:		null_read,
-	write:		generic_write,
-	console_write:	generic_console_write,
-	window_size:	generic_window_size,
-	free:		null_free,
-	winch:		0,
+	.type		= "null",
+	.init		= null_init,
+	.open		= null_open,
+	.close		= generic_close,
+	.read		= null_read,
+	.write		= generic_write,
+	.console_write	= generic_console_write,
+	.window_size	= generic_window_size,
+	.free		= null_free,
+	.winch		= 0,
 };
 
 /*
diff -Nru a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
--- a/arch/um/drivers/pcap_kern.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/drivers/pcap_kern.c	Mon Feb 10 10:39:33 2003
@@ -27,12 +27,12 @@
 	pri = dev->priv;
 	ppri = (struct pcap_data *) pri->user;
 	*ppri = ((struct pcap_data)
-		{ host_if :	init->host_if,
-		  promisc :	init->promisc,
-		  optimize :	init->optimize,
-		  filter :	init->filter,
-		  compiled :	NULL,
-		  pcap :	NULL });
+		{ .host_if 	= init->host_if,
+		  .promisc 	= init->promisc,
+		  .optimize 	= init->optimize,
+		  .filter 	= init->filter,
+		  .compiled 	= NULL,
+		  .pcap 	= NULL });
 }
 
 static int pcap_read(int fd, struct sk_buff **skb, 
@@ -51,10 +51,10 @@
 }
 
 static struct net_kern_info pcap_kern_info = {
-	init:			pcap_init,
-	protocol:		eth_protocol,
-	read:			pcap_read,
-	write:			pcap_write,
+	.init			= pcap_init,
+	.protocol		= eth_protocol,
+	.read			= pcap_read,
+	.write			= pcap_write,
 };
 
 int pcap_setup(char *str, char **mac_out, void *data)
@@ -64,10 +64,10 @@
 	int i;
 
 	*init = ((struct pcap_init)
-		{ host_if :	"eth0",
-		  promisc :	1,
-		  optimize :	0,
-		  filter :	NULL });
+		{ .host_if 	= "eth0",
+		  .promisc 	= 1,
+		  .optimize 	= 0,
+		  .filter 	= NULL });
 
 	remain = split_if_spec(str, &host_if, &init->filter, 
 			       &options[0], &options[1], NULL);
@@ -98,13 +98,13 @@
 }
 
 static struct transport pcap_transport = {
-	list :		LIST_HEAD_INIT(pcap_transport.list),
-	name :		"pcap",
-	setup : 	pcap_setup,
-	user :		&pcap_user_info,
-	kern :		&pcap_kern_info,
-	private_size :	sizeof(struct pcap_data),
-	setup_size :	sizeof(struct pcap_init),
+	.list 		= LIST_HEAD_INIT(pcap_transport.list),
+	.name 		= "pcap",
+	.setup  	= pcap_setup,
+	.user 		= &pcap_user_info,
+	.kern 		= &pcap_kern_info,
+	.private_size 	= sizeof(struct pcap_data),
+	.setup_size 	= sizeof(struct pcap_init),
 };
 
 static int register_pcap(void)
diff -Nru a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
--- a/arch/um/drivers/pcap_user.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/drivers/pcap_user.c	Mon Feb 10 10:39:31 2003
@@ -106,8 +106,8 @@
 int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
 {
 	struct pcap_handler_data hdata = ((struct pcap_handler_data)
-		                          { buffer : 	buffer,
-					    len :	len });
+		                          { .buffer  	= buffer,
+					    .len 	= len });
 	int n;
 
 	n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
@@ -121,14 +121,14 @@
 }
 
 struct net_user_info pcap_user_info = {
-	init:		pcap_user_init,
-	open:		pcap_open,
-	close:	 	NULL,
-	remove:	 	pcap_remove,
-	set_mtu:	NULL,
-	add_address:	NULL,
-	delete_address: NULL,
-	max_packet:	MAX_PACKET - ETH_HEADER_OTHER
+	.init		= pcap_user_init,
+	.open		= pcap_open,
+	.close	 	= NULL,
+	.remove	 	= pcap_remove,
+	.set_mtu	= NULL,
+	.add_address	= NULL,
+	.delete_address = NULL,
+	.max_packet	= MAX_PACKET - ETH_HEADER_OTHER
 };
 
 /*
diff -Nru a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
--- a/arch/um/drivers/port_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/port_kern.c	Mon Feb 10 10:39:23 2003
@@ -31,7 +31,6 @@
 
 struct port_dev {
 	struct port_list *port;
-	int fd;
 	int helper_pid;
 	int telnetd_pid;
 };
@@ -50,12 +49,13 @@
 	struct connection *conn = data;
 	int fd;
 
-	fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
+ 	fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
 	if(fd < 0){
 		if(fd == -EAGAIN)
 			return;
 
-		printk("os_rcv_fd returned %d\n", -fd);
+		printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
+		       -fd);
 		os_close_file(conn->fd);
 	}
 
@@ -75,37 +75,42 @@
 	fd = port_connection(port->fd, socket, &pid);
 	if(fd < 0){
 		if(fd != -EAGAIN)
-			printk("port_connection returned %d\n", -fd);
+			printk(KERN_ERR "port_accept : port_connection "
+			       "returned %d\n", -fd);
 		goto out;
 	}
 
 	conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
 	if(conn == NULL){
-		printk("port_interrupt : failed to allocate connection\n");
+		printk(KERN_ERR "port_accept : failed to allocate "
+		       "connection\n");
 		goto out_close;
 	}
 	*conn = ((struct connection) 
-		{ list :	LIST_HEAD_INIT(conn->list),
-		  fd :		fd,
-		  socket : 	{ socket[0], socket[1] },
-		  telnetd_pid :	pid,
-		  port :	port });
+		{ .list 	= LIST_HEAD_INIT(conn->list),
+		  .fd 		= fd,
+		  .socket  	= { socket[0], socket[1] },
+		  .telnetd_pid 	= pid,
+		  .port 	= port });
 
 	if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 
 			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			  "telnetd", conn)){
-		printk(KERN_ERR "Failed to get IRQ for telnetd\n");
+		printk(KERN_ERR "port_accept : failed to get IRQ for "
+		       "telnetd\n");
 		goto out_free;
 	}
 
 	list_add(&conn->list, &port->pending);
-	return(1);
+	ret = 1;
+	goto out;
 
  out_free:
 	kfree(conn);
  out_close:
 	os_close_file(fd);
-	if(pid != -1) os_kill_process(pid, 0);
+	if(pid != -1) 
+		os_kill_process(pid, 1);
  out:
 	return(ret);
 } 
@@ -173,14 +178,15 @@
 	}
 
 	*port = ((struct port_list) 
-		{ list :	 	LIST_HEAD_INIT(port->list),
-		  has_connection :	0,
-		  sem :			__SEMAPHORE_INITIALIZER(port->sem, 0),
-		  lock :		SPIN_LOCK_UNLOCKED,
-		  port :	 	port_num,
-		  fd : 			fd,
-		  pending :		LIST_HEAD_INIT(port->pending),
-		  connections :		LIST_HEAD_INIT(port->connections) });
+		{ .list 	 	= LIST_HEAD_INIT(port->list),
+		  .has_connection 	= 0,
+		  .sem 			= __SEMAPHORE_INITIALIZER(port->sem, 
+								  0),
+		  .lock 		= SPIN_LOCK_UNLOCKED,
+		  .port 	 	= port_num,
+		  .fd  			= fd,
+		  .pending 		= LIST_HEAD_INIT(port->pending),
+		  .connections 		= LIST_HEAD_INIT(port->connections) });
 	list_add(&port->list, &ports);
 
  found:
@@ -190,9 +196,9 @@
 		goto out;
 	}
 
-	*dev = ((struct port_dev) { port : 		port,
-				    fd :		-1,
-				    helper_pid : 	-1 });
+	*dev = ((struct port_dev) { .port  		= port,
+				    .helper_pid  	= -1,
+				    .telnetd_pid  	= -1 });
 	goto out;
 
  out_free:
@@ -204,38 +210,16 @@
 	return(dev);
 }
 
-void port_remove_dev(void *d)
-{
-	struct port_dev *dev = d;
-
-  	if(dev->helper_pid != -1)
- 		os_kill_process(dev->helper_pid, 0);
- 	if(dev->telnetd_pid != -1)
- 		os_kill_process(dev->telnetd_pid, 0);
- 	dev->helper_pid = -1;
-}
-
-static void free_port(void)
-{
-	struct list_head *ele;
-	struct port_list *port;
-
-	list_for_each(ele, &ports){
-		port = list_entry(ele, struct port_list, list);
-		os_close_file(port->fd);
-	}
-}
-
-__uml_exitcall(free_port);
-
 int port_wait(void *data)
 {
 	struct port_dev *dev = data;
 	struct connection *conn;
 	struct port_list *port = dev->port;
+	int fd;
 
 	while(1){
-		if(down_interruptible(&port->sem)) return(-ERESTARTSYS);
+		if(down_interruptible(&port->sem))
+			return(-ERESTARTSYS);
 
 		spin_lock(&port->lock);
 
@@ -262,22 +246,47 @@
 		kfree(conn);
 	}
 
-	dev->fd = conn->fd;
+	fd = conn->fd;
 	dev->helper_pid = conn->helper_pid;
 	dev->telnetd_pid = conn->telnetd_pid;
 	kfree(conn);
 
-	return(dev->fd);
+	return(fd);
+}
+
+void port_remove_dev(void *d)
+{
+	struct port_dev *dev = d;
+
+	if(dev->helper_pid != -1)
+		os_kill_process(dev->helper_pid, 0);
+	if(dev->telnetd_pid != -1)
+		os_kill_process(dev->telnetd_pid, 1);
+	dev->helper_pid = -1;
+	dev->telnetd_pid = -1;
 }
 
 void port_kern_free(void *d)
 {
 	struct port_dev *dev = d;
 
- 	if(dev->helper_pid != -1) os_kill_process(dev->helper_pid, 0);
- 	if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 0);
+	port_remove_dev(dev);
 	kfree(dev);
 }
+
+static void free_port(void)
+{
+	struct list_head *ele;
+	struct port_list *port;
+
+	list_for_each(ele, &ports){
+		port = list_entry(ele, struct port_list, list);
+		free_irq_by_fd(port->fd);
+		os_close_file(port->fd);
+	}
+}
+
+__uml_exitcall(free_port);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
--- a/arch/um/drivers/port_user.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/drivers/port_user.c	Mon Feb 10 10:39:29 2003
@@ -47,14 +47,28 @@
 		return(NULL);
 	}
 
-	if((kern_data = port_data(port)) == NULL) return(NULL);
+	if((kern_data = port_data(port)) == NULL) 
+		return(NULL);
 
-	if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
-	*data = ((struct port_chan) { raw : 		opts->raw,
-				      kernel_data :	kern_data });
+	if((data = um_kmalloc(sizeof(*data))) == NULL) 
+		goto err;
+
+	*data = ((struct port_chan) { .raw  		= opts->raw,
+				      .kernel_data 	= kern_data });
 	sprintf(data->dev, "%d", port);
-	
+
 	return(data);
+ err:
+	port_kern_free(kern_data);
+	return(NULL);
+}
+
+void port_free(void *d)
+{
+	struct port_chan *data = d;
+
+	port_kern_free(data->kernel_data);
+	kfree(data);
 }
 
 int port_open(int input, int output, int primary, void *d, char **dev_out)
@@ -86,25 +100,17 @@
 	return(generic_console_write(fd, buf, n, &data->tt));
 }
 
-void port_free(void *d)
-{
-	struct port_chan *data = d;
-
-	port_kern_free(data->kernel_data);
-	kfree(data);
-}
-
 struct chan_ops port_ops = {
-	type:		"port",
-	init:		port_init,
-	open:		port_open,
-	close:		port_close,
-	read:	        generic_read,
-	write:		generic_write,
-	console_write:	port_console_write,
-	window_size:	generic_window_size,
-	free:		port_free,
-	winch:		1,
+	.type		= "port",
+	.init		= port_init,
+	.open		= port_open,
+	.close		= port_close,
+	.read	        = generic_read,
+	.write		= generic_write,
+	.console_write	= port_console_write,
+	.window_size	= generic_window_size,
+	.free		= port_free,
+	.winch		= 1,
 };
 
 int port_listen_fd(int port)
@@ -113,7 +119,8 @@
 	int fd, err;
 
 	fd = socket(PF_INET, SOCK_STREAM, 0);
-	if(fd == -1) return(-errno);
+	if(fd == -1) 
+		return(-errno);
 
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(port);
@@ -163,14 +170,16 @@
 		return(-errno);
 
 	err = os_pipe(socket, 0, 0);
-	if(err) goto out_close;
+	if(err) 
+		goto out_close;
 
 	data = ((struct port_pre_exec_data)
-		{ sock_fd : 		new,
-		  pipe_fd :		socket[1] });
+		{ .sock_fd  		= new,
+		  .pipe_fd 		= socket[1] });
 
 	err = run_helper(port_pre_exec, &data, argv, NULL);
-	if(err < 0) goto out_shutdown;
+	if(err < 0) 
+		goto out_shutdown;
 
 	*pid_out = err;
 	return(new);
diff -Nru a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
--- a/arch/um/drivers/pty.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/drivers/pty.c	Mon Feb 10 10:39:31 2003
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 
@@ -27,9 +27,9 @@
 	struct pty_chan *data;
 
 	if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
-	*data = ((struct pty_chan) { announce : 	opts->announce, 
-				     dev : 		device,
-				     raw : 		opts->raw });
+	*data = ((struct pty_chan) { .announce  	= opts->announce, 
+				     .dev  		= device,
+				     .raw  		= opts->raw });
 	return(data);
 }
 
@@ -86,34 +86,15 @@
 	return(-1);
 }
 
-struct grantpt_info {
-	int fd;
-	int res;
-	int err;
-};
-
-static void grantpt_cb(void *arg)
-{
-	struct grantpt_info *info = arg;
-
-	info->res = grantpt(info->fd);
-	info->err = errno;
-}
-
 int pty_open(int input, int output, int primary, void *d, char **dev_out)
 {
 	struct pty_chan *data = d;
 	int fd;
 	char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
-	struct grantpt_info info;
 
 	fd = getmaster(dev);
 	if(fd < 0) return(-errno);
 	
-	info.fd = fd;
-	initial_thread_cb(grantpt_cb, &info);
-	unlockpt(fd);
-
 	if(data->raw) raw(fd, 0);
 	if(data->announce) (*data->announce)(dev, data->dev);
 
@@ -130,29 +111,29 @@
 }
 
 struct chan_ops pty_ops = {
-	type:		"pty",
-	init:		pty_chan_init,
-	open:		pty_open,
-	close:		generic_close,
-	read:		generic_read,
-	write:		generic_write,
-	console_write:	pty_console_write,
-	window_size:	generic_window_size,
-	free:		generic_free,
-	winch:		0,
+	.type		= "pty",
+	.init		= pty_chan_init,
+	.open		= pty_open,
+	.close		= generic_close,
+	.read		= generic_read,
+	.write		= generic_write,
+	.console_write	= pty_console_write,
+	.window_size	= generic_window_size,
+	.free		= generic_free,
+	.winch		= 0,
 };
 
 struct chan_ops pts_ops = {
-	type:		"pts",
-	init:		pty_chan_init,
-	open:		pts_open,
-	close:		generic_close,
-	read:		generic_read,
-	write:		generic_write,
-	console_write:	pty_console_write,
-	window_size:	generic_window_size,
-	free:		generic_free,
-	winch:		0,
+	.type		= "pts",
+	.init		= pty_chan_init,
+	.open		= pts_open,
+	.close		= generic_close,
+	.read		= generic_read,
+	.write		= generic_write,
+	.console_write	= pty_console_write,
+	.window_size	= generic_window_size,
+	.free		= generic_free,
+	.winch		= 0,
 };
 
 /*
diff -Nru a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
--- a/arch/um/drivers/slip_kern.c	Mon Feb 10 10:39:25 2003
+++ b/arch/um/drivers/slip_kern.c	Mon Feb 10 10:39:25 2003
@@ -22,15 +22,15 @@
 	private = dev->priv;
 	spri = (struct slip_data *) private->user;
 	*spri = ((struct slip_data)
-		{ name :	{ '\0' },
-		  addr:		NULL,
-		  gate_addr :	init->gate_addr,
-		  slave : 	-1,
-		  ibuf : 	{ '\0' },
-		  obuf : 	{ '\0' },
-		  pos :		0,
-		  esc :		0,
-		  dev :		dev });
+		{ .name 	= { '\0' },
+		  .addr		= NULL,
+		  .gate_addr 	= init->gate_addr,
+		  .slave  	= -1,
+		  .ibuf  	= { '\0' },
+		  .obuf  	= { '\0' },
+		  .pos 		= 0,
+		  .esc 		= 0,
+		  .dev 		= dev });
 
 	dev->init = NULL;
 	dev->hard_header_len = 0;
@@ -61,10 +61,10 @@
 }
 
 struct net_kern_info slip_kern_info = {
-	init:			slip_init,
-	protocol:		slip_protocol,
-	read:			slip_read,
-	write:			slip_write,
+	.init			= slip_init,
+	.protocol		= slip_protocol,
+	.read			= slip_read,
+	.write			= slip_write,
 };
 
 static int slip_setup(char *str, char **mac_out, void *data)
@@ -72,7 +72,7 @@
 	struct slip_init *init = data;
 
 	*init = ((struct slip_init)
-		{ gate_addr :		NULL });
+		{ .gate_addr 		= NULL });
 
 	if(str[0] != '\0') 
 		init->gate_addr = str;
@@ -80,13 +80,13 @@
 }
 
 static struct transport slip_transport = {
-	list :		LIST_HEAD_INIT(slip_transport.list),
-	name :		"slip",
-	setup : 	slip_setup,
-	user :		&slip_user_info,
-	kern :		&slip_kern_info,
-	private_size :	sizeof(struct slip_data),
-	setup_size :	sizeof(struct slip_init),
+	.list 		= LIST_HEAD_INIT(slip_transport.list),
+	.name 		= "slip",
+	.setup  	= slip_setup,
+	.user 		= &slip_user_info,
+	.kern 		= &slip_kern_info,
+	.private_size 	= sizeof(struct slip_data),
+	.setup_size 	= sizeof(struct slip_init),
 };
 
 static int register_slip(void)
diff -Nru a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
--- a/arch/um/drivers/slip_user.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/drivers/slip_user.c	Mon Feb 10 10:39:31 2003
@@ -257,14 +257,14 @@
 }
 
 struct net_user_info slip_user_info = {
-	init:		slip_user_init,
-	open:		slip_open,
-	close:	 	slip_close,
-	remove:	 	NULL,
-	set_mtu:	slip_set_mtu,
-	add_address:	slip_add_addr,
-	delete_address: slip_del_addr,
-	max_packet:	BUF_SIZE
+	.init		= slip_user_init,
+	.open		= slip_open,
+	.close	 	= slip_close,
+	.remove	 	= NULL,
+	.set_mtu	= slip_set_mtu,
+	.add_address	= slip_add_addr,
+	.delete_address = slip_del_addr,
+	.max_packet	= BUF_SIZE
 };
 
 /*
diff -Nru a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
--- a/arch/um/drivers/slirp_kern.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/drivers/slirp_kern.c	Mon Feb 10 10:39:33 2003
@@ -22,14 +22,14 @@
 	private = dev->priv;
 	spri = (struct slirp_data *) private->user;
 	*spri = ((struct slirp_data)
-		{ argw :	init->argw,
-		  pid : 	-1,
-		  slave : 	-1,
-		  ibuf : 	{ '\0' },
-		  obuf : 	{ '\0' },
-		  pos :		0,
-		  esc :		0,
-		  dev :		dev });
+		{ .argw 	= init->argw,
+		  .pid  	= -1,
+		  .slave  	= -1,
+		  .ibuf  	= { '\0' },
+		  .obuf  	= { '\0' },
+		  .pos 		= 0,
+		  .esc 		= 0,
+		  .dev 		= dev });
 
 	dev->init = NULL;
 	dev->hard_header_len = 0;
@@ -64,10 +64,10 @@
 }
 
 struct net_kern_info slirp_kern_info = {
-	init:			slirp_init,
-	protocol:		slirp_protocol,
-	read:			slirp_read,
-	write:			slirp_write,
+	.init			= slirp_init,
+	.protocol		= slirp_protocol,
+	.read			= slirp_read,
+	.write			= slirp_write,
 };
 
 static int slirp_setup(char *str, char **mac_out, void *data)
@@ -103,13 +103,13 @@
 }
 
 static struct transport slirp_transport = {
-	list :		LIST_HEAD_INIT(slirp_transport.list),
-	name :		"slirp",
-	setup : 	slirp_setup,
-	user :		&slirp_user_info,
-	kern :		&slirp_kern_info,
-	private_size :	sizeof(struct slirp_data),
-	setup_size :	sizeof(struct slirp_init),
+	.list 		= LIST_HEAD_INIT(slirp_transport.list),
+	.name 		= "slirp",
+	.setup  	= slirp_setup,
+	.user 		= &slirp_user_info,
+	.kern 		= &slirp_kern_info,
+	.private_size 	= sizeof(struct slirp_data),
+	.setup_size 	= sizeof(struct slirp_init),
 };
 
 static int register_slirp(void)
diff -Nru a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
--- a/arch/um/drivers/slirp_user.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/slirp_user.c	Mon Feb 10 10:39:23 2003
@@ -180,14 +180,14 @@
 }
 
 struct net_user_info slirp_user_info = {
-	init:		slirp_user_init,
-	open:		slirp_open,
-	close:	 	slirp_close,
-	remove:	 	NULL,
-	set_mtu:	slirp_set_mtu,
-	add_address:	NULL,
-	delete_address: NULL,
-	max_packet:	BUF_SIZE
+	.init		= slirp_user_init,
+	.open		= slirp_open,
+	.close	 	= slirp_close,
+	.remove	 	= NULL,
+	.set_mtu	= slirp_set_mtu,
+	.add_address	= NULL,
+	.delete_address = NULL,
+	.max_packet	= BUF_SIZE
 };
 
 /*
diff -Nru a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
--- a/arch/um/drivers/ssl.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/drivers/ssl.c	Mon Feb 10 10:39:27 2003
@@ -41,11 +41,11 @@
 }
 
 static struct chan_opts opts = {
-	announce: 	ssl_announce,
-	xterm_title:	"Serial Line #%d",
-	raw:		1,
-	tramp_stack :	0,
-	in_kernel :	1,
+	.announce 	= ssl_announce,
+	.xterm_title	= "Serial Line #%d",
+	.raw		= 1,
+	.tramp_stack 	= 0,
+	.in_kernel 	= 1,
 };
 
 static int ssl_config(char *str);
@@ -53,23 +53,23 @@
 static int ssl_remove(char *str);
 
 static struct line_driver driver = {
-	name :			"UML serial line",
-	devfs_name :		"tts/%d",
-	major :			TTYAUX_MAJOR,
-	minor_start :		64,
-	type :		 	TTY_DRIVER_TYPE_SERIAL,
-	subtype :	 	0,
-	read_irq :		SSL_IRQ,
-	read_irq_name :		"ssl",
-	write_irq :		SSL_WRITE_IRQ,
-	write_irq_name :	"ssl-write",
-	symlink_from :		"serial",
-	symlink_to :		"tts",
-	mc : {
-		name : 		"ssl",
-		config :	ssl_config,
-		get_config :	ssl_get_config,
-		remove :	ssl_remove,
+	.name 			= "UML serial line",
+	.devfs_name 		= "tts/%d",
+	.major 			= TTYAUX_MAJOR,
+	.minor_start 		= 64,
+	.type 		 	= TTY_DRIVER_TYPE_SERIAL,
+	.subtype 	 	= 0,
+	.read_irq 		= SSL_IRQ,
+	.read_irq_name 		= "ssl",
+	.write_irq 		= SSL_WRITE_IRQ,
+	.write_irq_name 	= "ssl-write",
+	.symlink_from 		= "serial",
+	.symlink_to 		= "tts",
+	.mc  = {
+		.name  		= "ssl",
+		.config 	= ssl_config,
+		.get_config 	= ssl_get_config,
+		.remove 	= ssl_remove,
 	},
 };
 
@@ -191,21 +191,21 @@
 }
 
 static struct tty_driver ssl_driver = {
-	refcount :		&ssl_refcount,
-	open :	 		ssl_open,
-	close :	 		ssl_close,
-	write :	 		ssl_write,
-	put_char :		ssl_put_char,
-	flush_chars :		ssl_flush_chars,
-	chars_in_buffer :	ssl_chars_in_buffer,
-	flush_buffer :		ssl_flush_buffer,
-	ioctl :	 		ssl_ioctl,
-	throttle :		ssl_throttle,
-	unthrottle :		ssl_unthrottle,
-	set_termios :		ssl_set_termios,
-	stop :	 		ssl_stop,
-	start :	 		ssl_start,
-	hangup :	 	ssl_hangup
+	.refcount 		= &ssl_refcount,
+	.open 	 		= ssl_open,
+	.close 	 		= ssl_close,
+	.write 	 		= ssl_write,
+	.put_char 		= ssl_put_char,
+	.flush_chars 		= ssl_flush_chars,
+	.chars_in_buffer 	= ssl_chars_in_buffer,
+	.flush_buffer 		= ssl_flush_buffer,
+	.ioctl 	 		= ssl_ioctl,
+	.throttle 		= ssl_throttle,
+	.unthrottle 		= ssl_unthrottle,
+	.set_termios 		= ssl_set_termios,
+	.stop 	 		= ssl_stop,
+	.start 	 		= ssl_start,
+	.hangup 	 	= ssl_hangup
 };
 
 /* Changed by ssl_init and referenced by ssl_exit, which are both serialized
diff -Nru a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
--- a/arch/um/drivers/stdio_console.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/drivers/stdio_console.c	Mon Feb 10 10:39:24 2003
@@ -42,28 +42,28 @@
 static int console_refcount = 0;
 
 static struct chan_ops init_console_ops = {
-	type:		"you shouldn't see this",
-	init : 		NULL,
-	open : 		NULL,
-	close :		NULL,
-	read : 		NULL,
-	write :		NULL,
-	console_write :	generic_write,
-	window_size :	NULL,
-	free : 		NULL,
-	winch:		0,
+	.type		= "you shouldn't see this",
+	.init  		= NULL,
+	.open  		= NULL,
+	.close 		= NULL,
+	.read  		= NULL,
+	.write 		= NULL,
+	.console_write 	= generic_write,
+	.window_size 	= NULL,
+	.free  		= NULL,
+	.winch		= 0,
 };
 
 static struct chan init_console_chan = {
-	list : 		{ },
-	primary :	1,
-	input :		0,
-	output :	1,
-	opened :	1,
-	fd :		1,
-	pri :		INIT_STATIC,
-	ops :		&init_console_ops,
-	data :		NULL
+	.list  		= { },
+	.primary 	= 1,
+	.input 		= 0,
+	.output 	= 1,
+	.opened 	= 1,
+	.fd 		= 1,
+	.pri 		= INIT_STATIC,
+	.ops 		= &init_console_ops,
+	.data 		= NULL
 };
 
 void stdio_announce(char *dev_name, int dev)
@@ -73,11 +73,11 @@
 }
 
 static struct chan_opts opts = {
-	announce: 	stdio_announce,
-	xterm_title:	"Virtual Console #%d",
-	raw:		1,
-	tramp_stack :	0,
-	in_kernel :	1,
+	.announce 	= stdio_announce,
+	.xterm_title	= "Virtual Console #%d",
+	.raw		= 1,
+	.tramp_stack 	= 0,
+	.in_kernel 	= 1,
 };
 
 static int con_config(char *str);
@@ -85,23 +85,23 @@
 static int con_remove(char *str);
 
 static struct line_driver driver = {
-	name :			"UML console",
-	devfs_name :		"vc/%d",
-	major :			TTY_MAJOR,
-	minor_start :		0,
-	type :		 	TTY_DRIVER_TYPE_CONSOLE,
-	subtype :	 	SYSTEM_TYPE_CONSOLE,
-	read_irq :		CONSOLE_IRQ,
-	read_irq_name :		"console",
-	write_irq :		CONSOLE_WRITE_IRQ,
-	write_irq_name :	"console-write",
-	symlink_from :		"ttys",
-	symlink_to :		"vc",
-	mc : {
-		name : 		"con",
-		config :	con_config,
-		get_config :	con_get_config,
-		remove :	con_remove,
+	.name 			= "UML console",
+	.devfs_name 		= "vc/%d",
+	.major 			= TTY_MAJOR,
+	.minor_start 		= 0,
+	.type 		 	= TTY_DRIVER_TYPE_CONSOLE,
+	.subtype 	 	= SYSTEM_TYPE_CONSOLE,
+	.read_irq 		= CONSOLE_IRQ,
+	.read_irq_name 		= "console",
+	.write_irq 		= CONSOLE_WRITE_IRQ,
+	.write_irq_name 	= "console-write",
+	.symlink_from 		= "ttys",
+	.symlink_to 		= "vc",
+	.mc  = {
+		.name  		= "con",
+		.config 	= con_config,
+		.get_config 	= con_get_config,
+		.remove 	= con_remove,
 	},
 };
 
@@ -192,12 +192,12 @@
 }
 
 static struct tty_driver console_driver = {
-	refcount :		&console_refcount,
-	open :	 		con_open,
-	close :	 		con_close,
-	write :	 		con_write,
-	chars_in_buffer :	chars_in_buffer,
-	set_termios :		set_termios
+	.refcount 		= &console_refcount,
+	.open 	 		= con_open,
+	.close 	 		= con_close,
+	.write 	 		= con_write,
+	.chars_in_buffer 	= chars_in_buffer,
+	.set_termios 		= set_termios
 };
 
 static kdev_t console_device(struct console *c)
diff -Nru a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
--- a/arch/um/drivers/tty.c	Mon Feb 10 10:39:25 2003
+++ b/arch/um/drivers/tty.c	Mon Feb 10 10:39:25 2003
@@ -32,8 +32,8 @@
 
 	if((data = um_kmalloc(sizeof(*data))) == NULL) 
 		return(NULL);
-	*data = ((struct tty_chan) { dev :	str,
-				     raw :	opts->raw });
+	*data = ((struct tty_chan) { .dev 	= str,
+				     .raw 	= opts->raw });
 				     
 	return(data);
 }
@@ -62,16 +62,16 @@
 }
 
 struct chan_ops tty_ops = {
-	type:		"tty",
-	init:		tty_chan_init,
-	open:		tty_open,
-	close:		generic_close,
-	read:		generic_read,
-	write:		generic_write,
-	console_write:	tty_console_write,
-	window_size:	generic_window_size,
-	free:		generic_free,
-	winch:		0,
+	.type		= "tty",
+	.init		= tty_chan_init,
+	.open		= tty_open,
+	.close		= generic_close,
+	.read		= generic_read,
+	.write		= generic_write,
+	.console_write	= tty_console_write,
+	.window_size	= generic_window_size,
+	.free		= generic_free,
+	.winch		= 0,
 };
 
 /*
diff -Nru a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
--- a/arch/um/drivers/ubd_kern.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/drivers/ubd_kern.c	Mon Feb 10 10:39:27 2003
@@ -77,9 +77,11 @@
 static struct gendisk *fake_gendisk[MAX_DEV];
  
 #ifdef CONFIG_BLK_DEV_UBD_SYNC
-#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0 })
+#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
+					 .cl = 1 })
 #else
-#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0 })
+#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
+					 .cl = 1 })
 #endif
 
 /* Not protected - changed only in ubd_setup_common and then only to
@@ -177,6 +179,8 @@
 	if(proc_ide_root == NULL) make_proc_ide();
 
 	dir = proc_mkdir(dev_name, proc_ide);
+	if(!dir) return;
+
 	ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
 	if(!ent) return;
 	ent->nlink = 1;
@@ -405,7 +409,8 @@
 
 void kill_io_thread(void)
 {
-	if(io_pid != -1) kill(io_pid, SIGKILL);
+	if(io_pid != -1) 
+		os_kill_process(io_pid, 1);
 }
 
 __uml_exitcall(kill_io_thread);
@@ -892,9 +897,9 @@
 	struct ubd *dev = inode->i_bdev->bd_disk->private_data;
 	int err;
 	struct hd_driveid ubd_id = {
-		.cyls =		0,
-		.heads =	128,
-		.sectors =	32,
+		.cyls		= 0,
+		.heads		= 128,
+		.sectors	= 32,
 	};
 
 	switch (cmd) {
diff -Nru a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
--- a/arch/um/drivers/xterm.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/drivers/xterm.c	Mon Feb 10 10:39:23 2003
@@ -37,13 +37,13 @@
 	struct xterm_chan *data;
 
 	if((data = malloc(sizeof(*data))) == NULL) return(NULL);
-	*data = ((struct xterm_chan) { pid :		-1, 
-				       helper_pid :	-1,
-				       device :		device, 
-				       title :		opts->xterm_title,
-				       raw : 		opts->raw,
-				       stack :		opts->tramp_stack,
-				       direct_rcv :	!opts->in_kernel } );
+	*data = ((struct xterm_chan) { .pid 		= -1, 
+				       .helper_pid 	= -1,
+				       .device 		= device, 
+				       .title 		= opts->xterm_title,
+				       .raw  		= opts->raw,
+				       .stack 		= opts->tramp_stack,
+				       .direct_rcv 	= !opts->in_kernel } );
 	return(data);
 }
 
@@ -137,7 +137,7 @@
 	}
 	if(new < 0){
 		printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
-		return(new);
+		goto out;
 	}
 
 	tcgetattr(new, &data->tt);
@@ -145,6 +145,8 @@
 
 	data->pid = pid;
 	*dev_out = NULL;
+ out:
+	unlink(file);
 	return(new);
 }
 
@@ -152,9 +154,11 @@
 {
 	struct xterm_chan *data = d;
 	
-	if(data->pid != -1) kill(data->pid, SIGKILL);
+	if(data->pid != -1) 
+		os_kill_process(data->pid, 1);
 	data->pid = -1;
-	if(data->helper_pid != -1) kill(data->helper_pid, SIGKILL);
+	if(data->helper_pid != -1) 
+		os_kill_process(data->helper_pid, 0);
 	data->helper_pid = -1;
 	close(fd);
 }
@@ -172,16 +176,16 @@
 }
 
 struct chan_ops xterm_ops = {
-	type:		"xterm",
-	init:		xterm_init,
-	open:		xterm_open,
-	close:		xterm_close,
-	read:		generic_read,
-	write:		generic_write,
-	console_write:	xterm_console_write,
-	window_size:	generic_window_size,
-	free:		xterm_free,
-	winch:		1,
+	.type		= "xterm",
+	.init		= xterm_init,
+	.open		= xterm_open,
+	.close		= xterm_close,
+	.read		= generic_read,
+	.write		= generic_write,
+	.console_write	= xterm_console_write,
+	.window_size	= generic_window_size,
+	.free		= xterm_free,
+	.winch		= 1,
 };
 
 /*
diff -Nru a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
--- a/arch/um/drivers/xterm_kern.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/drivers/xterm_kern.c	Mon Feb 10 10:39:30 2003
@@ -39,21 +39,21 @@
 
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
 	if(data == NULL){
-		printk(KERN_ERR "xterm_fd - failed to allocate semaphore\n");
+		printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
 		return(-ENOMEM);
 	}
 	*data = ((struct xterm_wait) 
-		{ sem : 	__SEMAPHORE_INITIALIZER(data->sem, 0),
-		  fd :		socket,
-		  pid :		-1,
-		  new_fd :	-1 });
+		{ .sem  	= __SEMAPHORE_INITIALIZER(data->sem, 0),
+		  .fd 		= socket,
+		  .pid 		= -1,
+		  .new_fd 	= -1 });
 
 	err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
 			     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			     "xterm", data);
 	if(err){
-		printk(KERN_ERR "Failed to get IRQ for xterm, err = %d\n", 
-		       err);
+		printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
+		       "err = %d\n",  err);
 		return(err);
 	}
 	down(&data->sem);
diff -Nru a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/dyn.lds.S	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,167 @@
+OUTPUT_FORMAT(ELF_FORMAT)
+OUTPUT_ARCH(ELF_ARCH)
+ENTRY(_start)
+jiffies = jiffies_64;
+
+SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  . = START + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  . = ALIGN(4096);
+  __binary_start = .;
+  . = ALIGN(4096);		/* Init code and data */
+  _stext = .;
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+
+  . = ALIGN(4096);
+
+  /* Read-only sections, merged into text segment: */
+  .hash           : { *(.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.init       : { *(.rel.init) }
+  .rela.init      : { *(.rela.init) }
+  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+  .rel.fini       : { *(.rel.fini) }
+  .rela.fini      : { *(.rela.fini) }
+  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+  .rel.tdata	  : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+  .rela.tdata	  : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+  .rel.tbss	  : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+  .rela.tbss	  : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+  .rel.ctors      : { *(.rel.ctors) }
+  .rela.ctors     : { *(.rela.ctors) }
+  .rel.dtors      : { *(.rel.dtors) }
+  .rela.dtors     : { *(.rela.dtors) }
+  .rel.got        : { *(.rel.got) }
+  .rela.got       : { *(.rela.got) }
+  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+  .rel.plt        : { *(.rel.plt) }
+  .rela.plt       : { *(.rela.plt) }
+  .init           : {
+    KEEP (*(.init))
+  } =0x90909090
+  .plt            : { *(.plt) }
+  .text           : {
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           : {
+    KEEP (*(.fini))
+  } =0x90909090
+
+  .kstrtab : { *(.kstrtab) }
+
+  #include "asm/common.lds.S"
+
+  .data.init : { *(.data.init) }
+
+  /* Ensure the __preinit_array_start label is properly aligned.  We
+     could instead move the label definition inside the section, but
+     the linker would then create the section even if it turns out to
+     be empty, which isn't pretty.  */
+  . = ALIGN(32 / 8);
+  .preinit_array     : { *(.preinit_array) }
+  .init_array     : { *(.init_array) }
+  .fini_array     : { *(.fini_array) }
+  .data           : {
+    . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
+    *(.data.init_task)
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table) }
+  .dynamic        : { *(.dynamic) }
+  .ctors          : {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          : {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .got            : { *(.got.plt) *(.got) }
+  _edata = .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .bss            : {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(32 / 8);
+  . = ALIGN(32 / 8);
+  }
+  _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) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+}
diff -Nru a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
--- a/arch/um/include/choose-mode.h	Mon Feb 10 10:39:29 2003
+++ b/arch/um/include/choose-mode.h	Mon Feb 10 10:39:29 2003
@@ -8,13 +8,13 @@
 
 #include "uml-config.h"
 
-#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
+#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
 #define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
 
-#elif defined(CONFIG_MODE_SKAS)
+#elif defined(UML_CONFIG_MODE_SKAS)
 #define CHOOSE_MODE(tt, skas) (skas)
 
-#elif defined(CONFIG_MODE_TT)
+#elif defined(UML_CONFIG_MODE_TT)
 #define CHOOSE_MODE(tt, skas) (tt)
 #endif
 
diff -Nru a/arch/um/include/frame.h b/arch/um/include/frame.h
--- a/arch/um/include/frame.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/include/frame.h	Mon Feb 10 10:39:24 2003
@@ -15,12 +15,12 @@
 	int sr_index;
 	int sr_relative;
 	int sp_index;
+	struct arch_frame_data arch;
 };
 
 struct sc_frame {
 	struct frame_common common;
 	int sc_index;
-	struct arch_frame_data arch;
 };
 
 extern struct sc_frame signal_frame_sc;
@@ -31,6 +31,8 @@
 	struct frame_common common;
 	int sip_index;
 	int si_index;
+	int ucp_index;
+	int uc_index;
 };
 
 extern struct si_frame signal_frame_si;
diff -Nru a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
--- a/arch/um/include/irq_user.h	Mon Feb 10 10:39:29 2003
+++ b/arch/um/include/irq_user.h	Mon Feb 10 10:39:29 2003
@@ -8,7 +8,7 @@
 
 enum { IRQ_READ, IRQ_WRITE };
 
-extern void sigio_handler(int sig, struct uml_pt_regs *regs);
+extern void sigio_handler(int sig, union uml_pt_regs *regs);
 extern int activate_fd(int irq, int fd, int type, void *dev_id);
 extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
 extern void free_irq_by_fd(int fd);
diff -Nru a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
--- a/arch/um/include/kern_util.h	Mon Feb 10 10:39:25 2003
+++ b/arch/um/include/kern_util.h	Mon Feb 10 10:39:25 2003
@@ -47,7 +47,7 @@
 extern void add_input_request(int op, void (*proc)(int), void *arg);
 extern int sys_execve(char *file, char **argv, char **env);
 extern char *current_cmd(void);
-extern void timer_handler(int sig, struct uml_pt_regs *regs);
+extern void timer_handler(int sig, union uml_pt_regs *regs);
 extern int set_signals(int enable);
 extern void force_sigbus(void);
 extern int pid_to_processor_id(int pid);
@@ -64,7 +64,7 @@
 extern void syscall_trace(void);
 extern int hz(void);
 extern void idle_timer(void);
-extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
+extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
 extern int external_pid(void *t);
 extern int pid_to_processor_id(int pid);
 extern void boot_timer_handler(int sig);
@@ -77,10 +77,10 @@
 extern int init_parent_proxy(int pid);
 extern int singlestepping(void *t);
 extern void check_stack_overflow(void *ptr);
-extern void relay_signal(int sig, struct uml_pt_regs *regs);
+extern void relay_signal(int sig, union uml_pt_regs *regs);
 extern void not_implemented(void);
 extern int user_context(unsigned long sp);
-extern void timer_irq(struct uml_pt_regs *regs);
+extern void timer_irq(union uml_pt_regs *regs);
 extern void unprotect_stack(unsigned long stack);
 extern void do_uml_exitcalls(void);
 extern int attach_debugger(int idle_pid, int pid, int stop);
@@ -101,7 +101,7 @@
 extern int clear_user_proc(void *buf, int size);
 extern int copy_to_user_proc(void *to, void *from, int size);
 extern int copy_from_user_proc(void *to, void *from, int size);
-extern void bus_handler(int sig, struct uml_pt_regs *regs);
+extern void bus_handler(int sig, union uml_pt_regs *regs);
 extern long execute_syscall(void *r);
 extern int smp_sigio_handler(void);
 extern void *get_current(void);
diff -Nru a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
--- a/arch/um/include/mconsole.h	Mon Feb 10 10:39:26 2003
+++ b/arch/um/include/mconsole.h	Mon Feb 10 10:39:26 2003
@@ -7,30 +7,35 @@
 #ifndef __MCONSOLE_H__
 #define __MCONSOLE_H__
 
+#ifndef __KERNEL__
+#include <stdint.h>
+#define u32 uint32_t
+#endif
+
 #define MCONSOLE_MAGIC (0xcafebabe)
 #define MCONSOLE_MAX_DATA (512)
 #define MCONSOLE_VERSION 2
 
 struct mconsole_request {
-	unsigned long magic;
-	int version;
-	int len;
+	u32 magic;
+	u32 version;
+	u32 len;
 	char data[MCONSOLE_MAX_DATA];
 };
 
 struct mconsole_reply {
-	int err;
-	int more;
-	int len;
+	u32 err;
+	u32 more;
+	u32 len;
 	char data[MCONSOLE_MAX_DATA];
 };
 
 struct mconsole_notify {
-	unsigned long magic;
-	int version;	
+	u32 magic;
+	u32 version;	
 	enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
 	       MCONSOLE_USER_NOTIFY } type;
-	int len;
+	u32 len;
 	char data[MCONSOLE_MAX_DATA];
 };
 
diff -Nru a/arch/um/include/mode.h b/arch/um/include/mode.h
--- a/arch/um/include/mode.h	Mon Feb 10 10:39:29 2003
+++ b/arch/um/include/mode.h	Mon Feb 10 10:39:29 2003
@@ -8,11 +8,11 @@
 
 #include "uml-config.h"
 
-#ifdef CONFIG_MODE_TT
+#ifdef UML_CONFIG_MODE_TT
 #include "../kernel/tt/include/mode.h"
 #endif
 
-#ifdef CONFIG_MODE_SKAS
+#ifdef UML_CONFIG_MODE_SKAS
 #include "../kernel/skas/include/mode.h"
 #endif
 
diff -Nru a/arch/um/include/os.h b/arch/um/include/os.h
--- a/arch/um/include/os.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/include/os.h	Mon Feb 10 10:39:24 2003
@@ -25,9 +25,11 @@
 	unsigned int t : 1;	/* O_TRUNC */
 	unsigned int a : 1;	/* O_APPEND */
 	unsigned int e : 1;	/* O_EXCL */
+	unsigned int cl : 1;    /* FD_CLOEXEC */
 };
 
-#define OPENFLAGS() ((struct openflags) { r : 0, w : 0, c : 0, s : 0 })
+#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
+ 					  .t = 0, .a = 0, .e = 0, .cl = 0 })
 
 static inline struct openflags of_read(struct openflags flags)
 {
@@ -83,9 +85,16 @@
 	return(flags); 
 }
  
+static inline struct openflags of_cloexec(struct openflags flags)
+{ 
+	flags.cl = 1; 
+	return(flags); 
+}
+  
 extern int os_seek_file(int fd, __u64 offset);
 extern int os_open_file(char *file, struct openflags flags, int mode);
-extern int os_read_file(int fd, char *buf, int len);
+extern int os_read_file(int fd, void *buf, int len);
+extern int os_write_file(int fd, void *buf, int count);
 extern int os_file_size(char *file, long long *size_out);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd, int owner);
@@ -98,7 +107,6 @@
 extern int os_connect_socket(char *name);
 extern int os_file_type(char *file);
 extern int os_file_mode(char *file, struct openflags *mode_out);
-extern int os_write_file(int fd, char *buf, int count);
 
 extern unsigned long os_process_pc(int pid);
 extern int os_process_parent(int pid);
diff -Nru a/arch/um/include/signal_kern.h b/arch/um/include/signal_kern.h
--- a/arch/um/include/signal_kern.h	Mon Feb 10 10:39:31 2003
+++ b/arch/um/include/signal_kern.h	Mon Feb 10 10:39:31 2003
@@ -1,15 +1,11 @@
 /* 
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
 
 #ifndef __SIGNAL_KERN_H__
 #define __SIGNAL_KERN_H__
 
-#include "sysdep/ptrace.h"
-
-extern void signal_deliverer(int sig);
-extern int probe_stack(unsigned long sp, int delta);
 extern int have_signals(void *t);
 
 #endif
diff -Nru a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/include/skas_ptrace.h	Mon Feb 10 10:39:31 2003
@@ -0,0 +1,36 @@
+/* 
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_PTRACE_H
+#define __SKAS_PTRACE_H
+
+struct ptrace_faultinfo {
+	int is_write;
+	unsigned long addr;
+};
+
+struct ptrace_ldt {
+	int func;
+  	void *ptr;
+	unsigned long bytecount;
+};
+
+#define PTRACE_FAULTINFO 52
+#define PTRACE_SIGPENDING 53
+#define PTRACE_LDT 54
+#define PTRACE_SWITCH_MM 55
+
+#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 -Nru a/arch/um/include/sysdep-i386/frame.h b/arch/um/include/sysdep-i386/frame.h
--- a/arch/um/include/sysdep-i386/frame.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/include/sysdep-i386/frame.h	Mon Feb 10 10:39:23 2003
@@ -7,7 +7,8 @@
 #define __FRAME_I386_H
 
 struct arch_frame_data_raw {
-	unsigned long sc_end;
+	unsigned long fp_start;
+	unsigned long sr;
 };
 
 struct arch_frame_data {
diff -Nru a/arch/um/include/sysdep-i386/frame_kern.h b/arch/um/include/sysdep-i386/frame_kern.h
--- a/arch/um/include/sysdep-i386/frame_kern.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/include/sysdep-i386/frame_kern.h	Mon Feb 10 10:39:24 2003
@@ -16,6 +16,15 @@
 	return((void *) sp);
 }
 
+static inline void *sp_to_uc(unsigned long sp)
+{
+	unsigned long uc;
+
+	uc = sp + signal_frame_si.uc_index - 
+		signal_frame_si.common.sp_index - 4;
+	return((void *) uc);
+}
+
 static inline void *sp_to_rt_sc(unsigned long sp)
 {
 	unsigned long sc;
@@ -42,7 +51,7 @@
 
 	mask = sp - signal_frame_si.common.sp_index + 
 		signal_frame_si.common.len + 
-		sc_size(&signal_frame_sc.arch) - 4;
+		sc_size(&signal_frame_si.common.arch) - 4;
 	return((void *) mask);
 }
 
diff -Nru a/arch/um/include/sysdep-i386/frame_user.h b/arch/um/include/sysdep-i386/frame_user.h
--- a/arch/um/include/sysdep-i386/frame_user.h	Mon Feb 10 10:39:32 2003
+++ b/arch/um/include/sysdep-i386/frame_user.h	Mon Feb 10 10:39:32 2003
@@ -18,26 +18,35 @@
  * setup_arch_frame uses that data to figure out what 
  * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
  * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
- * everything from the end of the sgcontext up to the top of the stack.  So,
+ * everything from the end of the sigcontext up to the top of the stack.  So,
  * it masks off the page number to get the offset within the page and subtracts
  * that from the page size, and that's how big the fpstate struct will be
  * considered to be.
  */
 
 static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
-					struct sigcontext *sc)
+					void *end, unsigned long srp)
 {
-	data->sc_end = (unsigned long) sc;
-	data->sc_end += sizeof(*sc);
+	unsigned long sr = *((unsigned long *) srp);
+
+	data->fp_start = (unsigned long) end;
+	if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
+		data->sr = sr;
+	else data->sr = 0;
 }
 
 static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
 				    struct arch_frame_data *out)
 {
-	unsigned long fpstate_start = in->sc_end;
+	unsigned long fpstate_start = in->fp_start;
 
-	fpstate_start &= ~PAGE_MASK;
-	out->fpstate_size = PAGE_SIZE - fpstate_start;
+	if(in->sr == 0){
+		fpstate_start &= ~PAGE_MASK;
+		out->fpstate_size = PAGE_SIZE - fpstate_start;
+	}
+	else {
+		out->fpstate_size = in->sr - fpstate_start;
+	}
 }
 
 /* This figures out where on the stack the SA_RESTORER function address
diff -Nru a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
--- a/arch/um/include/sysdep-i386/ptrace.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/include/sysdep-i386/ptrace.h	Mon Feb 10 10:39:23 2003
@@ -7,72 +7,101 @@
 #define __SYSDEP_I386_PTRACE_H
 
 #include "uml-config.h"
+
+#ifdef UML_CONFIG_MODE_TT
 #include "ptrace-tt.h"
+#endif
+
+#ifdef UML_CONFIG_MODE_SKAS
 #include "ptrace-skas.h"
+#endif
+
 #include "choose-mode.h"
 
-struct uml_pt_regs {
-	unsigned long args[6];
-	long syscall;
-	int is_user;
-	union {
-#ifdef CONFIG_MODE_TT
-		void *tt;
+union uml_pt_regs {
+#ifdef UML_CONFIG_MODE_TT
+	struct tt_regs {
+		long syscall;
+		void *sc;
+	} tt;
 #endif
-#ifdef CONFIG_MODE_SKAS
-		struct {
-			unsigned long regs[HOST_FRAME_SIZE];
-			unsigned long fp[HOST_FP_SIZE];
-			unsigned long xfp[HOST_XFP_SIZE];
-			unsigned long fault_addr;
-			unsigned long fault_type;
-			unsigned long trap_type;
-		} skas;
+#ifdef UML_CONFIG_MODE_SKAS
+	struct skas_regs {
+		unsigned long regs[HOST_FRAME_SIZE];
+		unsigned long fp[HOST_FP_SIZE];
+		unsigned long xfp[HOST_XFP_SIZE];
+		unsigned long fault_addr;
+		unsigned long fault_type;
+		unsigned long trap_type;
+		long syscall;
+		int is_user;
+	} skas;
 #endif
-	} mode;
 };
 
-#define EMPTY_UML_PT_REGS { \
-	syscall : 	-1, \
-	args : 		{ [0 ... 5] = 0 }, \
-	is_user :	0 }
+#define EMPTY_UML_PT_REGS { }
 
 extern int mode_tt;
 
+#define UPT_SC(r) ((r)->tt.sc)
 #define UPT_IP(r) \
-	CHOOSE_MODE(SC_IP((r)->mode.tt), REGS_IP((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
 #define UPT_SP(r) \
-	CHOOSE_MODE(SC_SP((r)->mode.tt), REGS_SP((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
 #define UPT_EFLAGS(r) \
-	CHOOSE_MODE(SC_EFLAGS((r)->mode.tt), REGS_EFLAGS((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
 #define UPT_EAX(r) \
-	CHOOSE_MODE(SC_EAX((r)->mode.tt), REGS_EAX((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
 #define UPT_EBX(r) \
-	CHOOSE_MODE(SC_EBX((r)->mode.tt), REGS_EBX((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
 #define UPT_ECX(r) \
-	CHOOSE_MODE(SC_ECX((r)->mode.tt), REGS_ECX((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
 #define UPT_EDX(r) \
-	CHOOSE_MODE(SC_EDX((r)->mode.tt), REGS_EDX((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
 #define UPT_ESI(r) \
-	CHOOSE_MODE(SC_ESI((r)->mode.tt), REGS_ESI((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
 #define UPT_EDI(r) \
-	CHOOSE_MODE(SC_EDI((r)->mode.tt), REGS_EDI((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
 #define UPT_EBP(r) \
-	CHOOSE_MODE(SC_EBP((r)->mode.tt), REGS_EBP((r)->mode.skas.regs))
-#define UPT_ORIG_EAX(r) ((r)->syscall)
+	CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
+#define UPT_ORIG_EAX(r) \
+	CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
 #define UPT_CS(r) \
-	CHOOSE_MODE(SC_CS((r)->mode.tt), REGS_CS((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
 #define UPT_SS(r) \
-	CHOOSE_MODE(SC_SS((r)->mode.tt), REGS_SS((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
 #define UPT_DS(r) \
-	CHOOSE_MODE(SC_DS((r)->mode.tt), REGS_DS((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
 #define UPT_ES(r) \
-	CHOOSE_MODE(SC_ES((r)->mode.tt), REGS_ES((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
 #define UPT_FS(r) \
-	CHOOSE_MODE(SC_FS((r)->mode.tt), REGS_FS((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
 #define UPT_GS(r) \
-	CHOOSE_MODE(SC_GS((r)->mode.tt), REGS_GS((r)->mode.skas.regs))
-#define UPT_SC(r) ((r)->mode.tt)
+	CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
+
+#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
+#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
+#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
+#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
+#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
+#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
+
+extern int user_context(unsigned long sp);
+
+#define UPT_IS_USER(r) \
+	CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
+
+struct syscall_args {
+	unsigned long args[6];
+};
+
+#define SYSCALL_ARGS(r) ((struct syscall_args) \
+                        { .args = { UPT_SYSCALL_ARG1(r), \
+                                    UPT_SYSCALL_ARG2(r), \
+ 			            UPT_SYSCALL_ARG3(r), \
+                                    UPT_SYSCALL_ARG4(r), \
+		                    UPT_SYSCALL_ARG5(r), \
+                                    UPT_SYSCALL_ARG6(r) } } )
 
 #define UPT_REG(regs, reg) \
 	({	unsigned long val; \
@@ -129,28 +158,26 @@
 	} while (0)
 
 #define UPT_SET_SYSCALL_RETURN(r, res) \
-	CHOOSE_MODE(SC_SET_SYSCALL_RETURN((r)->mode.tt, (res)), \
-                    REGS_SET_SYSCALL_RETURN((r)->mode.skas.regs, (res)))
+	CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
+                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
 
 #define UPT_RESTART_SYSCALL(r) \
-	CHOOSE_MODE(SC_RESTART_SYSCALL((r)->mode.tt), \
-		    REGS_RESTART_SYSCALL((r)->mode.skas.regs))
+	CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
+		    REGS_RESTART_SYSCALL((r)->skas.regs))
 
 #define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
-#define UPT_SYSCALL_NR(r) ((r)->syscall)
+#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
 #define UPT_SYSCALL_RET(r) UPT_EAX(r)
 
 #define UPT_SEGV_IS_FIXABLE(r) \
-	CHOOSE_MODE(SC_SEGV_IS_FIXABLE(r->mode.tt), \
-		    REGS_SEGV_IS_FIXABLE(&r->mode.skas))
+	CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
+                    REGS_SEGV_IS_FIXABLE(&r->skas))
 
 #define UPT_FAULT_ADDR(r) \
-	CHOOSE_MODE(SC_FAULT_ADDR(r->mode.tt), \
-		    REGS_FAULT_ADDR(&r->mode.skas))
+	CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
 
 #define UPT_FAULT_WRITE(r) \
-	CHOOSE_MODE(SC_FAULT_WRITE(r->mode.tt), \
-		    REGS_FAULT_WRITE(&r->mode.skas))
+	CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
 
 #endif
 
diff -Nru a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
--- a/arch/um/include/sysdep-i386/sigcontext.h	Mon Feb 10 10:39:30 2003
+++ b/arch/um/include/sysdep-i386/sigcontext.h	Mon Feb 10 10:39:30 2003
@@ -33,34 +33,6 @@
 
 #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
 
-#ifdef CONFIG_MODE_TT
-/* XXX struct sigcontext needs declaring by now */
-static inline void sc_to_regs(struct uml_pt_regs *regs, struct sigcontext *sc,
-			      unsigned long syscall)
-{
-	regs->syscall = syscall;
-	regs->args[0] = SC_EBX(sc);
-	regs->args[1] = SC_ECX(sc);
-	regs->args[2] = SC_EDX(sc);
-	regs->args[3] = SC_ESI(sc);
-	regs->args[4] = SC_EDI(sc);
-	regs->args[5] = SC_EBP(sc);
-}
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-static inline void host_to_regs(struct uml_pt_regs *regs)
-{
-	regs->syscall = UPT_ORIG_EAX(regs);
-	regs->args[0] = UPT_EBX(regs);
-	regs->args[1] = UPT_ECX(regs);
-	regs->args[2] = UPT_EDX(regs);
-	regs->args[3] = UPT_ESI(regs);
-	regs->args[4] = UPT_EDI(regs);
-	regs->args[5] = UPT_EBP(regs);
-}
-#endif
-
 extern unsigned long *sc_sigmask(void *sc_ptr);
 extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
 
diff -Nru a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
--- a/arch/um/include/sysdep-i386/syscalls.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/include/sysdep-i386/syscalls.h	Mon Feb 10 10:39:23 2003
@@ -4,10 +4,12 @@
  */
 
 #include "asm/unistd.h"
+#include "sysdep/ptrace.h"
 
 typedef long syscall_handler_t(struct pt_regs);
 
-#define EXECUTE_SYSCALL(syscall, regs) (*sys_call_table[syscall])(*regs);
+#define EXECUTE_SYSCALL(syscall, regs) \
+	((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
 
 extern syscall_handler_t sys_modify_ldt;
 extern syscall_handler_t old_mmap_i386;
diff -Nru a/arch/um/include/time_user.h b/arch/um/include/time_user.h
--- a/arch/um/include/time_user.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/include/time_user.h	Mon Feb 10 10:39:24 2003
@@ -11,7 +11,7 @@
 extern void set_interval(int timer_type);
 extern void idle_sleep(int secs);
 extern void enable_timer(void);
-extern void time_lock(void);
-extern void time_unlock(void);
+extern unsigned long time_lock(void);
+extern void time_unlock(unsigned long);
 
 #endif
diff -Nru a/arch/um/include/umid.h b/arch/um/include/umid.h
--- a/arch/um/include/umid.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/include/umid.h	Mon Feb 10 10:39:24 2003
@@ -3,7 +3,12 @@
  * Licensed under the GPL
  */
 
+#ifndef __UMID_H__
+#define __UMID_H__
+
 extern int umid_file_name(char *name, char *buf, int len);
+
+#endif
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/include/uml_uaccess.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UML_UACCESS_H__
+#define __UML_UACCESS_H__
+
+extern int __do_copy_to_user(void *to, const void *from, int n,
+				  void **fault_addr, void **fault_catcher);
+extern unsigned long __do_user_copy(void *to, const void *from, int n,
+				    void **fault_addr, void **fault_catcher,
+				    void (*op)(void *to, const void *from,
+					       int n), int *faulted_out);
+void __do_copy(void *to, const void *from, int n);
+
+#endif
+
+/*
+ * 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 -Nru a/arch/um/include/user_util.h b/arch/um/include/user_util.h
--- a/arch/um/include/user_util.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/include/user_util.h	Mon Feb 10 10:39:23 2003
@@ -24,7 +24,7 @@
 extern struct cpu_task cpu_tasks[];
 
 struct signal_info {
-	void (*handler)(int, struct uml_pt_regs *);
+	void (*handler)(int, union uml_pt_regs *);
 	int is_irq;
 };
 
@@ -61,7 +61,6 @@
 			    int clone_flags, int (*tramp)(void *));
 extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
 extern int linux_main(int argc, char **argv);
-extern void remap_data(void *segment_start, void *segment_end, int w);
 extern void set_cmdline(char *cmd);
 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
 extern int get_pty(void);
@@ -87,7 +86,7 @@
 extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
 extern void write_sigio_workaround(void);
 extern void arch_check_bugs(void);
-extern int arch_handle_signal(int sig, struct uml_pt_regs *regs);
+extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
 extern int arch_fixup(unsigned long address, void *sc_ptr);
 extern void forward_pending_sigio(int target);
 extern int can_do_skas(void);
diff -Nru a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
--- a/arch/um/kernel/Makefile	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,15 +3,13 @@
 # Licensed under the GPL
 #
 
-EXTRA_TARGETS	:= unmap_fin.o
-
 obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
 	helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
 	process.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 \
 	syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
-	time_kern.o tlb.o trap_kern.o trap_user.o um_arch.o \
-	umid.o user_util.o
+	time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+	umid.o user_syms.o user_util.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
@@ -23,23 +21,13 @@
 
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-# user_syms.o not included here because Rules.make has its own ideas about
-# building anything in export-objs
-
 USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
 	process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
-UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
-UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
-
 DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
 DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
 
-export-objs-$(CONFIG_GPROF) += gprof_syms.o
-export-objs-$(CONFIG_GCOV) += gmon_syms.o
-
-export-objs := ksyms.o process_kern.o signal_kern.o $(export-objs-y)
 
 CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
 	-I/usr/include -I../include
@@ -47,13 +35,7 @@
 CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
 
 $(USER_OBJS) : %.o: %.c
-	$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
-
-$(obj)/unmap.o: $(src)/unmap.c
-	$(CC) $(UNMAP_CFLAGS) -c -o $@ $<
-
-$(obj)/unmap_fin.o : $(src)/unmap.o
-	ld -r -o $@ $< -lc -L/usr/lib
+	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
 
 # This has to be separate because it needs be compiled with frame pointers
 # regardless of how the rest of the kernel is built.
diff -Nru a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c
--- a/arch/um/kernel/frame.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/frame.c	Mon Feb 10 10:39:24 2003
@@ -78,7 +78,8 @@
 
 	/* It has outlived its usefulness, so continue it so it can exit */
 	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
-		printf("capture_stack : mmap failed - errno = %d\n", errno);
+		printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
+		       errno);
 		exit(1);
 	}
 	if(waitpid(pid, &status, 0) < 0){
@@ -110,6 +111,7 @@
 	unsigned long sig;
 	unsigned long sr;
 	unsigned long sp;	
+	struct arch_frame_data_raw arch;
 };
 
 #define SA_RESTORER (0x04000000)
@@ -173,7 +175,6 @@
 	struct common_raw common;
 	unsigned long sc;
 	int restorer;
-	struct arch_frame_data_raw arch;
 };
 
 /* Changed only during early boot */
@@ -185,7 +186,8 @@
 	raw_sc->common.sr = frame_restorer();
 	raw_sc->common.sp = frame_sp();
 	raw_sc->sc = (unsigned long) &sc;
-	setup_arch_frame_raw(&raw_sc->arch, &sc);
+	setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
+
 	os_stop_process(os_getpid());
 	kill(getpid(), SIGKILL);
 }
@@ -205,18 +207,25 @@
 	struct common_raw common;
 	unsigned long sip;
 	unsigned long si;
+	unsigned long ucp;
+	unsigned long uc;
 };
 
 /* Changed only during early boot */
 static struct si_frame_raw *raw_si = NULL;
 
-static void si_handler(int sig, siginfo_t *si)
+static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
 {
 	raw_si->common.sig = (unsigned long) &sig;
 	raw_si->common.sr = frame_restorer();
 	raw_si->common.sp = frame_sp();
 	raw_si->sip = (unsigned long) &si;
 	raw_si->si = (unsigned long) si;
+	raw_si->ucp = (unsigned long) &ucontext;
+	raw_si->uc = (unsigned long) ucontext;
+	setup_arch_frame_raw(&raw_si->common.arch, 
+			     ucontext->uc_mcontext.fpregs, raw_si->common.sr);
+	
 	os_stop_process(os_getpid());
 	kill(getpid(), SIGKILL);
 }
@@ -292,7 +301,7 @@
 				    &signal_frame_sc.common);
 
 	signal_frame_sc.sc_index = raw_sc.sc - base;
-	setup_arch_frame(&raw_sc.arch, &signal_frame_sc.arch);
+	setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
 
 	/* Ditto for the sigcontext, sigrestorer layout */
 	raw_sc.restorer = 1;
@@ -300,6 +309,7 @@
 				    (void *) top, sigstack, PAGE_SIZE, 
 				    &signal_frame_sc_sr.common);
 	signal_frame_sc_sr.sc_index = raw_sc.sc - base;
+	setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
 
 	/* And the siginfo layout */
 
@@ -308,6 +318,9 @@
 				    &signal_frame_si.common);
 	signal_frame_si.sip_index = raw_si.sip - base;
 	signal_frame_si.si_index = raw_si.si - base;
+	signal_frame_si.ucp_index = raw_si.ucp - base;
+	signal_frame_si.uc_index = raw_si.uc - base;
+	setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
 
 	if((munmap(stack, PAGE_SIZE) < 0) || 
 	   (munmap(sigstack, PAGE_SIZE) < 0)){
diff -Nru a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c
--- a/arch/um/kernel/frame_kern.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/frame_kern.c	Mon Feb 10 10:39:33 2003
@@ -6,6 +6,8 @@
 #include "asm/ptrace.h"
 #include "asm/uaccess.h"
 #include "asm/signal.h"
+#include "asm/uaccess.h"
+#include "asm/ucontext.h"
 #include "frame_kern.h"
 #include "sigcontext.h"
 #include "sysdep/ptrace.h"
@@ -27,48 +29,62 @@
 			    sizeof(restorer)));
 }
 
-static int copy_sc_to_user(void *to, struct pt_regs *from)
+static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
+			   struct arch_frame_data *arch)
 {
-	return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt, 
-					      &signal_frame_sc_sr.arch),
-			   copy_sc_to_user_skas(to, &from->regs,
+	return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
+					      arch),
+			   copy_sc_to_user_skas(to, fp, &from->regs,
 						current->thread.cr2,
 						current->thread.err)));
 }
 
+static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
+				 unsigned long sp)
+{
+	int err = 0;
+
+	err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
+	err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
+	err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
+	err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
+			       &signal_frame_si.common.arch);
+	err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
+	return(err);
+}
+
 int setup_signal_stack_si(unsigned long stack_top, int sig, 
 			  unsigned long handler, void (*restorer)(void), 
 			  struct pt_regs *regs, siginfo_t *info, 
 			  sigset_t *mask)
 {
-	unsigned long start, sc, sigs;
-	void *sip;
-	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
+	unsigned long start;
+	void *sip, *ucp, *fp;
 
-	start = stack_top - signal_frame_si.common.len - 
-		sc_size(&signal_frame_sc.arch) - sig_size;
+	start = stack_top - signal_frame_si.common.len;
 	sip = (void *) (start + signal_frame_si.si_index);
-	sc = start + signal_frame_si.common.len;
-	sigs = sc + sc_size(&signal_frame_sc.arch);
+	ucp = (void *) (start + signal_frame_si.uc_index);
+	fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
 
 	if(restorer == NULL)
 		panic("setup_signal_stack_si - no restorer");
 
-	if(copy_sc_to_user((void *) sc, regs) ||
-	   copy_to_user((void *) start, signal_frame_si.common.data,
+	if(copy_to_user((void *) start, signal_frame_si.common.data,
 			signal_frame_si.common.len) ||
 	   copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
 			&sig, sizeof(sig)) ||
 	   copy_siginfo_to_user(sip, info) ||
 	   copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
 			sizeof(sip)) ||
-	   copy_to_user((void *) sigs, mask, sig_size) ||
+	   copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
+	   copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
+			sizeof(ucp)) ||
 	   copy_restorer(restorer, start, signal_frame_si.common.sr_index,
 			 signal_frame_si.common.sr_relative))
 		return(1);
 	
 	PT_REGS_IP(regs) = handler;
-	PT_REGS_SP(regs) = start + signal_frame_sc.common.sp_index;
+	PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
 	return(0);
 }
 
@@ -96,7 +112,8 @@
 	if(copy_to_user((void *) start, frame->data, frame->len) ||
 	   copy_to_user((void *) (start + frame->sig_index), &sig, 
 			sizeof(sig)) ||
-	   copy_sc_to_user(user_sc, regs) ||
+	   copy_sc_to_user(user_sc, NULL, regs, 
+			   &signal_frame_sc.common.arch) ||
 	   copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
 	   copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
 	   copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
diff -Nru a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
--- a/arch/um/kernel/init_task.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/init_task.c	Mon Feb 10 10:39:33 2003
@@ -3,6 +3,7 @@
  * Licensed under the GPL
  */
 
+#include "linux/config.h"
 #include "linux/mm.h"
 #include "linux/sched.h"
 #include "linux/init_task.h"
@@ -37,17 +38,16 @@
 __attribute__((__section__(".data.init_task"))) = 
 { INIT_THREAD_INFO(init_task) };
 
-struct task_struct *alloc_task_struct(void){
-	struct task_struct *task;
-
-	task = (struct task_struct *) __get_free_pages(GFP_KERNEL, 2);
-	if(task == NULL) return(NULL);
-	return(task);
+struct task_struct *alloc_task_struct(void)
+{
+	return((struct task_struct *) 
+	       __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
 }
 
 void unprotect_stack(unsigned long stack)
 {
-	protect_memory(stack, 4 * PAGE_SIZE, 1, 1, 0, 1);
+	protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
+		       1, 1, 0, 1);
 }
 
 void free_task_struct(struct task_struct *task)
@@ -55,7 +55,7 @@
 	/* free_pages decrements the page counter and only actually frees
 	 * the pages if they are now not accessed by anything.
 	 */
-	free_pages((unsigned long) task, 2);
+	free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
 }
 
 /*
diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
--- a/arch/um/kernel/irq.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/kernel/irq.c	Mon Feb 10 10:39:31 2003
@@ -271,7 +271,7 @@
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
-unsigned int do_IRQ(int irq, struct uml_pt_regs *regs)
+unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
 {	
 	/* 
 	 * 0 return value means that this irq is already being
diff -Nru a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
--- a/arch/um/kernel/irq_user.c	Mon Feb 10 10:39:26 2003
+++ b/arch/um/kernel/irq_user.c	Mon Feb 10 10:39:26 2003
@@ -42,7 +42,7 @@
 
 extern int io_count, intr_count;
 
-void sigio_handler(int sig, struct uml_pt_regs *regs)
+void sigio_handler(int sig, union uml_pt_regs *regs)
 {
 	struct irq_fd *irq_fd, *next;
 	int i, n;
@@ -128,15 +128,15 @@
 
 	if(type == IRQ_READ) events = POLLIN | POLLPRI;
 	else events = POLLOUT;
-	*new_fd = ((struct irq_fd) { next : 		NULL,
-				     id :		dev_id,
-				     fd :		fd,
-				     type :		type,
-				     irq :		irq,
-				     pid : 		pid,
-				     events :		events,
-				     current_events: 	0,
-				     freed :		0  } );
+	*new_fd = ((struct irq_fd) { .next  		= NULL,
+				     .id 		= dev_id,
+				     .fd 		= fd,
+				     .type 		= type,
+				     .irq 		= irq,
+				     .pid  		= pid,
+				     .events 		= events,
+				     .current_events 	= 0,
+				     .freed 		= 0  } );
 
 	/* Critical section - locked by a spinlock because this stuff can
 	 * be changed from interrupt handlers.  The stuff above is done 
@@ -191,9 +191,9 @@
 	if(type == IRQ_WRITE) 
 		fd = -1;
 
-	pollfds[pollfds_num] = ((struct pollfd) { fd :	fd,
-						  events :	events,
-						  revents :	0 });
+	pollfds[pollfds_num] = ((struct pollfd) { .fd 	= fd,
+						  .events 	= events,
+						  .revents 	= 0 });
 	pollfds_num++;
 
 	*last_irq_ptr = new_fd;
@@ -265,8 +265,8 @@
 
 void free_irq_by_irq_and_dev(int irq, void *dev)
 {
-	struct irq_and_dev data = ((struct irq_and_dev) { irq : irq,
-							  dev : dev });
+	struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
+							  .dev  = dev });
 
 	free_irq_by_cb(same_irq_and_dev, &data);
 }
diff -Nru a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
--- a/arch/um/kernel/ksyms.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/ksyms.c	Mon Feb 10 10:39:23 2003
@@ -14,6 +14,7 @@
 #include "asm/processor.h"
 #include "asm/unistd.h"
 #include "asm/pgalloc.h"
+#include "asm/pgtable.h"
 #include "asm/page.h"
 #include "asm/tlbflush.h"
 #include "kern_util.h"
@@ -42,7 +43,11 @@
 EXPORT_SYMBOL(phys_to_page);
 EXPORT_SYMBOL(high_physmem);
 EXPORT_SYMBOL(empty_zero_page);
+EXPORT_SYMBOL(um_virt_to_phys);
+EXPORT_SYMBOL(mode_tt);
+EXPORT_SYMBOL(handle_page_fault);
 
+EXPORT_SYMBOL(os_getpid);
 EXPORT_SYMBOL(os_open_file);
 EXPORT_SYMBOL(os_read_file);
 EXPORT_SYMBOL(os_write_file);
@@ -75,7 +80,6 @@
 extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
-EXPORT_SYMBOL(smp_num_cpus);
 #endif
 
 #ifdef CONFIG_HIGHMEM
diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
--- a/arch/um/kernel/mem.c	Mon Feb 10 10:39:25 2003
+++ b/arch/um/kernel/mem.c	Mon Feb 10 10:39:25 2003
@@ -27,6 +27,7 @@
 #include "init.h"
 #include "os.h"
 #include "mode_kern.h"
+#include "uml_uaccess.h"
 
 /* Changed during early boot */
 pgd_t swapper_pg_dir[1024];
@@ -231,11 +232,11 @@
 			panic("Failed to allocating mem_region");
 	}
 
-	*region = ((struct mem_region) { driver :	driver,
-					 start_pfn :	pfn,
-					 start :	start, 
-					 len :		len, 
-					 fd :		fd } );
+	*region = ((struct mem_region) { .driver 	= driver,
+					 .start_pfn 	= pfn,
+					 .start 	= start, 
+					 .len 		= len, 
+					 .fd 		= fd } );
 	regions[i] = region;
  out:
 	up(&regions_sem);
@@ -414,8 +415,28 @@
 
 struct page *arch_validate(struct page *page, int mask, int order)
 {
-	return(CHOOSE_MODE_PROC(arch_validate_tt, arch_validate_skas, page, 
-				mask, order));
+	unsigned long addr, zero = 0;
+	int i;
+
+ again:
+	if(page == NULL) return(page);
+	if(PageHighMem(page)) return(page);
+
+	addr = (unsigned long) page_address(page);
+	for(i = 0; i < (1 << order); i++){
+		current->thread.fault_addr = (void *) addr;
+		if(__do_copy_to_user((void *) addr, &zero, 
+				     sizeof(zero),
+				     &current->thread.fault_addr,
+				     &current->thread.fault_catcher)){
+			if(!(mask & __GFP_WAIT)) return(NULL);
+			else break;
+		}
+		addr += PAGE_SIZE;
+	}
+	if(i == (1 << order)) return(page);
+	page = alloc_pages(mask, order);
+	goto again;
 }
 
 DECLARE_MUTEX(vm_reserved_sem);
@@ -423,15 +444,15 @@
 
 /* Static structures, linked in to the list in early boot */
 static struct vm_reserved head = {
-	list :		LIST_HEAD_INIT(head.list),
-	start :		0,
-	end :		0xffffffff
+	.list 		= LIST_HEAD_INIT(head.list),
+	.start 		= 0,
+	.end 		= 0xffffffff
 };
 
 static struct vm_reserved tail = {
-	list :		LIST_HEAD_INIT(tail.list),
-	start :		0,
-	end :		0xffffffff
+	.list 		= LIST_HEAD_INIT(tail.list),
+	.start 		= 0,
+	.end 		= 0xffffffff
 };
 
 void set_usable_vm(unsigned long start, unsigned long end)
@@ -467,9 +488,9 @@
 		goto out;
 	}
 	*entry = ((struct vm_reserved) 
-		{ list :	LIST_HEAD_INIT(entry->list),
-		  start :	start,
-		  end :		end });
+		{ .list 	= LIST_HEAD_INIT(entry->list),
+		  .start 	= start,
+		  .end 		= end });
 	list_add(&entry->list, &prev->list);
 	err = 0;
  out:
@@ -539,9 +560,9 @@
  */
 
 struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
-					 { name : 	NULL,
-					   fd : 	-1,
-					   size :	0 } };
+					 { .name  	= NULL,
+					   .fd  	= -1,
+					   .size 	= 0 } };
 
 int num_iomem_regions = 0;
 
@@ -551,9 +572,9 @@
 		return;
 	size = (size + PAGE_SIZE - 1) & PAGE_MASK;
 	iomem_regions[num_iomem_regions++] = 
-		((struct iomem) { name :	name,
-				  fd :		fd,
-				  size :	size } );
+		((struct iomem) { .name 	= name,
+				  .fd 		= fd,
+				  .size 	= size } );
 }
 
 int setup_iomem(void)
diff -Nru a/arch/um/kernel/process.c b/arch/um/kernel/process.c
--- a/arch/um/kernel/process.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/kernel/process.c	Mon Feb 10 10:39:31 2003
@@ -37,17 +37,18 @@
 #include "uml-config.h"
 #include "choose-mode.h"
 #include "mode.h"
-#ifdef CONFIG_MODE_SKAS
-#include "skas_ptrace.h"
+#ifdef UML_CONFIG_MODE_SKAS
 #include "skas.h"
+#include "skas_ptrace.h"
 #endif
 
 void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
 {
-	int flags = 0;
+	int flags = 0, pages;
 
 	if(sig_stack != NULL){
-		set_sigstack(sig_stack, 2 * page_size());
+		pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
+		set_sigstack(sig_stack, pages * page_size());
 		flags = SA_ONSTACK;
 	}
 	if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
@@ -251,32 +252,32 @@
 
 int can_do_skas(void)
 {
-#ifdef CONFIG_MODE_SKAS
+#ifdef UML_CONFIG_MODE_SKAS
 	struct ptrace_faultinfo fi;
 	void *stack;
 	int pid, n, ret = 1;
 
-	printk("Checking for the skas3 patch in the host...");
+	printf("Checking for the skas3 patch in the host...");
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
 	if(n < 0){
 		if(errno == EIO)
-			printk("not found\n");
-		else printk("No (unexpected errno - %d)\n", errno);
+			printf("not found\n");
+		else printf("No (unexpected errno - %d)\n", errno);
 		ret = 0;
 	}
-	else printk("found\n");
+	else printf("found\n");
 
 	init_registers(pid);
 	stop_ptraced_child(pid, stack, 1);
 
-	printk("Checking for /proc/mm...");
+	printf("Checking for /proc/mm...");
 	if(access("/proc/mm", W_OK)){
-		printk("not found\n");
+		printf("not found\n");
 		ret = 0;
 	}
-	else printk("found\n");
+	else printf("found\n");
 
 	return(ret);
 #else
diff -Nru a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
--- a/arch/um/kernel/process_kern.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/process_kern.c	Mon Feb 10 10:39:27 2003
@@ -169,8 +169,12 @@
 
 void initial_thread_cb(void (*proc)(void *), void *arg)
 {
+	int save_kmalloc_ok = kmalloc_ok;
+
+	kmalloc_ok = 0;
 	CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 
 			 arg);
+	kmalloc_ok = save_kmalloc_ok;
 }
  
 unsigned long stack_sp(unsigned long page)
@@ -306,7 +310,11 @@
 
 int user_context(unsigned long sp)
 {
-	return((sp & (PAGE_MASK << 1)) != current->thread.kernel_stack);
+	unsigned long stack;
+
+	stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
+	stack += 2 * PAGE_SIZE;
+	return(stack != current->thread.kernel_stack);
 }
 
 extern void remove_umid_dir(void);
diff -Nru a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
--- a/arch/um/kernel/ptrace.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/ptrace.c	Mon Feb 10 10:39:23 2003
@@ -9,7 +9,9 @@
 #include "linux/smp_lock.h"
 #include "linux/security.h"
 #include "linux/ptrace.h"
+#ifdef CONFIG_PROC_MM
 #include "linux/proc_mm.h"
+#endif
 #include "asm/ptrace.h"
 #include "asm/uaccess.h"
 #include "kern_util.h"
diff -Nru a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
--- a/arch/um/kernel/sigio_user.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/sigio_user.c	Mon Feb 10 10:39:33 2003
@@ -52,7 +52,7 @@
 {
 	struct sigaction old, new;
 	struct termios tt;
-	struct openpty_arg pty = { master : -1, slave : -1 };
+	struct openpty_arg pty = { .master = -1, .slave = -1 };
 	int master, slave, flags;
 
 	initial_thread_cb(openpty_cb, &pty);
@@ -111,6 +111,7 @@
 
 	printk("Checking that host ptys support output SIGIO...");
 
+	memset(buf, 0, sizeof(buf));
 	while(write(master, buf, sizeof(buf)) > 0) ;
 	if(errno != EAGAIN)
 		panic("check_sigio : write failed, errno = %d\n", errno);
@@ -170,15 +171,15 @@
  * synchronizes with it.
  */
 struct pollfds current_poll = {
-	poll : 		NULL,
-	size :		0,
-	used :		0
+	.poll  		= NULL,
+	.size 		= 0,
+	.used 		= 0
 };
 
 struct pollfds next_poll = {
-	poll : 		NULL,
-	size :		0,
-	used :		0
+	.poll  		= NULL,
+	.size 		= 0,
+	.used 		= 0
 };
 
 static int write_sigio_thread(void *unused)
@@ -267,7 +268,8 @@
 	return;
  fail:
 	sigio_lock();
-	if(write_sigio_pid != -1) kill(write_sigio_pid, SIGKILL);
+	if(write_sigio_pid != -1) 
+		os_kill_process(write_sigio_pid, 1);
 	write_sigio_pid = -1;
 	close(sigio_private[0]);
 	close(sigio_private[1]);	
@@ -298,9 +300,9 @@
 	if(read) events = POLLIN;
 	else events = POLLOUT;
 
-	next_poll.poll[n - 1] = ((struct pollfd) { fd : 	fd,
-						   events :	events,
-						   revents :	0 });
+	next_poll.poll[n - 1] = ((struct pollfd) { .fd  	= fd,
+						   .events 	= events,
+						   .revents 	= 0 });
 	update_thread();
  out:
 	sigio_unlock();
@@ -348,12 +350,12 @@
 		printk("setup_initial_poll : failed to allocate poll\n");
 		return(-1);
 	}
-	*p = ((struct pollfd) { fd : 	fd,
-				events :	POLLIN,
-				revents :	0 });
-	current_poll = ((struct pollfds) { poll :	p,
-					   used :	1,
-					   size :	1 });
+	*p = ((struct pollfd) { .fd  	= fd,
+				.events 	= POLLIN,
+				.revents 	= 0 });
+	current_poll = ((struct pollfds) { .poll 	= p,
+					   .used 	= 1,
+					   .size 	= 1 });
 	return(0);
 }
 
@@ -394,7 +396,7 @@
 	return;
 
  out_kill:
-	kill(write_sigio_pid, SIGKILL);
+	os_kill_process(write_sigio_pid, 1);
 	write_sigio_pid = -1;
  out_close2:
 	close(sigio_private[0]);
@@ -420,7 +422,8 @@
 
 static void sigio_cleanup(void)
 {
-	if(write_sigio_pid != -1) kill(write_sigio_pid, SIGKILL);
+	if(write_sigio_pid != -1)
+		os_kill_process(write_sigio_pid, 1);
 }
 
 __uml_exitcall(sigio_cleanup);
diff -Nru a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
--- a/arch/um/kernel/signal_kern.c	Mon Feb 10 10:39:28 2003
+++ b/arch/um/kernel/signal_kern.c	Mon Feb 10 10:39:28 2003
@@ -18,6 +18,7 @@
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
 #include "user_util.h"
+#include "asm/ucontext.h"
 #include "kern_util.h"
 #include "signal_kern.h"
 #include "signal_user.h"
@@ -29,18 +30,6 @@
 EXPORT_SYMBOL(block_signals);
 EXPORT_SYMBOL(unblock_signals);
 
-int probe_stack(unsigned long sp, int delta)
-{
-	int n;
-
-	if((get_user(n, (int *) sp) != 0) ||
-	   (put_user(n, (int *) sp) != 0) ||
-	   (get_user(n, (int *) (sp - delta)) != 0) ||
-	   (put_user(n, (int *) (sp - delta)) != 0))
-		return(-EFAULT);
-	return(0);
-}
-
 static void force_segv(int sig)
 {
 	if(sig == SIGSEGV){
@@ -106,12 +95,12 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked, &current->blocked, 
 			  &ka->sa.sa_mask);
 		sigaddset(&current->blocked, signr);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 
 	sp = PT_REGS_SP(regs);
@@ -197,11 +186,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
@@ -223,11 +212,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
@@ -237,45 +226,48 @@
 	}
 }
 
-static int copy_sc_from_user(struct pt_regs *to, void *from)
+static int copy_sc_from_user(struct pt_regs *to, void *from, 
+			     struct arch_frame_data *arch)
 {
 	int ret;
 
-	ret = CHOOSE_MODE(copy_sc_from_user_tt(to->regs.mode.tt, from, 
-					       &signal_frame_sc.arch),
+	ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
 			  copy_sc_from_user_skas(&to->regs, from));
 	return(ret);
 }
 
 int sys_sigreturn(struct pt_regs regs)
 {
-	void *sc = sp_to_sc(PT_REGS_SP(&regs));
-	void *mask = sp_to_mask(PT_REGS_SP(&regs));
+	void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
+	void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
 	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
 		       sizeof(current->blocked.sig[0]));
 	copy_from_user(&current->blocked.sig[1], mask, sig_size);
 	sigdelsetmask(&current->blocked, ~_BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
-	copy_sc_from_user(&current->thread.regs, sc);
+	spin_unlock_irq(&current->sighand->siglock);
+	copy_sc_from_user(&current->thread.regs, sc, 
+			  &signal_frame_sc.common.arch);
 	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
 }
 
 int sys_rt_sigreturn(struct pt_regs regs)
 {
-	void *sc = sp_to_rt_sc(PT_REGS_SP(&regs));
-	void *mask = sp_to_rt_mask(PT_REGS_SP(&regs));
+	struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
+	void *fp;
 	int sig_size = _NSIG_WORDS * sizeof(unsigned long);
 
-	spin_lock_irq(&current->sig->siglock);
-	copy_from_user(&current->blocked, mask, sig_size);
+	spin_lock_irq(&current->sighand->siglock);
+	copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
 	sigdelsetmask(&current->blocked, ~_BLOCKABLE);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
-	copy_sc_from_user(&current->thread.regs, sc);
+	spin_unlock_irq(&current->sighand->siglock);
+	fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
+	copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
+			  &signal_frame_si.common.arch);
 	return(PT_REGS_SYSCALL_RET(&current->thread.regs));
 }
 
diff -Nru a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
--- a/arch/um/kernel/skas/include/mode.h	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/skas/include/mode.h	Mon Feb 10 10:39:27 2003
@@ -12,10 +12,11 @@
 extern int have_fpx_regs;
 
 extern void user_time_init_skas(void);
-extern int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr);
-extern int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, 
+extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
+extern int copy_sc_to_user_skas(void *to_ptr, void *fp, 
+				union uml_pt_regs *regs, 
 				unsigned long fault_addr, int fault_type);
-extern void sig_handler_common_skas(int sig, struct sigcontext *sc);
+extern void sig_handler_common_skas(int sig, void *sc_ptr);
 extern void halt_skas(void);
 extern void reboot_skas(void);
 extern void kill_off_processes_skas(void);
diff -Nru a/arch/um/kernel/skas/include/mode_kern.h b/arch/um/kernel/skas/include/mode_kern.h
--- a/arch/um/kernel/skas/include/mode_kern.h	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/skas/include/mode_kern.h	Mon Feb 10 10:39:27 2003
@@ -21,6 +21,8 @@
 extern void exit_thread_skas(void);
 extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
 extern void init_idle_skas(void);
+extern void flush_tlb_kernel_range_skas(unsigned long start, 
+					unsigned long end);
 extern void flush_tlb_kernel_vm_skas(void);
 extern void __flush_tlb_one_skas(unsigned long addr);
 extern void flush_tlb_range_skas(struct vm_area_struct *vma, 
@@ -32,11 +34,10 @@
 extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
 					 unsigned long *task_size_out);
 extern int start_uml_skas(void);
-extern struct page *arch_validate_skas(struct page *page, int mask, int order);
 extern int external_pid_skas(struct task_struct *task);
 extern int thread_pid_skas(struct task_struct *task);
 
-#define kmem_end_skas (host_task_size)
+#define kmem_end_skas (host_task_size - 1024 * 1024)
 
 #endif
 
diff -Nru a/arch/um/kernel/skas/include/ptrace-skas.h b/arch/um/kernel/skas/include/ptrace-skas.h
--- a/arch/um/kernel/skas/include/ptrace-skas.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/skas/include/ptrace-skas.h	Mon Feb 10 10:39:23 2003
@@ -8,7 +8,7 @@
 
 #include "uml-config.h"
 
-#ifdef CONFIG_MODE_SKAS
+#ifdef UML_CONFIG_MODE_SKAS
 
 #include "skas_ptregs.h"
 
diff -Nru a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
--- a/arch/um/kernel/skas/include/skas.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/skas/include/skas.h	Mon Feb 10 10:39:24 2003
@@ -17,21 +17,21 @@
 extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
 			     void **fork_buf_ptr);
 extern int user_thread(unsigned long stack, int flags);
-extern void userspace(struct uml_pt_regs *regs);
+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(struct uml_pt_regs *regs);
+extern void handle_syscall(union uml_pt_regs *regs);
 extern void map(int fd, unsigned long virt, unsigned long phys, 
 		unsigned long len, int r, int w, int x);
 extern int unmap(int fd, void *addr, int len);
 extern int protect(int fd, unsigned long addr, unsigned long len, 
 		   int r, int w, int x, int must_succeed);
-extern void user_signal(int sig, struct uml_pt_regs *regs);
+extern void user_signal(int sig, union uml_pt_regs *regs);
 extern int singlestepping_skas(void);
 extern int new_mm(int from);
-extern void save_registers(struct uml_pt_regs *regs);
-extern void restore_registers(struct uml_pt_regs *regs);
+extern void save_registers(union uml_pt_regs *regs);
+extern void restore_registers(union uml_pt_regs *regs);
 extern void start_userspace(void);
 extern void init_registers(int pid);
 
diff -Nru a/arch/um/kernel/skas/include/skas_ptrace.h b/arch/um/kernel/skas/include/skas_ptrace.h
--- a/arch/um/kernel/skas/include/skas_ptrace.h	Mon Feb 10 10:39:31 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,36 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_PTRACE_H
-#define __SKAS_PTRACE_H
-
-struct ptrace_faultinfo {
-	int is_write;
-	unsigned long addr;
-};
-
-struct ptrace_ldt {
-	int func;
-  	void *ptr;
-	unsigned long bytecount;
-};
-
-#define PTRACE_FAULTINFO 52
-#define PTRACE_SIGPENDING 53
-#define PTRACE_LDT 54
-#define PTRACE_SWITCH_MM 55
-
-#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 -Nru a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
--- a/arch/um/kernel/skas/include/uaccess.h	Mon Feb 10 10:39:26 2003
+++ b/arch/um/kernel/skas/include/uaccess.h	Mon Feb 10 10:39:26 2003
@@ -27,9 +27,6 @@
 	return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
 }
 
-extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
-			     pte_t *pte_out);
-
 static inline unsigned long maybe_map(unsigned long virt, int is_write)
 {
 	pte_t pte;
diff -Nru a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
--- a/arch/um/kernel/skas/mem.c	Mon Feb 10 10:39:32 2003
+++ b/arch/um/kernel/skas/mem.c	Mon Feb 10 10:39:32 2003
@@ -18,11 +18,6 @@
 	return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
 }
 
-struct page *arch_validate_skas(struct page *page, int mask, int order)
-{
-	return(page);
-}
-
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -Nru a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
--- a/arch/um/kernel/skas/mem_user.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/skas/mem_user.c	Mon Feb 10 10:39:24 2003
@@ -33,7 +33,7 @@
 					 .fd		= region->fd,
 					 .offset	= phys_offset(phys)
 				       } } } );
-	n = os_write_file(fd, (char *) &map, sizeof(map));
+	n = os_write_file(fd, &map, sizeof(map));
 	if(n != sizeof(map)) 
 		printk("map : /proc/mm map failed, errno = %d\n", errno);
 }
@@ -48,7 +48,7 @@
 				       { .munmap	= 
 					 { .addr 	= (unsigned long) addr,
 					   .len		= len } } } );
-	n = os_write_file(fd, (char *) &unmap, sizeof(unmap));
+	n = os_write_file(fd, &unmap, sizeof(unmap));
 	if((n != 0) && (n != sizeof(unmap)))
 		return(-errno);
 	return(0);
@@ -70,7 +70,7 @@
 					   .len		= len,
 					   .prot	= prot } } } );
 
-	n = os_write_file(fd, (char *) &protect, sizeof(protect));
+	n = os_write_file(fd, &protect, sizeof(protect));
 	if((n != 0) && (n != sizeof(protect))){
 		if(must_succeed)
 			panic("protect failed, errno = %d", errno);
diff -Nru a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
--- a/arch/um/kernel/skas/process.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/skas/process.c	Mon Feb 10 10:39:33 2003
@@ -20,10 +20,10 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "skas.h"
-#include "skas_ptrace.h"
 #include "sysdep/sigcontext.h"
 #include "os.h"
 #include "proc_mm.h"
+#include "skas_ptrace.h"
 
 unsigned long exec_regs[FRAME_SIZE];
 unsigned long exec_fp_regs[HOST_FP_SIZE];
@@ -39,14 +39,15 @@
 	if(err)
 		panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
 		      errno);
+
 	segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
 }
 
-static void handle_trap(int pid, struct uml_pt_regs *regs)
+static void handle_trap(int pid, union uml_pt_regs *regs)
 {
 	int err, syscall_nr, status;
 
-	syscall_nr = PT_SYSCALL_NR(regs->mode.skas.regs);
+	syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
 	if(syscall_nr < 1){
 		relay_signal(SIGTRAP, regs);
 		return;
@@ -79,6 +80,7 @@
 	enable_timer();
 	ptrace(PTRACE_TRACEME, 0, 0, 0);
 	os_stop_process(os_getpid());
+	return(0);
 }
 
 void start_userspace(void)
@@ -115,7 +117,7 @@
 	userspace_pid = pid;
 }
 
-void userspace(struct uml_pt_regs *regs)
+void userspace(union uml_pt_regs *regs)
 {
 	int err, status, op;
 
@@ -131,7 +133,7 @@
 			panic("userspace - waitpid failed, errno = %d\n", 
 			      errno);
 
-		regs->is_user = 1;
+		regs->skas.is_user = 1;
 		save_registers(regs);
 
 		if(WIFSTOPPED(status)){
@@ -191,28 +193,28 @@
 		longjmp(*fork_buf, 1);
 }
 
-static int move_registers(int int_op, int fp_op, struct uml_pt_regs *regs,
+static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
 			  unsigned long *fp_regs)
 {
-	if(ptrace(int_op, userspace_pid, 0, regs->mode.skas.regs) < 0)
+	if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
 		return(-errno);
 	if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
 		return(-errno);
 	return(0);
 }
 
-void save_registers(struct uml_pt_regs *regs)
+void save_registers(union uml_pt_regs *regs)
 {
 	unsigned long *fp_regs;
 	int err, fp_op;
 
 	if(have_fpx_regs){
 		fp_op = PTRACE_GETFPXREGS;
-		fp_regs = regs->mode.skas.xfp;
+		fp_regs = regs->skas.xfp;
 	}
 	else {
 		fp_op = PTRACE_GETFPREGS;
-		fp_regs = regs->mode.skas.fp;
+		fp_regs = regs->skas.fp;
 	}
 
 	err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
@@ -221,18 +223,18 @@
 		      err);
 }
 
-void restore_registers(struct uml_pt_regs *regs)
+void restore_registers(union uml_pt_regs *regs)
 {
 	unsigned long *fp_regs;
 	int err, fp_op;
 
 	if(have_fpx_regs){
 		fp_op = PTRACE_SETFPXREGS;
-		fp_regs = regs->mode.skas.xfp;
+		fp_regs = regs->skas.xfp;
 	}
 	else {
 		fp_op = PTRACE_SETFPREGS;
-		fp_regs = regs->mode.skas.fp;
+		fp_regs = regs->skas.fp;
 	}
 
 	err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
@@ -272,10 +274,14 @@
 		(*cb_proc)(cb_arg);
 		longjmp(*cb_back, 1);
 	}
-	else if(n == 3)
+	else if(n == 3){
+		kmalloc_ok = 0;
 		return(0);
-	else if(n == 4)
+	}
+	else if(n == 4){
+		kmalloc_ok = 0;
 		return(1);
+	}
 	longjmp(**switch_buf, 1);
 }
 
@@ -296,8 +302,11 @@
 	cb_proc = proc;
 	cb_arg = arg;
 	cb_back = &here;
+
+	block_signals();
 	if(setjmp(here) == 0)
 		longjmp(initial_jmpbuf, 2);
+	unblock_signals();
 
 	cb_proc = NULL;
 	cb_arg = NULL;
@@ -328,7 +337,7 @@
 		copy = ((struct proc_mm_op) { .op 	= MM_COPY_SEGMENTS,
 					      .u 	= 
 					      { .copy_segments	= from } } );
-		n = os_write_file(fd, (char *) &copy, sizeof(copy));
+		n = os_write_file(fd, &copy, sizeof(copy));
 		if(n != sizeof(copy)) 
 			printk("new_mm : /proc/mm copy_segments failed, "
 			       "errno = %d\n", errno);
diff -Nru a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
--- a/arch/um/kernel/skas/process_kern.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/skas/process_kern.c	Mon Feb 10 10:39:24 2003
@@ -68,8 +68,7 @@
 	n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
 	if(n == 1)
 		userspace(&current->thread.regs.regs);
-	else if(n == 2)
-		do_exit(0);
+	else do_exit(0);
 }
 
 void new_thread_proc(void *stack, void (*handler)(int sig))
@@ -109,21 +108,21 @@
   	void (*handler)(int);
 
 	if(current->thread.forking){
-	  	memcpy(&p->thread.regs.regs.mode.skas, 
-		       &current->thread.regs.regs.mode.skas, 
-		       sizeof(p->thread.regs.regs.mode.skas));
-		REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.skas.regs, 0);
-		if(sp != 0) REGS_SP(p->thread.regs.regs.mode.skas.regs) = sp;
+	  	memcpy(&p->thread.regs.regs.skas, 
+		       &current->thread.regs.regs.skas, 
+		       sizeof(p->thread.regs.regs.skas));
+		REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
+		if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
 
 		handler = fork_handler;
 	}
 	else {
-	  	memcpy(p->thread.regs.regs.mode.skas.regs, exec_regs, 
-		       sizeof(p->thread.regs.regs.mode.skas.regs));
-		memcpy(p->thread.regs.regs.mode.skas.fp, exec_fp_regs, 
-		       sizeof(p->thread.regs.regs.mode.skas.fp));
-	  	memcpy(p->thread.regs.regs.mode.skas.xfp, exec_fpx_regs, 
-		       sizeof(p->thread.regs.regs.mode.skas.xfp));
+	  	memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
+		       sizeof(p->thread.regs.regs.skas.regs));
+		memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
+		       sizeof(p->thread.regs.regs.skas.fp));
+	  	memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
+		       sizeof(p->thread.regs.regs.skas.xfp));
                 p->thread.request.u.thread = current->thread.request.u.thread;
 		handler = new_thread_handler;
 	}
diff -Nru a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c
--- a/arch/um/kernel/skas/sys-i386/sigcontext.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/skas/sys-i386/sigcontext.c	Mon Feb 10 10:39:23 2003
@@ -15,7 +15,7 @@
 
 extern int userspace_pid;
 
-int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr)
+int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
 {
   	struct sigcontext sc, *from = from_ptr;
 	unsigned long fpregs[FP_FRAME_SIZE];
@@ -26,26 +26,26 @@
 	if(err)
 		return(err);
 
-	regs->mode.skas.regs[GS] = sc.gs;
-	regs->mode.skas.regs[FS] = sc.fs;
-	regs->mode.skas.regs[ES] = sc.es;
-	regs->mode.skas.regs[DS] = sc.ds;
-	regs->mode.skas.regs[EDI] = sc.edi;
-	regs->mode.skas.regs[ESI] = sc.esi;
-	regs->mode.skas.regs[EBP] = sc.ebp;
-	regs->mode.skas.regs[UESP] = sc.esp;
-	regs->mode.skas.regs[EBX] = sc.ebx;
-	regs->mode.skas.regs[EDX] = sc.edx;
-	regs->mode.skas.regs[ECX] = sc.ecx;
-	regs->mode.skas.regs[EAX] = sc.eax;
-	regs->mode.skas.regs[EIP] = sc.eip;
-	regs->mode.skas.regs[CS] = sc.cs;
-	regs->mode.skas.regs[EFL] = sc.eflags;
-	regs->mode.skas.regs[UESP] = sc.esp_at_signal;
-	regs->mode.skas.regs[SS] = sc.ss;
-	regs->mode.skas.fault_addr = sc.cr2;
-	regs->mode.skas.fault_type = FAULT_WRITE(sc.err);
-	regs->mode.skas.trap_type = sc.trapno;
+	regs->skas.regs[GS] = sc.gs;
+	regs->skas.regs[FS] = sc.fs;
+	regs->skas.regs[ES] = sc.es;
+	regs->skas.regs[DS] = sc.ds;
+	regs->skas.regs[EDI] = sc.edi;
+	regs->skas.regs[ESI] = sc.esi;
+	regs->skas.regs[EBP] = sc.ebp;
+	regs->skas.regs[UESP] = sc.esp;
+	regs->skas.regs[EBX] = sc.ebx;
+	regs->skas.regs[EDX] = sc.edx;
+	regs->skas.regs[ECX] = sc.ecx;
+	regs->skas.regs[EAX] = sc.eax;
+	regs->skas.regs[EIP] = sc.eip;
+	regs->skas.regs[CS] = sc.cs;
+	regs->skas.regs[EFL] = sc.eflags;
+	regs->skas.regs[UESP] = sc.esp_at_signal;
+	regs->skas.regs[SS] = sc.ss;
+	regs->skas.fault_addr = sc.cr2;
+	regs->skas.fault_type = FAULT_WRITE(sc.err);
+	regs->skas.trap_type = sc.trapno;
 
 	err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
 	if(err < 0){
@@ -57,7 +57,7 @@
 	return(0);
 }
 
-int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, 
+int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, 
 			 unsigned long fault_addr, int fault_type)
 {
   	struct sigcontext sc, *to = to_ptr;
@@ -65,26 +65,26 @@
 	unsigned long fpregs[FP_FRAME_SIZE];
 	int err;
 
-	sc.gs = regs->mode.skas.regs[GS];
-	sc.fs = regs->mode.skas.regs[FS];
-	sc.es = regs->mode.skas.regs[ES];
-	sc.ds = regs->mode.skas.regs[DS];
-	sc.edi = regs->mode.skas.regs[EDI];
-	sc.esi = regs->mode.skas.regs[ESI];
-	sc.ebp = regs->mode.skas.regs[EBP];
-	sc.esp = regs->mode.skas.regs[UESP];
-	sc.ebx = regs->mode.skas.regs[EBX];
-	sc.edx = regs->mode.skas.regs[EDX];
-	sc.ecx = regs->mode.skas.regs[ECX];
-	sc.eax = regs->mode.skas.regs[EAX];
-	sc.eip = regs->mode.skas.regs[EIP];
-	sc.cs = regs->mode.skas.regs[CS];
-	sc.eflags = regs->mode.skas.regs[EFL];
-	sc.esp_at_signal = regs->mode.skas.regs[UESP];
-	sc.ss = regs->mode.skas.regs[SS];
+	sc.gs = regs->skas.regs[GS];
+	sc.fs = regs->skas.regs[FS];
+	sc.es = regs->skas.regs[ES];
+	sc.ds = regs->skas.regs[DS];
+	sc.edi = regs->skas.regs[EDI];
+	sc.esi = regs->skas.regs[ESI];
+	sc.ebp = regs->skas.regs[EBP];
+	sc.esp = regs->skas.regs[UESP];
+	sc.ebx = regs->skas.regs[EBX];
+	sc.edx = regs->skas.regs[EDX];
+	sc.ecx = regs->skas.regs[ECX];
+	sc.eax = regs->skas.regs[EAX];
+	sc.eip = regs->skas.regs[EIP];
+	sc.cs = regs->skas.regs[CS];
+	sc.eflags = regs->skas.regs[EFL];
+	sc.esp_at_signal = regs->skas.regs[UESP];
+	sc.ss = regs->skas.regs[SS];
 	sc.cr2 = fault_addr;
 	sc.err = TO_SC_ERR(fault_type);
-	sc.trapno = regs->mode.skas.trap_type;
+	sc.trapno = regs->skas.trap_type;
 
 	err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
 	if(err < 0){
@@ -92,7 +92,8 @@
 		       "errno = %d\n", errno);
 		return(1);
 	}
-	to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to));
+	to_fp = (struct _fpstate *) 
+		(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
 	sc.fpstate = to_fp;
 
 	if(err)
diff -Nru a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c
--- a/arch/um/kernel/skas/syscall_kern.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/skas/syscall_kern.c	Mon Feb 10 10:39:29 2003
@@ -21,7 +21,7 @@
 
 	current->thread.nsyscalls++;
 	nsyscalls++;
-	syscall = regs->regs.syscall;
+	syscall = UPT_SYSCALL_NR(&regs->regs);
 
 	if((syscall >= NR_syscalls) || (syscall < 0))
 		res = -ENOSYS;
diff -Nru a/arch/um/kernel/skas/syscall_user.c b/arch/um/kernel/skas/syscall_user.c
--- a/arch/um/kernel/skas/syscall_user.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/skas/syscall_user.c	Mon Feb 10 10:39:33 2003
@@ -15,18 +15,17 @@
 #define ERESTARTNOINTR	513
 #define ERESTARTNOHAND	514
 
-void handle_syscall(struct uml_pt_regs *regs)
+void handle_syscall(union uml_pt_regs *regs)
 {
 	long result;
 	int index;
 
-	host_to_regs(regs);
 	index = record_syscall_start(UPT_SYSCALL_NR(regs));
 
 	syscall_trace();
 	result = execute_syscall(regs);
 
-	REGS_SET_SYSCALL_RETURN(regs->mode.skas.regs, result);
+	REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
 	if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
 	   (result == -ERESTARTNOINTR))
 		do_signal(result);
diff -Nru a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
--- a/arch/um/kernel/skas/tlb.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/skas/tlb.c	Mon Feb 10 10:39:27 2003
@@ -67,7 +67,7 @@
 	}
 }
 
-static void flush_kernel_vm_range(unsigned long start, unsigned long end)
+void flush_tlb_kernel_range_skas(unsigned long start, unsigned long end)
 {
 	struct mm_struct *mm;
 	pgd_t *pgd;
@@ -99,7 +99,6 @@
 				protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
 			}
 			addr += PAGE_SIZE;
-
 		}
 		else {
 			if(pmd_newpage(*pmd)){
@@ -116,27 +115,26 @@
 
 void flush_tlb_kernel_vm_skas(void)
 {
-	flush_kernel_vm_range(start_vm, end_vm);
+	flush_tlb_kernel_range_skas(start_vm, end_vm);
 }
 
 void __flush_tlb_one_skas(unsigned long addr)
 {
-	flush_kernel_vm_range(addr, addr + PAGE_SIZE);
+	flush_tlb_kernel_range_skas(addr, addr + PAGE_SIZE);
 }
 
 void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, 
 		     unsigned long end)
 {
 	if(vma->vm_mm == NULL)
-		flush_kernel_vm_range(start, end);
+		flush_tlb_kernel_range_skas(start, end);
 	else fix_range(vma->vm_mm, start, end, 0);
 }
 
 void flush_tlb_mm_skas(struct mm_struct *mm)
 {
-	if(mm == NULL)
-		flush_tlb_kernel_vm_skas();
-	else fix_range(mm, 0, host_task_size, 0);
+	flush_tlb_kernel_vm_skas();
+	fix_range(mm, 0, host_task_size, 0);
 }
 
 void force_flush_all_skas(void)
diff -Nru a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
--- a/arch/um/kernel/skas/trap_user.c	Mon Feb 10 10:39:26 2003
+++ b/arch/um/kernel/skas/trap_user.c	Mon Feb 10 10:39:26 2003
@@ -13,41 +13,40 @@
 #include "task.h"
 #include "sigcontext.h"
 
-void sig_handler_common_skas(int sig, struct sigcontext *sc)
+void sig_handler_common_skas(int sig, void *sc_ptr)
 {
-	struct uml_pt_regs save_regs, *r;
+	struct sigcontext *sc = sc_ptr;
+	struct skas_regs *r;
 	struct signal_info *info;
 	int save_errno = errno;
 
-	r = (struct uml_pt_regs *) TASK_REGS(get_current());
-	save_regs = *r;
+	r = &TASK_REGS(get_current())->skas;
 	r->is_user = 0;
-	r->mode.skas.fault_addr = SC_FAULT_ADDR(sc);
-	r->mode.skas.fault_type = SC_FAULT_TYPE(sc);
-	r->mode.skas.trap_type = SC_TRAP_TYPE(sc);
+	r->fault_addr = SC_FAULT_ADDR(sc);
+	r->fault_type = SC_FAULT_TYPE(sc);
+	r->trap_type = SC_TRAP_TYPE(sc);
 
 	change_sig(SIGUSR1, 1);
 	info = &sig_info[sig];
 	if(!info->is_irq) unblock_signals();
 
-	(*info->handler)(sig, r);
+	(*info->handler)(sig, (union uml_pt_regs *) r);
 
-	*r = save_regs;
 	errno = save_errno;
 }
 
 extern int missed_ticks[];
 
-void user_signal(int sig, struct uml_pt_regs *regs)
+void user_signal(int sig, union uml_pt_regs *regs)
 {
 	struct signal_info *info;
 
 	if(sig == SIGVTALRM)
 		missed_ticks[cpu()]++;
-	regs->is_user = 1;
-	regs->mode.skas.fault_addr = 0;
-	regs->mode.skas.fault_type = 0;
-	regs->mode.skas.trap_type = 0;
+	regs->skas.is_user = 1;
+	regs->skas.fault_addr = 0;
+	regs->skas.fault_type = 0;
+	regs->skas.trap_type = 0;
 	info = &sig_info[sig];
 	(*info->handler)(sig, regs);
 
diff -Nru a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
--- a/arch/um/kernel/smp.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/smp.c	Mon Feb 10 10:39:24 2003
@@ -13,6 +13,7 @@
 #include "linux/sched.h"
 #include "linux/threads.h"
 #include "linux/interrupt.h"
+#include "linux/err.h"
 #include "asm/smp.h"
 #include "asm/processor.h"
 #include "asm/spinlock.h"
@@ -140,7 +141,7 @@
 
         current->thread.request.u.thread.proc = idle_proc;
         current->thread.request.u.thread.arg = (void *) cpu;
-	new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL);
+	new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
 	if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
 
 	cpu_tasks[cpu] = ((struct cpu_task) 
@@ -186,7 +187,7 @@
 	}
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void smp_prepare_boot_cpu(void)
 {
 	set_bit(smp_processor_id(), &cpu_online_map);
 }
diff -Nru a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
--- a/arch/um/kernel/sys_call_table.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/kernel/sys_call_table.c	Mon Feb 10 10:39:31 2003
@@ -481,8 +481,6 @@
 	[ __NR_io_getevents ] = sys_io_getevents,
 	[ __NR_io_submit ] = sys_io_submit,
 	[ __NR_io_cancel ] = sys_io_cancel,
-	[ __NR_alloc_hugepages ] = sys_ni_syscall,
-	[ __NR_free_hugepages ] = sys_ni_syscall,
 	[ __NR_exit_group ] = sys_exit_group,
 	[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
 	[ __NR_epoll_create ] = sys_epoll_create,
diff -Nru a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
--- a/arch/um/kernel/tempfile.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/tempfile.c	Mon Feb 10 10:39:27 2003
@@ -23,20 +23,19 @@
 	if(tempdir != NULL) return;	/* We've already been called */
 	for(i = 0; dirs[i]; i++){
 		dir = getenv(dirs[i]);
-		if(dir != NULL) break;
+		if((dir != NULL) && (*dir != '\0'))
+			break;
 	}
-	if(dir == NULL) dir = "/tmp";
-	else if(*dir == '\0') dir = NULL;
-	if(dir != NULL) {
-		tempdir = malloc(strlen(dir) + 2);
-		if(tempdir == NULL){
-			fprintf(stderr, "Failed to malloc tempdir, "
-				"errno = %d\n", errno);
-			return;
-		}
-		strcpy(tempdir, dir);
-		strcat(tempdir, "/");
+	if((dir == NULL) || (*dir == '\0')) 
+		dir = "/tmp";
+	tempdir = malloc(strlen(dir) + 2);
+	if(tempdir == NULL){
+		fprintf(stderr, "Failed to malloc tempdir, "
+			"errno = %d\n", errno);
+		return;
 	}
+	strcpy(tempdir, dir);
+	strcat(tempdir, "/");
 }
 
 int make_tempfile(const char *template, char **out_tempname, int do_unlink)
diff -Nru a/arch/um/kernel/time.c b/arch/um/kernel/time.c
--- a/arch/um/kernel/time.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/time.c	Mon Feb 10 10:39:24 2003
@@ -86,20 +86,23 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	time_lock();
+	unsigned long flags;
+
+	flags = time_lock();
 	gettimeofday(tv, NULL);
 	timeradd(tv, &local_offset, tv);
-	time_unlock();
+	time_unlock(flags);
 }
 
 void do_settimeofday(struct timeval *tv)
 {
 	struct timeval now;
+	unsigned long flags;
 
-	time_lock();
+	flags = time_lock();
 	gettimeofday(&now, NULL);
 	timersub(tv, &now, &local_offset);
-	time_unlock();
+	time_unlock(flags);
 }
 
 void idle_sleep(int secs)
@@ -108,7 +111,7 @@
 
 	ts.tv_sec = secs;
 	ts.tv_nsec = 0;
-	nanosleep(&ts, &ts);
+	nanosleep(&ts, NULL);
 }
 
 /*
diff -Nru a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
--- a/arch/um/kernel/time_kern.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/time_kern.c	Mon Feb 10 10:39:29 2003
@@ -7,6 +7,7 @@
 #include "linux/unistd.h"
 #include "linux/stddef.h"
 #include "linux/spinlock.h"
+#include "linux/time.h"
 #include "linux/sched.h"
 #include "linux/interrupt.h"
 #include "linux/init.h"
@@ -21,8 +22,6 @@
 
 u64 jiffies_64;
 
-extern rwlock_t xtime_lock;
-
 int hz(void)
 {
 	return(HZ);
@@ -37,7 +36,7 @@
  */
 int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
 
-void timer_irq(struct uml_pt_regs *regs)
+void timer_irq(union uml_pt_regs *regs)
 {
 	int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
 
@@ -50,16 +49,18 @@
 {
 	struct pt_regs regs;
 
-	regs.regs.is_user = 0;
+	CHOOSE_MODE((void) 
+		    (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
+		    (void) (regs.regs.skas.is_user = 0));
 	do_timer(&regs);
 }
 
 void um_timer(int irq, void *dev, struct pt_regs *regs)
 {
 	do_timer(regs);
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	timer();
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 long um_time(int * tloc)
@@ -118,7 +119,7 @@
 	for(i=0;i<n;i++) ;
 }
 
-void timer_handler(int sig, struct uml_pt_regs *regs)
+void timer_handler(int sig, union uml_pt_regs *regs)
 {
 #ifdef CONFIG_SMP
 	update_process_times(user_context(UPT_SP(regs)));
@@ -129,14 +130,16 @@
 
 static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
 
-void time_lock(void)
+unsigned long time_lock(void)
 {
-	spin_lock(&timer_spinlock);
+	unsigned long flags;
+	spin_lock_irqsave(&timer_spinlock, flags);
+	return(flags);
 }
 
-void time_unlock(void)
+void time_unlock(unsigned long flags)
 {
-	spin_unlock(&timer_spinlock);
+	spin_unlock_irqrestore(&timer_spinlock, flags);
 }
 
 int __init timer_init(void)
diff -Nru a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
--- a/arch/um/kernel/tlb.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/kernel/tlb.c	Mon Feb 10 10:39:30 2003
@@ -21,6 +21,12 @@
 	flush_tlb_mm(current->mm);
 }
   
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, 
+			 flush_tlb_kernel_range_skas, start, end);
+}
+
 void flush_tlb_kernel_vm(void)
 {
 	CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
diff -Nru a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
--- a/arch/um/kernel/trap_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/trap_kern.c	Mon Feb 10 10:39:23 2003
@@ -109,7 +109,8 @@
                 flush_tlb_kernel_vm();
                 return(0);
         }
-        if(current->mm == NULL) panic("Segfault with no mm");
+        if(current->mm == NULL)
+		panic("Segfault with no mm");
 	err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
 
 	catcher = current->thread.fault_catcher;
@@ -164,14 +165,15 @@
 	force_sig_info(SIGSEGV, &si, current);
 }
 
-void relay_signal(int sig, struct uml_pt_regs *regs)
+void relay_signal(int sig, union uml_pt_regs *regs)
 {
 	if(arch_handle_signal(sig, regs)) return;
-	if(!regs->is_user) panic("Kernel mode signal %d", sig);
+	if(!UPT_IS_USER(regs))
+		panic("Kernel mode signal %d", sig);
 	force_sig(sig, current);
 }
 
-void bus_handler(int sig, struct uml_pt_regs *regs)
+void bus_handler(int sig, union uml_pt_regs *regs)
 {
 	if(current->thread.fault_catcher != NULL)
 		do_longjmp(current->thread.fault_catcher, 1);
diff -Nru a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
--- a/arch/um/kernel/trap_user.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/trap_user.c	Mon Feb 10 10:39:27 2003
@@ -48,11 +48,11 @@
 	int is_user;
 } segfault_record[1024];
 
-void segv_handler(int sig, struct uml_pt_regs *regs)
+void segv_handler(int sig, union uml_pt_regs *regs)
 {
 	int index, max;
 
-	if(regs->is_user && !UPT_SEGV_IS_FIXABLE(regs)){
+	if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
 		bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
 			 UPT_FAULT_WRITE(regs));
 		return;
@@ -65,35 +65,35 @@
 	segfault_record[index].pid = os_getpid();
 	segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
 	segfault_record[index].sp = UPT_SP(regs);
-	segfault_record[index].is_user = regs->is_user;
+	segfault_record[index].is_user = UPT_IS_USER(regs);
 	segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
-	     regs->is_user, regs);
+	     UPT_IS_USER(regs), regs);
 }
 
-void usr2_handler(int sig, struct uml_pt_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 },
-	[ 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 },
+	[ SIGTRAP ] { .handler 		= relay_signal,
+		      .is_irq 		= 0 },
+	[ SIGFPE ] { .handler 		= relay_signal,
+		     .is_irq 		= 0 },
+	[ SIGILL ] { .handler 		= relay_signal,
+		     .is_irq 		= 0 },
+	[ 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 sig_handler(int sig, struct sigcontext sc)
diff -Nru a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
--- a/arch/um/kernel/tt/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/um/kernel/tt/Makefile	Mon Feb 10 10:39:27 2003
@@ -3,18 +3,29 @@
 # Licensed under the GPL
 #
 
-obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o ksyms.o mem.o process_kern.o \
+EXTRA_TARGETS := unmap_fin.o
+
+obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
 	syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
 	uaccess_user.o sys-$(SUBARCH)/
 
-obj-$(CONFIG_PT_PROXY) += ptproxy/
-
-export-objs = ksyms.o
+obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
 
 USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
+UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
+UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
+
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+$(O_TARGET) : $(obj)/unmap_fin.o
+
+$(obj)/unmap.o: $(src)/unmap.c
+	$(CC) $(UNMAP_CFLAGS) -c -o $@ $<
+
+$(obj)/unmap_fin.o : $(src)/unmap.o
+	ld -r -o $@ $< -lc -L/usr/lib
 
 clean :
diff -Nru a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
--- a/arch/um/kernel/tt/gdb.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/tt/gdb.c	Mon Feb 10 10:39:23 2003
@@ -44,7 +44,7 @@
 	return(ptrace(PTRACE_CONT, pid, 0, 0));
 }
 
-#ifdef CONFIG_PT_PROXY
+#ifdef UML_CONFIG_PT_PROXY
 
 int debugger_signal(int status, pid_t pid)
 {
@@ -62,11 +62,11 @@
 }
 
 static struct chan_opts opts = {
-	announce : 	gdb_announce,
-	xterm_title :	"UML kernel debugger",
-	raw :		0,
-	tramp_stack :	0,
-	in_kernel : 	0,
+	.announce  	= gdb_announce,
+	.xterm_title 	= "UML kernel debugger",
+	.raw 		= 0,
+	.tramp_stack 	= 0,
+	.in_kernel  	= 0,
 };
 
 /* Accessed by the tracing thread, which automatically serializes access */
@@ -74,16 +74,16 @@
 static int xterm_fd;
 
 extern void *xterm_init(char *, int, struct chan_opts *);
-extern int xterm_open(int, int, int, void *);
+extern int xterm_open(int, int, int, void *, char **);
 extern void xterm_close(int, void *);
 
 int open_gdb_chan(void)
 {
-	char stack[UM_KERN_PAGE_SIZE];
+	char stack[UM_KERN_PAGE_SIZE], *dummy;
 
 	opts.tramp_stack = (unsigned long) stack;
 	xterm_data = xterm_init("", 0, &opts);
-	xterm_fd = xterm_open(1, 1, 1, xterm_data);
+	xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
 	return(xterm_fd);
 }
 
diff -Nru a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
--- a/arch/um/kernel/tt/gdb_kern.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/kernel/tt/gdb_kern.c	Mon Feb 10 10:39:30 2003
@@ -13,9 +13,9 @@
 extern int gdb_remove(char *unused);
 
 static struct mc_device gdb_mc = {
-	name:		"gdb",
-	config:		gdb_config,
-	remove:		gdb_remove,
+	.name		= "gdb",
+	.config		= gdb_config,
+	.remove		= gdb_remove,
 };
 
 int gdb_mc_init(void)
diff -Nru a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h
--- a/arch/um/kernel/tt/include/mode.h	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/tt/include/mode.h	Mon Feb 10 10:39:29 2003
@@ -13,9 +13,10 @@
 extern int tracer(int (*init_proc)(void *), void *sp);
 extern void user_time_init_tt(void);
 extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
-extern int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data);
-extern void sig_handler_common_tt(int sig, struct sigcontext *sc);
-extern void syscall_handler_tt(int sig, struct uml_pt_regs *regs);
+extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, 
+			      void *data);
+extern void sig_handler_common_tt(int sig, void *sc);
+extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
 extern void reboot_tt(void);
 extern void halt_tt(void);
 extern int is_tracer_winch(int pid, int fd, void *data);
diff -Nru a/arch/um/kernel/tt/include/mode_kern.h b/arch/um/kernel/tt/include/mode_kern.h
--- a/arch/um/kernel/tt/include/mode_kern.h	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/tt/include/mode_kern.h	Mon Feb 10 10:39:24 2003
@@ -22,6 +22,7 @@
 extern void exit_thread_tt(void);
 extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
 extern void init_idle_tt(void);
+extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
 extern void flush_tlb_kernel_vm_tt(void);
 extern void __flush_tlb_one_tt(unsigned long addr);
 extern void flush_tlb_range_tt(struct vm_area_struct *vma, 
@@ -33,7 +34,6 @@
 extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
 				       unsigned long *task_size_out);
 extern int start_uml_tt(void);
-extern struct page *arch_validate_tt(struct page *page, int mask, int order);
 extern int external_pid_tt(struct task_struct *task);
 extern int thread_pid_tt(struct task_struct *task);
 
diff -Nru a/arch/um/kernel/tt/include/ptrace-tt.h b/arch/um/kernel/tt/include/ptrace-tt.h
--- a/arch/um/kernel/tt/include/ptrace-tt.h	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/tt/include/ptrace-tt.h	Mon Feb 10 10:39:33 2003
@@ -8,7 +8,7 @@
 
 #include "uml-config.h"
 
-#ifdef CONFIG_MODE_TT
+#ifdef UML_CONFIG_MODE_TT
 #include "sysdep/sc.h"
 #endif
 
diff -Nru a/arch/um/kernel/tt/include/tt.h b/arch/um/kernel/tt/include/tt.h
--- a/arch/um/kernel/tt/include/tt.h	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/tt/include/tt.h	Mon Feb 10 10:39:23 2003
@@ -26,10 +26,11 @@
 extern int is_tracing(void *task);
 extern int singlestepping_tt(void *t);
 extern void clear_singlestep(void *t);
-extern void syscall_handler(int sig, struct uml_pt_regs *regs);
+extern void syscall_handler(int sig, union uml_pt_regs *regs);
 extern void exit_kernel(int pid, void *task);
 extern int do_syscall(void *task, int pid);
 extern int is_valid_pid(int pid);
+extern void remap_data(void *segment_start, void *segment_end, int w);
 
 #endif
 
diff -Nru a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
--- a/arch/um/kernel/tt/include/uaccess.h	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/tt/include/uaccess.h	Mon Feb 10 10:39:29 2003
@@ -12,6 +12,7 @@
 #include "asm/errno.h"
 #include "asm/current.h"
 #include "asm/a.out.h"
+#include "uml_uaccess.h"
 
 #define ABOVE_KMEM (16 * 1024 * 1024)
 
@@ -50,9 +51,6 @@
 				   &current->thread.fault_addr,
 				   &current->thread.fault_catcher) : n);
 }
-
-extern int __do_copy_to_user(void *to, const void *from, int n,
-				  void **fault_addr, void **fault_catcher);
 
 static inline int copy_to_user_tt(void *to, const void *from, int n)
 {
diff -Nru a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
--- a/arch/um/kernel/tt/mem.c	Mon Feb 10 10:39:26 2003
+++ b/arch/um/kernel/tt/mem.c	Mon Feb 10 10:39:26 2003
@@ -39,32 +39,6 @@
 	return(START);
 }
 
-struct page *arch_validate_tt(struct page *page, int mask, int order)
-{
-        unsigned long addr, zero = 0;
-        int i;
-
- again:
-        if(page == NULL) return(page);
-        if(PageHighMem(page)) return(page);
-
-        addr = (unsigned long) page_address(page);
-        for(i = 0; i < (1 << order); i++){
-                current->thread.fault_addr = (void *) addr;
-                if(__do_copy_to_user((void *) addr, &zero, 
-                                     sizeof(zero),
-                                     &current->thread.fault_addr,
-                                     &current->thread.fault_catcher)){
-                        if(!(mask & __GFP_WAIT)) return(NULL);
-                        else break;
-                }
-                addr += PAGE_SIZE;
-        }
-        if(i == (1 << order)) return(page);
-        page = alloc_pages(mask, order);
-        goto again;
-}
-
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -Nru a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/kernel/tt/mem_user.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,50 @@
+/* 
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "tt.h"
+#include "mem_user.h"
+#include "user_util.h"
+
+void remap_data(void *segment_start, void *segment_end, int w)
+{
+	void *addr;
+	unsigned long size;
+	int data, prot;
+
+	if(w) prot = PROT_WRITE;
+	else prot = 0;
+	prot |= PROT_READ | PROT_EXEC;
+	size = (unsigned long) segment_end - 
+		(unsigned long) segment_start;
+	data = create_mem_file(size);
+	if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, 
+			MAP_SHARED, data, 0)) == MAP_FAILED){
+		perror("mapping new data segment");
+		exit(1);
+	}
+	memcpy(addr, segment_start, size);
+	if(switcheroo(data, prot, addr, segment_start, 
+		      size) < 0){
+		printf("switcheroo failed\n");
+		exit(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:
+ */
diff -Nru a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
--- a/arch/um/kernel/tt/process_kern.c	Mon Feb 10 10:39:31 2003
+++ b/arch/um/kernel/tt/process_kern.c	Mon Feb 10 10:39:31 2003
@@ -6,6 +6,7 @@
 #include "linux/sched.h"
 #include "linux/signal.h"
 #include "linux/kernel.h"
+#include "linux/interrupt.h"
 #include "asm/system.h"
 #include "asm/pgalloc.h"
 #include "asm/ptrace.h"
@@ -111,7 +112,7 @@
 	close(current->thread.mode.tt.switch_pipe[1]);
 }
 
-extern void schedule_tail(struct task_struct *prev);
+void schedule_tail(task_t *prev);
 
 static void new_thread_handler(int sig)
 {
@@ -120,13 +121,13 @@
 
 	fn = current->thread.request.u.thread.proc;
 	arg = current->thread.request.u.thread.arg;
-	current->thread.regs.regs.mode.tt = (void *) (&sig + 1);
+	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
 
 	block_signals();
 	init_new_thread_signals(1);
 #ifdef CONFIG_SMP
-	schedule_tail(NULL);
+	schedule_tail(current->thread.prev_sched);
 #endif
 	enable_timer();
 	free_page(current->thread.temp_stack);
@@ -160,7 +161,7 @@
 
 void finish_fork_handler(int sig)
 {
-	current->thread.regs.regs.mode.tt = (void *) (&sig + 1);
+ 	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
 	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
 
 #ifdef CONFIG_SMP	
@@ -168,6 +169,7 @@
 #endif
 	enable_timer();
 	change_sig(SIGVTALRM, 1);
+	local_irq_enable();
 	force_flush_all();
 	if(current->mm != current->parent->mm)
 		protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
@@ -187,6 +189,7 @@
 {
 	int sig = sigusr1;
 
+	local_irq_disable();
 	init_new_thread_stack(stack, finish_fork_handler);
 
 	kill(os_getpid(), sig);
@@ -232,10 +235,10 @@
 	}
 
 	if(current->thread.forking){
-		sc_to_sc(p->thread.regs.regs.mode.tt, 
-			 current->thread.regs.regs.mode.tt);
-		SC_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.tt, 0);
-		if(sp != 0) SC_SP(p->thread.regs.regs.mode.tt) = sp;
+		sc_to_sc(UPT_SC(&p->thread.regs.regs), 
+			 UPT_SC(&current->thread.regs.regs));
+		SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
+		if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
 	}
 	p->thread.mode.tt.extern_pid = new_pid;
 
@@ -367,11 +370,14 @@
 static void mprotect_kernel_mem(int w)
 {
 	unsigned long start, end;
+	int pages;
 
 	if(!jail || (current == &init_task)) return;
 
+	pages = (1 << CONFIG_KERNEL_STACK_ORDER);
+
 	start = (unsigned long) current->thread_info + PAGE_SIZE;
-	end = (unsigned long) current->thread_info + PAGE_SIZE * 4;
+	end = (unsigned long) current + PAGE_SIZE * pages;
 	protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
 	protect_memory(end, high_physmem - end, 1, w, 1, 1);
 
@@ -470,8 +476,10 @@
 int start_uml_tt(void)
 {
 	void *sp;
+	int pages;
 
-	sp = (void *) init_task.thread.kernel_stack + 2 * PAGE_SIZE - 
+	pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
+	sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - 
 		sizeof(unsigned long);
 	return(tracer(start_kernel_proc, sp));
 }
diff -Nru a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
--- a/arch/um/kernel/tt/ptproxy/proxy.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/tt/ptproxy/proxy.c	Mon Feb 10 10:39:29 2003
@@ -129,14 +129,14 @@
 
 int init_parent_proxy(int pid)
 {
-	parent = ((debugger_state) { pid :		pid,
-				     wait_options :	0,
-				     wait_status_ptr :	NULL,
-				     waiting :		0,
-				     real_wait :	0,
-				     expecting_child :	0,
-				     handle_trace : 	parent_syscall,
-				     debugee :		NULL } );
+	parent = ((debugger_state) { .pid 		= pid,
+				     .wait_options 	= 0,
+				     .wait_status_ptr 	= NULL,
+				     .waiting 		= 0,
+				     .real_wait 	= 0,
+				     .expecting_child 	= 0,
+				     .handle_trace  	= parent_syscall,
+				     .debugee 		= NULL } );
 	return(0);
 }
 
diff -Nru a/arch/um/kernel/tt/sys-i386/sigcontext.c b/arch/um/kernel/tt/sys-i386/sigcontext.c
--- a/arch/um/kernel/tt/sys-i386/sigcontext.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/kernel/tt/sys-i386/sigcontext.c	Mon Feb 10 10:39:33 2003
@@ -29,14 +29,15 @@
 	return(err);
 }
 
-int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data)
+int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
 {
 	struct arch_frame_data *arch = data;
 	struct sigcontext *to = to_ptr, *from = from_ptr;
 	struct _fpstate *to_fp, *from_fp;
 	int err;
 
-	to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to));
+	to_fp = (struct _fpstate *) 
+		(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
 	from_fp = from->fpstate;
 	err = copy_to_user_proc(to, from, sizeof(*to));
 	if(from_fp != NULL){
diff -Nru a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
--- a/arch/um/kernel/tt/syscall_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/tt/syscall_kern.c	Mon Feb 10 10:39:23 2003
@@ -20,29 +20,32 @@
 
 static int check_readlink(struct pt_regs *regs)
 {
-	return(check_area((void *) regs->regs.args[1], regs->regs.args[2]));
+	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
+			  UPT_SYSCALL_ARG2(&regs->regs)));
 }
 
 static int check_utime(struct pt_regs *regs)
 {
-	return(check_area((void *) regs->regs.args[1],
+	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
 			  sizeof(struct utimbuf)));
 }
 
 static int check_oldstat(struct pt_regs *regs)
 {
-	return(check_area((void *) regs->regs.args[1], 
+	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
 			  sizeof(struct __old_kernel_stat)));
 }
 
 static int check_stat(struct pt_regs *regs)
 {
-	return(check_area((void *) regs->regs.args[1], sizeof(struct stat)));
+	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
+			  sizeof(struct stat)));
 }
 
 static int check_stat64(struct pt_regs *regs)
 {
-	return(check_area((void *) regs->regs.args[1], sizeof(struct stat64)));
+	return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
+			  sizeof(struct stat64)));
 }
 
 struct bogus {
@@ -90,7 +93,7 @@
 
 static int check_bogosity(struct pt_regs *regs)
 {
-	struct bogus *bogon = &this_is_bogus[regs->regs.syscall];
+	struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
 
 	if(!bogon->kernel_ds) return(0);
 	if(bogon->check_params && (*bogon->check_params)(regs))
@@ -109,7 +112,7 @@
 
 	current->thread.nsyscalls++;
 	nsyscalls++;
-	syscall = regs->regs.syscall;
+	syscall = UPT_SYSCALL_NR(&regs->regs);
 
 	if((syscall >= NR_syscalls) || (syscall < 0))
 		res = -ENOSYS;
diff -Nru a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
--- a/arch/um/kernel/tt/syscall_user.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/kernel/tt/syscall_user.c	Mon Feb 10 10:39:29 2003
@@ -22,15 +22,14 @@
 #define ERESTARTNOINTR	513
 #define ERESTARTNOHAND	514
 
-void syscall_handler_tt(int sig, struct uml_pt_regs *regs)
+void syscall_handler_tt(int sig, union uml_pt_regs *regs)
 {
 	void *sc;
 	long result;
 	int index, syscall;
 
-	syscall = regs->syscall;
-	sc = regs->mode.tt;
-	sc_to_regs(regs, sc, syscall);
+	syscall = UPT_SYSCALL_NR(regs);
+	sc = UPT_SC(regs);
 	SC_START_SYSCALL(sc);
 
 	index = record_syscall_start(syscall);
@@ -40,7 +39,7 @@
 	/* regs->sc may have changed while the system call ran (there may
 	 * have been an interrupt or segfault), so it needs to be refreshed.
 	 */
-	regs->mode.tt = sc;
+	UPT_SC(regs) = sc;
 
 	SC_SET_SYSCALL_RETURN(sc, result);
 	if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
@@ -54,7 +53,7 @@
 int do_syscall(void *task, int pid)
 {
 	unsigned long proc_regs[FRAME_SIZE];
-	struct uml_pt_regs *regs;
+	union uml_pt_regs *regs;
 	int syscall;
 
 	if(ptrace_getregs(pid, proc_regs) < 0)
diff -Nru a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
--- a/arch/um/kernel/tt/tlb.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/tt/tlb.c	Mon Feb 10 10:39:23 2003
@@ -132,7 +132,7 @@
 	if(updated && update_seq) atomic_inc(&vmchange_seq);
 }
 
-void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
 {
         flush_kernel_vm_range(start, end, 1);
 }
diff -Nru a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
--- a/arch/um/kernel/tt/tracer.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/kernel/tt/tracer.c	Mon Feb 10 10:39:23 2003
@@ -120,16 +120,6 @@
 	return((*proc)(NULL));
 }
 
-static void last_ditch_exit(int sig)
-{
-	kmalloc_ok = 0;
-	signal(SIGINT, SIG_DFL);
-	signal(SIGTERM, SIG_DFL);
-	signal(SIGHUP, SIG_DFL);
-	uml_cleanup();
-	exit(1);
-}
-
 static void sleeping_process_signal(int pid, int sig)
 {
 	switch(sig){
@@ -214,9 +204,6 @@
 
 	signal(SIGSEGV, (sighandler_t) tracer_segv);
 	signal(SIGUSR1, signal_usr1);
-	set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
-	set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
-	set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
 	if(debug_trace){
 		printf("Tracing thread pausing to be attached\n");
 		stop();
diff -Nru a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
--- a/arch/um/kernel/tt/trap_user.c	Mon Feb 10 10:39:28 2003
+++ b/arch/um/kernel/tt/trap_user.c	Mon Feb 10 10:39:28 2003
@@ -14,26 +14,27 @@
 #include "task.h"
 #include "tt.h"
 
-void sig_handler_common_tt(int sig, struct sigcontext *sc)
+void sig_handler_common_tt(int sig, void *sc_ptr)
 {
-	struct uml_pt_regs save_regs, *r;
+	struct sigcontext *sc = sc_ptr;
+	struct tt_regs save_regs, *r;
 	struct signal_info *info;
 	int save_errno = errno, is_user;
 
 	unprotect_kernel_mem();
 
-	r = (struct uml_pt_regs *) TASK_REGS(get_current());
+	r = &TASK_REGS(get_current())->tt;
 	save_regs = *r;
 	is_user = user_context(SC_SP(sc));
-	r->is_user = is_user;
-	r->mode.tt = sc;
-	if(sig != SIGUSR2) r->syscall = -1;
+	r->sc = sc;
+	if(sig != SIGUSR2) 
+		r->syscall = -1;
 
 	change_sig(SIGUSR1, 1);
 	info = &sig_info[sig];
 	if(!info->is_irq) unblock_signals();
 
-	(*info->handler)(sig, r);
+	(*info->handler)(sig, (union uml_pt_regs *) r);
 
 	if(is_user){
 		interrupt_end();
diff -Nru a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
--- a/arch/um/kernel/tt/uaccess_user.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/tt/uaccess_user.c	Mon Feb 10 10:39:24 2003
@@ -7,34 +7,7 @@
 #include <setjmp.h>
 #include <string.h>
 #include "user_util.h"
-
-static unsigned long __do_user_copy(void *to, const void *from, int n,
-				    void **fault_addr, void **fault_catcher,
-				    void (*op)(void *to, const void *from,
-					       int n), int *faulted_out)
-{
-	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
-
-	jmp_buf jbuf;
-	*fault_catcher = &jbuf;
-	if(setjmp(jbuf) == 0){
-		(*op)(to, from, n);
-		ret = 0;
-		*faulted_out = 0;
-	} 
-	else {
-		ret = *faddrp;
-		*faulted_out = 1;
-	}
-	*fault_addr = NULL;
-	*fault_catcher = NULL;
-	return ret;
-}
-
-static void __do_copy(void *to, const void *from, int n)
-{
-	memcpy(to, from, n);
-}	
+#include "uml_uaccess.h"
 
 int __do_copy_from_user(void *to, const void *from, int n,
 			void **fault_addr, void **fault_catcher)
@@ -46,19 +19,6 @@
 			       __do_copy, &faulted);
 	if(!faulted) return(0);
 	else return(n - (fault - (unsigned long) from));
-}
-
-
-int __do_copy_to_user(void *to, const void *from, int n,
-		      void **fault_addr, void **fault_catcher)
-{
-	unsigned long fault;
-	int faulted;
-
-	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
-			       __do_copy, &faulted);
-	if(!faulted) return(0);
-	else return(n - (fault - (unsigned long) to));
 }
 
 static void __do_strncpy(void *dst, const void *src, int count)
diff -Nru a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/kernel/tt/unmap.c	Mon Feb 10 10:39:30 2003
@@ -0,0 +1,34 @@
+/* 
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "user.h"
+
+int switcheroo(int fd, int prot, void *from, void *to, int size)
+{
+	if(munmap(to, size) < 0){
+		return(-1);
+	}
+	if(mmap(to, size, prot,	MAP_SHARED | MAP_FIXED, fd, 0) != to){
+		return(-1);
+	}
+	if(munmap(from, size) < 0){
+		return(-1);
+	}
+	return(0);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -Nru a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/kernel/uaccess_user.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,64 @@
+/* 
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <setjmp.h>
+#include <string.h>
+
+/* These are here rather than tt/uaccess.c because skas mode needs them in
+ * order to do SIGBUS recovery when a tmpfs mount runs out of room.
+ */
+
+unsigned long __do_user_copy(void *to, const void *from, int n,
+			     void **fault_addr, void **fault_catcher,
+			     void (*op)(void *to, const void *from,
+					int n), int *faulted_out)
+{
+	unsigned long *faddrp = (unsigned long *) fault_addr, ret;
+
+	jmp_buf jbuf;
+	*fault_catcher = &jbuf;
+	if(setjmp(jbuf) == 0){
+		(*op)(to, from, n);
+		ret = 0;
+		*faulted_out = 0;
+	} 
+	else {
+		ret = *faddrp;
+		*faulted_out = 1;
+	}
+	*fault_addr = NULL;
+	*fault_catcher = NULL;
+	return ret;
+}
+
+void __do_copy(void *to, const void *from, int n)
+{
+	memcpy(to, from, n);
+}	
+
+
+int __do_copy_to_user(void *to, const void *from, int n,
+		      void **fault_addr, void **fault_catcher)
+{
+	unsigned long fault;
+	int faulted;
+
+	fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+			       __do_copy, &faulted);
+	if(!faulted) return(0);
+	else return(n - (fault - (unsigned long) to));
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff -Nru a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
--- a/arch/um/kernel/um_arch.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/kernel/um_arch.c	Mon Feb 10 10:39:30 2003
@@ -85,10 +85,10 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
 };
 
 pte_t * __bad_pagetable(void)
@@ -110,12 +110,14 @@
 unsigned long end_vm;
 int ncpus = 1;
 
+#ifdef CONFIG_MODE_TT
 /* Pointer set in linux_main, the array itself is private to each thread,
  * and changed at address space creation time so this poses no concurrency
  * problems.
  */
 static char *argv1_begin = NULL;
 static char *argv1_end = NULL;
+#endif
 
 /* Set in early boot */
 static int have_root __initdata = 0;
@@ -123,6 +125,7 @@
 
 void set_cmdline(char *cmd)
 {
+#ifdef CONFIG_MODE_TT
 	char *umid, *ptr;
 
 	if(CHOOSE_MODE(honeypot, 0)) return;
@@ -139,6 +142,7 @@
 	snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
 	memset(argv1_begin + strlen(argv1_begin), '\0', 
 	       argv1_end - argv1_begin - strlen(argv1_begin));
+#endif
 }
 
 static char *usage_string = 
@@ -199,23 +203,28 @@
 	return(0);
 }
 
-__uml_setup("mode=tt", mode_tt_setup,
-"mode=tt\n"
-"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
-"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
-"    because it's slower and less secure than skas mode.\n\n"
-);
-
 #else
 #ifdef CONFIG_MODE_SKAS
 
 #define DEFAULT_TT 0
 
+static int __init mode_tt_setup(char *line, int *add)
+{
+	printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
+	return(0);
+}
+
 #else
 #ifdef CONFIG_MODE_TT
 
 #define DEFAULT_TT 1
 
+static int __init mode_tt_setup(char *line, int *add)
+{
+	printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
+	return(0);
+}
+
 #else
 
 #error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
@@ -224,6 +233,13 @@
 #endif
 #endif
 
+__uml_setup("mode=tt", mode_tt_setup,
+"mode=tt\n"
+"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
+"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
+"    because it's slower and less secure than skas mode.\n\n"
+);
+
 int mode_tt = DEFAULT_TT;
 
 static int __init Usage(char *line, int *add)
@@ -307,8 +323,10 @@
 
 	setup_machinename(system_utsname.machine);
 
+#ifdef CONFIG_MODE_TT
 	argv1_begin = argv[1];
 	argv1_end = &argv[1][strlen(argv[1])];
+#endif
   
 	set_usable_vm(uml_physmem, get_kmem_end());
 
@@ -317,6 +335,11 @@
 	if(physmem_size > max_physmem){
 		highmem = physmem_size - max_physmem;
 		physmem_size -= highmem;
+#ifndef CONFIG_HIGHMEM
+		highmem = 0;
+		printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
+		       "to %ld bytes\n", physmem_size);
+#endif
 	}
 
 	high_physmem = uml_physmem + physmem_size;
@@ -361,9 +384,9 @@
 }
 
 static struct notifier_block panic_exit_notifier = {
-	notifier_call :		panic_exit,
-	next :			NULL,
-	priority :		0
+	.notifier_call 		= panic_exit,
+	.next 			= NULL,
+	.priority 		= 0
 };
 
 void __init setup_arch(char **cmdline_p)
diff -Nru a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
--- a/arch/um/kernel/umid.c	Mon Feb 10 10:39:32 2003
+++ b/arch/um/kernel/umid.c	Mon Feb 10 10:39:32 2003
@@ -35,7 +35,7 @@
 
 static int make_umid(void);
 
-static int __init set_umid(char *name, int *add)
+static int __init set_umid(char *name, int is_random)
 {
 	if(umid_inited){
 		printk("Unique machine name can't be set twice\n");
@@ -48,12 +48,17 @@
 	strncpy(umid, name, UMID_LEN - 1);
 	umid[UMID_LEN - 1] = '\0';
 
-	umid_is_random = 0;
+	umid_is_random = is_random;
 	umid_inited = 1;
 	return 0;
 }
 
-__uml_setup("umid=", set_umid,
+static int __init set_umid_arg(char *name, int *add)
+{
+	return(set_umid(name, 0));
+}
+
+__uml_setup("umid=", set_umid_arg,
 "umid=<name>\n"
 "    This is used to assign a unique identity to this UML machine and\n"
 "    is used for naming the pid file and management console socket.\n\n"
@@ -186,7 +191,6 @@
 	}
 	if(!dead) return(1);
 	return(actually_do_remove(dir));
-	return(0);
 }
 
 static int __init set_uml_dir(char *name, int *add)
@@ -254,7 +258,7 @@
 		strcat(tmp, "XXXXXX");
 		fd = mkstemp(tmp);
 		if(fd < 0){
-			printk("set_umid - mkstemp failed, errno = %d\n",
+			printk("make_umid - mkstemp failed, errno = %d\n",
 			       errno);
 			return(1);
 		}
@@ -265,7 +269,7 @@
 		 * for directories.
 		 */
 		unlink(tmp);
-		strcpy(umid, &tmp[strlen(uml_dir)]);
+		set_umid(&tmp[strlen(uml_dir)], 1);
 	}
 	
 	sprintf(tmp, "%s%s", uml_dir, umid);
diff -Nru a/arch/um/kernel/unmap.c b/arch/um/kernel/unmap.c
--- a/arch/um/kernel/unmap.c	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,34 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include "user.h"
-
-int switcheroo(int fd, int prot, void *from, void *to, int size)
-{
-	if(munmap(to, size) < 0){
-		return(-1);
-	}
-	if(mmap(to, size, prot,	MAP_SHARED | MAP_FIXED, fd, 0) != to){
-		return(-1);
-	}
-	if(munmap(from, size) < 0){
-		return(-1);
-	}
-	return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -Nru a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c
--- a/arch/um/kernel/user_syms.c	Mon Feb 10 10:39:32 2003
+++ b/arch/um/kernel/user_syms.c	Mon Feb 10 10:39:32 2003
@@ -10,10 +10,7 @@
 #include <sys/ioctl.h>
 #include "user_util.h"
 #include "mem_user.h"
-
-/* XXX All the __CONFIG_* stuff is broken because this file can't include
- * config.h
- */
+#include "uml-config.h"
 
 /* Had to steal this from linux/module.h because that file can't be included
  * since this includes various user-level headers.
@@ -36,7 +33,7 @@
 #define EXPORT_SYMBOL(var)	   error config_must_be_included_before_module
 #define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
 
-#elif !defined(__CONFIG_MODULES__)
+#elif !defined(UML_CONFIG_MODULES)
 
 #define __EXPORT_SYMBOL(sym,str)
 #define EXPORT_SYMBOL(var)
@@ -51,7 +48,7 @@
 __attribute__((section("__ksymtab"))) =			\
 { (unsigned long)&sym, __kstrtab_##sym }
 
-#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
+#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS)
 #define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
 #else
 #define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
diff -Nru a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
--- a/arch/um/kernel/user_util.c	Mon Feb 10 10:39:24 2003
+++ b/arch/um/kernel/user_util.c	Mon Feb 10 10:39:24 2003
@@ -29,6 +29,7 @@
 #include "mem_user.h"
 #include "init.h"
 #include "helper.h"
+#include "uml-config.h"
 
 #define COMMAND_LINE_SIZE _POSIX_ARG_MAX
 
@@ -46,31 +47,6 @@
 	strcat(cmd_line, arg);
 }
 
-void remap_data(void *segment_start, void *segment_end, int w)
-{
-	void *addr;
-	unsigned long size;
-	int data, prot;
-
-	if(w) prot = PROT_WRITE;
-	else prot = 0;
-	prot |= PROT_READ | PROT_EXEC;
-	size = (unsigned long) segment_end - 
-		(unsigned long) segment_start;
-	data = create_mem_file(size);
-	if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, 
-			MAP_SHARED, data, 0)) < 0){
-		perror("mapping new data segment");
-		exit(1);
-	}
-	memcpy(addr, segment_start, size);
-	if(switcheroo(data, prot, addr, segment_start, 
-		      size) < 0){
-		printf("switcheroo failed\n");
-		exit(1);
-	}
-}
-
 void stop(void)
 {
 	while(1) sleep(1000000);
@@ -88,12 +64,15 @@
 {
 	unsigned long guard = address + page_size();
 	unsigned long stack = guard + page_size();
-	int prot = 0;
+	int prot = 0, pages;
 
+#ifdef notdef
 	if(mprotect((void *) stack, page_size(), prot) < 0)
 		panic("protecting guard page failed, errno = %d", errno);
+#endif
+	pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
 	prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-	if(mprotect((void *) stack, 2 * page_size(), prot) < 0)
+	if(mprotect((void *) stack, pages * page_size(), prot) < 0)
 		panic("protecting stack failed, errno = %d", errno);
 }
 
diff -Nru a/arch/um/main.c b/arch/um/main.c
--- a/arch/um/main.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/main.c	Mon Feb 10 10:39:30 2003
@@ -15,10 +15,12 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "mem_user.h"
+#include "signal_user.h"
 #include "user.h"
 #include "init.h"
 #include "mode.h"
 #include "choose-mode.h"
+#include "uml-config.h"
 
 /* Set in set_stklim, which is called from main and __wrap_malloc.  
  * __wrap_malloc only calls it if main hasn't started.
@@ -32,11 +34,6 @@
 #define STACKSIZE (8 * 1024 * 1024)
 #define THREAD_NAME_LEN (256)
 
-/* Never changed */
-static char padding[THREAD_NAME_LEN] = { 
-	[ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
-};
-
 static void set_stklim(void)
 {
 	struct rlimit lim;
@@ -66,26 +63,43 @@
 	}
 }
 
+static void last_ditch_exit(int sig)
+{
+	CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
+	signal(SIGINT, SIG_DFL);
+	signal(SIGTERM, SIG_DFL);
+	signal(SIGHUP, SIG_DFL);
+	uml_cleanup();
+	exit(1);
+}
+
 extern int uml_exitcode;
 
 int main(int argc, char **argv, char **envp)
 {
+	char **new_argv;
 	sigset_t mask;
 	int ret, i;
-	char **new_argv;
 
-	/* Enable all signals - in some environments, we can enter with
-	 * some signals blocked
+	/* Enable all signals except SIGIO - in some environments, we can 
+	 * enter with some signals blocked
 	 */
 
 	sigemptyset(&mask);
+	sigaddset(&mask, SIGIO);
 	if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
 		perror("sigprocmask");
 		exit(1);
 	}
 
+#ifdef UML_CONFIG_MODE_TT
 	/* Allocate memory for thread command lines */
 	if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
+
+		char padding[THREAD_NAME_LEN] = { 
+			[ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
+		};
+
 		new_argv = malloc((argc + 2) * sizeof(char*));
 		if(!new_argv) {
 			perror("Allocating extended argv");
@@ -103,6 +117,7 @@
 		perror("execing with extended args");
 		exit(1);
 	}	
+#endif
 
 	linux_prog = argv[0];
 
@@ -120,6 +135,10 @@
 	}
 	new_argv[argc] = NULL;
 
+	set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
+	set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
+	set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
+
 	do_uml_initcalls();
 	ret = linux_main(argc, argv);
 	
@@ -141,8 +160,10 @@
 
 void *__wrap_malloc(int size)
 {
-	if(CAN_KMALLOC()) return(um_kmalloc(size));
-	else return(__real_malloc(size));
+	if(CAN_KMALLOC())
+		return(um_kmalloc(size));
+	else
+		return(__real_malloc(size));
 }
 
 void *__wrap_calloc(int n, int size)
diff -Nru a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
--- a/arch/um/os-Linux/drivers/ethertap_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c	Mon Feb 10 10:39:23 2003
@@ -28,11 +28,11 @@
 	pri = dev->priv;
 	epri = (struct ethertap_data *) pri->user;
 	*epri = ((struct ethertap_data)
-		{ dev_name :		init->dev_name,
-		  gate_addr :		init->gate_addr,
-		  data_fd :		-1,
-		  control_fd :		-1,
-		  dev :			dev });
+		{ .dev_name 		= init->dev_name,
+		  .gate_addr 		= init->gate_addr,
+		  .data_fd 		= -1,
+		  .control_fd 		= -1,
+		  .dev 			= dev });
 
 	printk("ethertap backend - %s", epri->dev_name);
 	if(epri->gate_addr != NULL) 
@@ -69,10 +69,10 @@
 }
 
 struct net_kern_info ethertap_kern_info = {
-	init:			etap_init,
-	protocol:		eth_protocol,
-	read:			etap_read,
-	write: 			etap_write,
+	.init			= etap_init,
+	.protocol		= eth_protocol,
+	.read			= etap_read,
+	.write 			= etap_write,
 };
 
 int ethertap_setup(char *str, char **mac_out, void *data)
@@ -80,8 +80,8 @@
 	struct ethertap_init *init = data;
 
 	*init = ((struct ethertap_init)
-		{ dev_name :	NULL,
-		  gate_addr :	NULL });
+		{ .dev_name 	= NULL,
+		  .gate_addr 	= NULL });
 	if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
 			    &init->gate_addr))
 		return(0);
@@ -94,12 +94,12 @@
 }
 
 static struct transport ethertap_transport = {
-	list :		LIST_HEAD_INIT(ethertap_transport.list),
-	name :		"ethertap",
-	setup : 	ethertap_setup,
-	user :		&ethertap_user_info,
-	kern :		&ethertap_kern_info,
-	private_size :	sizeof(struct ethertap_data),
+	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
+	.name 		= "ethertap",
+	.setup  	= ethertap_setup,
+	.user 		= &ethertap_user_info,
+	.kern 		= &ethertap_kern_info,
+	.private_size 	= sizeof(struct ethertap_data),
 };
 
 static int register_ethertap(void)
diff -Nru a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
--- a/arch/um/os-Linux/drivers/ethertap_user.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/os-Linux/drivers/ethertap_user.c	Mon Feb 10 10:39:27 2003
@@ -216,14 +216,14 @@
 }
 
 struct net_user_info ethertap_user_info = {
-	init:		etap_user_init,
-	open:		etap_open,
-	close:	 	etap_close,
-	remove:	 	NULL,
-	set_mtu:	etap_set_mtu,
-	add_address:	etap_add_addr,
-	delete_address: etap_del_addr,
-	max_packet:	MAX_PACKET - ETH_HEADER_ETHERTAP
+	.init		= etap_user_init,
+	.open		= etap_open,
+	.close	 	= etap_close,
+	.remove	 	= NULL,
+	.set_mtu	= etap_set_mtu,
+	.add_address	= etap_add_addr,
+	.delete_address = etap_del_addr,
+	.max_packet	= MAX_PACKET - ETH_HEADER_ETHERTAP
 };
 
 /*
diff -Nru a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
--- a/arch/um/os-Linux/drivers/tuntap_kern.c	Mon Feb 10 10:39:29 2003
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c	Mon Feb 10 10:39:29 2003
@@ -28,11 +28,11 @@
 	pri = dev->priv;
 	tpri = (struct tuntap_data *) pri->user;
 	*tpri = ((struct tuntap_data)
-		{ dev_name :		init->dev_name,
-		  fixed_config :	(init->dev_name != NULL),
-		  gate_addr :		init->gate_addr,
-		  fd :			-1,
-		  dev :			dev });
+		{ .dev_name 		= init->dev_name,
+		  .fixed_config 	= (init->dev_name != NULL),
+		  .gate_addr 		= init->gate_addr,
+		  .fd 			= -1,
+		  .dev 			= dev });
 	printk("TUN/TAP backend - ");
 	if(tpri->gate_addr != NULL) 
 		printk("IP = %s", tpri->gate_addr);
@@ -55,10 +55,10 @@
 }
 
 struct net_kern_info tuntap_kern_info = {
-	init:			tuntap_init,
-	protocol:		eth_protocol,
-	read:			tuntap_read,
-	write: 			tuntap_write,
+	.init			= tuntap_init,
+	.protocol		= eth_protocol,
+	.read			= tuntap_read,
+	.write 			= tuntap_write,
 };
 
 int tuntap_setup(char *str, char **mac_out, void *data)
@@ -66,8 +66,8 @@
 	struct tuntap_init *init = data;
 
 	*init = ((struct tuntap_init)
-		{ dev_name :	NULL,
-		  gate_addr :	NULL });
+		{ .dev_name 	= NULL,
+		  .gate_addr 	= NULL });
 	if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
 			    &init->gate_addr))
 		return(0);
@@ -76,13 +76,13 @@
 }
 
 static struct transport tuntap_transport = {
-	list :		LIST_HEAD_INIT(tuntap_transport.list),
-	name :		"tuntap",
-	setup : 	tuntap_setup,
-	user :		&tuntap_user_info,
-	kern :		&tuntap_kern_info,
-	private_size :	sizeof(struct tuntap_data),
-	setup_size :	sizeof(struct tuntap_init),
+	.list 		= LIST_HEAD_INIT(tuntap_transport.list),
+	.name 		= "tuntap",
+	.setup  	= tuntap_setup,
+	.user 		= &tuntap_user_info,
+	.kern 		= &tuntap_kern_info,
+	.private_size 	= sizeof(struct tuntap_data),
+	.setup_size 	= sizeof(struct tuntap_init),
 };
 
 static int register_tuntap(void)
diff -Nru a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
--- a/arch/um/os-Linux/drivers/tuntap_user.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/os-Linux/drivers/tuntap_user.c	Mon Feb 10 10:39:33 2003
@@ -201,14 +201,14 @@
 }
 
 struct net_user_info tuntap_user_info = {
-	init:		tuntap_user_init,
-	open:		tuntap_open,
-	close:	 	tuntap_close,
-	remove:	 	NULL,
-	set_mtu:	tuntap_set_mtu,
-	add_address:	tuntap_add_addr,
-	delete_address: tuntap_del_addr,
-	max_packet:	MAX_PACKET
+	.init		= tuntap_user_init,
+	.open		= tuntap_open,
+	.close	 	= tuntap_close,
+	.remove	 	= NULL,
+	.set_mtu	= tuntap_set_mtu,
+	.add_address	= tuntap_add_addr,
+	.delete_address = tuntap_del_addr,
+	.max_packet	= MAX_PACKET
 };
 
 /*
diff -Nru a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
--- a/arch/um/os-Linux/file.c	Mon Feb 10 10:39:33 2003
+++ b/arch/um/os-Linux/file.c	Mon Feb 10 10:39:33 2003
@@ -28,8 +28,8 @@
 	else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
 	else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
 	else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
-	else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
-	else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
+	else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
+	else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
 	else return(OS_TYPE_FILE);
 }
 
@@ -64,6 +64,15 @@
 
 	fd = open64(file, f, mode);
 	if(fd < 0) return(-errno);
+	
+	if(flags.cl){
+		if(fcntl(fd, F_SETFD, 1)){
+			close(fd);
+			return(-errno);
+		}
+	}
+
+ 	return(fd);
 	return(fd);
 }
 
@@ -100,7 +109,7 @@
 	return(0);
 }
 
-int os_read_file(int fd, char *buf, int len)
+int os_read_file(int fd, void *buf, int len)
 {
 	int n;
 
@@ -118,7 +127,7 @@
 	return(n);
 }
 
-int os_write_file(int fd, char *buf, int count)
+int os_write_file(int fd, void *buf, int count)
 {
 	int n;
 
@@ -276,8 +285,8 @@
 
 	msg.msg_name = NULL;
 	msg.msg_namelen = 0;
-	iov = ((struct iovec) { iov_base : helper_pid_out,
-				iov_len :  sizeof(*helper_pid_out) });
+	iov = ((struct iovec) { .iov_base  = helper_pid_out,
+				.iov_len   = sizeof(*helper_pid_out) });
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 	msg.msg_control = buf;
diff -Nru a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
--- a/arch/um/os-Linux/process.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/os-Linux/process.c	Mon Feb 10 10:39:23 2003
@@ -106,7 +106,7 @@
 
 	loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
 		   fd, off);
-	if(loc < 0)
+	if(loc == MAP_FAILED)
 		return(-errno);
 	return(0);
 }
diff -Nru a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
--- a/arch/um/sys-i386/Makefile	Mon Feb 10 10:39:23 2003
+++ b/arch/um/sys-i386/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,15 +3,13 @@
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 
-export-objs = ksyms.o
-
 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
-SYMLINKS = semaphore.c extable.c highmem.c module.c
+SYMLINKS = semaphore.c highmem.c module.c
+SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
 
 semaphore.c-dir = kernel
-extable.c-dir = mm
 highmem.c-dir = mm
 module.c-dir = kernel
 
@@ -23,7 +21,7 @@
 $(USER_OBJS) : %.o: %.c
 	$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
 
-$(foreach f,$(SYMLINKS),$(src)/$f): 
+$(SYMLINKS): 
 	$(call make_link,$@)
 
 clean:
diff -Nru a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
--- a/arch/um/sys-i386/bugs.c	Mon Feb 10 10:39:30 2003
+++ b/arch/um/sys-i386/bugs.c	Mon Feb 10 10:39:30 2003
@@ -117,7 +117,7 @@
 	if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
 }
 
-int arch_handle_signal(int sig, struct uml_pt_regs *regs)
+int arch_handle_signal(int sig, union uml_pt_regs *regs)
 {
 	unsigned long ip;
 
diff -Nru a/arch/um/sys-i386/extable.c b/arch/um/sys-i386/extable.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/sys-i386/extable.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/i386/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+	       const struct exception_table_entry *last,
+	       unsigned long value)
+{
+        while (first <= last) {
+		const struct exception_table_entry *mid;
+		long diff;
+
+		mid = (last - first) / 2 + first;
+		diff = mid->insn - value;
+                if (diff == 0)
+                        return mid;
+                else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        return NULL;
+}
diff -Nru a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
--- a/arch/um/sys-i386/fault.c	Mon Feb 10 10:39:27 2003
+++ b/arch/um/sys-i386/fault.c	Mon Feb 10 10:39:27 2003
@@ -14,7 +14,7 @@
 	struct sigcontext *sc = sc_ptr;
 	unsigned long fixup;
 
-	fixup = search_exception_table(address);
+	fixup = search_exception_tables(address);
 	if(fixup != 0){
 		sc->eip = fixup;
 		return(1);
diff -Nru a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c
--- a/arch/um/sys-i386/sigcontext.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/sys-i386/sigcontext.c	Mon Feb 10 10:39:23 2003
@@ -21,7 +21,7 @@
 void sc_to_sc(void *to_ptr, void *from_ptr)
 {
 	struct sigcontext *to = to_ptr, *from = from_ptr;
-	int size = sizeof(*to) + signal_frame_sc.arch.fpstate_size;
+	int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
 
 	memcpy(to, from, size);
 	if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
diff -Nru a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c
--- a/arch/um/sys-i386/util/mk_thread_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/sys-i386/util/mk_thread_kern.c	Mon Feb 10 10:39:23 2003
@@ -1,3 +1,4 @@
+#include "linux/config.h"
 #include "linux/stddef.h"
 #include "linux/sched.h"
 
@@ -12,7 +13,9 @@
 {
   print_head();
   print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
+#ifdef CONFIG_MODE_TT
   print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
+#endif
   print_tail();
   return(0);
 }
diff -Nru a/arch/um/uml.lds.S b/arch/um/uml.lds.S
--- a/arch/um/uml.lds.S	Mon Feb 10 10:39:26 2003
+++ b/arch/um/uml.lds.S	Mon Feb 10 10:39:26 2003
@@ -11,15 +11,17 @@
 
   . = ALIGN(4096);
   __binary_start = .;
+#ifdef MODE_TT
   .thread_private : {
     __start_thread_private = .;
     errno = .;
     . += 4;
-    arch/um/kernel/unmap_fin.o (.data)
+    arch/um/kernel/tt/unmap_fin.o (.data)
     __end_thread_private = .;
   }
   . = ALIGN(4096);
-  .remap : { arch/um/kernel/unmap_fin.o (.text) }
+  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
+#endif
 
   . = ALIGN(4096);		/* Init code and data */
   _stext = .;
@@ -34,80 +36,12 @@
     *(.gnu.linkonce.t*)
   }
 
-  . = ALIGN(16);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
+  #include "asm/common.lds.S"
 
-  RODATA
-
-  .fini      : { *(.fini)    } =0x9090
-  _etext = .;
-  PROVIDE (etext = .);
-
-  . = ALIGN(4096);
-  PROVIDE (_sdata = .);
-
-  .unprotected : { *(.unprotected) }
-  . = ALIGN(4096);
-  PROVIDE (_unprotected_end = .);
-
-  . = ALIGN(4096);
-  __uml_setup_start = .;
-  .uml.setup.init : { *(.uml.setup.init) }
-  __uml_setup_end = .;
-	
-  __uml_help_start = .;
-  .uml.help.init : { *(.uml.help.init) }
-  __uml_help_end = .;
-	
-  __uml_postsetup_start = .;
-  .uml.postsetup.init : { *(.uml.postsetup.init) }
-  __uml_postsetup_end = .;
-	
-  __setup_start = .;
-  .init.setup : { *(.init.setup) }
-  __setup_end = .;
-
-  __start___param = .;
-  __param : { *(__param) }
-  __stop___param = .;
-
-  __per_cpu_start = . ; 
-  .data.percpu : { *(.data.percpu) }
-  __per_cpu_end = . ;
-	
-  __initcall_start = .;
-  .initcall.init : {
-	*(.initcall1.init) 
-	*(.initcall2.init) 
-	*(.initcall3.init) 
-	*(.initcall4.init) 
-	*(.initcall5.init) 
-	*(.initcall6.init) 
-	*(.initcall7.init)
-  }
-  __initcall_end = .;
-  __uml_initcall_start = .;
-  .uml.initcall.init : { *(.uml.initcall.init) }
-  __uml_initcall_end = .;
-  __init_end = .;
-  __exitcall_begin = .;
-  .exitcall : { *(.exitcall.exit) }
-  __exitcall_end = .;
-  __uml_exitcall_begin = .;
-  .uml.exitcall : { *(.uml.exitcall.exit) }
-  __uml_exitcall_end = .;
-
-   . = ALIGN(4096);
-   __initramfs_start = .;
-   .init.ramfs : { *(.init.ramfs) }
-   __initramfs_end = .;
- 
   .data.init : { *(.data.init) }
   .data    :
   {
-    . = ALIGN(16384);		/* init_task */
+    . = ALIGN(KERNEL_STACK_SIZE);		/* init_task */
     *(.data.init_task)
     *(.data)
     *(.gnu.linkonce.d*)
diff -Nru a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c
--- a/arch/um/util/mk_task_kern.c	Mon Feb 10 10:39:23 2003
+++ b/arch/um/util/mk_task_kern.c	Mon Feb 10 10:39:23 2003
@@ -9,7 +9,7 @@
 int main(int argc, char **argv)
 {
   print_head();
-  print_ptr("TASK_REGS", "struct uml_pt_regs", 
+  print_ptr("TASK_REGS", "union uml_pt_regs", 
 	    offsetof(struct task_struct, thread.regs));
   print("TASK_PID", "int", offsetof(struct task_struct, pid));
   print_tail();
diff -Nru a/arch/um/vmlinux.lds.S b/arch/um/vmlinux.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/um/vmlinux.lds.S	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,11 @@
+#include <asm-generic/vmlinux.lds.h>
+	
+OUTPUT_FORMAT(ELF_FORMAT)
+OUTPUT_ARCH(ELF_ARCH)
+ENTRY(_start)
+jiffies = jiffies_64;
+
+SECTIONS
+{
+#include "asm/common.lds.S"
+}
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig	Mon Feb 10 10:39:26 2003
+++ b/arch/v850/Kconfig	Mon Feb 10 10:39:27 2003
@@ -351,7 +351,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/v850/Makefile b/arch/v850/Makefile
--- a/arch/v850/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/v850/Makefile	Mon Feb 10 10:39:33 2003
@@ -31,7 +31,7 @@
 OBJCOPY_FLAGS_BLOB := -I binary -O elf32-little -B v850e
 
 
-HEAD := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o
+head-y := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o
 core-y += $(arch_dir)/kernel/
 libs-y += $(arch_dir)/lib/
 
diff -Nru a/arch/v850/kernel/Makefile b/arch/v850/kernel/Makefile
--- a/arch/v850/kernel/Makefile	Mon Feb 10 10:39:33 2003
+++ b/arch/v850/kernel/Makefile	Mon Feb 10 10:39:33 2003
@@ -13,8 +13,6 @@
 
 obj-y += intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \
 	 signal.o irq.o mach.o ptrace.o bug.o
-export-objs += v850_ksyms.o rte_mb_a_pci.o
-
 obj-$(CONFIG_MODULES)		+= module.o v850_ksyms.o
 # chip-specific code
 obj-$(CONFIG_V850E_MA1)		+= ma.o	nb85e_utils.o nb85e_timer_d.o
diff -Nru a/arch/v850/kernel/mach.h b/arch/v850/kernel/mach.h
--- a/arch/v850/kernel/mach.h	Mon Feb 10 10:39:33 2003
+++ b/arch/v850/kernel/mach.h	Mon Feb 10 10:39:33 2003
@@ -45,7 +45,7 @@
 extern void (*mach_tick) (void);
 
 /* The following establishes aliases for various mach_ functions to the
-   name by which the rest of the kernal calls them.  These statements
+   name by which the rest of the kernel calls them.  These statements
    should only have an effect in the file that defines the actual functions. */
 #define MACH_ALIAS(to, from)						      \
    asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";"		      \
diff -Nru a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
--- a/arch/v850/kernel/rte_mb_a_pci.c	Mon Feb 10 10:39:24 2003
+++ b/arch/v850/kernel/rte_mb_a_pci.c	Mon Feb 10 10:39:24 2003
@@ -689,7 +689,7 @@
 	free_dma_mapping (mapping);
 }
 
-/* Make physical memory consistant for a single streaming mode DMA
+/* Make physical memory consistent for a single streaming mode DMA
    translation after a transfer.
 
    If you perform a pci_map_single() but wish to interrogate the
@@ -731,7 +731,7 @@
 	BUG ();
 }
 
-/* Make physical memory consistant for a set of streaming mode DMA
+/* Make physical memory consistent for a set of streaming mode DMA
    translations after a transfer.  The same as pci_dma_sync_single but
    for a scatter-gather list, same rules and usage.  */
 
diff -Nru a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
--- a/arch/v850/kernel/signal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/v850/kernel/signal.c	Mon Feb 10 10:39:33 2003
@@ -50,11 +50,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->gpr[GPR_RVAL] = -EINTR;
 	while (1) {
@@ -78,11 +78,11 @@
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs->gpr[GPR_RVAL] = -EINTR;
 	while (1) {
@@ -188,10 +188,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(regs, &frame->sc, &rval))
 		goto badframe;
@@ -216,10 +216,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
 		goto badframe;
@@ -472,11 +472,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
--- a/arch/v850/kernel/time.c	Mon Feb 10 10:39:29 2003
+++ b/arch/v850/kernel/time.c	Mon Feb 10 10:39:29 2003
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/profile.h>
 
@@ -107,8 +108,6 @@
 #endif /* 0 */
 }
 
-extern rwlock_t xtime_lock;
-
 /*
  * This version of gettimeofday has near microsecond resolution.
  */
@@ -120,21 +119,24 @@
 #endif
 	unsigned long flags;
 	unsigned long usec, sec;
+	unsigned long seq;
+
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
-	read_lock_irqsave (&xtime_lock, flags);
 #if 0
-	usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
+		usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
 #else
-	usec = 0;
+		usec = 0;
 #endif
 #if 0 /* DAVIDM later if possible */
-	lost = lost_ticks;
-	if (lost)
-		usec += lost * (1000000/HZ);
+		lost = lost_ticks;
+		if (lost)
+			usec += lost * (1000000/HZ);
 #endif
-	sec = xtime.tv_sec;
-	usec += xtime.tv_nsec / 1000;
-	read_unlock_irqrestore (&xtime_lock, flags);
+		sec = xtime.tv_sec;
+		usec += xtime.tv_nsec / 1000;
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 
 	while (usec >= 1000000) {
 		usec -= 1000000;
@@ -147,7 +149,7 @@
 
 void do_settimeofday (struct timeval *tv)
 {
-	write_lock_irq (&xtime_lock);
+	write_seqlock_irq (&xtime_lock);
 
 	/* This is revolting. We need to set the xtime.tv_nsec
 	 * correctly. However, the value in this location is
@@ -172,7 +174,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq (&xtime_lock);
+	write_sequnlock_irq (&xtime_lock);
 }
 
 static int timer_dev_id;
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/arch/x86_64/Kconfig	Mon Feb 10 10:39:30 2003
@@ -427,7 +427,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf.o. Saying M or N here is dangerous because
+	  will be called binfmt_elf. Saying M or N here is dangerous because
 	  some crucial programs on your system might be in ELF format.
 
 config BINFMT_MISC
@@ -452,7 +452,7 @@
 	  use this part of the kernel.
 
 	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc.o. If you
+	  you have use for it; the module is called binfmt_misc. If you
 	  don't know what to answer at this point, say Y.
 
 config IA32_EMULATION
@@ -518,7 +518,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called ide.o.
+	  will be called ide.
 
 	  For further information, please read <file:Documentation/ide.txt>.
 
@@ -545,7 +545,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scsi_mod.o.  If you want to compile it as
+	  The module will be called scsi_mod.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  However, do not compile this as a
 	  module if your root file system (the one containing the directory /)
@@ -615,7 +615,7 @@
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/sound/oss/README.modules>; the module will be
-	  called soundcore.o.
+	  called soundcore.
 
 	  I'm told that even without a sound card, you can make your computer
 	  say more than an occasional beep, by programming the PC speaker.
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile	Mon Feb 10 10:39:31 2003
+++ b/arch/x86_64/Makefile	Mon Feb 10 10:39:31 2003
@@ -48,7 +48,7 @@
 CFLAGS += -finline-limit=2000
 #CFLAGS += -g
 
-HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
+head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
 
 libs-y 					+= arch/x86_64/lib/
 core-y					+= arch/x86_64/kernel/ arch/x86_64/mm/
diff -Nru a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/x86_64/ia32/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-export-objs := ia32_ioctl.o sys_ia32.o
-
 obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
 	ia32_signal.o \
 	ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o syscall32.o
diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c	Mon Feb 10 10:39:33 2003
+++ b/arch/x86_64/ia32/ia32_signal.c	Mon Feb 10 10:39:33 2003
@@ -83,11 +83,11 @@
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	regs.rax = -EINTR;
 	while (1) {
@@ -243,10 +243,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (ia32_restore_sigcontext(&regs, &frame->sc, &eax))
 		goto badframe;
@@ -270,10 +270,10 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (ia32_restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
 		goto badframe;
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	Mon Feb 10 10:39:30 2003
+++ b/arch/x86_64/kernel/Makefile	Mon Feb 10 10:39:30 2003
@@ -4,8 +4,6 @@
 
 EXTRA_TARGETS 	:= head.o head64.o init_task.o
 EXTRA_AFLAGS  := -traditional
-export-objs     := x8664_ksyms.o pci-gart.o pci-dma.o
-
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
 		pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	Mon Feb 10 10:39:23 2003
+++ b/arch/x86_64/kernel/apic.c	Mon Feb 10 10:39:23 2003
@@ -895,7 +895,7 @@
  * value into /proc/profile.
  */
 
-inline void smp_local_timer_interrupt(struct pt_regs *regs)
+void smp_local_timer_interrupt(struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
 
diff -Nru a/arch/x86_64/kernel/mtrr/Makefile b/arch/x86_64/kernel/mtrr/Makefile
--- a/arch/x86_64/kernel/mtrr/Makefile	Mon Feb 10 10:39:27 2003
+++ b/arch/x86_64/kernel/mtrr/Makefile	Mon Feb 10 10:39:27 2003
@@ -7,8 +7,6 @@
 obj-y		+= cyrix.o
 obj-y		+= centaur.o
 
-export-objs	:= main.o
-
 $(obj)/main.c: $(obj)/mtrr.h
 	@ln -sf ../../../i386/kernel/cpu/mtrr/main.c $(obj)/main.c
 $(obj)/if.c: $(obj)/mtrr.h
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c	Mon Feb 10 10:39:29 2003
+++ b/arch/x86_64/kernel/signal.c	Mon Feb 10 10:39:29 2003
@@ -52,11 +52,11 @@
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
 	current->blocked = newset;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 #if DEBUG_SIG
 	printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
 		saveset, newset, &regs, regs.rip);
@@ -155,10 +155,10 @@
 	} 
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = set;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax)) { 
 		goto badframe;
@@ -401,11 +401,11 @@
 		ka->sa.sa_handler = SIG_DFL;
 
 	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	Mon Feb 10 10:39:29 2003
+++ b/arch/x86_64/kernel/time.c	Mon Feb 10 10:39:29 2003
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/mc146818rtc.h>
 #include <linux/irq.h>
+#include <linux/time.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -27,9 +28,12 @@
 
 u64 jiffies_64; 
 
-extern rwlock_t xtime_lock;
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
+extern int using_apic_timer;
+extern void smp_local_timer_interrupt(struct pt_regs * regs);
+
+
 unsigned int cpu_khz;					/* TSC clocks / usec, not used here */
 unsigned long hpet_period;				/* fsecs / HPET clock */
 unsigned long hpet_tick;				/* HPET clocks / interrupt */
@@ -70,21 +74,22 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags, t;
+	unsigned long flags, t, seq;
  	unsigned int sec, usec;
 
-	read_lock_irqsave(&xtime_lock, flags);
-	spin_lock(&time_offset_lock);
-
-	sec = xtime.tv_sec;
-	usec = xtime.tv_nsec / 1000;
-
-	t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset();
-	if (t > timeoffset) timeoffset = t;
-	usec += timeoffset;
+	spin_lock_irqsave(&time_offset_lock, flags);
+	do {
+		seq = read_seqbegin(&xtime_lock);
+
+		sec = xtime.tv_sec;
+		usec = xtime.tv_nsec / 1000;
+
+		t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset();
+		if (t > timeoffset) timeoffset = t;
+		usec += timeoffset;
 
-	spin_unlock(&time_offset_lock);
-	read_unlock_irqrestore(&xtime_lock, flags);
+	} while (read_seqretry(&xtime_lock, seq));
+	spin_unlock_irqrestore(&time_offset_lock, flags);
 
 	tv->tv_sec = sec + usec / 1000000;
 	tv->tv_usec = usec % 1000000;
@@ -98,7 +103,7 @@
 
 void do_settimeofday(struct timeval *tv)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	vxtime_lock();
 
 	tv->tv_usec -= do_gettimeoffset() +
@@ -118,7 +123,7 @@
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
 
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /*
@@ -201,7 +206,7 @@
  * variables, because both do_timer() and us change them -arca+vojtech
 	 */
 
-	write_lock(&xtime_lock);
+	write_seqlock(&xtime_lock);
 	vxtime_lock();
 
 	{
@@ -214,6 +219,7 @@
 		hpet.ticks = min_t(long, max_t(long, (t  - hpet.last_tsc) * (1000000L / HZ) / (1000000L / HZ - hpet.offset),
 				cpu_khz * 1000/HZ * 15 / 16), cpu_khz * 1000/HZ * 16 / 15); 
 		hpet.last_tsc = t;
+		timeoffset = 0;
 	}
 
 /*
@@ -250,7 +256,7 @@
 	}
  
 	vxtime_unlock();
-	write_unlock(&xtime_lock);
+	write_sequnlock(&xtime_lock);
 }
 
 unsigned long get_cmos_time(void)
diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
--- a/arch/x86_64/lib/Makefile	Mon Feb 10 10:39:24 2003
+++ b/arch/x86_64/lib/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,8 +3,6 @@
 #
 
 L_TARGET := lib.a
-export-objs := io.o csum-wrappers.o csum-partial.o
-
 CFLAGS_csum-partial.o := -funroll-loops
 
 obj-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
--- a/arch/x86_64/mm/Makefile	Mon Feb 10 10:39:30 2003
+++ b/arch/x86_64/mm/Makefile	Mon Feb 10 10:39:30 2003
@@ -2,7 +2,5 @@
 # Makefile for the linux i386-specific parts of the memory manager.
 #
 
-export-objs := pageattr.o
-
 obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff -Nru a/arch/x86_64/mm/hugetlbpage.c b/arch/x86_64/mm/hugetlbpage.c
--- a/arch/x86_64/mm/hugetlbpage.c	Mon Feb 10 10:39:27 2003
+++ b/arch/x86_64/mm/hugetlbpage.c	Mon Feb 10 10:39:27 2003
@@ -25,7 +25,6 @@
 int     htlbpage_max;
 static long    htlbzone_pages;
 
-struct vm_operations_struct hugetlb_vm_ops;
 static LIST_HEAD(htlbpage_freelist);
 static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
 
@@ -134,6 +133,7 @@
 		page = pte_page(pte);
 		if (pages) {
 			page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
+			get_page(page);
 			pages[i] = page;
 		}
 		if (vmas)
@@ -204,6 +204,7 @@
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
+	struct inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -227,6 +228,8 @@
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
+			loff_t i_size;
+
 			page = alloc_hugetlb_page();
 			if (!page) {
 				ret = -ENOMEM;
@@ -238,6 +241,9 @@
 				free_huge_page(page);
 				goto out;
 			}
+			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
+			if (i_size > inode->i_size)
+				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
@@ -263,11 +269,6 @@
 			page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER);
 			if (page == NULL)
 				break;
-			map = page;
-			for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-				SetPageReserved(map);
-				map++;
-			}
 			spin_lock(&htlbpage_lock);
 			list_add(&page->list, &htlbpage_freelist);
 			htlbpagemem++;
@@ -286,8 +287,9 @@
 		spin_unlock(&htlbpage_lock);
 		map = page;
 		for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
-			map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
-					1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
+			map->flags &= ~(1 << PG_locked | 1 << PG_error |
+					1 << PG_referenced |
+					1 << PG_dirty | 1 << PG_active |
 					1 << PG_private | 1<< PG_writeback);
 			set_page_count(map, 0);
 			map++;
@@ -346,7 +348,8 @@
 			HPAGE_SIZE/1024);
 }
 
-static struct page * hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+static struct page *
+hugetlb_nopage(struct vm_area_struct *vma, unsigned long address, int unused)
 {
 	BUG();
 	return NULL;
diff -Nru a/crypto/Makefile b/crypto/Makefile
--- a/crypto/Makefile	Mon Feb 10 10:39:33 2003
+++ b/crypto/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Cryptographic API
 #
 
-export-objs := api.o hmac.o
-
 autoload-crypto-$(CONFIG_KMOD) = autoload.o
 proc-crypto-$(CONFIG_PROC_FS) = proc.o
 
diff -Nru a/crypto/cipher.c b/crypto/cipher.c
--- a/crypto/cipher.c	Mon Feb 10 10:39:27 2003
+++ b/crypto/cipher.c	Mon Feb 10 10:39:27 2003
@@ -4,6 +4,7 @@
  * Cipher operations.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.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
@@ -16,12 +17,22 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 #include <linux/highmem.h>
 #include <asm/scatterlist.h>
 #include "internal.h"
 
 typedef void (cryptfn_t)(void *, u8 *, const u8 *);
-typedef void (procfn_t)(struct crypto_tfm *, u8 *, cryptfn_t, int enc);
+typedef void (procfn_t)(struct crypto_tfm *, u8 *, u8*, cryptfn_t, int enc);
+
+struct scatter_walk {
+	struct scatterlist	*sg;
+	struct page		*page;
+	void			*data;
+	unsigned int		len_this_page;
+	unsigned int		len_this_segment;
+	unsigned int		offset;
+};
 
 static inline void xor_64(u8 *a, const u8 *b)
 {
@@ -37,165 +48,191 @@
 	((u32 *)a)[3] ^= ((u32 *)b)[3];
 }
 
-static inline unsigned int sglen(struct scatterlist *sg, unsigned int nsg)
+
+/* Define sg_next is an inline routine now in case we want to change
+   scatterlist to a linked list later. */
+static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	unsigned int i, n;
-	
-	for (i = 0, n = 0; i < nsg; i++)
-		n += sg[i].length;
-			
-	return n;
+	return sg + 1;
 }
 
-/*
- * Do not call this unless the total length of all of the fragments 
- * has been verified as multiple of the block size.
- */
-static unsigned int copy_chunks(struct crypto_tfm *tfm, u8 *buf,
-                                struct scatterlist *sg, unsigned int sgidx,
-                                unsigned int rlen, unsigned int *last, int in)
-{
-	unsigned int i, copied, coff, j, aligned;
-	unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-
-	for (i = sgidx, j = copied = 0, aligned = 0 ; copied < bsize; i++) {
-		unsigned int len = sg[i].length;
-		unsigned int clen;
-		char *p;
-
-		if (copied) {
-			coff = 0;
-			clen = min(len,  bsize - copied);
-			
-			if (len == bsize - copied)
-				aligned = 1;	/* last + right aligned */
-				
-		} else {
-			coff = len - rlen;
-			clen = rlen;
-		}
+void *which_buf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
+{
+	if (nbytes <= walk->len_this_page &&
+	    (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
+	    PAGE_CACHE_SIZE)
+		return walk->data;
+	else
+		return scratch;
+}
 
-		p = crypto_kmap(sg[i].page) + sg[i].offset + coff;
-		
-		if (in)
-			memcpy(&buf[copied], p, clen);
+static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
+{
+	if (out)
+		memcpy(sgdata, buf, nbytes);
+	else
+		memcpy(buf, sgdata, nbytes);
+}
+
+static void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
+{
+	unsigned int rest_of_page;
+
+	walk->sg = sg;
+
+	walk->page = sg->page;
+	walk->len_this_segment = sg->length;
+
+	rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
+	walk->len_this_page = min(sg->length, rest_of_page);
+	walk->offset = sg->offset;
+}
+
+static void scatterwalk_map(struct scatter_walk *walk, int out)
+{
+	walk->data = crypto_kmap(walk->page, out) + walk->offset;
+}
+
+static void scatter_page_done(struct scatter_walk *walk, int out,
+			      unsigned int more)
+{
+	/* walk->data may be pointing the first byte of the next page;
+	   however, we know we transfered at least one byte.  So,
+	   walk->data - 1 will be a virutual address in the mapped page. */
+
+	if (out)
+		flush_dcache_page(walk->page);
+
+	if (more) {
+		walk->len_this_segment -= walk->len_this_page;
+
+		if (walk->len_this_segment) {
+			walk->page++;
+			walk->len_this_page = min(walk->len_this_segment,
+						  (unsigned)PAGE_CACHE_SIZE);
+			walk->offset = 0;
+		}
 		else
-			memcpy(p, &buf[copied], clen);
-		
-		crypto_kunmap(p);
-		*last = aligned ? 0 : clen;
-		copied += clen;
+			scatterwalk_start(walk, sg_next(walk->sg));
 	}
-	
-	return i - sgidx - 2 + aligned;
 }
 
-static inline unsigned int gather_chunks(struct crypto_tfm *tfm, u8 *buf,
-                                         struct scatterlist *sg,
-                                         unsigned int sgidx, unsigned int rlen,
-                                         unsigned int *last)
+static void scatter_done(struct scatter_walk *walk, int out, int more)
 {
-	return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 1);
+	crypto_kunmap(walk->data, out);
+	if (walk->len_this_page == 0 || !more)
+		scatter_page_done(walk, out, more);
 }
 
-static inline unsigned int scatter_chunks(struct crypto_tfm *tfm, u8 *buf,
-                                          struct scatterlist *sg,
-                                          unsigned int sgidx, unsigned int rlen,
-                                          unsigned int *last)
+/*
+ * Do not call this unless the total length of all of the fragments 
+ * has been verified as multiple of the block size.
+ */
+static int copy_chunks(void *buf, struct scatter_walk *walk,
+			size_t nbytes, int out)
 {
-	return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 0);
+	if (buf != walk->data) {
+		while (nbytes > walk->len_this_page) {
+			memcpy_dir(buf, walk->data, walk->len_this_page, out);
+			buf += walk->len_this_page;
+			nbytes -= walk->len_this_page;
+
+			crypto_kunmap(walk->data, out);
+			scatter_page_done(walk, out, 1);
+			scatterwalk_map(walk, out);
+		}
+
+		memcpy_dir(buf, walk->data, nbytes, out);
+	}
+
+	walk->offset += nbytes;
+	walk->len_this_page -= nbytes;
+	walk->len_this_segment -= nbytes;
+	return 0;
 }
 
 /* 
- * Generic encrypt/decrypt wrapper for ciphers.
- *
- * If we find a a remnant at the end of a frag, we have to encrypt or
- * decrypt across possibly multiple page boundaries via a temporary
- * block, then continue processing with a chunk offset until the end
- * of a frag is block aligned.
- *
- * The code is further complicated by having to remap a page after
- * processing a block then yielding.  The data will be offset from the
- * start of page at the scatterlist offset, the chunking offset (coff)
- * and the block offset (boff).
+ * Generic encrypt/decrypt wrapper for ciphers, handles operations across
+ * multiple page boundaries by using temporary blocks.  In user context,
+ * the kernel is given a chance to schedule us once per block.
  */
-static int crypt(struct crypto_tfm *tfm, struct scatterlist *sg,
-                 unsigned int nsg, cryptfn_t crfn, procfn_t prfn, int enc)
-{
-	unsigned int i, coff;
-	unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-	u8 tmp[bsize];
+static int crypt(struct crypto_tfm *tfm,
+		 struct scatterlist *dst,
+		 struct scatterlist *src,
+                 unsigned int nbytes, cryptfn_t crfn, procfn_t prfn, int enc)
+{
+	struct scatter_walk walk_in, walk_out;
+	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+	u8 tmp_src[nbytes > src->length ? bsize : 0];
+	u8 tmp_dst[nbytes > dst->length ? bsize : 0];
 
-	if (sglen(sg, nsg) % bsize) {
+	if (!nbytes)
+		return 0;
+
+	if (nbytes % bsize) {
 		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
 		return -EINVAL;
 	}
 
-	for (i = 0, coff = 0; i < nsg; i++) {
-		unsigned int n = 0, boff = 0;
-		unsigned int len = sg[i].length - coff;
-		char *p = crypto_kmap(sg[i].page) + sg[i].offset + coff;
-
-		while (len) {
-			if (len < bsize) {
-				crypto_kunmap(p);
-				n = gather_chunks(tfm, tmp, sg, i, len, &coff);
-				prfn(tfm, tmp, crfn, enc);
-				scatter_chunks(tfm, tmp, sg, i, len, &coff);
-				crypto_yield(tfm);
-				goto unmapped;
-			} else {
-				prfn(tfm, p, crfn, enc);
-				crypto_kunmap(p);
-				crypto_yield(tfm);
-				
-				/* remap and point to recalculated offset */
-				boff += bsize;
-				p = crypto_kmap(sg[i].page)
-				    + sg[i].offset + coff + boff;
-				
-				len -= bsize;
-				
-				/* End of frag with no remnant? */
-				if (coff && len == 0)
-					coff = 0;
-			}
-		}
-		crypto_kunmap(p);	
-unmapped:
-		i += n;
+	scatterwalk_start(&walk_in, src);
+	scatterwalk_start(&walk_out, dst);
+
+	for(;;) {
+		u8 *src_p, *dst_p;
+
+		scatterwalk_map(&walk_in, 0);
+		scatterwalk_map(&walk_out, 1);
+		src_p = which_buf(&walk_in, bsize, tmp_src);
+		dst_p = which_buf(&walk_out, bsize, tmp_dst);
+
+		nbytes -= bsize;
 
+		copy_chunks(src_p, &walk_in, bsize, 0);
+
+		prfn(tfm, dst_p, src_p, crfn, enc);
+
+		scatter_done(&walk_in, 0, nbytes);
+
+		copy_chunks(dst_p, &walk_out, bsize, 1);
+		scatter_done(&walk_out, 1, nbytes);
+
+		if (!nbytes)
+			return 0;
+
+		crypto_yield(tfm);
 	}
-	return 0;
 }
 
 static void cbc_process(struct crypto_tfm *tfm,
-                        u8 *block, cryptfn_t fn, int enc)
+                        u8 *dst, u8 *src, cryptfn_t fn, int enc)
 {
 	/* Null encryption */
 	if (!tfm->crt_cipher.cit_iv)
 		return;
 		
 	if (enc) {
-		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, block);
-		fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv);
-		memcpy(tfm->crt_cipher.cit_iv, block,
+		tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, src);
+		fn(tfm->crt_ctx, dst, tfm->crt_cipher.cit_iv);
+		memcpy(tfm->crt_cipher.cit_iv, dst,
 		       crypto_tfm_alg_blocksize(tfm));
 	} else {
-		u8 buf[crypto_tfm_alg_blocksize(tfm)];
+		const int need_stack = (src == dst);
+		u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0];
+		u8 *buf = need_stack ? stack : dst;
 		
-		fn(tfm->crt_ctx, buf, block);
+		fn(tfm->crt_ctx, buf, src);
 		tfm->crt_u.cipher.cit_xor_block(buf, tfm->crt_cipher.cit_iv);
-		memcpy(tfm->crt_cipher.cit_iv, block,
+		memcpy(tfm->crt_cipher.cit_iv, src,
 		       crypto_tfm_alg_blocksize(tfm));
-		memcpy(block, buf, crypto_tfm_alg_blocksize(tfm));
+		if (buf != dst)
+			memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
 	}
 }
 
-static void ecb_process(struct crypto_tfm *tfm, u8 *block,
+static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
                         cryptfn_t fn, int enc)
 {
-	fn(tfm->crt_ctx, block, block);
+	fn(tfm->crt_ctx, dst, src);
 }
 
 static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
@@ -211,35 +248,44 @@
 }
 
 static int ecb_encrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *sg, unsigned int nsg)
+		       struct scatterlist *dst,
+                       struct scatterlist *src, unsigned int nbytes)
 {
-	return crypt(tfm, sg, nsg,
+	return crypt(tfm, dst, src, nbytes,
 	             tfm->__crt_alg->cra_cipher.cia_encrypt, ecb_process, 1);
 }
 
 static int ecb_decrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *sg, unsigned int nsg)
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
 {
-	return crypt(tfm, sg, nsg,
+	return crypt(tfm, dst, src, nbytes,
 	             tfm->__crt_alg->cra_cipher.cia_decrypt, ecb_process, 1);
 }
 
 static int cbc_encrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *sg, unsigned int nsg)
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
 {
-	return crypt(tfm, sg, nsg,
+	return crypt(tfm, dst, src, nbytes,
 	             tfm->__crt_alg->cra_cipher.cia_encrypt, cbc_process, 1);
 }
 
 static int cbc_decrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *sg, unsigned int nsg)
+                       struct scatterlist *dst,
+                       struct scatterlist *src,
+		       unsigned int nbytes)
 {
-	return crypt(tfm, sg, nsg,
+	return crypt(tfm, dst, src, nbytes,
 	             tfm->__crt_alg->cra_cipher.cia_decrypt, cbc_process, 0);
 }
 
 static int nocrypt(struct crypto_tfm *tfm,
-                   struct scatterlist *sg, unsigned int nsg)
+                   struct scatterlist *dst,
+                   struct scatterlist *src,
+		   unsigned int nbytes)
 {
 	return -ENOSYS;
 }
diff -Nru a/crypto/digest.c b/crypto/digest.c
--- a/crypto/digest.c	Mon Feb 10 10:39:23 2003
+++ b/crypto/digest.c	Mon Feb 10 10:39:23 2003
@@ -28,10 +28,10 @@
 	unsigned int i;
 	
 	for (i = 0; i < nsg; i++) {
-		char *p = crypto_kmap(sg[i].page) + sg[i].offset;
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
 		tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx,
 		                                      p, sg[i].length);
-		crypto_kunmap(p);
+		crypto_kunmap(p, 0);
 		crypto_yield(tfm);
 	}
 }
@@ -49,10 +49,10 @@
 	tfm->crt_digest.dit_init(tfm);
 		
 	for (i = 0; i < nsg; i++) {
-		char *p = crypto_kmap(sg[i].page) + sg[i].offset;
+		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
 		tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx,
 		                                      p, sg[i].length);
-		crypto_kunmap(p);
+		crypto_kunmap(p, 0);
 		crypto_yield(tfm);
 	}
 	crypto_digest_final(tfm, out);
diff -Nru a/crypto/internal.h b/crypto/internal.h
--- a/crypto/internal.h	Mon Feb 10 10:39:23 2003
+++ b/crypto/internal.h	Mon Feb 10 10:39:23 2003
@@ -16,17 +16,29 @@
 #include <linux/init.h>
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
+#include <asm/kmap_types.h>
 
-static inline void *crypto_kmap(struct page *page)
+static enum km_type km_types[] = {
+	KM_USER0,
+	KM_USER1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+};
+
+static inline enum km_type crypto_kmap_type(int out)
+{
+	return km_types[(in_softirq() ? 2 : 0) + out];
+}
+	
+
+static inline void *crypto_kmap(struct page *page, int out)
 {
-	return kmap_atomic(page, in_softirq() ?
-	                   KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER);
+	return kmap_atomic(page, crypto_kmap_type(out));
 }
 
-static inline void crypto_kunmap(void *vaddr)
+static inline void crypto_kunmap(void *vaddr, int out)
 {
-	kunmap_atomic(vaddr, in_softirq() ?
-		      KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER);
+	kunmap_atomic(vaddr, crypto_kmap_type(out));
 }
 
 static inline void crypto_yield(struct crypto_tfm *tfm)
diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c	Mon Feb 10 10:39:30 2003
+++ b/crypto/tcrypt.c	Mon Feb 10 10:39:30 2003
@@ -703,7 +703,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = len;
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -746,7 +746,7 @@
 	sg[1].offset = ((long) p & ~PAGE_MASK);
 	sg[1].length = 8;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 2);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
 	if (ret) {
 		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 		goto out;
@@ -814,7 +814,7 @@
 	sg[2].offset = ((long) p & ~PAGE_MASK);
 	sg[2].length = 8;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 3);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
 
 	if (ret) {
 		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
@@ -890,7 +890,7 @@
 	sg[3].offset = ((long) p & ~PAGE_MASK);
 	sg[3].length = 18;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 4);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
 
 	if (ret) {
 		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
@@ -979,7 +979,7 @@
 	sg[4].offset = ((long) p & ~PAGE_MASK);
 	sg[4].length = 8;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 5);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
 
 	if (ret) {
 		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
@@ -1078,7 +1078,7 @@
 	sg[7].offset = ((long) p & ~PAGE_MASK);
 	sg[7].length = 1;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 8);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
 	if (ret) {
 		printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 		goto out;
@@ -1120,7 +1120,7 @@
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = len;
 
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("des_decrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1163,7 +1163,7 @@
 	sg[1].offset = ((long) p & ~PAGE_MASK);
 	sg[1].length = 8;
 
-	ret = crypto_cipher_decrypt(tfm, sg, 2);
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
 	if (ret) {
 		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 		goto out;
@@ -1220,7 +1220,7 @@
 	sg[2].offset = ((long) p & ~PAGE_MASK);
 	sg[2].length = 1;
 
-	ret = crypto_cipher_decrypt(tfm, sg, 3);
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
 
 	if (ret) {
 		printk("decrypt() failed flags=%x\n", tfm->crt_flags);
@@ -1290,7 +1290,7 @@
 		crypto_cipher_set_iv(tfm, des_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
 
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
 		if (ret) {
 			printk("des_cbc_encrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1349,7 +1349,7 @@
 
 	crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
 
-	ret = crypto_cipher_encrypt(tfm, sg, 2);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
 	if (ret) {
 		printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
 		goto out;
@@ -1398,7 +1398,7 @@
 		crypto_cipher_set_iv(tfm, des_tv[i].iv,
 				      crypto_tfm_alg_blocksize(tfm));
 
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, len);
 		if (ret) {
 			printk("des_cbc_decrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1450,7 +1450,7 @@
 
 	crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
 
-	ret = crypto_cipher_decrypt(tfm, sg, 2);
+	ret = crypto_cipher_decrypt(tfm, sg, sg, 8);
 	if (ret) {
 		printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
 		goto out;
@@ -1518,7 +1518,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = len;
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, len);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1561,7 +1561,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = len;
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, len);
 		if (ret) {
 			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1624,7 +1624,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = bf_tv[i].plen;
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1666,7 +1666,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = bf_tv[i].plen;
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1719,7 +1719,7 @@
 		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
 
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("blowfish_cbc_encrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1764,7 +1764,7 @@
 		crypto_cipher_set_iv(tfm, bf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
 
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("blowfish_cbc_decrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1829,7 +1829,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = tf_tv[i].plen;
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1871,7 +1871,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = tf_tv[i].plen;
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -1924,7 +1924,7 @@
 		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
 
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("blowfish_cbc_encrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -1970,7 +1970,7 @@
 		crypto_cipher_set_iv(tfm, tf_tv[i].iv,
 				     crypto_tfm_alg_ivsize(tfm));
 
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("blowfish_cbc_decrypt() failed flags=%x\n",
 			       tfm->crt_flags);
@@ -2030,7 +2030,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = sizeof(serp_tv[i].plaintext);
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -2070,7 +2070,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = sizeof(serp_tv[i].plaintext);
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -2133,7 +2133,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = aes_tv[i].plen;
-		ret = crypto_cipher_encrypt(tfm, sg, 1);
+		ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("encrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
@@ -2175,7 +2175,7 @@
 		sg[0].page = virt_to_page(p);
 		sg[0].offset = ((long) p & ~PAGE_MASK);
 		sg[0].length = aes_tv[i].plen;
-		ret = crypto_cipher_decrypt(tfm, sg, 1);
+		ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
 		if (ret) {
 			printk("decrypt() failed flags=%x\n", tfm->crt_flags);
 			goto out;
diff -Nru a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
--- a/drivers/acorn/char/pcf8583.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/acorn/char/pcf8583.c	Mon Feb 10 10:39:32 2003
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/mc146818rtc.h>
 #include <linux/init.h>
+#include <linux/errno.h>
 #include <linux/bcd.h>
 
 #include "pcf8583.h"
diff -Nru a/drivers/acorn/scsi/Makefile b/drivers/acorn/scsi/Makefile
--- a/drivers/acorn/scsi/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/acorn/scsi/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,7 +2,6 @@
 # Makefile for drivers/acorn/scsi
 #
 
-export-objs		:= fas216.o queue.o msgqueue.o
 acornscsi_mod-objs	:= acornscsi.o acornscsi-io.o
 
 obj-$(CONFIG_SCSI_ACORNSCSI_3)	+= acornscsi_mod.o queue.o msgqueue.o
diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
--- a/drivers/acorn/scsi/acornscsi.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/acorn/scsi/acornscsi.c	Mon Feb 10 10:39:27 2003
@@ -3110,7 +3110,8 @@
 	.remove		= __devexit_p(acornscsi_remove),
 	.id_table	= acornscsi_cids,
 	.drv = {
-		.name	= "acornscsi",
+		.devclass	= &shost_devclass,
+		.name		= "acornscsi",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c
--- a/drivers/acorn/scsi/arxescsi.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/acorn/scsi/arxescsi.c	Mon Feb 10 10:39:27 2003
@@ -40,33 +40,18 @@
 #include "fas216.h"
 
 struct arxescsi_info {
-    FAS216_Info info;
-
-    /* other info... */
-    unsigned int	cstatus;	/* card status register	*/
-    unsigned int	dmaarea;	/* Pseudo DMA area	*/
+	FAS216_Info		info;
+	struct expansion_card	*ec;
 };
 
-#define CSTATUS_IRQ	(1 << 0)
-#define CSTATUS_DRQ	(1 << 0)
+#define DMADATA_OFFSET	(0x200)
 
-#ifndef CAN_QUEUE
-#define CAN_QUEUE	1
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN	1
-#endif
+#define DMASTAT_OFFSET	(0x600)
+#define DMASTAT_DRQ	(1 << 0)
 
-/* Hmm - this should go somewhere else */
-#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE)
+#define CSTATUS_IRQ	(1 << 0)
 
-/*
- * Version
- */
-#define VER_MAJOR	0
-#define VER_MINOR	1
-#define VER_PATCH	1
+#define VERSION "1.10 (23/01/2003 2.5.57)"
 
 /*
  * Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type)
@@ -87,44 +72,7 @@
 	return fasdma_pseudo;
 }
 
-
-
-/* Faster transfer routines, written by SH to speed up the loops */
-
-static inline unsigned char getb(unsigned int address, unsigned int reg)
-{
-	unsigned char value;
-
-	__asm__ __volatile__(
-	"ldrb	%0, [%1, %2, lsl #5]"
-	: "=r" (value)
-	: "r" (address), "r" (reg) );
-	return value;
-}
-
-static inline unsigned int getw(unsigned int address, unsigned int reg)
-{
-	unsigned int value;
-	
-	__asm__ __volatile__(
-	"ldr	%0, [%1, %2, lsl #5]\n\t"
-	"mov	%0, %0, lsl #16\n\t"
-	"mov	%0, %0, lsr #16"
-	: "=r" (value)
-	: "r" (address), "r" (reg) );
-	return value;
-}
-
-static inline void putw(unsigned int address, unsigned int reg, unsigned long value)
-{
-	__asm__ __volatile__(
-	"mov	%0, %0, lsl #16\n\t"
-	"str	%0, [%1, %2, lsl #5]"
-	:
-	: "r" (value), "r" (address), "r" (reg) );
-}
-
-void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned int io)
+static void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned char *base)
 {
        __asm__ __volatile__(
        "               stmdb   sp!, {r0-r12}\n"
@@ -149,7 +97,7 @@
        "               bne     .loop_1\n"
        "               ldmia   sp!, {r0-r12}\n"
        :
-       : "r" (addr), "r" (io) );
+       : "r" (addr), "r" (base));
 }
 
 /*
@@ -160,40 +108,41 @@
  *	     direction - DMA on to/off of card
  *	     transfer  - minimum number of bytes we expect to transfer
  */
-void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
-			fasdmadir_t direction, int transfer)
+static void
+arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
+		    fasdmadir_t direction, int transfer)
 {
 	struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
-	unsigned int length, io, error=0;
+	unsigned int length, error = 0;
+	unsigned char *base = info->info.scsi.io_base;
 	unsigned char *addr;
 
 	length = SCp->this_residual;
 	addr = SCp->ptr;
-	io = __ioaddr(host->io_port);
 
 	if (direction == DMA_OUT) {
 		unsigned int word;
 		while (length > 256) {
-			if (getb(io, 4) & STAT_INT) {
-				error=1;
+			if (readb(base + 0x80) & STAT_INT) {
+				error = 1;
 				break;
 			}
-			arxescsi_pseudo_dma_write(addr, io);
+			arxescsi_pseudo_dma_write(addr, base);
 			addr += 256;
 			length -= 256;
 		}
 
 		if (!error)
 			while (length > 0) {
-				if (getb(io, 4) & STAT_INT)
+				if (readb(base + 0x80) & STAT_INT)
 					break;
 	 
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ))
 					continue;
 
 				word = *addr | *(addr + 1) << 8;
 
-				putw(io, 16, word);
+				writew(word, base + DMADATA_OFFSET);
 				if (length > 1) {
 					addr += 2;
 					length -= 2;
@@ -206,15 +155,15 @@
 	else {
 		if (transfer && (transfer & 255)) {
 			while (length >= 256) {
-				if (getb(io, 4) & STAT_INT) {
-					error=1;
+				if (readb(base + 0x80) & STAT_INT) {
+					error = 1;
 					break;
 				}
 	    
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ))
 					continue;
 
-				insw(info->dmaarea, addr, 256 >> 1);
+				readsw(base + DMADATA_OFFSET, addr, 256 >> 1);
 				addr += 256;
 				length -= 256;
 			}
@@ -224,13 +173,13 @@
 			while (length > 0) {
 				unsigned long word;
 
-				if (getb(io, 4) & STAT_INT)
+				if (readb(base + 0x80) & STAT_INT)
 					break;
 
-				if (!(getb(io, 48) & CSTATUS_IRQ))
+				if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ))
 					continue;
 
-				word = getw(io, 16);
+				word = readw(base + DMADATA_OFFSET);
 				*addr++ = word;
 				if (--length > 0) {
 					*addr++ = word >> 8;
@@ -259,15 +208,14 @@
  * Params  : host - driver host structure to return info for.
  * Returns : pointer to a static buffer containing null terminated string.
  */
-const char *arxescsi_info(struct Scsi_Host *host)
+static const char *arxescsi_info(struct Scsi_Host *host)
 {
 	struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
-	static char string[100], *p;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH);
+	sprintf(string, "%s (%s) in slot %d v%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION);
 
 	return string;
 }
@@ -286,8 +234,9 @@
  *	     inout  - 0 for reading, 1 for writing.
  * Returns : length of data written to buffer.
  */
-int arxescsi_proc_info(char *buffer, char **start, off_t offset,
-			    int length, int host_no, int inout)
+static int
+arxescsi_proc_info(char *buffer, char **start, off_t offset, int length,
+		   int host_no, int inout)
 {
 	int pos, begin;
 	struct Scsi_Host *host;
@@ -303,9 +252,7 @@
 		return -EINVAL;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"ARXE 16-bit SCSI driver version %d.%d.%d\n",
-			VER_MAJOR, VER_MINOR, VER_PATCH);
+	pos = sprintf(buffer, "ARXE 16-bit SCSI driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += fas216_print_stats(&info->info, buffer + pos);
 
@@ -343,7 +290,7 @@
 	.can_queue			= 0,
 	.this_id			= 7,
 	.sg_tablesize			= SG_ALL,
-	.cmd_per_lun			= CMD_PER_LUN,
+	.cmd_per_lun			= 1,
 	.use_clustering			= DISABLE_CLUSTERING,
 	.proc_name			= "arxescsi",
 };
@@ -352,21 +299,41 @@
 arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
 	struct Scsi_Host *host;
-      	struct arxescsi_info *info;
-      	int ret = -ENOMEM;
+	struct arxescsi_info *info;
+	unsigned long resbase, reslen;
+	unsigned char *base;
+	int ret;
 
-	host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info));
-	if (!host)
+	resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
+	reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
+
+	if (!request_mem_region(resbase, reslen, "arxescsi")) {
+		ret = -EBUSY;
 		goto out;
+	}
 
-	host->io_port = ecard_address(ec, ECARD_MEMC, 0) + 0x0800;
+	base = ioremap(resbase, reslen);
+	if (!base) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
+
+	host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_unmap;
+	}
+
+	host->base = (unsigned long)base;
 	host->irq = NO_IRQ;
 	host->dma_channel = NO_DMA;
 
 	info = (struct arxescsi_info *)host->hostdata;
-	info->info.scsi.io_port		= host->io_port;
+	info->ec = ec;
+
+	info->info.scsi.io_base		= base + 0x2000;
 	info->info.scsi.irq		= host->irq;
-	info->info.scsi.io_shift	= 3;
+	info->info.scsi.io_shift	= 5;
 	info->info.ifcfg.clockrate	= 24; /* MHz */
 	info->info.ifcfg.select_timeout = 255;
 	info->info.ifcfg.asyncperiod	= 200; /* ns */
@@ -374,39 +341,29 @@
 	info->info.ifcfg.cntl3		= CNTL3_FASTSCSI | CNTL3_FASTCLK;
 	info->info.ifcfg.disconnect_ok	= 0;
 	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
 	info->info.dma.setup		= arxescsi_dma_setup;
 	info->info.dma.pseudo		= arxescsi_dma_pseudo;
 	info->info.dma.stop		= arxescsi_dma_stop;
-	info->dmaarea			= host->io_port + 128;
-	info->cstatus			= host->io_port + 384;
 		
-	ec->irqaddr = (unsigned char *)BUS_ADDR(host->io_port);
+	ec->irqaddr = base;
 	ec->irqmask = CSTATUS_IRQ;
 
-	if (!request_region(host->io_port, 120, "arxescsi-fas")) {
-		ret = -EBUSY;
-		goto out_free;
-	}
-			
-	if (!request_region(host->io_port + 128, 384, "arxescsi-dma")) {
-		ret = -EBUSY;
-		goto out_release;
-	}
-
-	printk("scsi%d: Has no interrupts - using polling mode\n",
-	       host->host_no);
+	ret = fas216_init(host);
+	if (ret)
+		goto out_unregister;
 
-	fas216_init(host);
-
-	ret = scsi_add_host(host, &ec->dev);
+	ret = fas216_add(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
-	release_region(host->io_port + 128, 384);
- out_release:
-	release_region(host->io_port, 120);
- out_free:
+	fas216_release(host);
+ out_unregister:
 	scsi_unregister(host);
+ out_unmap:
+	iounmap(base);
+ out_region:
+	release_mem_region(resbase, reslen);
  out:
 	return ret;
 }
@@ -414,13 +371,19 @@
 static void __devexit arxescsi_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	unsigned long resbase, reslen;
 
 	ecard_set_drvdata(ec, NULL);
-	scsi_remove_host(host);
-	fas216_release(host);
+	fas216_remove(host);
+
+	iounmap((void *)host->base);
+
+	resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
+	reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
 
-	release_region(host->io_port + 128, 384);
-	release_region(host->io_port, 120);
+	release_mem_region(resbase, reslen);
+
+	fas216_release(host);
 	scsi_unregister(host);
 }
 
@@ -434,7 +397,8 @@
 	.remove		= __devexit_p(arxescsi_remove),
 	.id_table	= arxescsi_cids,
 	.drv = {
-		.name	= "arxescsi",
+		.devclass	= &shost_devclass,
+		.name		= "arxescsi",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c
--- a/drivers/acorn/scsi/cumana_1.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/acorn/scsi/cumana_1.c	Mon Feb 10 10:39:23 2003
@@ -334,7 +334,8 @@
 	.remove		= __devexit_p(cumanascsi1_remove),
 	.id_table	= cumanascsi1_cids,
 	.drv = {
-		.name	= "cumanascsi1",
+		.devclass	= &shost_devclass,
+		.name		= "cumanascsi1",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c
--- a/drivers/acorn/scsi/cumana_2.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/acorn/scsi/cumana_2.c	Mon Feb 10 10:39:30 2003
@@ -41,12 +41,12 @@
 
 #include <scsi/scsicam.h>
 
-#define CUMANASCSI2_STATUS		(0)
+#define CUMANASCSI2_STATUS		(0x0000)
 #define STATUS_INT			(1 << 0)
 #define STATUS_DRQ			(1 << 1)
 #define STATUS_LATCHED			(1 << 3)
 
-#define CUMANASCSI2_ALATCH		(5)
+#define CUMANASCSI2_ALATCH		(0x0014)
 #define ALATCH_ENA_INT			(3)
 #define ALATCH_DIS_INT			(2)
 #define ALATCH_ENA_TERM			(5)
@@ -58,11 +58,10 @@
 #define ALATCH_DMA_OUT			(15)
 #define ALATCH_DMA_IN			(14)
 
-#define CUMANASCSI2_PSEUDODMA		(0x80)
+#define CUMANASCSI2_PSEUDODMA		(0x0200)
 
-#define CUMANASCSI2_FAS216_OFFSET	(0xc0)
-#define CUMANASCSI2_FAS216_SHIFT	0
-#define CUMANASCSI2_FAS216_SIZE		(16)
+#define CUMANASCSI2_FAS216_OFFSET	(0x0300)
+#define CUMANASCSI2_FAS216_SHIFT	2
 
 /*
  * Version
@@ -77,13 +76,14 @@
 #define NR_SG	256
 
 struct cumanascsi2_info {
-	FAS216_Info info;
+	FAS216_Info		info;
+	struct expansion_card	*ec;
 
-	unsigned int	status;		/* card status register	*/
-	unsigned int	alatch;		/* Control register	*/
-	unsigned int	terms;		/* Terminator state	*/
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
+	void			*status;	/* card status register	*/
+	void			*alatch;	/* Control register	*/
+	unsigned int		terms;		/* Terminator state	*/
+	void			*dmaarea;	/* Pseudo DMA area	*/
+	struct scatterlist	sg[NR_SG];	/* Scatter DMA list	*/
 };
 
 #define CSTATUS_IRQ	(1 << 0)
@@ -97,8 +97,7 @@
 static void
 cumanascsi_2_irqenable(struct expansion_card *ec, int irqnr)
 {
-	unsigned int port = (unsigned int)ec->irq_data;
-	outb(ALATCH_ENA_INT, port);
+	writeb(ALATCH_ENA_INT, ec->irq_data);
 }
 
 /* Prototype: void cumanascsi_2_irqdisable(ec, irqnr)
@@ -109,8 +108,7 @@
 static void
 cumanascsi_2_irqdisable(struct expansion_card *ec, int irqnr)
 {
-	unsigned int port = (unsigned int)ec->irq_data;
-	outb(ALATCH_DIS_INT, port);
+	writeb(ALATCH_DIS_INT, ec->irq_data);
 }
 
 static const expansioncard_ops_t cumanascsi_2_ops = {
@@ -130,10 +128,10 @@
 
 	if (on_off) {
 		info->terms = 1;
-		outb (ALATCH_ENA_TERM, info->alatch);
+		writeb(ALATCH_ENA_TERM, info->alatch);
 	} else {
 		info->terms = 0;
-		outb (ALATCH_DIS_TERM, info->alatch);
+		writeb(ALATCH_DIS_TERM, info->alatch);
 	}
 }
 
@@ -146,9 +144,9 @@
 static void
 cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	struct cumanascsi2_info *info = dev_id;
 
-	fas216_intr(host);
+	fas216_intr(&info->info);
 }
 
 /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type)
@@ -167,7 +165,7 @@
 	struct device *dev = scsi_get_device(host);
 	int dmach = host->dma_channel;
 
-	outb(ALATCH_DIS_DMA, info->alatch);
+	writeb(ALATCH_DIS_DMA, info->alatch);
 
 	if (dmach != NO_DMA &&
 	    (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
@@ -188,11 +186,11 @@
 
 		disable_dma(dmach);
 		set_dma_sg(dmach, info->sg, bufs + 1);
-		outb(alatch_dir, info->alatch);
+		writeb(alatch_dir, info->alatch);
 		set_dma_mode(dmach, dma_dir);
 		enable_dma(dmach);
-		outb(ALATCH_ENA_DMA, info->alatch);
-		outb(ALATCH_DIS_BIT32, info->alatch);
+		writeb(ALATCH_ENA_DMA, info->alatch);
+		writeb(ALATCH_DIS_BIT32, info->alatch);
 		return fasdma_real_all;
 	}
 
@@ -226,7 +224,7 @@
 #if 0
 		while (length > 1) {
 			unsigned long word;
-			unsigned int status = inb(info->status);
+			unsigned int status = readb(info->status);
 
 			if (status & STATUS_INT)
 				goto end;
@@ -235,7 +233,7 @@
 				continue;
 
 			word = *addr | *(addr + 1) << 8;
-			outw (info->dmaarea);
+			writew(word, info->dmaarea);
 			addr += 2;
 			length -= 2;
 		}
@@ -245,15 +243,15 @@
 	else {
 		if (transfer && (transfer & 255)) {
 			while (length >= 256) {
-				unsigned int status = inb(info->status);
+				unsigned int status = readb(info->status);
 
 				if (status & STATUS_INT)
-					goto end;
+					return;
 	    
 				if (!(status & STATUS_DRQ))
 					continue;
 
-				insw(info->dmaarea, addr, 256 >> 1);
+				readsw(info->dmaarea, addr, 256 >> 1);
 				addr += 256;
 				length -= 256;
 			}
@@ -261,15 +259,15 @@
 
 		while (length > 0) {
 			unsigned long word;
-			unsigned int status = inb(info->status);
+			unsigned int status = readb(info->status);
 
 			if (status & STATUS_INT)
-				goto end;
+				return;
 
 			if (!(status & STATUS_DRQ))
 				continue;
 
-			word = inw (info->dmaarea);
+			word = readw(info->dmaarea);
 			*addr++ = word;
 			if (--length > 0) {
 				*addr++ = word >> 8;
@@ -277,8 +275,6 @@
 			}
 		}
 	}
-
-end:
 }
 
 /* Prototype: int cumanascsi_2_dma_stop(host, SCpnt)
@@ -291,7 +287,7 @@
 {
 	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
 	if (host->dma_channel != NO_DMA) {
-		outb(ALATCH_DIS_DMA, info->alatch);
+		writeb(ALATCH_DIS_DMA, info->alatch);
 		disable_dma(host->dma_channel);
 	}
 }
@@ -304,13 +300,11 @@
 const char *cumanascsi_2_info(struct Scsi_Host *host)
 {
 	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
-	static char string[100], *p;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%s terminators o%s",
-		     VERSION, info->terms ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION, info->terms ? "n" : "ff");
 
 	return string;
 }
@@ -377,10 +371,7 @@
 	info = (struct cumanascsi2_info *)host->hostdata;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"Cumana SCSI II driver version v%s\n",
-			VERSION);
-
+	pos = sprintf(buffer, "Cumana SCSI II driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
 			info->terms ? "n" : "ff");
@@ -440,38 +431,52 @@
 cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
 	struct Scsi_Host *host;
-    	struct cumanascsi2_info *info;
-    	int ret = -ENOMEM;
+	struct cumanascsi2_info *info;
+	unsigned long resbase, reslen;
+	unsigned char *base;
+	int ret;
 
-	host = scsi_register(&cumanascsi2_template, sizeof (struct cumanascsi2_info));
-	if (!host)
+	resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
+	reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
+
+	if (!request_mem_region(resbase, reslen, "cumanascsi2")) {
+		ret = -EBUSY;
 		goto out;
+	}
 
-	host->io_port = ecard_address(ec, ECARD_MEMC, 0);
-	host->irq = ec->irq;
-	host->dma_channel = ec->dma;
+	base = ioremap(resbase, reslen);
+	if (!base) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
 
-	if (!request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
-			    CUMANASCSI2_FAS216_SIZE, "cumanascsi2-fas")) {
-		ret = -EBUSY;
-		goto out_free;
+	host = scsi_register(&cumanascsi2_template,
+			     sizeof(struct cumanascsi2_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_unmap;
 	}
 
+	host->base	  = (unsigned long)base;
+	host->irq	  = ec->irq;
+	host->dma_channel = ec->dma;
+
 	ecard_set_drvdata(ec, host);
 
 	info = (struct cumanascsi2_info *)host->hostdata;
-	info->dmaarea	= host->io_port + CUMANASCSI2_PSEUDODMA;
-	info->status	= host->io_port + CUMANASCSI2_STATUS;
-	info->alatch	= host->io_port + CUMANASCSI2_ALATCH;
+	info->ec	= ec;
+	info->dmaarea	= base + CUMANASCSI2_PSEUDODMA;
+	info->status	= base + CUMANASCSI2_STATUS;
+	info->alatch	= base + CUMANASCSI2_ALATCH;
 
-	ec->irqaddr	= (unsigned char *)ioaddr(info->status);
+	ec->irqaddr	= info->status;
 	ec->irqmask	= STATUS_INT;
-	ec->irq_data	= (void *)info->alatch;
-	ec->ops		= (expansioncard_ops_t *)&cumanascsi_2_ops;
+	ec->irq_data	= base + CUMANASCSI2_ALATCH;
+	ec->ops		= &cumanascsi_2_ops;
 
 	cumanascsi_2_terminator_ctl(host, term[ec->slot_no]);
 
-	info->info.scsi.io_port		= host->io_port + CUMANASCSI2_FAS216_OFFSET;
+	info->info.scsi.io_base		= base + CUMANASCSI2_FAS216_OFFSET;
 	info->info.scsi.io_shift	= CUMANASCSI2_FAS216_SHIFT;
 	info->info.scsi.irq		= host->irq;
 	info->info.ifcfg.clockrate	= 40; /* MHz */
@@ -481,16 +486,21 @@
 	info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
 	info->info.ifcfg.disconnect_ok	= 1;
 	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
 	info->info.dma.setup		= cumanascsi_2_dma_setup;
 	info->info.dma.pseudo		= cumanascsi_2_dma_pseudo;
 	info->info.dma.stop		= cumanascsi_2_dma_stop;
 
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
 	ret = request_irq(host->irq, cumanascsi_2_intr,
-			  SA_INTERRUPT, "cumanascsi2", host);
+			  SA_INTERRUPT, "cumanascsi2", info);
 	if (ret) {
 		printk("scsi%d: IRQ%d not free: %d\n",
 		       host->host_no, host->irq, ret);
-		goto out_region;
+		goto out_release;
 	}
 
 	if (host->dma_channel != NO_DMA) {
@@ -500,26 +510,30 @@
 			host->dma_channel = NO_DMA;
 		} else {
 			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
 		}
 	}
 
-	fas216_init(host);
-
-	ret = scsi_add_host(host, &ec->dev);
+	ret = fas216_add(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
-	fas216_release(host);
-
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
 	free_irq(host->irq, host);
- out_region:
-	release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
-		       CUMANASCSI2_FAS216_SIZE);
+
+ out_release:
+	fas216_release(host);
+
  out_free:
 	scsi_unregister(host);
 
+ out_unmap:
+	iounmap(base);
+
+ out_region:
+	release_mem_region(resbase, reslen);
+
  out:
 	return ret;
 }
@@ -527,17 +541,24 @@
 static void __devexit cumanascsi2_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata;
+	unsigned long resbase, reslen;
 
 	ecard_set_drvdata(ec, NULL);
-	scsi_remove_host(host);
-	fas216_release(host);
+	fas216_remove(host);
 
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
-	free_irq(host->irq, host);
-	release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET,
-		       CUMANASCSI2_FAS216_SIZE);
+	free_irq(host->irq, info);
 
+	iounmap((void *)host->base);
+
+	resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
+	reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
+
+	release_mem_region(resbase, reslen);
+
+	fas216_release(host);
 	scsi_unregister(host);
 }
 
@@ -551,7 +572,8 @@
 	.remove		= __devexit_p(cumanascsi2_remove),
 	.id_table	= cumanascsi2_cids,
 	.drv = {
-		.name	= "cumanascsi2",
+		.devclass	= &shost_devclass,
+		.name		= "cumanascsi2",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c
--- a/drivers/acorn/scsi/eesox.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/acorn/scsi/eesox.c	Mon Feb 10 10:39:33 2003
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/eesox.c
  *
- *  Copyright (C) 1997-2002 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * 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
@@ -47,25 +47,21 @@
 
 #include <scsi/scsicam.h>
 
-#define EESOX_FAS216_OFFSET	0xc00
-#define EESOX_FAS216_SHIFT	3
-#define EESOX_FAS216_SIZE	(16 << EESOX_FAS216_SHIFT)
+#define EESOX_FAS216_OFFSET	0x3000
+#define EESOX_FAS216_SHIFT	5
 
-#define EESOX_STATUS		0xa00
+#define EESOX_DMASTAT		0x2800
 #define EESOX_STAT_INTR		0x01
 #define EESOX_STAT_DMA		0x02
 
-#define EESOX_CONTROL		0xa00
+#define EESOX_CONTROL		0x2800
 #define EESOX_INTR_ENABLE	0x04
 #define EESOX_TERM_ENABLE	0x02
 #define EESOX_RESET		0x01
 
-#define EESOX_DMA_OFFSET	0xe00
+#define EESOX_DMADATA		0x3800
 
-/*
- * Version
- */
-#define VERSION "1.00 (13/11/2002 2.5.47)"
+#define VERSION "1.10 (17/01/2003 2.5.59)"
 
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
@@ -75,12 +71,12 @@
 #define NR_SG	256
 
 struct eesoxscsi_info {
-	FAS216_Info info;
+	FAS216_Info		info;
+	struct expansion_card	*ec;
 
-	unsigned int	ctl_port;
-	unsigned int	control;
-	unsigned int	dmaarea;	/* Pseudo DMA area	*/
-	struct scatterlist sg[NR_SG];	/* Scatter DMA list	*/
+	void			*ctl_port;
+	unsigned int		control;
+	struct scatterlist	sg[NR_SG];	/* Scatter DMA list	*/
 };
 
 /* Prototype: void eesoxscsi_irqenable(ec, irqnr)
@@ -95,7 +91,7 @@
 
 	info->control |= EESOX_INTR_ENABLE;
 
-	outb(info->control, info->ctl_port);
+	writeb(info->control, info->ctl_port);
 }
 
 /* Prototype: void eesoxscsi_irqdisable(ec, irqnr)
@@ -110,7 +106,7 @@
 
 	info->control &= ~EESOX_INTR_ENABLE;
 
-	outb(info->control, info->ctl_port);
+	writeb(info->control, info->ctl_port);
 }
 
 static const expansioncard_ops_t eesoxscsi_ops = {
@@ -135,7 +131,7 @@
 	else
 		info->control &= ~EESOX_TERM_ENABLE;
 
-	outb(info->control, info->ctl_port);
+	writeb(info->control, info->ctl_port);
 	spin_unlock_irqrestore(host->host_lock, flags);
 }
 
@@ -148,9 +144,9 @@
 static void
 eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	struct eesoxscsi_info *info = dev_id;
 
-	fas216_intr(host);
+	fas216_intr(&info->info);
 }
 
 /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type)
@@ -198,93 +194,164 @@
 	return fasdma_pseudo;
 }
 
+static void eesoxscsi_buffer_in(void *buf, int length, void *base)
+{
+	const void *reg_fas = base + EESOX_FAS216_OFFSET;
+	const void *reg_dmastat = base + EESOX_DMASTAT;
+	const void *reg_dmadata = base + EESOX_DMADATA;
+	const register unsigned long mask = 0xffff;
+
+	do {
+		unsigned int status;
+
+		/*
+		 * Interrupt request?
+		 */
+		status = readb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT));
+		if (status & STAT_INT)
+			break;
+
+		/*
+		 * DMA request active?
+		 */
+		status = readb(reg_dmastat);
+		if (!(status & EESOX_STAT_DMA))
+			continue;
+
+		/*
+		 * Get number of bytes in FIFO
+		 */
+		status = readb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF;
+		if (status > 16)
+			status = 16;
+		if (status > length)
+			status = length;
+
+		/*
+		 * Align buffer.
+		 */
+		if (((u32)buf) & 2 && status >= 2) {
+			*((u16 *)buf)++ = readl(reg_dmadata);
+			status -= 2;
+			length -= 2;
+		}
+
+		if (status >= 8) {
+			unsigned long l1, l2;
+
+			l1 = readl(reg_dmadata) & mask;
+			l1 |= readl(reg_dmadata) << 16;
+			l2 = readl(reg_dmadata) & mask;
+			l2 |= readl(reg_dmadata) << 16;
+			*((u32 *)buf)++ = l1;
+			*((u32 *)buf)++ = l2;
+			length -= 8;
+			continue;
+		}
+
+		if (status >= 4) {
+			unsigned long l1;
+
+			l1 = readl(reg_dmadata) & mask;
+			l1 |= readl(reg_dmadata) << 16;
+
+			*((u32 *)buf)++ = l1;
+			length -= 4;
+			continue;
+		}
+
+		if (status >= 2) {
+			*((u16 *)buf)++ = readl(reg_dmadata);
+			length -= 2;
+		}
+	} while (length);
+}
+
+static void eesoxscsi_buffer_out(void *buf, int length, void *base)
+{
+	const void *reg_fas = base + EESOX_FAS216_OFFSET;
+	const void *reg_dmastat = base + EESOX_DMASTAT;
+	const void *reg_dmadata = base + EESOX_DMADATA;
+
+	do {
+		unsigned int status;
+
+		/*
+		 * Interrupt request?
+		 */
+		status = readb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT));
+		if (status & STAT_INT)
+			break;
+
+		/*
+		 * DMA request active?
+		 */
+		status = readb(reg_dmastat);
+		if (!(status & EESOX_STAT_DMA))
+			continue;
+
+		/*
+		 * Get number of bytes in FIFO
+		 */
+		status = readb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF;
+		if (status > 16)
+			status = 16;
+		status = 16 - status;
+		if (status > length)
+			status = length;
+		status &= ~1;
+
+		/*
+		 * Align buffer.
+		 */
+		if (((u32)buf) & 2 && status >= 2) {
+			writel(*((u16 *)buf)++ << 16, reg_dmadata);
+			status -= 2;
+			length -= 2;
+		}
+
+		if (status >= 8) {
+			unsigned long l1, l2;
+
+			l1 = *((u32 *)buf)++;
+			l2 = *((u32 *)buf)++;
+
+			writel(l1 << 16, reg_dmadata);
+			writel(l1, reg_dmadata);
+			writel(l2 << 16, reg_dmadata);
+			writel(l2, reg_dmadata);
+			length -= 8;
+			continue;
+		}
+
+		if (status >= 4) {
+			unsigned long l1;
+
+			l1 = *((u32 *)buf)++;
+
+			writel(l1 << 16, reg_dmadata);
+			writel(l1, reg_dmadata);
+			length -= 4;
+			continue;
+		}
+
+		if (status >= 2) {
+			writel(*((u16 *)buf)++ << 16, reg_dmadata);
+			length -= 2;
+		}
+	} while (length);
+}
+
 static void
 eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
 		     fasdmadir_t dir, int transfer_size)
 {
-	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
-	unsigned int status;
-	unsigned int length = SCp->this_residual;
-	union {
-		unsigned char *c;
-		unsigned short *s;
-		unsigned long *l;
-	} buffer;
-
-	buffer.c = SCp->ptr;
-
-	status = inb(host->io_port + EESOX_STATUS);
+	void *base = (void *)host->base;
 	if (dir == DMA_IN) {
-		while (length > 8) {
-			if (status & EESOX_STAT_DMA) {
-				unsigned long l1, l2;
-
-				l1 = inw(info->dmaarea);
-				l1 |= inw(info->dmaarea) << 16;
-				l2 = inw(info->dmaarea);
-				l2 |= inw(info->dmaarea) << 16;
-				*buffer.l++ = l1;
-				*buffer.l++ = l2;
-				length -= 8;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 1) {
-			if (status & EESOX_STAT_DMA) {
-				*buffer.s++ = inw(info->dmaarea);
-				length -= 2;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 0) {
-			if (status & EESOX_STAT_DMA) {
-				*buffer.c++ = inw(info->dmaarea);
-				length -= 1;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
+		eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, base);
 	} else {
-		while (length > 8) {
-			if (status & EESOX_STAT_DMA) {
-				unsigned long l1, l2;
-
-				l1 = *buffer.l++;
-				l2 = *buffer.l++;
-
-				outw(l1, info->dmaarea);
-				outw(l1 >> 16, info->dmaarea);
-				outw(l2, info->dmaarea);
-				outw(l2 >> 16, info->dmaarea);
-				length -= 8;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 1) {
-			if (status & EESOX_STAT_DMA) {
-				outw(*buffer.s++, info->dmaarea);
-				length -= 2;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
-
-		while (length > 0) {
-			if (status & EESOX_STAT_DMA) {
-				outw(*buffer.c++, info->dmaarea);
-				length -= 1;
-			} else if (status & EESOX_STAT_INTR)
-				goto end;
-			status = inb(host->io_port + EESOX_STATUS);
-		}
+		eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, base);
 	}
-end:
 }
 
 /* Prototype: int eesoxscsi_dma_stop(host, SCpnt)
@@ -307,14 +374,11 @@
 const char *eesoxscsi_info(struct Scsi_Host *host)
 {
 	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
-	static char string[100], *p;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%s terminators o%s",
-		     VERSION,
-		     info->control & EESOX_TERM_ENABLE ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION, info->control & EESOX_TERM_ENABLE ? "n" : "ff");
 
 	return string;
 }
@@ -381,9 +445,7 @@
 	info = (struct eesoxscsi_info *)host->hostdata;
 
 	begin = 0;
-	pos = sprintf(buffer,
-			"EESOX SCSI driver version v%s\n",
-			VERSION);
+	pos = sprintf(buffer, "EESOX SCSI driver v%s\n", VERSION);
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
 			info->control & EESOX_TERM_ENABLE ? "n" : "ff");
@@ -417,6 +479,39 @@
 	return pos;
 }
 
+static ssize_t eesoxscsi_show_term(struct device *dev, char *buf)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
+
+	return sprintf(buf, "%d\n", info->control & EESOX_TERM_ENABLE ? 1 : 0);
+}
+
+static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t len)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
+	unsigned long flags;
+
+	if (len > 1) {
+		spin_lock_irqsave(host->host_lock, flags);
+		if (buf[0] != '0') {
+			info->control |= EESOX_TERM_ENABLE;
+		} else {
+			info->control &= ~EESOX_TERM_ENABLE;
+		}
+		writeb(info->control, info->ctl_port);
+		spin_unlock_irqrestore(host->host_lock, flags);
+	}
+
+	return len;
+}
+
+static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
+		   eesoxscsi_show_term, eesoxscsi_store_term);
+
 static Scsi_Host_Template eesox_template = {
 	.module				= THIS_MODULE,
 	.proc_info			= eesoxscsi_proc_info,
@@ -440,57 +535,75 @@
 eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
 	struct Scsi_Host *host;
-    	struct eesoxscsi_info *info;
-    	int ret = -ENOMEM;
+	struct eesoxscsi_info *info;
+	unsigned long resbase, reslen;
+	unsigned char *base;
+	int ret;
 
-	host = scsi_register(&eesox_template,
-			     sizeof(struct eesoxscsi_info));
-	if (!host)
+	resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
+	reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
+
+	if (!request_mem_region(resbase, reslen, "eesoxscsi")) {
+		ret = -EBUSY;
 		goto out;
+	}
 
-	host->io_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
-	host->irq = ec->irq;
-	host->dma_channel = ec->dma;
+	base = ioremap(resbase, reslen);
+	if (!base) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
 
-	if (!request_region(host->io_port + EESOX_FAS216_OFFSET,
-			    EESOX_FAS216_SIZE, "eesox2-fas")) {
-		ret = -EBUSY;
-		goto out_free;
+	host = scsi_register(&eesox_template,
+			     sizeof(struct eesoxscsi_info));
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_unmap;
 	}
 
+	host->base	  = (unsigned long)base;
+	host->irq	  = ec->irq;
+	host->dma_channel = ec->dma;
+
 	ecard_set_drvdata(ec, host);
 
 	info = (struct eesoxscsi_info *)host->hostdata;
-	info->ctl_port = host->io_port + EESOX_CONTROL;
-	info->control = term[ec->slot_no] ? EESOX_TERM_ENABLE : 0;
-	outb(info->control, info->ctl_port);
-
-	ec->irqaddr = (unsigned char *)ioaddr(host->io_port + EESOX_STATUS);
-	ec->irqmask = EESOX_STAT_INTR;
-	ec->irq_data = info;
-	ec->ops = (expansioncard_ops_t *)&eesoxscsi_ops;
+	info->ec	= ec;
+	info->ctl_port	= base + EESOX_CONTROL;
+	info->control	= term[ec->slot_no] ? EESOX_TERM_ENABLE : 0;
+	writeb(info->control, info->ctl_port);
+
+	ec->irqaddr	= base + EESOX_DMASTAT;
+	ec->irqmask	= EESOX_STAT_INTR;
+	ec->irq_data	= info;
+	ec->ops		= &eesoxscsi_ops;
 
-	info->info.scsi.io_port		= host->io_port + EESOX_FAS216_OFFSET;
+	info->info.scsi.io_base		= base + EESOX_FAS216_OFFSET;
 	info->info.scsi.io_shift	= EESOX_FAS216_SHIFT;
 	info->info.scsi.irq		= host->irq;
 	info->info.ifcfg.clockrate	= 40; /* MHz */
 	info->info.ifcfg.select_timeout	= 255;
 	info->info.ifcfg.asyncperiod	= 200; /* ns */
 	info->info.ifcfg.sync_max_depth	= 7;
-	info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+	info->info.ifcfg.cntl3		= CNTL3_FASTSCSI | CNTL3_FASTCLK;
 	info->info.ifcfg.disconnect_ok	= 1;
 	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
 	info->info.dma.setup		= eesoxscsi_dma_setup;
 	info->info.dma.pseudo		= eesoxscsi_dma_pseudo;
 	info->info.dma.stop		= eesoxscsi_dma_stop;
-	info->dmaarea			= host->io_port + EESOX_DMA_OFFSET;
 
-	ret = request_irq(host->irq, eesoxscsi_intr,
-			  SA_INTERRUPT, "eesox", host);
+	device_create_file(&ec->dev, &dev_attr_bus_term);
+
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
+	ret = request_irq(host->irq, eesoxscsi_intr, 0, "eesoxscsi", info);
 	if (ret) {
 		printk("scsi%d: IRQ%d not free: %d\n",
 		       host->host_no, host->irq, ret);
-		goto out_region;
+		goto out_remove;
 	}
 
 	if (host->dma_channel != NO_DMA) {
@@ -500,24 +613,32 @@
 			host->dma_channel = NO_DMA;
 		} else {
 			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
+			info->info.ifcfg.cntl3 |= CNTL3_BS8;
 		}
 	}
 
-	fas216_init(host);
-	ret = scsi_add_host(host, &ec->dev);
+	ret = fas216_add(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
-	fas216_release(host);
-
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
 	free_irq(host->irq, host);
- out_region:
-	release_region(host->io_port + EESOX_FAS216_OFFSET,
-		       EESOX_FAS216_SIZE);
+
+ out_remove:
+	fas216_remove(host);
+
  out_free:
+	device_remove_file(&ec->dev, &dev_attr_bus_term);
 	scsi_unregister(host);
+
+ out_unmap:
+	iounmap(base);
+
+ out_region:
+	release_mem_region(resbase, reslen);
+
  out:
 	return ret;
 }
@@ -525,15 +646,26 @@
 static void __devexit eesoxscsi_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata;
+	unsigned long resbase, reslen;
 
 	ecard_set_drvdata(ec, NULL);
-	scsi_remove_host(host);
-	fas216_release(host);
+	fas216_remove(host);
 
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
-	free_irq(host->irq, host);
-	release_region(host->io_port + EESOX_FAS216_OFFSET, EESOX_FAS216_SIZE);
+	free_irq(host->irq, info);
+
+	device_remove_file(&ec->dev, &dev_attr_bus_term);
+
+	iounmap((void *)host->base);
+
+	resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
+	reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
+
+	release_mem_region(resbase, reslen);
+
+	fas216_release(host);
 	scsi_unregister(host);
 }
 
@@ -547,7 +679,8 @@
 	.remove		= __devexit_p(eesoxscsi_remove),
 	.id_table	= eesoxscsi_cids,
 	.drv = {
-		.name	= "eesoxscsi",
+		.devclass	= &shost_devclass,
+		.name		= "eesoxscsi",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c
--- a/drivers/acorn/scsi/fas216.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/acorn/scsi/fas216.c	Mon Feb 10 10:39:25 2003
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/fas216.c
  *
- *  Copyright (C) 1997-2000 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * 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
@@ -10,7 +10,7 @@
  * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
  * other sources, including:
  *   the AMD Am53CF94 data sheet
- *   the AMD Am53C94 data sheet 
+ *   the AMD Am53C94 data sheet
  *
  * This is a generic driver.  To use it, have a look at cumana_2.c.  You
  * should define your own structure that overlays FAS216_Info, eg:
@@ -33,9 +33,6 @@
  *  02-04-2000	RMK	Converted to use the new error handling, and
  *			automatically request sense data upon check
  *			condition status from targets.
- *
- * Todo:
- *  - allow individual devices to enable sync xfers.
  */
 #include <linux/module.h>
 #include <linux/blk.h>
@@ -45,6 +42,7 @@
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 #include <linux/init.h>
 
 #include <asm/dma.h>
@@ -52,17 +50,11 @@
 #include <asm/irq.h>
 #include <asm/ecard.h>
 
-#define FAS216_C
-
 #include "../../scsi/scsi.h"
 #include "../../scsi/hosts.h"
 #include "fas216.h"
 #include "scsi.h"
 
-#define VER_MAJOR	0
-#define VER_MINOR	0
-#define VER_PATCH	5
-
 /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
  *  the data sheet.  This restriction is crazy, especially when
  *  you only want to send 16 bytes!  What were the guys who
@@ -104,22 +96,43 @@
 
 static int level_mask = LOG_ERROR;
 
+static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
+{
+	unsigned int off = reg << info->scsi.io_shift;
+	if (info->scsi.io_base)
+		return readb(info->scsi.io_base + off);
+	else
+		return inb(info->scsi.io_port + off);
+}
+
+static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
+{
+	unsigned int off = reg << info->scsi.io_shift;
+	if (info->scsi.io_base)
+		writeb(val, info->scsi.io_base + off);
+	else
+		outb(val, info->scsi.io_port + off);
+}
+
 static void fas216_dumpstate(FAS216_Info *info)
 {
 	unsigned char is, stat, inst;
 
-	is   = inb(REG_IS(info));
-	stat = inb(REG_STAT(info));
-	inst = inb(REG_INST(info));
+	is   = fas216_readb(info, REG_IS);
+	stat = fas216_readb(info, REG_STAT);
+	inst = fas216_readb(info, REG_INST);
 	
 	printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
 	       " INST=%02X IS=%02X CFIS=%02X",
-		inb(REG_CTCL(info)), inb(REG_CTCM(info)),
-		inb(REG_CMD(info)),  stat, inst, is,
-		inb(REG_CFIS(info)));
+		fas216_readb(info, REG_CTCL),
+		fas216_readb(info, REG_CTCM),
+		fas216_readb(info, REG_CMD),  stat, inst, is,
+		fas216_readb(info, REG_CFIS));
 	printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
-		inb(REG_CNTL1(info)), inb(REG_CNTL2(info)),
-		inb(REG_CNTL3(info)), inb(REG_CTCH(info)));
+		fas216_readb(info, REG_CNTL1),
+		fas216_readb(info, REG_CNTL2),
+		fas216_readb(info, REG_CNTL3),
+		fas216_readb(info, REG_CTCH));
 }
 
 static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix)
@@ -236,19 +249,63 @@
 		return 'H';
 }
 
+static void
+fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
+{
+	static char buf[1024];
+
+	vsnprintf(buf, sizeof(buf), fmt, ap);
+	printk("scsi%d.%c: %s", info->host->host_no, target, buf);
+}
+
+static void
+fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...)
+{
+	va_list args;
+
+	if (level != 0 && !(level & level_mask))
+		return;
+
+	va_start(args, fmt);
+	fas216_do_log(info, '0' + SCpnt->target, fmt, args);
+	va_end(args);
+
+	printk(" CDB: ");
+	print_command(SCpnt->cmnd);
+}
+
+static void
+fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
+{
+	va_list args;
+
+	if (level != 0 && !(level & level_mask))
+		return;
+
+	if (target < 0)
+		target = 'H';
+	else
+		target += '0';
+
+	va_start(args, fmt);
+	fas216_do_log(info, target, fmt, args);
+	va_end(args);
+
+	printk("\n");
+}
+
 static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
 {
 	va_list args;
-	static char buf[1024];
 
 	if (level != 0 && !(level & level_mask))
 		return;
 
 	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
+	fas216_do_log(info, fas216_target(info), fmt, args);
 	va_end(args);
 
-	printk("scsi%d.%c: %s\n", info->host->host_no, fas216_target(info), buf);
+	printk("\n");
 }
 
 #define PH_SIZE	32
@@ -276,7 +333,7 @@
 
 	cmd_ptr = (cmd_ptr + 1) & 7;
 
-	outb(command, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, command);
 }
 
 static void print_debug_list(void)
@@ -308,11 +365,11 @@
 
 static void fas216_done(FAS216_Info *info, unsigned int result);
 
-/** 
- * fast216_clockrate - calculate clock conversion factor
+/**
+ * fas216_clockrate - calculate clock conversion factor
  * @clock: clock speed in MHz
- * 
- * Calculate correct value to be written into clock conversion factor 
+ *
+ * Calculate correct value to be written into clock conversion factor
  * register. Returns CLKF_ value.
  */
 static int fas216_clockrate(int clock)
@@ -327,11 +384,11 @@
 	return clock;
 }
 
-/** 
+/**
  * fas216_get_last_msg - retrive last message from the list
  * @info: interface to search
  * @pos: current fifo position
- * 
+ *
  * Retrieve a last message from the list, using position in fifo.
  */
 static inline unsigned short
@@ -359,12 +416,12 @@
 	return packed_msg;
 }
 
-/** 
+/**
  * fas216_syncperiod - calculate STP register value
  * @info: state structure for interface connected to device
  * @ns: period in ns (between subsequent bytes)
- * 
- * Calculate value to be loaded into the STP register for a given period 
+ *
+ * Calculate value to be loaded into the STP register for a given period
  * in ns. Returns a value suitable for REG_STP.
  */
 static int fas216_syncperiod(FAS216_Info *info, int ns)
@@ -381,11 +438,11 @@
 	return value & 31;
 }
 
-/**  
+/**
  * fas216_set_sync - setup FAS216 chip for specified transfer period.
- * @info: state structure for interface connected to device 
+ * @info: state structure for interface connected to device
  * @target: target
- * 
+ *
  * Correctly setup FAS216 chip for specified transfer period.
  * Notes   : we need to switch the chip out of FASTSCSI mode if we have
  *           a transfer period >= 200ns - otherwise the chip will violate
@@ -393,12 +450,16 @@
  */
 static void fas216_set_sync(FAS216_Info *info, int target)
 {
-	outb(info->device[target].sof, REG_SOF(info));
-	outb(info->device[target].stp, REG_STP(info));
+	unsigned int cntl3;
+
+	fas216_writeb(info, REG_SOF, info->device[target].sof);
+	fas216_writeb(info, REG_STP, info->device[target].stp);
+
+	cntl3 = info->scsi.cfg[2];
 	if (info->device[target].period >= (200 / 4))
-		outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
-	else
-		outb(info->scsi.cfg[2], REG_CNTL3(info));
+		cntl3 = cntl3 & ~CNTL3_FASTSCSI;
+
+	fas216_writeb(info, REG_CNTL3, cntl3);
 }
 
 /* Synchronous transfer support
@@ -428,8 +489,8 @@
 /**
  * fas216_handlesync - Handle a synchronous transfer message
  * @info: state structure for interface
- * @ms: message from target
- * 
+ * @msg: message from target
+ *
  * Handle a synchronous transfer message from the target
  */
 static void fas216_handlesync(FAS216_Info *info, char *msg)
@@ -538,11 +599,11 @@
 	}
 }
 
-/** 
- * fas216_handlewide - Handle a wide transfer message 
+/**
+ * fas216_handlewide - Handle a wide transfer message
  * @info: state structure for interface
  * @msg: message from target
- * 
+ *
  * Handle a wide transfer message from the target
  */
 static void fas216_handlewide(FAS216_Info *info, char *msg)
@@ -637,11 +698,11 @@
 	}
 }
 
-/** 
+/**
  * fas216_updateptrs - update data pointers after transfer suspended/paused
  * @info: interface's local pointer to update
  * @bytes_transferred: number of bytes transferred
- * 
+ *
  * Update data pointers after transfer suspended/paused
  */
 static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
@@ -662,7 +723,7 @@
 		 * next buffer.
 		 */
 		bytes_transferred -= SCp->this_residual;
-		if (!next_SCp(&info->scsi.SCp) && bytes_transferred) {
+		if (!next_SCp(SCp) && bytes_transferred) {
 			printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
 				info->host->host_no, '0' + info->SCpnt->target);
 			return;
@@ -680,33 +741,67 @@
  * fas216_pio - transfer data off of/on to card using programmed IO
  * @info: interface to transfer data to/from
  * @direction: direction to transfer data (DMA_OUT/DMA_IN)
- * 
+ *
  * Transfer data off of/on to card using programmed IO.
  * Notes: this is incredibly slow.
  */
 static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
 {
+	Scsi_Pointer *SCp = &info->scsi.SCp;
+
 	fas216_checkmagic(info);
 
 	if (direction == DMA_OUT)
-		outb(get_next_SCp_byte(&info->scsi.SCp), REG_FF(info));
+		fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
 	else
-		put_next_SCp_byte(&info->scsi.SCp, inb(REG_FF(info)));
+		put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
+
+	if (SCp->this_residual == 0)
+		next_SCp(SCp);
+}
+
+static void fas216_set_stc(FAS216_Info *info, unsigned int length)
+{
+	fas216_writeb(info, REG_STCL, length);
+	fas216_writeb(info, REG_STCM, length >> 8);
+	fas216_writeb(info, REG_STCH, length >> 16);
+}
+
+static unsigned int fas216_get_ctc(FAS216_Info *info)
+{
+	return fas216_readb(info, REG_CTCL) +
+	       (fas216_readb(info, REG_CTCM) << 8) +
+	       (fas216_readb(info, REG_CTCH) << 16);
 }
 
+/**
+ * fas216_cleanuptransfer - clean up after a transfer has completed.
+ * @info: interface to clean up
+ *
+ * Update the data pointers according to the number of bytes transferred
+ * on the SCSI bus.
+ */
 static void fas216_cleanuptransfer(FAS216_Info *info)
 {
 	unsigned long total, residual, fifo;
+	fasdmatype_t dmatype = info->dma.transfer_type;
+
+	info->dma.transfer_type = fasdma_none;
 
-	if (info->dma.transfer_type == fasdma_real_all)
+	/*
+	 * PIO transfers do not need to be cleaned up.
+	 */
+	if (dmatype == fasdma_pio || dmatype == fasdma_none)
+		return;
+
+	if (dmatype == fasdma_real_all)
 		total = info->SCpnt->request_bufflen;
 	else
 		total = info->scsi.SCp.this_residual;
 
-	residual = inb(REG_CTCL(info)) + (inb(REG_CTCM(info)) << 8) +
-		   (inb(REG_CTCH(info)) << 16);
+	residual = fas216_get_ctc(info);
 
-	fifo = inb(REG_CFIS(info)) & CFIS_CF;
+	fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
 
 	fas216_log(info, LOG_BUFFER, "cleaning up from previous "
 		   "transfer: length 0x%06x, residual 0x%x, fifo %d",
@@ -718,54 +813,22 @@
 	 * host to the FIFO.  This means we must include the
 	 * bytes left in the FIFO from the transfer counter.
 	 */
-	if (info->scsi.phase == PHASE_DATAOUT) {
+	if (info->scsi.phase == PHASE_DATAOUT)
 		residual += fifo;
-		fifo = 0;
-	}
-
-	if (info->dma.transfer_type != fasdma_none &&
-	    info->dma.transfer_type != fasdma_pio) {
-		fas216_updateptrs(info, total - residual);
-	}
-
-	/*
-	 * If we were performing Data-In, then the FIFO counter
-	 * contains the number of bytes not transferred via DMA
-	 * from the on-board FIFO.  Read them manually.
-	 */
-	if (info->scsi.phase == PHASE_DATAIN) {
-		while (fifo && info->scsi.SCp.ptr) {
-			*info->scsi.SCp.ptr = inb(REG_FF(info));
-			fas216_updateptrs(info, 1);
-			fifo--;
-		}
-	}
 
-	info->dma.transfer_type = fasdma_none;
+	fas216_updateptrs(info, total - residual);
 }
 
-/** 
- * fas216_starttransfer - Start a DMA/PIO transfer off of/on to card
+/**
+ * fas216_transfer - Perform a DMA/PIO transfer off of/on to card
  * @info: interface from which device disconnected from
- * @direction: transfer direction (DMA_OUT/DMA_IN)
- * 
+ *
  * Start a DMA/PIO transfer off of/on to card
  */
-static void fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction)
+static void fas216_transfer(FAS216_Info *info)
 {
+	fasdmadir_t direction;
 	fasdmatype_t dmatype;
-	int phase = (direction == DMA_OUT) ? PHASE_DATAOUT : PHASE_DATAIN;
-
-	fas216_checkmagic(info);
-
-	if (phase != info->scsi.phase) {
-		info->scsi.phase = phase;
-
-		if (direction == DMA_OUT)
-			fas216_cmd(info, CMD_FLUSHFIFO);
-	} else {
-		fas216_cleanuptransfer(info);
-	}
 
 	fas216_log(info, LOG_BUFFER,
 		   "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
@@ -781,36 +844,41 @@
 	}
 
 	/*
-	 * Default to PIO mode or DMA mode if we have
-	 * a synchronous transfer agreement.
+	 * If we have a synchronous transfer agreement in effect, we must
+	 * use DMA mode.  If we are using asynchronous transfers, we may
+	 * use DMA mode or PIO mode.
 	 */
-	if (info->device[info->SCpnt->target].sof && info->dma.setup)
+	if (info->device[info->SCpnt->target].sof)
 		dmatype = fasdma_real_all;
 	else
 		dmatype = fasdma_pio;
 
+	if (info->scsi.phase == PHASE_DATAOUT)
+		direction = DMA_OUT;
+	else
+		direction = DMA_IN;
+
 	if (info->dma.setup)
 		dmatype = info->dma.setup(info->host, &info->scsi.SCp,
 					  direction, dmatype);
 	info->dma.transfer_type = dmatype;
 
+	if (dmatype == fasdma_real_all)
+		fas216_set_stc(info, info->SCpnt->request_bufflen);
+	else
+		fas216_set_stc(info, info->scsi.SCp.this_residual);
+
 	switch (dmatype) {
 	case fasdma_pio:
 		fas216_log(info, LOG_BUFFER, "PIO transfer");
-		outb(0, REG_SOF(info));
-		outb(info->scsi.async_stp, REG_STP(info));
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
+		fas216_writeb(info, REG_SOF, 0);
+		fas216_writeb(info, REG_STP, info->scsi.async_stp);
 		fas216_cmd(info, CMD_TRANSFERINFO);
 		fas216_pio(info, direction);
 		break;
 
 	case fasdma_pseudo:
 		fas216_log(info, LOG_BUFFER, "pseudo transfer");
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
 		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		info->dma.pseudo(info->host, &info->scsi.SCp,
 				 direction, info->SCpnt->transfersize);
@@ -818,17 +886,11 @@
 
 	case fasdma_real_block:
 		fas216_log(info, LOG_BUFFER, "block dma transfer");
-		outb(info->scsi.SCp.this_residual, REG_STCL(info));
-		outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info));
-		outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info));
 		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		break;
 
 	case fasdma_real_all:
 		fas216_log(info, LOG_BUFFER, "total dma transfer");
-		outb(info->SCpnt->request_bufflen, REG_STCL(info));
-		outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info));
-		outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info));
 		fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
 		break;
 
@@ -839,44 +901,61 @@
 	}
 }
 
-/** 
+/**
  * fas216_stoptransfer - Stop a DMA transfer onto / off of the card
  * @info: interface from which device disconnected from
- * 
- * Stop a DMA transfer onto / off of the card
+ *
+ * Called when we switch away from DATA IN or DATA OUT phases.
  */
 static void fas216_stoptransfer(FAS216_Info *info)
 {
 	fas216_checkmagic(info);
 
-	if ((info->dma.transfer_type == fasdma_real_all ||
-	     info->dma.transfer_type == fasdma_real_block) &&
-	    info->dma.stop)
+	if (info->dma.transfer_type == fasdma_real_all ||
+	    info->dma.transfer_type == fasdma_real_block)
 		info->dma.stop(info->host, &info->scsi.SCp);
 
 	fas216_cleanuptransfer(info);
 
-	if (info->scsi.phase == PHASE_DATAOUT)
+	if (info->scsi.phase == PHASE_DATAIN) {
+		unsigned int fifo;
+
+		/*
+		 * If we were performing Data-In, then the FIFO counter
+		 * contains the number of bytes not transferred via DMA
+		 * from the on-board FIFO.  Read them manually.
+		 */
+		fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
+		while (fifo && info->scsi.SCp.ptr) {
+			*info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
+			fas216_updateptrs(info, 1);
+			fifo--;
+		}
+	} else {
+		/*
+		 * After a Data-Out phase, there may be unsent
+		 * bytes left in the FIFO.  Flush them out.
+		 */
 		fas216_cmd(info, CMD_FLUSHFIFO);
+	}
 }
 
 static void fas216_aborttransfer(FAS216_Info *info)
 {
 	fas216_checkmagic(info);
 
-	if ((info->dma.transfer_type == fasdma_real_all ||
-	     info->dma.transfer_type == fasdma_real_block) &&
-	    info->dma.stop)
+	if (info->dma.transfer_type == fasdma_real_all ||
+	    info->dma.transfer_type == fasdma_real_block)
 		info->dma.stop(info->host, &info->scsi.SCp);
 
 	info->dma.transfer_type = fasdma_none;
 	fas216_cmd(info, CMD_FLUSHFIFO);
 }
 
-/** 
+/**
  * fas216_disconnected_intr - handle device disconnection
  * @info: interface from which device disconnected from
- * 
+ *
  * Handle device disconnection
  */
 static void fas216_disconnect_intr(FAS216_Info *info)
@@ -924,10 +1003,10 @@
 	}
 }
 
-/** 
+/**
  * fas216_reselected_intr - start reconnection of a device
  * @info: interface which was reselected
- * 
+ *
  * Start reconnection of a device
  */
 static void
@@ -952,19 +1031,14 @@
 
 	fas216_log(info, LOG_CONNECT, "reconnect phase=%02X", info->scsi.phase);
 
-	if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) {
+	if ((fas216_readb(info, REG_CFIS) & CFIS_CF) != 2) {
 		printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
 			info->host->host_no);
-		fas216_cmd(info, CMD_SETATN);
-		msgqueue_flush(&info->scsi.msgs);
-		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-		fas216_cmd(info, CMD_MSGACCEPTED);
-		return;
+		goto initiator_error;
 	}
 
-	target = inb(REG_FF(info));
-	identify_msg = inb(REG_FF(info));
+	target = fas216_readb(info, REG_FF);
+	identify_msg = fas216_readb(info, REG_FF);
 
 	ok = 1;
 	if (!(target & (1 << info->host->this_id))) {
@@ -983,26 +1057,11 @@
 		 * Something went wrong - send an initiator error to
 		 * the target.
 		 */
-		fas216_cmd(info, CMD_SETATN);
-		msgqueue_flush(&info->scsi.msgs);
-		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
-		info->scsi.phase = PHASE_MSGOUT_EXPECT;
-		fas216_cmd(info, CMD_MSGACCEPTED);
-		return;
+		goto initiator_error;
 	}
 
 	target &= ~(1 << info->host->this_id);
-	switch (target) {
-	case   1:  target = 0; break;
-	case   2:  target = 1; break;
-	case   4:  target = 2; break;
-	case   8:  target = 3; break;
-	case  16:  target = 4; break;
-	case  32:  target = 5; break;
-	case  64:  target = 6; break;
-	case 128:  target = 7; break;
-	default:   target = info->host->this_id; break;
-	}
+	target = ffs(target) - 1;
 
 	identify_msg &= 7;
 	info->scsi.reconnected.target = target;
@@ -1023,7 +1082,7 @@
 	msgqueue_flush(&info->scsi.msgs);
 	if (ok) {
 		info->scsi.phase = PHASE_RECONNECTED;
-		outb(target, REG_SDID(info));
+		fas216_writeb(info, REG_SDID, target);
 	} else {
 		/*
 		 * Our command structure not found - abort the
@@ -1037,9 +1096,17 @@
 	}
 
 	fas216_cmd(info, CMD_MSGACCEPTED);
+	return;
+
+ initiator_error:
+	fas216_cmd(info, CMD_SETATN);
+	msgqueue_flush(&info->scsi.msgs);
+	msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
+	info->scsi.phase = PHASE_MSGOUT_EXPECT;
+	fas216_cmd(info, CMD_MSGACCEPTED);
 }
 
-/** 
+/**
  * fas216_finish_reconnect - finish reconnection sequence for device
  * @info: interface which caused function done interrupt
  *
@@ -1232,7 +1299,7 @@
 	fas216_cmd(info, cmd);
 
 	for (tout = 1000; tout; tout -= 1) {
-		stat = inb(REG_STAT(info));
+		stat = fas216_readb(info, REG_STAT);
 		if (stat & (STAT_INT|STAT_PARITYERROR))
 			break;
 		udelay(1);
@@ -1251,7 +1318,7 @@
 	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
 		goto unexpected_phase_change;
 
-	inb(REG_INST(info));
+	fas216_readb(info, REG_INST);
 
 	stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
 
@@ -1264,9 +1331,9 @@
 	if ((stat & STAT_BUSMASK) != STAT_MESGIN)
 		goto unexpected_phase_change;
 
-	inb(REG_INST(info));
+	fas216_readb(info, REG_INST);
 
-	return inb(REG_FF(info));
+	return fas216_readb(info, REG_FF);
 
 timedout:
 	fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
@@ -1284,7 +1351,7 @@
 /**
  * fas216_message - handle a function done interrupt from FAS216 chip
  * @info: interface which caused function done interrupt
- * 
+ *
  * Handle a function done interrupt from FAS216 chip
  */
 static void fas216_message(FAS216_Info *info)
@@ -1295,7 +1362,7 @@
 
 	fas216_checkmagic(info);
 
-	message[0] = inb(REG_FF(info));
+	message[0] = fas216_readb(info, REG_FF);
 
 	if (message[0] == EXTENDED_MESSAGE) {
 		msgbyte = fas216_get_msg_byte(info);
@@ -1317,8 +1384,6 @@
 	if (msgbyte == -3)
 		goto parity_error;
 
-	info->scsi.msglen = msglen;
-
 #ifdef DEBUG_MESSAGES
 	{
 		int i;
@@ -1354,7 +1419,7 @@
 /**
  * fas216_send_command - send command after all message bytes have been sent
  * @info: interface which caused bus service
- * 
+ *
  * Send a command to a target after all message bytes have been sent
  */
 static void fas216_send_command(FAS216_Info *info)
@@ -1368,17 +1433,17 @@
 
 	/* load command */
 	for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
-		outb(info->SCpnt->cmnd[i], REG_FF(info));
+		fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);
 
 	fas216_cmd(info, CMD_TRANSFERINFO);
 
 	info->scsi.phase = PHASE_COMMAND;
 }
 
-/** 
+/**
  * fas216_send_messageout - handle bus service to send a message
  * @info: interface which caused bus service
- * 
+ *
  * Handle bus service to send a message.
  * Note: We do not allow the device to change the data direction!
  */
@@ -1398,25 +1463,25 @@
 			int i;
 
 			for (i = start; i < msg->length; i++)
-				outb(msg->msg[i], REG_FF(info));
+				fas216_writeb(info, REG_FF, msg->msg[i]);
 
-			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
 			start = 0;
 		}
 	} else
-		outb(NOP, REG_FF(info));
+		fas216_writeb(info, REG_FF, NOP);
 
 	fas216_cmd(info, CMD_TRANSFERINFO);
 
 	info->scsi.phase = PHASE_MSGOUT;
 }
 
-/** 
+/**
  * fas216_busservice_intr - handle bus service interrupt from FAS216 chip
  * @info: interface which caused bus service interrupt
  * @stat: Status register contents
  * @ssr: SCSI Status register contents
- * 
+ *
  * Handle a bus service interrupt from FAS216 chip
  */
 static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
@@ -1429,7 +1494,7 @@
 
 	switch (info->scsi.phase) {
 	case PHASE_SELECTION:
-		if ((ssr & IS_BITS) != 1)
+		if ((ssr & IS_BITS) != IS_MSGBYTESENT)
 			goto bad_is;
 		break;
 
@@ -1464,15 +1529,17 @@
 	case STATE(STAT_DATAIN, PHASE_RECONNECTED):
 		fas216_finish_reconnect(info);
 	case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In      */
-	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_MSGOUT):  /* Message Out  -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command      -> Data In      */
 	case STATE(STAT_DATAIN, PHASE_MSGIN):   /* Message In   -> Data In      */
-		fas216_starttransfer(info, DMA_IN);
+		info->scsi.phase = PHASE_DATAIN;
+		fas216_transfer(info);
 		return;
 
+	case STATE(STAT_DATAIN, PHASE_DATAIN):  /* Data In      -> Data In      */
 	case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out     -> Data Out     */
-		fas216_starttransfer(info, DMA_OUT);
+		fas216_cleanuptransfer(info);
+		fas216_transfer(info);
 		return;
 
 						/* Reselmsgin   -> Data Out     */
@@ -1482,7 +1549,9 @@
 	case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out  -> Data Out     */
 	case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command      -> Data Out     */
 	case STATE(STAT_DATAOUT, PHASE_MSGIN):  /* Message In   -> Data Out     */
-		fas216_starttransfer(info, DMA_OUT);
+		fas216_cmd(info, CMD_FLUSHFIFO);
+		info->scsi.phase = PHASE_DATAOUT;
+		fas216_transfer(info);
 		return;
 
 						/* Reselmsgin   -> Status       */
@@ -1507,7 +1576,7 @@
 	case STATE(STAT_MESGIN, PHASE_COMMAND):	/* Command	-> Message In	*/
 	case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In   */
 	case STATE(STAT_MESGIN, PHASE_MSGOUT):  /* Message Out  -> Message In   */
-		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
 		fas216_cmd(info, CMD_FLUSHFIFO);
 		fas216_cmd(info, CMD_TRANSFERINFO);
 		info->scsi.phase = PHASE_MSGIN;
@@ -1516,7 +1585,7 @@
 						/* Reselmsgin   -> Message In   */
 	case STATE(STAT_MESGIN, PHASE_RECONNECTED):
 	case STATE(STAT_MESGIN, PHASE_MSGIN):
-		info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF;
+		info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
 		fas216_cmd(info, CMD_TRANSFERINFO);
 		return;
 
@@ -1555,7 +1624,7 @@
 			 */
 			info->device[info->SCpnt->target].parity_check = 0;
 			info->device[info->SCpnt->target].parity_enabled = 1;
-			outb(info->scsi.cfg[0], REG_CNTL1(info));
+			fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
 		}
 
 		if (msgqueue_msglength(&info->scsi.msgs) > 1)
@@ -1584,9 +1653,7 @@
 			"target trying to receive more command bytes\n",
 			info->host->host_no, fas216_target(info));
 		fas216_cmd(info, CMD_SETATN);
-		outb(15, REG_STCL(info));
-		outb(0, REG_STCM(info));
-		outb(0, REG_STCH(info));
+		fas216_set_stc(info, 15);
 		fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
 		msgqueue_flush(&info->scsi.msgs);
 		msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
@@ -1615,6 +1682,7 @@
 
 bad_is:
 	fas216_log(info, 0, "bus service at step %d?", ssr & IS_BITS);
+	fas216_dumpstate(info);
 	print_debug_list();
 
 	fas216_done(info, DID_ERROR);
@@ -1625,12 +1693,12 @@
  * @info: interface which caused function done interrupt
  * @stat: Status register contents
  * @ssr: SCSI Status register contents
- * 
+ *
  * Handle a function done interrupt from FAS216 chip
  */
 static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
 {
-	unsigned int fifo_len = inb(REG_CFIS(info)) & CFIS_CF;
+	unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;
 	unsigned int status, message;
 
 	fas216_checkmagic(info);
@@ -1644,8 +1712,8 @@
 		if (fifo_len != 2) {
 			fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
 		}
-		status = inb(REG_FF(info));
-		message = inb(REG_FF(info));
+		status = fas216_readb(info, REG_FF);
+		message = fas216_readb(info, REG_FF);
 		info->scsi.SCp.Message = message;
 		info->scsi.SCp.Status = status;
 		info->scsi.phase = PHASE_DONE;
@@ -1679,26 +1747,21 @@
 	info->scsi.reconnected.lun = 0;
 	info->scsi.reconnected.tag = 0;
 
-	if (info->ifcfg.wide_max_size == 0)
-		wide_state = neg_invalid;
-	else
+	wide_state = neg_invalid;
+	sync_state = neg_invalid;
+
 #ifdef SCSI2_WIDE
+	if (info->ifcfg.wide_max_size != 0)
 		wide_state = neg_wait;
-#else
-		wide_state = neg_invalid;
 #endif
-
-	if (info->host->dma_channel == NO_DMA || !info->dma.setup)
-		sync_state = neg_invalid;
-	else
 #ifdef SCSI2_SYNC
+	if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
 		sync_state = neg_wait;
-#else
-		sync_state = neg_invalid;
 #endif
 
 	info->scsi.phase = PHASE_IDLE;
 	info->SCpnt = NULL; /* bug! */
+	memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));
 
 	for (i = 0; i < 8; i++) {
 		info->device[i].disconnect_ok	= info->ifcfg.disconnect_ok;
@@ -1714,22 +1777,21 @@
 	wake_up(&info->eh_wait);
 }
 
-/** 
+/**
  * fas216_intr - handle interrupts to progress a command
- * @instance: interface to service
- * 
+ * @info: interface to service
+ *
  * Handle interrupts from the interface to progress a command
  */
-void fas216_intr(struct Scsi_Host *instance)
+void fas216_intr(FAS216_Info *info)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
 	unsigned char isr, ssr, stat;
 
 	fas216_checkmagic(info);
 
-	stat = inb(REG_STAT(info));
-	ssr = inb(REG_IS(info));
-	isr = inb(REG_INST(info));
+	stat = fas216_readb(info, REG_STAT);
+	ssr = fas216_readb(info, REG_IS);
+	isr = fas216_readb(info, REG_INST);
 
 	add_debug_list(stat, ssr, isr, info->scsi.phase);
 
@@ -1762,17 +1824,15 @@
 	int tot_msglen;
 
 	/* following what the ESP driver says */
-	outb(0, REG_STCL(info));
-	outb(0, REG_STCM(info));
-	outb(0, REG_STCH(info));
+	fas216_set_stc(info, 0);
 	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
 
 	/* flush FIFO */
 	fas216_cmd(info, CMD_FLUSHFIFO);
 
 	/* load bus-id and timeout */
-	outb(BUSID(SCpnt->target), REG_SDID(info));
-	outb(info->ifcfg.select_timeout, REG_STIM(info));
+	fas216_writeb(info, REG_SDID, BUSID(SCpnt->target));
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
 
 	/* synchronous transfers */
 	fas216_set_sync(info, SCpnt->target);
@@ -1808,13 +1868,13 @@
 		/* load message bytes */
 		while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
 			for (i = 0; i < msg->length; i++)
-				outb(msg->msg[i], REG_FF(info));
-			msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF);
+				fas216_writeb(info, REG_FF, msg->msg[i]);
+			msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
 		}
 
 		/* load command */
 		for (i = 0; i < SCpnt->cmd_len; i++)
-			outb(SCpnt->cmnd[i], REG_FF(info));
+			fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);
 
 		if (tot_msglen == 1)
 			fas216_cmd(info, CMD_SELECTATN);
@@ -1828,7 +1888,7 @@
 		 */
 		struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
 
-		outb(msg->msg[0], REG_FF(info));
+		fas216_writeb(info, REG_FF, msg->msg[0]);
 		msg->fifo = 1;
 
 		fas216_cmd(info, CMD_SELECTATNSTOP);
@@ -1855,11 +1915,6 @@
 {
 	int disconnect_ok;
 
-	if (parity_test(info, SCpnt->target))
-		outb(info->scsi.cfg[0] | CNTL1_PTE, REG_CNTL1(info));
-	else
-		outb(info->scsi.cfg[0], REG_CNTL1(info));
-
 	/*
 	 * claim host busy
 	 */
@@ -1868,6 +1923,11 @@
 	info->SCpnt = SCpnt;
 	info->dma.transfer_type = fasdma_none;
 
+	if (parity_test(info, SCpnt->target))
+		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
+	else
+		fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+
 	/*
 	 * Don't allow request sense commands to disconnect.
 	 */
@@ -1966,24 +2026,22 @@
 	msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
 
 	/* following what the ESP driver says */
-	outb(0, REG_STCL(info));
-	outb(0, REG_STCM(info));
-	outb(0, REG_STCH(info));
+	fas216_set_stc(info, 0);
 	fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
 
 	/* flush FIFO */
 	fas216_cmd(info, CMD_FLUSHFIFO);
 
 	/* load bus-id and timeout */
-	outb(BUSID(SCpnt->target), REG_SDID(info));
-	outb(info->ifcfg.select_timeout, REG_STIM(info));
+	fas216_writeb(info, REG_SDID, BUSID(SCpnt->target));
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
 
 	/* synchronous transfers */
 	fas216_set_sync(info, SCpnt->target);
 
 	msg = msgqueue_getmsg(&info->scsi.msgs, 0);
 
-	outb(BUS_DEVICE_RESET, REG_FF(info));
+	fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
 	msg->fifo = 1;
 
 	fas216_cmd(info, CMD_SELECTATNSTOP);
@@ -1992,8 +2050,8 @@
 /**
  * fas216_kick - kick a command to the interface
  * @info: our host interface to kick
- * 
- * kick a command to the interface, interface should be idle.
+ *
+ * Kick a command to the interface, interface should be idle.
  * Notes: Interrupts are always disabled!
  */
 static void fas216_kick(FAS216_Info *info)
@@ -2050,11 +2108,8 @@
 		info->SCpnt = NULL;
 	}
 
-#if defined(DEBUG_CONNECT) || defined(DEBUG_MESSAGES)
-	printk("scsi%d.%c: starting ",
-		info->host->host_no, '0' + SCpnt->target);
-	print_command(SCpnt->cmnd);
-#endif
+	fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
+			   "starting");
 
 	switch (where_from) {
 	case TYPE_QUEUE:
@@ -2094,13 +2149,13 @@
  * @info: interface that completed
  * @SCpnt: command that completed
  * @result: driver byte of result
- * 
+ *
  * Finish processing automatic request sense command
  */
 static void
 fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
 {
-	fas216_log(info, LOG_CONNECT,
+	fas216_log_target(info, LOG_CONNECT, SCpnt->target,
 		   "request sense complete, result=0x%04x%02x%02x",
 		   result, SCpnt->SCp.Message, SCpnt->SCp.Status);
 
@@ -2127,7 +2182,7 @@
  * @info: interface that completed
  * @SCpnt: command that completed
  * @result: driver byte of result
- * 
+ *
  * Finish processing of standard command
  */
 static void
@@ -2138,17 +2193,14 @@
 	SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 |
 			info->scsi.SCp.Status;
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.%c: command complete, result=%08X, command=",
-		info->host->host_no, '0' + SCpnt->target, SCpnt->result);
-	print_command(SCpnt->cmnd);
-#endif
+	fas216_log_command(info, LOG_CONNECT, SCpnt,
+		"command complete, result=0x%08x", SCpnt->result);
 
 	/*
-	 * If the driver detected an error, or the command
-	 * was request sense, then we're all done.
+	 * If the driver detected an error, we're all done.
 	 */
-	if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE)
+	if (host_byte(SCpnt->result) != DID_OK ||
+	    msg_byte(SCpnt->result) != COMMAND_COMPLETE)
 		goto done;
 
 	/*
@@ -2163,7 +2215,7 @@
 	 * If the command did not complete with GOOD status,
 	 * we are all done here.
 	 */
-	if (info->scsi.SCp.Status != GOOD)
+	if (status_byte(SCpnt->result) != GOOD)
 		goto done;
 
 	/*
@@ -2177,17 +2229,19 @@
 		switch (SCpnt->cmnd[0]) {
 		case INQUIRY:
 		case START_STOP:
-//		case READ_CAPACITY:
 		case MODE_SENSE:
 			break;
 
 		default:
 			printk(KERN_ERR "scsi%d.%c: incomplete data transfer "
-				"detected: res=%08X ptr=%p len=%X command=",
+				"detected: res=%08X ptr=%p len=%X CDB: ",
 				info->host->host_no, '0' + SCpnt->target,
 				SCpnt->result, info->scsi.SCp.ptr,
 				info->scsi.SCp.this_residual);
 			print_command(SCpnt->cmnd);
+			SCpnt->result &= ~(255 << 16);
+			SCpnt->result |= DID_BAD_TARGET << 16;
+			goto request_sense;
 		}
 	}
 
@@ -2202,6 +2256,11 @@
 
 
 request_sense:
+	if (SCpnt->cmnd[0] == REQUEST_SENSE)
+		goto done;
+
+	fas216_log_target(info, LOG_CONNECT, SCpnt->target,
+			  "requesting sense");
 	memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd));
 	SCpnt->cmnd[0] = REQUEST_SENSE;
 	SCpnt->cmnd[1] = SCpnt->lun << 5;
@@ -2213,6 +2272,7 @@
 	SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
 	SCpnt->SCp.Message = 0;
 	SCpnt->SCp.Status = 0;
+	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
 	SCpnt->sc_data_direction = SCSI_DATA_READ;
 	SCpnt->use_sg = 0;
 	SCpnt->tag = 0;
@@ -2233,7 +2293,7 @@
  * fas216_done - complete processing for current command
  * @info: interface that completed
  * @result: driver byte of result
- * 
+ *
  * Complete processing for current command
  */
 static void fas216_done(FAS216_Info *info, unsigned int result)
@@ -2263,7 +2323,7 @@
 	 */
 	if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
 		printk("scsi%d.%c: zero bytes left to transfer, but "
-		       "buffer pointer still valid: ptr=%p len=%08x command=",
+		       "buffer pointer still valid: ptr=%p len=%08x CDB: ",
 		       info->host->host_no, '0' + SCpnt->target,
 		       info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
 		info->scsi.SCp.ptr = NULL;
@@ -2298,9 +2358,9 @@
  * fas216_queue_command - queue a command for adapter to process.
  * @SCpnt: Command to queue
  * @done: done function to call once command is complete
- * 
+ *
  * Queue a command for adapter to process.
- * Returns: 0 in success, else error. 
+ * Returns: 0 on success, else error.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
 int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
@@ -2310,11 +2370,8 @@
 
 	fas216_checkmagic(info);
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.H: received command for id %d (%p) ",
-		SCpnt->host->host_no, SCpnt->target, SCpnt);
-	print_command(SCpnt->cmnd);
-#endif
+	fas216_log_command(info, LOG_CONNECT, SCpnt,
+			   "received command (%p)", SCpnt);
 
 	SCpnt->scsi_done = done;
 	SCpnt->host_scribble = (void *)fas216_std_done;
@@ -2341,10 +2398,8 @@
 		fas216_kick(info);
 	spin_unlock(&info->host_lock);
 
-#ifdef DEBUG_CONNECT
-	printk("scsi%d.H: queue %s\n", info->host->host_no,
+	fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
 		result ? "failure" : "success");
-#endif
 
 	return result;
 }
@@ -2352,7 +2407,7 @@
 /**
  * fas216_internal_done - trigger restart of a waiting thread in fas216_command
  * @SCpnt: Command to wake
- * 
+ *
  * Trigger restart of a waiting thread in fas216_command
  */
 static void fas216_internal_done(Scsi_Cmnd *SCpnt)
@@ -2366,9 +2421,9 @@
 
 /**
  * fas216_command - queue a command for adapter to process.
- * @SCpnt:  Command to queue
- * 
- * Qqueue a command for adapter to process.
+ * @SCpnt: Command to queue
+ *
+ * Queue a command for adapter to process.
  * Returns: scsi result code.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
@@ -2405,9 +2460,9 @@
 		 * and go to sleep if we know that the device is going
 		 * to be some time (eg, disconnected).
 		 */
-		if (inb(REG_STAT(info)) & STAT_INT) {
+		if (fas216_readb(info, REG_STAT) & STAT_INT) {
 			spin_lock_irq(info->host->host_lock);
-			fas216_intr(info->host);
+			fas216_intr(info);
 			spin_unlock_irq(info->host->host_lock);
 		}
 	}
@@ -2446,7 +2501,7 @@
 /**
  * fas216_do_abort - decide how to abort a command
  * @SCpnt: command to abort
- * 
+ *
  * Decide how to abort a command.
  * Returns: abort status
  */
@@ -2512,7 +2567,7 @@
 /**
  * fas216_eh_abort - abort this command
  * @SCpnt: command to abort
- * 
+ *
  * Abort this command.
  * Returns: FAILED if unable to abort
  * Notes: io_request_lock is taken, and irqs are disabled
@@ -2567,12 +2622,12 @@
 
 /**
  * fas216_eh_device_reset - Reset the device associated with this command
- * @SCpnt:  command specifing device to reset
- * 
+ * @SCpnt: command specifing device to reset
+ *
  * Reset the device associated with this command.
  * Returns: FAILED if unable to reset.
  * Notes: We won't be re-entered, so we'll only have one device
- *        reset on the go at one time.
+ * reset on the go at one time.
  */
 int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
 {
@@ -2650,7 +2705,7 @@
 /**
  * fas216_eh_bus_reset - Reset the bus associated with the command
  * @SCpnt: command specifing bus to reset
- * 
+ *
  * Reset the bus associated with the command.
  * Returns: FAILED if unable to reset.
  * Notes: Further commands are blocked.
@@ -2672,13 +2727,13 @@
 	 * Stop all activity on this interface.
 	 */
 	fas216_aborttransfer(info);
-	outb(info->scsi.cfg[2], REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
 
 	/*
 	 * Clear any pending interrupts.
 	 */
-	while (inb(REG_STAT(info)) & STAT_INT)
-		inb(REG_INST(info));
+	while (fas216_readb(info, REG_STAT) & STAT_INT)
+		fas216_readb(info, REG_INST);
 
 	info->rst_bus_status = 0;
 
@@ -2728,26 +2783,26 @@
 
 /**
  * fas216_init_chip - Initialise FAS216 state after reset
- * @info:  state structure for interface
- * 
+ * @info: state structure for interface
+ *
  * Initialise FAS216 state after reset
  */
 static void fas216_init_chip(FAS216_Info *info)
 {
-	outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info));
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
-	outb(info->scsi.cfg[1], REG_CNTL2(info));
-	outb(info->scsi.cfg[2], REG_CNTL3(info));
-	outb(info->ifcfg.select_timeout, REG_STIM(info));
-	outb(0, REG_SOF(info));
-	outb(info->scsi.async_stp, REG_STP(info));
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
+	fas216_writeb(info, REG_CLKF, fas216_clockrate(info->ifcfg.clockrate));
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+	fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
+	fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
+	fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
+	fas216_writeb(info, REG_SOF, 0);
+	fas216_writeb(info, REG_STP, info->scsi.async_stp);
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
 }
 
 /**
  * fas216_eh_host_reset - Reset the host associated with this command
  * @SCpnt: command specifing host to reset
- * 
+ *
  * Reset the host associated with this command.
  * Returns: FAILED if unable to reset.
  * Notes: io_request_lock is taken, and irqs are disabled
@@ -2811,56 +2866,56 @@
 	/*
 	 * Reset the chip.
 	 */
-	outb(CMD_RESETCHIP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
 	udelay(50);
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_NOP);
 
 	/*
 	 * Check to see if control reg 2 is present.
 	 */
-	outb(0, REG_CNTL3(info));
-	outb(CNTL2_S2FE, REG_CNTL2(info));
+	fas216_writeb(info, REG_CNTL3, 0);
+	fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
 
 	/*
 	 * If we are unable to read back control reg 2
 	 * correctly, it is not present, and we have a
 	 * NCR53C90.
 	 */
-	if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE)
+	if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
 		return TYPE_NCR53C90;
 
 	/*
 	 * Now, check control register 3
 	 */
-	outb(0, REG_CNTL2(info));
-	outb(0, REG_CNTL3(info));
-	outb(5, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL2, 0);
+	fas216_writeb(info, REG_CNTL3, 0);
+	fas216_writeb(info, REG_CNTL3, 5);
 
 	/*
 	 * If we are unable to read the register back
 	 * correctly, we have a NCR53C90A
 	 */
-	if (inb(REG_CNTL3(info)) != 5)
+	if (fas216_readb(info, REG_CNTL3) != 5)
 		return TYPE_NCR53C90A;
 
 	/*
 	 * Now read the ID from the chip.
 	 */
-	outb(0, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL3, 0);
 
-	outb(CNTL3_ADIDCHK, REG_CNTL3(info));
-	outb(0, REG_CNTL3(info));
+	fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
+	fas216_writeb(info, REG_CNTL3, 0);
 
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	udelay(5);
-	outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	udelay(50);
+	fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
 
-	outb(CNTL2_ENF, REG_CNTL2(info));
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	udelay(5);
-	outb(CMD_NOP, REG_CMD(info));
+	fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	udelay(50);
+	fas216_writeb(info, REG_CMD, CMD_NOP);
 
-	rev     = inb(REG1_ID(info));
+	rev     = fas216_readb(info, REG_ID);
 	family  = rev >> 3;
 	rev    &= 7;
 
@@ -2886,10 +2941,10 @@
 	return TYPE_NCR53C9x;
 }
 
-/** 
+/**
  * fas216_reset_state - Initialise driver internal state
  * @info: state to initialise
- * 
+ *
  * Initialise driver internal state
  */
 static void fas216_reset_state(FAS216_Info *info)
@@ -2927,23 +2982,23 @@
 }
 
 /**
- * fas216_init - initialise FAS/NCR/AMD SCSI ic.
- * @instance: a driver-specific filled-out structure
- * 
- * Initialise FAS/NCR/AMD SCSI ic.
+ * fas216_init - initialise FAS/NCR/AMD SCSI structures.
+ * @host: a driver-specific filled-out structure
+ *
+ * Initialise FAS/NCR/AMD SCSI structures.
  * Returns: 0 on success
  */
-int fas216_init(struct Scsi_Host *instance)
+int fas216_init(struct Scsi_Host *host)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
-	int type;
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
 
 	info->magic_start    = MAGIC;
 	info->magic_end      = MAGIC;
-	info->host           = instance;
-	info->scsi.cfg[0]    = instance->this_id | CNTL1_PERE;
+	info->host           = host;
+	info->scsi.cfg[0]    = host->this_id | CNTL1_PERE;
 	info->scsi.cfg[1]    = CNTL2_ENF | CNTL2_S2FE;
-	info->scsi.cfg[2]    = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB;
+	info->scsi.cfg[2]    = info->ifcfg.cntl3 |
+			       CNTL3_ADIDCHK | CNTL3_G2CB | CNTL3_LBTM;
 	info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
 
 	info->rst_dev_status = -1;
@@ -2960,13 +3015,29 @@
 	msgqueue_initialise(&info->scsi.msgs);
 
 	if (!queue_initialise(&info->queues.issue))
-		return 1;
+		return -ENOMEM;
 
 	if (!queue_initialise(&info->queues.disconnected)) {
 		queue_free(&info->queues.issue);
-		return 1;
+		return -ENOMEM;
 	}
 
+	return 0;
+}
+
+/**
+ * fas216_add - initialise FAS/NCR/AMD SCSI ic.
+ * @host: a driver-specific filled-out structure
+ * @dev: parent device
+ *
+ * Initialise FAS/NCR/AMD SCSI ic.
+ * Returns: 0 on success
+ */
+int fas216_add(struct Scsi_Host *host, struct device *dev)
+{
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
+	int type, ret;
+
 	fas216_reset_state(info);
 	type = fas216_detect_type(info);
 	info->scsi.type = chip_types[type];
@@ -2983,8 +3054,8 @@
 	 * the resulting reset interrupt, so mask it
 	 * out.
 	 */
-	outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info));
-	outb(CMD_RESETSCSI, REG_CMD(info));
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
+	fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
 
 	/*
 	 * scsi standard says wait 250ms
@@ -2993,60 +3064,40 @@
 	scsi_sleep(100*HZ/100);
 	spin_lock_irq(info->host->host_lock);
 
-	outb(info->scsi.cfg[0], REG_CNTL1(info));
-	inb(REG_INST(info));
+	fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
+	fas216_readb(info, REG_INST);
 
 	fas216_checkmagic(info);
 
-	return 0;
+	ret = scsi_add_host(host, dev);
+	if (ret)
+		fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+
+	return ret;
 }
 
-/**
- * fas216_release - release all resources for FAS/NCR/AMD SCSI ic.
- * @instance: a driver-specific filled-out structure
- * 
- * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic,
- * Returns: 0 on success.
- */
-int fas216_release(struct Scsi_Host *instance)
+void fas216_remove(struct Scsi_Host *host)
 {
-	FAS216_Info *info = (FAS216_Info *)instance->hostdata;
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
 
 	fas216_checkmagic(info);
+	scsi_remove_host(host);
 
-	outb(CMD_RESETCHIP, REG_CMD(info));
-	queue_free(&info->queues.disconnected);
-	queue_free(&info->queues.issue);
-
-	return 0;
+	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
 }
 
 /**
- * fas216_info - generate a string containing information about host.
- * @info: FAS216 host information
- * @buffer: string buffer to build string
- * 
- * Generate a string containing information about this host.
- * Returns: size of built string
+ * fas216_release - release all resources for FAS/NCR/AMD SCSI ic.
+ * @host: a driver-specific filled-out structure
+ *
+ * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic.
  */
-int fas216_info(FAS216_Info *info, char *buffer)
+void fas216_release(struct Scsi_Host *host)
 {
-	char *p = buffer;
-
-	p += sprintf(p, "(%s) at port 0x%08lX ",
-		     info->scsi.type, info->host->io_port);
+	FAS216_Info *info = (FAS216_Info *)host->hostdata;
 
-	if (info->host->irq != NO_IRQ)
-		p += sprintf(p, "irq %d ", info->host->irq);
-	else
-		p += sprintf(p, "no irq ");
-
-	if (info->host->dma_channel != NO_DMA)
-		p += sprintf(p, "dma %d ", info->host->dma_channel);
-	else
-		p += sprintf(p, "no dma ");
-
-	return p - buffer;
+	queue_free(&info->queues.disconnected);
+	queue_free(&info->queues.issue);
 }
 
 int fas216_print_host(FAS216_Info *info, char *buffer)
@@ -3054,7 +3105,7 @@
 	return sprintf(buffer,
 			"\n"
 			"Chip    : %s\n"
-			" Address: 0x%08lX\n"
+			" Address: 0x%08lx\n"
 			" IRQ    : %d\n"
 			" DMA    : %d\n",
 			info->scsi.type, info->host->io_port,
@@ -3116,11 +3167,12 @@
 	return p - buffer;
 }
 
-EXPORT_SYMBOL(fas216_info);
 EXPORT_SYMBOL(fas216_init);
+EXPORT_SYMBOL(fas216_add);
 EXPORT_SYMBOL(fas216_queue_command);
 EXPORT_SYMBOL(fas216_command);
 EXPORT_SYMBOL(fas216_intr);
+EXPORT_SYMBOL(fas216_remove);
 EXPORT_SYMBOL(fas216_release);
 EXPORT_SYMBOL(fas216_eh_abort);
 EXPORT_SYMBOL(fas216_eh_device_reset);
diff -Nru a/drivers/acorn/scsi/fas216.h b/drivers/acorn/scsi/fas216.h
--- a/drivers/acorn/scsi/fas216.h	Mon Feb 10 10:39:33 2003
+++ b/drivers/acorn/scsi/fas216.h	Mon Feb 10 10:39:33 2003
@@ -22,18 +22,18 @@
 /* FAS register definitions */
 
 /* transfer count low */
-#define REG_CTCL(x)		((x)->scsi.io_port)
-#define REG_STCL(x)		((x)->scsi.io_port)
+#define REG_CTCL		(0)
+#define REG_STCL		(0)
 
 /* transfer count medium */
-#define REG_CTCM(x)		((x)->scsi.io_port + (1 << (x)->scsi.io_shift))
-#define REG_STCM(x)		((x)->scsi.io_port + (1 << (x)->scsi.io_shift))
+#define REG_CTCM		(1)
+#define REG_STCM		(1)
 
 /* fifo data */
-#define REG_FF(x)		((x)->scsi.io_port + (2 << (x)->scsi.io_shift))
+#define REG_FF			(2)
 
 /* command */
-#define REG_CMD(x)		((x)->scsi.io_port + (3 << (x)->scsi.io_shift))
+#define REG_CMD			(3)
 #define CMD_NOP			0x00
 #define CMD_FLUSHFIFO		0x01
 #define CMD_RESETCHIP		0x02
@@ -57,7 +57,7 @@
 #define CMD_WITHDMA		0x80
 
 /* status register (read) */
-#define REG_STAT(x)		((x)->scsi.io_port + (4 << (x)->scsi.io_shift))
+#define REG_STAT		(4)
 #define STAT_IO			(1 << 0)			/* IO phase		*/
 #define STAT_CD			(1 << 1)			/* CD phase		*/
 #define STAT_MSG		(1 << 2)			/* MSG phase		*/
@@ -76,11 +76,11 @@
 #define STAT_MESGIN		(STAT_MSG|STAT_CD|STAT_IO)	/* Message In		*/
 
 /* bus ID for select / reselect */
-#define REG_SDID(x)		((x)->scsi.io_port + (4 << (x)->scsi.io_shift))
+#define REG_SDID		(4)
 #define BUSID(target)		((target) & 7)
 
 /* Interrupt status register (read) */
-#define REG_INST(x)		((x)->scsi.io_port + (5 << (x)->scsi.io_shift))
+#define REG_INST		(5)
 #define INST_SELWOATN		(1 << 0)			/* Select w/o ATN	*/
 #define INST_SELATN		(1 << 1)			/* Select w/ATN		*/
 #define INST_RESELECTED		(1 << 2)			/* Reselected		*/
@@ -91,10 +91,10 @@
 #define INST_BUSRESET		(1 << 7)			/* SCSI Bus reset	*/
 
 /* Timeout register (write) */
-#define REG_STIM(x)		((x)->scsi.io_port + (5 << (x)->scsi.io_shift))
+#define REG_STIM		(5)
 
 /* Sequence step register (read) */
-#define REG_IS(x)		((x)->scsi.io_port + (6 << (x)->scsi.io_shift))
+#define REG_IS			(6)
 #define IS_BITS			0x07
 #define IS_SELARB		0x00				/* Select & Arb ok	*/
 #define IS_MSGBYTESENT		0x01				/* One byte message sent*/
@@ -104,18 +104,18 @@
 #define IS_SOF			0x08				/* Sync off flag	*/
 
 /* Transfer period step (write) */
-#define REG_STP(x)		((x)->scsi.io_port + (6 << (x)->scsi.io_shift))
+#define REG_STP			(6)
 
 /* Synchronous Offset (write) */
-#define REG_SOF(x)		((x)->scsi.io_port + (7 << (x)->scsi.io_shift))
+#define REG_SOF			(7)
 
 /* Fifo state register (read) */
-#define REG_CFIS(x)		((x)->scsi.io_port + (7 << (x)->scsi.io_shift))
+#define REG_CFIS		(7)
 #define CFIS_CF			0x1f				/* Num bytes in FIFO	*/
 #define CFIS_IS			0xe0				/* Step			*/
 
 /* config register 1 */
-#define REG_CNTL1(x)		((x)->scsi.io_port + (8 << (x)->scsi.io_shift))
+#define REG_CNTL1		(8)
 #define CNTL1_CID		(7 << 0)			/* Chip ID			*/
 #define CNTL1_STE		(1 << 3)			/* Self test enable		*/
 #define CNTL1_PERE		(1 << 4)			/* Parity enable reporting en.	*/
@@ -124,7 +124,7 @@
 #define CNTL1_ETM		(1 << 7)			/* Extended Timing Mode		*/
 
 /* Clock conversion factor (read) */
-#define REG_CLKF(x)		((x)->scsi.io_port + (9 << (x)->scsi.io_shift))
+#define REG_CLKF		(9)
 #define CLKF_F37MHZ		0x00				/* 35.01 - 40 MHz		*/
 #define CLKF_F10MHZ		0x02				/* 10 MHz			*/
 #define CLKF_F12MHZ		0x03				/* 10.01 - 15 MHz		*/
@@ -134,13 +134,13 @@
 #define CLKF_F32MHZ		0x07				/* 30.01 - 35 MHz		*/
 
 /* Chip test register (write) */
-#define REG0_FTM(x)		((x)->scsi.io_port + (10 << (x)->scsi.io_shift))
+#define REG_FTM			(10)
 #define TEST_FTM		0x01				/* Force target mode		*/
 #define TEST_FIM		0x02				/* Force initiator mode		*/
 #define TEST_FHI		0x04				/* Force high impedance mode	*/
 
 /* Configuration register 2 (read/write) */
-#define REG_CNTL2(x)		((x)->scsi.io_port + (11 << (x)->scsi.io_shift))
+#define REG_CNTL2		(11)
 #define CNTL2_PGDP		(1 << 0)			/* Pass Th/Generate Data Parity	*/
 #define CNTL2_PGRP		(1 << 1)			/* Pass Th/Generate Reg Parity	*/
 #define CNTL2_ACDPE		(1 << 2)			/* Abort on Cmd/Data Parity Err	*/
@@ -151,7 +151,7 @@
 #define CNTL2_DAE		(1 << 7)			/* Data Alignment Enable	*/
 
 /* Configuration register 3 (read/write) */
-#define REG_CNTL3(x)		((x)->scsi.io_port + (12 << (x)->scsi.io_shift))
+#define REG_CNTL3		(12)
 #define CNTL3_BS8		(1 << 0)			/* Burst size 8			*/
 #define CNTL3_MDM		(1 << 1)			/* Modify DMA mode		*/
 #define CNTL3_LBTM		(1 << 2)			/* Last Byte Transfer mode	*/
@@ -162,14 +162,14 @@
 #define CNTL3_ADIDCHK		(1 << 7)			/* Additional ID check		*/
 
 /* High transfer count (read/write) */
-#define REG_CTCH(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
-#define REG_STCH(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
+#define REG_CTCH		(14)
+#define REG_STCH		(14)
 
-/* ID reigster (read only) */
-#define REG1_ID(x)		((x)->scsi.io_port + (14 << (x)->scsi.io_shift))
+/* ID register (read only) */
+#define REG_ID			(14)
 
 /* Data alignment */
-#define REG0_DAL(x)		((x)->scsi.io_port + (15 << (x)->scsi.io_shift))
+#define REG_DAL			(15)
 
 typedef enum {
 	PHASE_IDLE,					/* we're not planning on doing anything	*/
@@ -212,6 +212,9 @@
 #define MAGIC	0x441296bdUL
 #define NR_MSGS	8
 
+#define FASCAP_DMA		(1 << 0)
+#define FASCAP_PSEUDODMA	(1 << 1)
+
 typedef struct {
 	unsigned long		magic_start;
 	spinlock_t		host_lock;
@@ -233,12 +236,13 @@
 
 	/* driver information */
 	struct {
+		phase_t		phase;			/* current phase			*/
+		void		*io_base;		/* iomem base of FAS216			*/
 		unsigned int	io_port;		/* base address of FAS216		*/
 		unsigned int	io_shift;		/* shift to adjust reg offsets by	*/
-		unsigned int	irq;			/* interrupt				*/
 		unsigned char	cfg[4];			/* configuration registers		*/
 		const char	*type;			/* chip type				*/
-		phase_t		phase;			/* current phase			*/
+		unsigned int	irq;			/* interrupt				*/
 
 		struct {
 			unsigned char	target;		/* reconnected target			*/
@@ -253,7 +257,6 @@
 		unsigned int	async_stp;		/* Async transfer STP value		*/
 		unsigned char	msgin_fifo;		/* bytes in fifo at time of message in	*/
 		unsigned char	message[256];		/* last message received from device	*/
-		unsigned int	msglen;			/* length of last message received	*/
 
 		unsigned char	disconnectable:1;	/* this command can be disconnected	*/
 		unsigned char	aborting:1;		/* aborting command			*/
@@ -281,6 +284,7 @@
 		unsigned char	wide_max_size;		/* Maximum wide transfer size		*/
 		unsigned char	cntl3;			/* Control Reg 3			*/
 		unsigned int	asyncperiod;		/* Async transfer period (ns)		*/
+		unsigned int	capabilities;		/* driver capabilities			*/
 		unsigned int	disconnect_ok:1;	/* Disconnects allowed?			*/
 	} ifcfg;
 
@@ -319,26 +323,18 @@
 } FAS216_Info;
 
 /* Function: int fas216_init (struct Scsi_Host *instance)
- * Purpose : initialise FAS/NCR/AMD SCSI ic.
+ * Purpose : initialise FAS/NCR/AMD SCSI structures.
  * Params  : instance - a driver-specific filled-out structure
  * Returns : 0 on success
  */
 extern int fas216_init (struct Scsi_Host *instance);
 
-/* Function: int fas216_abort (Scsi_Cmnd *SCpnt)
- * Purpose : abort a command if something horrible happens.
- * Params  : SCpnt - Command that is believed to be causing a problem.
- * Returns : one of SCSI_ABORT_ macros.
- */
-extern int fas216_abort (Scsi_Cmnd *);
-
-/* Function: int fas216_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
- * Purpose : resets the adapter if something horrible happens.
- * Params  : SCpnt - Command that is believed to be causing a problem.
- *	     reset_flags - flags indicating reset type that is believed to be required.
- * Returns : one of SCSI_RESET_ macros, or'd with the SCSI_RESET_*_RESET macros.
+/* Function: int fas216_add (struct Scsi_Host *instance, struct device *dev)
+ * Purpose : initialise FAS/NCR/AMD SCSI ic.
+ * Params  : instance - a driver-specific filled-out structure
+ * Returns : 0 on success
  */
-extern int fas216_reset (Scsi_Cmnd *, unsigned int);
+extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
 
 /* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  * Purpose : queue a command for adapter to process.
@@ -355,20 +351,21 @@
  */
 extern int fas216_command (Scsi_Cmnd *);
 
-/* Function: void fas216_intr (struct Scsi_Host *instance)
+/* Function: void fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
- * Params  : instance - interface to service
+ * Params  : info - interface to service
  */
-extern void fas216_intr (struct Scsi_Host *instance);
+extern void fas216_intr (FAS216_Info *info);
+
+extern void fas216_remove (struct Scsi_Host *instance);
 
-/* Function: int fas216_release (struct Scsi_Host *instance)
+/* Function: void fas216_release (struct Scsi_Host *instance)
  * Purpose : release all resources and put everything to bed for FAS/NCR/AMD SCSI ic.
  * Params  : instance - a driver-specific filled-out structure
  * Returns : 0 on success
  */
-extern int fas216_release (struct Scsi_Host *instance);
+extern void fas216_release (struct Scsi_Host *instance);
 
-extern int fas216_info(FAS216_Info *info, char *buffer);
 extern int fas216_print_host(FAS216_Info *info, char *buffer);
 extern int fas216_print_stats(FAS216_Info *info, char *buffer);
 extern int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer);
diff -Nru a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c
--- a/drivers/acorn/scsi/oak.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/acorn/scsi/oak.c	Mon Feb 10 10:39:22 2003
@@ -192,7 +192,8 @@
 	.remove		= __devexit_p(oakscsi_remove),
 	.id_table	= oakscsi_cids,
 	.drv = {
-		.name	= "oakscsi",
+		.devclass	= &shost_devclass,
+		.name		= "oakscsi",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c
--- a/drivers/acorn/scsi/powertec.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/acorn/scsi/powertec.c	Mon Feb 10 10:39:29 2003
@@ -1,7 +1,7 @@
 /*
  *  linux/drivers/acorn/scsi/powertec.c
  *
- *  Copyright (C) 1997-2002 Russell King
+ *  Copyright (C) 1997-2003 Russell King
  *
  * 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
@@ -32,24 +32,23 @@
 
 #include <scsi/scsicam.h>
 
-#define POWERTEC_FAS216_OFFSET	0xc00
-#define POWERTEC_FAS216_SHIFT	4
-#define POWERTEC_FAS216_SIZE	(16 << POWERTEC_FAS216_SHIFT)
+#define POWERTEC_FAS216_OFFSET	0x3000
+#define POWERTEC_FAS216_SHIFT	6
 
-#define POWERTEC_INTR_STATUS	0x800
+#define POWERTEC_INTR_STATUS	0x2000
 #define POWERTEC_INTR_BIT	0x80
 
-#define POWERTEC_RESET_CONTROL	0x406
+#define POWERTEC_RESET_CONTROL	0x1018
 #define POWERTEC_RESET_BIT	1
 
-#define POWERTEC_TERM_CONTROL	0x806
+#define POWERTEC_TERM_CONTROL	0x2018
 #define POWERTEC_TERM_ENABLE	1
 
-#define POWERTEC_INTR_CONTROL	0x407
+#define POWERTEC_INTR_CONTROL	0x101c
 #define POWERTEC_INTR_ENABLE	1
 #define POWERTEC_INTR_DISABLE	0
 
-#define VERSION	"1.00 (13/11/2002 2.5.47)"
+#define VERSION	"1.10 (19/01/2003 2.5.59)"
 
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off.
@@ -60,10 +59,11 @@
 #define NR_SG	256
 
 struct powertec_info {
-	FAS216_Info	info;
-	unsigned int	term_port;
-	unsigned int	term_ctl;
-	struct scatterlist sg[NR_SG];
+	FAS216_Info		info;
+	struct expansion_card	*ec;
+	void			*term_port;
+	unsigned int		term_ctl;
+	struct scatterlist	sg[NR_SG];
 };
 
 /* Prototype: void powertecscsi_irqenable(ec, irqnr)
@@ -74,8 +74,7 @@
 static void
 powertecscsi_irqenable(struct expansion_card *ec, int irqnr)
 {
-	unsigned int port = (unsigned int)ec->irq_data;
-	outb(POWERTEC_INTR_ENABLE, port);
+	writeb(POWERTEC_INTR_ENABLE, ec->irq_data);
 }
 
 /* Prototype: void powertecscsi_irqdisable(ec, irqnr)
@@ -86,8 +85,7 @@
 static void
 powertecscsi_irqdisable(struct expansion_card *ec, int irqnr)
 {
-	unsigned int port = (unsigned int)ec->irq_data;
-	outb(POWERTEC_INTR_DISABLE, port);
+	writeb(POWERTEC_INTR_DISABLE, ec->irq_data);
 }
 
 static const expansioncard_ops_t powertecscsi_ops = {
@@ -106,7 +104,7 @@
 	struct powertec_info *info = (struct powertec_info *)host->hostdata;
 
 	info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0;
-	outb(info->term_ctl, info->term_port);
+	writeb(info->term_ctl, info->term_port);
 }
 
 /* Prototype: void powertecscsi_intr(irq, *dev_id, *regs)
@@ -118,9 +116,9 @@
 static void
 powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+	struct powertec_info *info = dev_id;
 
-	fas216_intr(host);
+	fas216_intr(&info->info);
 }
 
 /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type)
@@ -139,8 +137,8 @@
 	struct device *dev = scsi_get_device(host);
 	int dmach = host->dma_channel;
 
-	if (dmach != NO_DMA &&
-	    (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
+	if (info->info.ifcfg.capabilities & FASCAP_DMA &&
+	    min_type == fasdma_real_all) {
 		int bufs, map_dir, dma_dir;
 
 		bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG);
@@ -188,13 +186,11 @@
 const char *powertecscsi_info(struct Scsi_Host *host)
 {
 	struct powertec_info *info = (struct powertec_info *)host->hostdata;
-	static char string[100], *p;
+	static char string[150];
 
-	p = string;
-	p += sprintf(p, "%s ", host->hostt->name);
-	p += fas216_info(&info->info, p);
-	p += sprintf(p, "v%s terminators o%s",
-		     VERSION, info->term_ctl ? "n" : "ff");
+	sprintf(string, "%s (%s) in slot %d v%s terminators o%s",
+		host->hostt->name, info->info.scsi.type, info->ec->slot_no,
+		VERSION, info->term_ctl ? "n" : "ff");
 
 	return string;
 }
@@ -262,7 +258,6 @@
 
 	begin = 0;
 	pos = sprintf(buffer, "PowerTec SCSI driver v%s\n", VERSION);
-
 	pos += fas216_print_host(&info->info, buffer + pos);
 	pos += sprintf(buffer + pos, "Term    : o%s\n",
 			info->term_ctl ? "n" : "ff");
@@ -290,6 +285,30 @@
 	return pos;
 }
 
+static ssize_t powertecscsi_show_term(struct device *dev, char *buf)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct powertec_info *info = (struct powertec_info *)host->hostdata;
+
+	return sprintf(buf, "%d\n", info->term_ctl ? 1 : 0);
+}
+
+static ssize_t
+powertecscsi_store_term(struct device *dev, const char *buf, size_t len)
+{
+	struct expansion_card *ec = ECARD_DEV(dev);
+	struct Scsi_Host *host = ecard_get_drvdata(ec);
+
+	if (len > 1)
+		powertecscsi_terminator_ctl(host, buf[0] != '0');
+
+	return len;
+}
+
+static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR,
+		   powertecscsi_show_term, powertecscsi_store_term);
+
 static Scsi_Host_Template powertecscsi_template = {
 	.module				= THIS_MODULE,
 	.proc_info			= powertecscsi_proc_info,
@@ -302,10 +321,10 @@
 	.eh_device_reset_handler	= fas216_eh_device_reset,
 	.eh_abort_handler		= fas216_eh_abort,
 
-	.can_queue			= 1,
+	.can_queue			= 8,
 	.this_id			= 7,
 	.sg_tablesize			= SG_ALL,
-	.cmd_per_lun			= 1,
+	.cmd_per_lun			= 2,
 	.use_clustering			= ENABLE_CLUSTERING,
 	.proc_name			= "powertec",
 };
@@ -314,37 +333,50 @@
 powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
 	struct Scsi_Host *host;
-    	struct powertec_info *info;
-    	int ret = -ENOMEM;
+	struct powertec_info *info;
+	unsigned long resbase, reslen;
+	unsigned char *base;
+	int ret;
+
+	resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
+	reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
+
+	if (!request_mem_region(resbase, reslen, "powertecscsi")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	base = ioremap(resbase, reslen);
+	if (!base) {
+		ret = -ENOMEM;
+		goto out_region;
+	}
 
 	host = scsi_register(&powertecscsi_template,
 			     sizeof (struct powertec_info));
-	if (!host)
-		goto out;
+	if (!host) {
+		ret = -ENOMEM;
+		goto out_unmap;
+	}
 
-	host->io_port	  = ecard_address(ec, ECARD_IOC, ECARD_FAST);
+	host->base	  = (unsigned long)base;
 	host->irq	  = ec->irq;
 	host->dma_channel = ec->dma;
 
-	if (!request_region(host->io_port + POWERTEC_FAS216_OFFSET,
-			    POWERTEC_FAS216_SIZE, "powertec2-fas")) {
-		ret = -EBUSY;
-		goto out_free;
-	}
-
-	ec->irqaddr	= (unsigned char *)
-			    ioaddr(host->io_port + POWERTEC_INTR_STATUS);
+	ec->irqaddr	= base + POWERTEC_INTR_STATUS;
 	ec->irqmask	= POWERTEC_INTR_BIT;
-	ec->irq_data	= (void *)(host->io_port + POWERTEC_INTR_CONTROL);
-	ec->ops		= (expansioncard_ops_t *)&powertecscsi_ops;
+	ec->irq_data	= base + POWERTEC_INTR_CONTROL;
+	ec->ops		= &powertecscsi_ops;
 
 	ecard_set_drvdata(ec, host);
 
 	info = (struct powertec_info *)host->hostdata;
-	info->term_port = host->io_port + POWERTEC_TERM_CONTROL;
+	info->term_port = base + POWERTEC_TERM_CONTROL;
 	powertecscsi_terminator_ctl(host, term[ec->slot_no]);
 
-	info->info.scsi.io_port		= host->io_port + POWERTEC_FAS216_OFFSET;
+	device_create_file(&ec->dev, &dev_attr_bus_term);
+
+	info->info.scsi.io_base		= base + POWERTEC_FAS216_OFFSET;
 	info->info.scsi.io_shift	= POWERTEC_FAS216_SHIFT;
 	info->info.scsi.irq		= host->irq;
 	info->info.ifcfg.clockrate	= 40; /* MHz */
@@ -354,16 +386,21 @@
 	info->info.ifcfg.cntl3		= CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
 	info->info.ifcfg.disconnect_ok	= 1;
 	info->info.ifcfg.wide_max_size	= 0;
+	info->info.ifcfg.capabilities	= 0;
 	info->info.dma.setup		= powertecscsi_dma_setup;
 	info->info.dma.pseudo		= NULL;
 	info->info.dma.stop		= powertecscsi_dma_stop;
 
+	ret = fas216_init(host);
+	if (ret)
+		goto out_free;
+
 	ret = request_irq(host->irq, powertecscsi_intr,
-			  SA_INTERRUPT, "powertec", host);
+			  SA_INTERRUPT, "powertec", info);
 	if (ret) {
 		printk("scsi%d: IRQ%d not free: %d\n",
 		       host->host_no, host->irq, ret);
-		goto out_region;
+		goto out_release;
 	}
 
 	if (host->dma_channel != NO_DMA) {
@@ -373,26 +410,31 @@
 			host->dma_channel = NO_DMA;
 		} else {
 			set_dma_speed(host->dma_channel, 180);
+			info->info.ifcfg.capabilities |= FASCAP_DMA;
 		}
 	}
 
-	fas216_init(host);
-
-	ret = scsi_add_host(host, &ec->dev);
+	ret = fas216_add(host, &ec->dev);
 	if (ret == 0)
 		goto out;
 
-	fas216_release(host);
-
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
 	free_irq(host->irq, host);
- out_region:
-	release_region(host->io_port + POWERTEC_FAS216_OFFSET,
-		       POWERTEC_FAS216_SIZE);
+
+ out_release:
+	fas216_release(host);
+
  out_free:
+	device_remove_file(&ec->dev, &dev_attr_bus_term);
 	scsi_unregister(host);
 
+ out_unmap:
+	iounmap(base);
+
+ out_region:
+	release_mem_region(resbase, reslen);
+
  out:
 	return ret;
 }
@@ -400,16 +442,26 @@
 static void __devexit powertecscsi_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	struct powertecscsi_info *info = (struct powertecscsi_info *)host->hostdata;
+	unsigned long resbase, reslen;
 
 	ecard_set_drvdata(ec, NULL);
-	scsi_remove_host(host);
-	fas216_release(host);
+	fas216_remove(host);
+
+	device_remove_file(&ec->dev, &dev_attr_bus_term);
 
 	if (host->dma_channel != NO_DMA)
 		free_dma(host->dma_channel);
-	free_irq(host->irq, host);
-	release_region(host->io_port + POWERTEC_FAS216_OFFSET,
-		       POWERTEC_FAS216_SIZE);
+	free_irq(host->irq, info);
+
+	iounmap((void *)host->base);
+
+	resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
+	reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
+
+	release_mem_region(resbase, reslen);
+
+	fas216_release(host);
 	scsi_unregister(host);
 }
 
@@ -423,7 +475,8 @@
 	.remove		= __devexit_p(powertecscsi_remove),
 	.id_table	= powertecscsi_cids,
 	.drv = {
-		.name	= "powertecscsi",
+		.devclass	= &shost_devclass,
+		.name		= "powertecscsi",
 	},
 };
 
diff -Nru a/drivers/acorn/scsi/scsi.h b/drivers/acorn/scsi/scsi.h
--- a/drivers/acorn/scsi/scsi.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/acorn/scsi/scsi.h	Mon Feb 10 10:39:23 2003
@@ -55,8 +55,6 @@
 
 	SCp->ptr += 1;
 	SCp->this_residual -= 1;
-	if (SCp->this_residual == 0)
-		next_SCp(SCp);
 
 	return c;
 }
@@ -66,8 +64,6 @@
 	*SCp->ptr = c;
 	SCp->ptr += 1;
 	SCp->this_residual -= 1;
-	if (SCp->this_residual == 0)
-		next_SCp(SCp);
 }
 
 static inline void init_SCp(Scsi_Cmnd *SCpnt)
@@ -112,7 +108,7 @@
 	 * we aren't interested in the buffer pointer.
 	 */
 	if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) {
-#ifdef BELT_AND_BRACES
+#if 0 //def BELT_AND_BRACES
 		printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for "
 		       "command ", SCpnt->host->host_no, '0' + SCpnt->target);
 		print_command(SCpnt->cmnd);
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/acpi/Kconfig	Mon Feb 10 10:39:33 2003
@@ -116,14 +116,6 @@
 	  ACPI C2 and C3 processor states to save power, on systems that
 	  support it.
 
-config ACPI_PROCESSOR_PERF
-	bool "Processor Performance States"
-	depends on X86 && ACPI && !ACPI_HT_ONLY && ACPI_PROCESSOR && CPU_FREQ
-	help
-	  This driver adds support for CPU frequency scaling, if this is supported
-	  by the hardware and the BIOS. If you are compiling for a mobile system,
-	  say Y.
-
 config ACPI_THERMAL
 	tristate "Thermal Zone"
 	depends on ACPI_PROCESSOR
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/acpi/Makefile	Mon Feb 10 10:39:33 2003
@@ -4,15 +4,13 @@
 
 export ACPI_CFLAGS
 
-ACPI_CFLAGS	:= -D_LINUX -Idrivers/acpi/include
+ACPI_CFLAGS	:= -D_LINUX -Os -Iinclude/acpi
 
 ifdef CONFIG_ACPI_DEBUG
   ACPI_CFLAGS	+= -DACPI_DEBUG_OUTPUT
 endif
 
 EXTRA_CFLAGS	+= $(ACPI_CFLAGS)
-
-export-objs 	:= acpi_ksyms.o processor.o
 
 obj-y		:= acpi_ksyms.o 
 
diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c
--- a/drivers/acpi/ac.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/acpi/ac.c	Mon Feb 10 10:39:26 2003
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include "acpi_bus.h"
diff -Nru a/drivers/acpi/acpi_bus.h b/drivers/acpi/acpi_bus.h
--- a/drivers/acpi/acpi_bus.h	Mon Feb 10 10:39:25 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,312 +0,0 @@
-/*
- *  acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more 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 __ACPI_BUS_H__
-#define __ACPI_BUS_H__
-
-#include <linux/version.h>
-#include <linux/kobject.h>
-
-#include "include/acpi.h"
-
-#define PREFIX			"ACPI: "
-
-extern int			acpi_disabled;
-
-/* TBD: Make dynamic */
-#define ACPI_MAX_HANDLES	10
-struct acpi_handle_list {
-	u32			count;
-	acpi_handle		handles[ACPI_MAX_HANDLES];
-};
-
-
-/* acpi_utils.h */
-acpi_status
-acpi_extract_package (
-	union acpi_object       *package,
-	struct acpi_buffer      *format,
-	struct acpi_buffer      *buffer);
-acpi_status
-acpi_evaluate_integer (
-	acpi_handle             handle,
-	acpi_string             pathname,
-	struct acpi_object_list *arguments,
-	unsigned long           *data);
-acpi_status
-acpi_evaluate_reference (
-	acpi_handle             handle,
-	acpi_string             pathname,
-	struct acpi_object_list *arguments,
-	struct acpi_handle_list *list);
-
-
-#ifdef CONFIG_ACPI_BUS
-
-#include <linux/proc_fs.h>
-
-#define ACPI_BUS_FILE_ROOT	"acpi"
-extern struct proc_dir_entry	*acpi_root_dir;
-extern FADT_DESCRIPTOR		acpi_fadt;
-
-enum acpi_bus_removal_type {
-	ACPI_BUS_REMOVAL_NORMAL	= 0,
-	ACPI_BUS_REMOVAL_EJECT,
-	ACPI_BUS_REMOVAL_SUPRISE,
-	ACPI_BUS_REMOVAL_TYPE_COUNT
-};
-
-enum acpi_bus_device_type {
-	ACPI_BUS_TYPE_DEVICE	= 0,
-	ACPI_BUS_TYPE_POWER,
-	ACPI_BUS_TYPE_PROCESSOR,
-	ACPI_BUS_TYPE_THERMAL,
-	ACPI_BUS_TYPE_SYSTEM,
-	ACPI_BUS_TYPE_POWER_BUTTON,
-	ACPI_BUS_TYPE_SLEEP_BUTTON,
-	ACPI_BUS_DEVICE_TYPE_COUNT
-};
-
-struct acpi_driver;
-struct acpi_device;
-
-
-/*
- * ACPI Driver
- * -----------
- */
-
-typedef int (*acpi_op_add)	(struct acpi_device *device);
-typedef int (*acpi_op_remove)	(struct acpi_device *device, int type);
-typedef int (*acpi_op_lock)	(struct acpi_device *device, int type);
-typedef int (*acpi_op_start)	(struct acpi_device *device);
-typedef int (*acpi_op_stop)	(struct acpi_device *device, int type);
-typedef int (*acpi_op_suspend)	(struct acpi_device *device, int state);
-typedef int (*acpi_op_resume)	(struct acpi_device *device, int state);
-typedef int (*acpi_op_scan)	(struct acpi_device *device);
-typedef int (*acpi_op_bind)	(struct acpi_device *device);
-
-struct acpi_device_ops {
-	acpi_op_add		add;
-	acpi_op_remove		remove;
-	acpi_op_lock		lock;
-	acpi_op_start		start;
-	acpi_op_stop		stop;
-	acpi_op_suspend		suspend;
-	acpi_op_resume		resume;
-	acpi_op_scan		scan;
-	acpi_op_bind		bind;
-};
-
-struct acpi_driver {
-	struct list_head	node;
-	char			name[80];
-	char			class[80];
-	atomic_t		references;
-	char			*ids;		/* Supported Hardware IDs */
-	struct acpi_device_ops	ops;
-};
-
-/*
- * ACPI Device
- * -----------
- */
-
-/* Status (_STA) */
-
-struct acpi_device_status {
-	u32			present:1;
-	u32			enabled:1;
-	u32			show_in_ui:1;
-	u32			functional:1;
-	u32			battery_present:1;
-	u32			reserved:27;
-};
-
-
-/* Flags */
-
-struct acpi_device_flags {
-	u32			dynamic_status:1;
-	u32			hardware_id:1;
-	u32			compatible_ids:1;
-	u32			bus_address:1;
-	u32			unique_id:1;
-	u32			removable:1;
-	u32			ejectable:1;
-	u32			lockable:1;
-	u32			suprise_removal_ok:1;
-	u32			power_manageable:1;
-	u32			performance_manageable:1;
-	u32			reserved:21;
-};
-
-
-/* File System */
-
-struct acpi_device_dir {
-	struct proc_dir_entry	*entry;
-};
-
-#define acpi_device_dir(d)	((d)->dir.entry)
-
-
-/* Plug and Play */
-
-typedef char			acpi_bus_id[5];
-typedef unsigned long		acpi_bus_address;
-typedef char			acpi_hardware_id[9];
-typedef char			acpi_unique_id[9];
-typedef char			acpi_device_name[40];
-typedef char			acpi_device_class[20];
-
-struct acpi_device_pnp {
-	acpi_bus_id		bus_id;		               /* Object name */
-	acpi_bus_address	bus_address;	                      /* _ADR */
-	acpi_hardware_id	hardware_id;	                      /* _HID */
-	acpi_unique_id		unique_id;	                      /* _UID */
-	acpi_device_name	device_name;	         /* Driver-determined */
-	acpi_device_class	device_class;	         /*        "          */
-};
-
-#define acpi_device_bid(d)	((d)->pnp.bus_id)
-#define acpi_device_adr(d)	((d)->pnp.bus_address)
-#define acpi_device_hid(d)	((d)->pnp.hardware_id)
-#define acpi_device_uid(d)	((d)->pnp.unique_id)
-#define acpi_device_name(d)	((d)->pnp.device_name)
-#define acpi_device_class(d)	((d)->pnp.device_class)
-
-
-/* Power Management */
-
-struct acpi_device_power_flags {
-	u32			explicit_get:1;		     /* _PSC present? */
-	u32			power_resources:1;	   /* Power resources */
-	u32			inrush_current:1;	  /* Serialize Dx->D0 */
-	u32			wake_capable:1;		 /* Wakeup supported? */
-	u32			wake_enabled:1;		/* Enabled for wakeup */
-	u32			power_removed:1;	   /* Optimize Dx->D0 */
-	u32			reserved:26;
-};
-
-struct acpi_device_power_state {
-	struct {
-		u8			valid:1;	
-		u8			explicit_set:1;	     /* _PSx present? */
-		u8			reserved:6;
-	}			flags;
-	int			power;		  /* % Power (compared to D0) */
-	int			latency;	/* Dx->D0 time (microseconds) */
-	struct acpi_handle_list	resources;	/* Power resources referenced */
-};
-
-struct acpi_device_power {
-	int			state;		             /* Current state */
-	struct acpi_device_power_flags flags;
-	struct acpi_device_power_state states[4];     /* Power states (D0-D3) */
-};
-
-
-/* Performance Management */
-
-struct acpi_device_perf_flags {
-	u8			reserved:8;
-};
-
-struct acpi_device_perf_state {
-	struct {
-		u8			valid:1;	
-		u8			reserved:7;
-	}			flags;
-	u8			power;		  /* % Power (compared to P0) */
-	u8			performance;	  /* % Performance (    "   ) */
-	int			latency;	/* Px->P0 time (microseconds) */
-};
-
-struct acpi_device_perf {
-	int			state;
-	struct acpi_device_perf_flags flags;
-	int			state_count;
-	struct acpi_device_perf_state *states;
-};
-
-
-/* Device */
-
-struct acpi_device {
-	acpi_handle		handle;
-	struct acpi_device	*parent;
-	struct list_head	children;
-	struct list_head	node;
-	struct list_head	g_list;
-	struct acpi_device_status status;
-	struct acpi_device_flags flags;
-	struct acpi_device_pnp	pnp;
-	struct acpi_device_power power;
-	struct acpi_device_perf	performance;
-	struct acpi_device_dir	dir;
-	struct acpi_device_ops	ops;
-	struct acpi_driver	*driver;
-	void			*driver_data;
-	struct kobject		kobj;
-};
-
-#define acpi_driver_data(d)	((d)->driver_data)
-
-
-/*
- * Events
- * ------
- */
-
-struct acpi_bus_event {
-	struct list_head	node;
-	acpi_device_class	device_class;
-	acpi_bus_id		bus_id;
-	u32			type;
-	u32			data;
-};
-
-extern struct subsystem acpi_subsys;
-
-/*
- * External Functions
- */
-
-int acpi_bus_get_device(acpi_handle, struct acpi_device **device);
-int acpi_bus_get_status (struct acpi_device *device);
-int acpi_bus_get_power (acpi_handle handle, int *state);
-int acpi_bus_set_power (acpi_handle handle, int state);
-int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
-int acpi_bus_receive_event (struct acpi_bus_event *event);
-int acpi_bus_register_driver (struct acpi_driver *driver);
-int acpi_bus_unregister_driver (struct acpi_driver *driver);
-
-int acpi_create_dir(struct acpi_device *);
-void acpi_remove_dir(struct acpi_device *);
-
-#endif /*CONFIG_ACPI_BUS*/
-
-#endif /*__ACPI_BUS_H__*/
diff -Nru a/drivers/acpi/acpi_drivers.h b/drivers/acpi/acpi_drivers.h
--- a/drivers/acpi/acpi_drivers.h	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,163 +0,0 @@
-/*
- *  acpi_drivers.h  ($Revision: 31 $)
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more 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 __ACPI_DRIVERS_H__
-#define __ACPI_DRIVERS_H__
-
-#include <linux/acpi.h>
-#include "acpi_bus.h"
-
-
-#define ACPI_MAX_STRING			80
-
-#define ACPI_BUS_COMPONENT		0x00010000
-#define ACPI_SYSTEM_COMPONENT		0x02000000
-
-/* _HID definitions */
-
-#define ACPI_POWER_HID			"ACPI_PWR"
-#define ACPI_PROCESSOR_HID		"ACPI_CPU"
-#define ACPI_SYSTEM_HID			"ACPI_SYS"
-#define ACPI_THERMAL_HID		"ACPI_THM"
-#define ACPI_BUTTON_HID_POWERF		"ACPI_FPB"
-#define ACPI_BUTTON_HID_SLEEPF		"ACPI_FSB"
-
-
-/* --------------------------------------------------------------------------
-                                       PCI
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_PCI
-
-#define ACPI_PCI_COMPONENT		0x00400000
-
-/* ACPI PCI Root Bridge (pci_root.c) */
-
-void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra);
-
-/* ACPI PCI Interrupt Link (pci_link.c) */
-
-int acpi_pci_link_check (void);
-int acpi_pci_link_get_irq (acpi_handle handle, int index);
-
-/* ACPI PCI Interrupt Routing (pci_irq.c) */
-
-int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus);
-
-/* ACPI PCI Device Binding (pci_bind.c) */
-
-struct pci_bus;
-
-int acpi_pci_bind (struct acpi_device *device);
-int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
-
-#endif /*CONFIG_ACPI_PCI*/
-
-
-/* --------------------------------------------------------------------------
-                                  Power Resource
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_POWER
-
-int acpi_power_get_inferred_state (struct acpi_device *device);
-int acpi_power_transition (struct acpi_device *device, int state);
-#endif
-
-
-/* --------------------------------------------------------------------------
-                                  Embedded Controller
-   -------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_EC
-int acpi_ec_ecdt_probe (void);
-#endif
-
-/* --------------------------------------------------------------------------
-                                    Processor
-   -------------------------------------------------------------------------- */
-
-#define ACPI_PROCESSOR_LIMIT_NONE	0x00
-#define ACPI_PROCESSOR_LIMIT_INCREMENT	0x01
-#define ACPI_PROCESSOR_LIMIT_DECREMENT	0x02
-
-int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
-
-
-/* --------------------------------------------------------------------------
-                                Debug Support
-   -------------------------------------------------------------------------- */
-
-#define ACPI_DEBUG_RESTORE	0
-#define ACPI_DEBUG_LOW		1
-#define ACPI_DEBUG_MEDIUM	2
-#define ACPI_DEBUG_HIGH		3
-#define ACPI_DEBUG_DRIVERS	4
-
-extern u32 acpi_dbg_level;
-extern u32 acpi_dbg_layer;
-
-static inline void
-acpi_set_debug (
-	u32			flag)
-{
-	static u32		layer_save;
-	static u32		level_save;
-
-	switch (flag) {
-	case ACPI_DEBUG_RESTORE:
-		acpi_dbg_layer = layer_save;
-		acpi_dbg_level = level_save;
-		break;
-	case ACPI_DEBUG_LOW:
-	case ACPI_DEBUG_MEDIUM:
-	case ACPI_DEBUG_HIGH:
-	case ACPI_DEBUG_DRIVERS:
-		layer_save = acpi_dbg_layer;
-		level_save = acpi_dbg_level;
-		break;
-	}
-
-	switch (flag) {
-	case ACPI_DEBUG_LOW:
-		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
-		acpi_dbg_level = ACPI_DEBUG_DEFAULT;
-		break;
-	case ACPI_DEBUG_MEDIUM:
-		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
-		acpi_dbg_level = ACPI_LV_FUNCTIONS | ACPI_LV_ALL_EXCEPTIONS;
-		break;
-	case ACPI_DEBUG_HIGH:
-		acpi_dbg_layer = 0xFFFFFFFF;
-		acpi_dbg_level = 0xFFFFFFFF;
-		break;
-	case ACPI_DEBUG_DRIVERS:
-		acpi_dbg_layer = ACPI_ALL_DRIVERS;
-		acpi_dbg_level = 0xFFFFFFFF;
-		break;
-	}
-}
-
-
-#endif /*__ACPI_DRIVERS_H__*/
diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
--- a/drivers/acpi/acpi_ksyms.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/acpi/acpi_ksyms.c	Mon Feb 10 10:39:24 2003
@@ -25,7 +25,7 @@
 
 #include <linux/module.h>
 #include <linux/acpi.h>
-#include "include/acpi.h"
+#include <acpi/acpi.h>
 #include "acpi_bus.h"
 
 
diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c
--- a/drivers/acpi/battery.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/acpi/battery.c	Mon Feb 10 10:39:30 2003
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include "acpi_bus.h"
 #include "acpi_drivers.h"
diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/acpi/button.c	Mon Feb 10 10:39:23 2003
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include "acpi_bus.h"
diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
--- a/drivers/acpi/dispatcher/dsinit.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/acpi/dispatcher/dsinit.c	Mon Feb 10 10:39:32 2003
@@ -24,11 +24,8 @@
 
 
 #include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
 #include "acdispat.h"
 #include "acnamesp.h"
-#include "acinterp.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsinit")
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/acpi/ec.c	Mon Feb 10 10:39:27 2003
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/delay.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <asm/io.h>
 #include "acpi_bus.h"
diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c
--- a/drivers/acpi/fan.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/acpi/fan.c	Mon Feb 10 10:39:23 2003
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include "acpi_bus.h"
 #include "acpi_drivers.h"
diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
--- a/drivers/acpi/hardware/hwtimer.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/acpi/hardware/hwtimer.c	Mon Feb 10 10:39:23 2003
@@ -117,7 +117,10 @@
  *              Note that this function accomodates only a single timer
  *              rollover.  Thus for 24-bit timers, this function should only
  *              be used for calculating durations less than ~4.6 seconds
- *              (~20 hours for 32-bit timers).
+ *              (~20 minutes for 32-bit timers) -- calculations below
+ *
+ *              2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
+ *              2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
  *
  ******************************************************************************/
 
diff -Nru a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h
--- a/drivers/acpi/include/acconfig.h	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,188 +0,0 @@
-/******************************************************************************
- *
- * Name: acconfig.h - Global configuration constants
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 _ACCONFIG_H
-#define _ACCONFIG_H
-
-
-/******************************************************************************
- *
- * Compile-time options
- *
- *****************************************************************************/
-
-/*
- * ACPI_DEBUG_OUTPUT    - This switch enables all the debug facilities of the
- *                        ACPI subsystem.  This includes the DEBUG_PRINT output
- *                        statements.  When disabled, all DEBUG_PRINT
- *                        statements are compiled out.
- *
- * ACPI_APPLICATION     - Use this switch if the subsystem is going to be run
- *                        at the application level.
- *
- */
-
-
-/******************************************************************************
- *
- * Subsystem Constants
- *
- *****************************************************************************/
-
-
-/* Version string */
-
-#define ACPI_CA_VERSION                 0x20030109
-
-/* Version of ACPI supported */
-
-#define ACPI_CA_SUPPORT_LEVEL           2
-
-/* Maximum objects in the various object caches */
-
-#define ACPI_MAX_STATE_CACHE_DEPTH      64          /* State objects for stacks */
-#define ACPI_MAX_PARSE_CACHE_DEPTH      96          /* Parse tree objects */
-#define ACPI_MAX_EXTPARSE_CACHE_DEPTH   64          /* Parse tree objects */
-#define ACPI_MAX_OBJECT_CACHE_DEPTH     64          /* Interpreter operand objects */
-#define ACPI_MAX_WALK_CACHE_DEPTH       4           /* Objects for parse tree walks */
-
-/* String size constants */
-
-#define ACPI_MAX_STRING_LENGTH          512
-#define ACPI_PATHNAME_MAX               256         /* A full namespace pathname */
-
-/* Maximum count for a semaphore object */
-
-#define ACPI_MAX_SEMAPHORE_COUNT        256
-
-/* Max reference count (for debug only) */
-
-#define ACPI_MAX_REFERENCE_COUNT        0x400
-
-/* Size of cached memory mapping for system memory operation region */
-
-#define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
-
-
-/******************************************************************************
- *
- * Configuration of subsystem behavior
- *
- *****************************************************************************/
-
-
-/*
- * Should the subystem abort the loading of an ACPI table if the
- * table checksum is incorrect?
- */
-#define ACPI_CHECKSUM_ABORT             FALSE
-
-
-/******************************************************************************
- *
- * ACPI Specification constants (Do not change unless the specification changes)
- *
- *****************************************************************************/
-
-/* Number of distinct GPE register blocks and register width */
-
-#define ACPI_MAX_GPE_BLOCKS             2
-#define ACPI_GPE_REGISTER_WIDTH         8
-
-/*
- * Method info (in WALK_STATE), containing local variables and argumetns
- */
-#define ACPI_METHOD_NUM_LOCALS          8
-#define ACPI_METHOD_MAX_LOCAL           7
-
-#define ACPI_METHOD_NUM_ARGS            7
-#define ACPI_METHOD_MAX_ARG             6
-
-/* Maximum length of resulting string when converting from a buffer */
-
-#define ACPI_MAX_STRING_CONVERSION      200
-
-/*
- * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
- */
-#define ACPI_OBJ_NUM_OPERANDS           8
-#define ACPI_OBJ_MAX_OPERAND            7
-
-/* Names within the namespace are 4 bytes long */
-
-#define ACPI_NAME_SIZE                  4
-#define ACPI_PATH_SEGMENT_LENGTH        5           /* 4 chars for name + 1 char for separator */
-#define ACPI_PATH_SEPARATOR             '.'
-
-/* Constants used in searching for the RSDP in low memory */
-
-#define ACPI_LO_RSDP_WINDOW_BASE        0           /* Physical Address */
-#define ACPI_HI_RSDP_WINDOW_BASE        0xE0000     /* Physical Address */
-#define ACPI_LO_RSDP_WINDOW_SIZE        0x400
-#define ACPI_HI_RSDP_WINDOW_SIZE        0x20000
-#define ACPI_RSDP_SCAN_STEP             16
-
-/* Operation regions */
-
-#define ACPI_NUM_PREDEFINED_REGIONS     8
-#define ACPI_USER_REGION_BEGIN          0x80
-
-/* Maximum space_ids for Operation Regions */
-
-#define ACPI_MAX_ADDRESS_SPACE          255
-
-/* Array sizes.  Used for range checking also */
-
-#define ACPI_NUM_ACCESS_TYPES           6
-#define ACPI_NUM_UPDATE_RULES           3
-#define ACPI_NUM_LOCK_RULES             2
-#define ACPI_NUM_MATCH_OPS              6
-#define ACPI_NUM_OPCODES                256
-#define ACPI_NUM_FIELD_NAMES            2
-
-/* RSDP checksums */
-
-#define ACPI_RSDP_CHECKSUM_LENGTH       20
-#define ACPI_RSDP_XCHECKSUM_LENGTH      36
-
-/* SMBus bidirectional buffer size */
-
-#define ACPI_SMBUS_BUFFER_SIZE          34
-
-
-/******************************************************************************
- *
- * ACPI AML Debugger
- *
- *****************************************************************************/
-
-
-#define ACPI_DEBUGGER_MAX_ARGS          8  /* Must be max method args + 1 */
-
-#define ACPI_DEBUGGER_COMMAND_PROMPT    '-'
-#define ACPI_DEBUGGER_EXECUTE_PROMPT    '%'
-
-
-#endif /* _ACCONFIG_H */
-
diff -Nru a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h
--- a/drivers/acpi/include/acdebug.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,430 +0,0 @@
-/******************************************************************************
- *
- * Name: acdebug.h - ACPI/AML debugger
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACDEBUG_H__
-#define __ACDEBUG_H__
-
-
-#define ACPI_DEBUG_BUFFER_SIZE  4196
-
-struct command_info
-{
-	char                            *name;          /* Command Name */
-	u8                              min_args;       /* Minimum arguments required */
-};
-
-
-struct argument_info
-{
-	char                            *name;          /* Argument Name */
-};
-
-
-#define PARAM_LIST(pl)                  pl
-
-#define DBTEST_OUTPUT_LEVEL(lvl)        if (acpi_gbl_db_opt_verbose)
-
-#define VERBOSE_PRINT(fp)               DBTEST_OUTPUT_LEVEL(lvl) {\
-			  acpi_os_printf PARAM_LIST(fp);}
-
-#define EX_NO_SINGLE_STEP       1
-#define EX_SINGLE_STEP          2
-
-
-/* Prototypes */
-
-
-/*
- * dbapi - external debugger interfaces
- */
-
-acpi_status
-acpi_db_initialize (
-	void);
-
-void
-acpi_db_terminate (
-	void);
-
-acpi_status
-acpi_db_single_step (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	u32                             op_type);
-
-
-/*
- * dbcmds - debug commands and output routines
- */
-
-void
-acpi_db_display_table_info (
-	char                            *table_arg);
-
-void
-acpi_db_unload_acpi_table (
-	char                            *table_arg,
-	char                            *instance_arg);
-
-void
-acpi_db_set_method_breakpoint (
-	char                            *location,
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-void
-acpi_db_set_method_call_breakpoint (
-	union acpi_parse_object         *op);
-
-void
-acpi_db_disassemble_aml (
-	char                            *statements,
-	union acpi_parse_object         *op);
-
-void
-acpi_db_dump_namespace (
-	char                            *start_arg,
-	char                            *depth_arg);
-
-void
-acpi_db_dump_namespace_by_owner (
-	char                            *owner_arg,
-	char                            *depth_arg);
-
-void
-acpi_db_send_notify (
-	char                            *name,
-	u32                             value);
-
-void
-acpi_db_set_method_data (
-	char                            *type_arg,
-	char                            *index_arg,
-	char                            *value_arg);
-
-acpi_status
-acpi_db_display_objects (
-	char                            *obj_type_arg,
-	char                            *display_count_arg);
-
-acpi_status
-acpi_db_find_name_in_namespace (
-	char                            *name_arg);
-
-void
-acpi_db_set_scope (
-	char                            *name);
-
-void
-acpi_db_find_references (
-	char                            *object_arg);
-
-void
-acpi_db_display_locks (void);
-
-
-void
-acpi_db_display_resources (
-	char                            *object_arg);
-
-void
-acpi_db_check_integrity (
-	void);
-
-acpi_status
-acpi_db_integrity_walk (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_and_match_name (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_for_references (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_for_specific_objects (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-
-/*
- * dbdisply - debug display commands
- */
-
-void
-acpi_db_display_method_info (
-	union acpi_parse_object         *op);
-
-void
-acpi_db_decode_and_display_object (
-	char                            *target,
-	char                            *output_type);
-
-void
-acpi_db_decode_node (
-	struct acpi_namespace_node      *node);
-
-void
-acpi_db_display_result_object (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_db_display_all_methods (
-	char                            *display_count_arg);
-
-void
-acpi_db_display_internal_object (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_db_display_arguments (
-	void);
-
-void
-acpi_db_display_locals (
-	void);
-
-void
-acpi_db_display_results (
-	void);
-
-void
-acpi_db_display_calling_tree (
-	void);
-
-void
-acpi_db_display_argument_object (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_db_dump_parser_descriptor (
-	union acpi_parse_object         *op);
-
-void *
-acpi_db_get_pointer (
-	void                            *target);
-
-void
-acpi_db_decode_internal_object (
-	union acpi_operand_object       *obj_desc);
-
-
-/*
- * dbexec - debugger control method execution
- */
-
-void
-acpi_db_execute (
-	char                            *name,
-	char                            **args,
-	u32                             flags);
-
-void
-acpi_db_create_execution_threads (
-	char                            *num_threads_arg,
-	char                            *num_loops_arg,
-	char                            *method_name_arg);
-
-acpi_status
-acpi_db_execute_method (
-	struct acpi_db_method_info      *info,
-	struct acpi_buffer              *return_obj);
-
-void
-acpi_db_execute_setup (
-	struct acpi_db_method_info      *info);
-
-u32
-acpi_db_get_outstanding_allocations (
-	void);
-
-void ACPI_SYSTEM_XFACE
-acpi_db_method_thread (
-	void                            *context);
-
-
-/*
- * dbfileio - Debugger file I/O commands
- */
-
-acpi_object_type
-acpi_db_match_argument (
-	char                            *user_argument,
-	struct argument_info            *arguments);
-
-acpi_status
-ae_local_load_table (
-	struct acpi_table_header        *table_ptr);
-
-void
-acpi_db_close_debug_file (
-	void);
-
-void
-acpi_db_open_debug_file (
-	char                            *name);
-
-acpi_status
-acpi_db_load_acpi_table (
-	char                            *filename);
-
-acpi_status
-acpi_db_get_acpi_table (
-	char                            *filename);
-
-/*
- * dbhistry - debugger HISTORY command
- */
-
-void
-acpi_db_add_to_history (
-	char                            *command_line);
-
-void
-acpi_db_display_history (void);
-
-char *
-acpi_db_get_from_history (
-	char                            *command_num_arg);
-
-
-/*
- * dbinput - user front-end to the AML debugger
- */
-
-acpi_status
-acpi_db_command_dispatch (
-	char                            *input_buffer,
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-void ACPI_SYSTEM_XFACE
-acpi_db_execute_thread (
-	void                            *context);
-
-acpi_status
-acpi_db_user_commands (
-	char                            prompt,
-	union acpi_parse_object         *op);
-
-void
-acpi_db_display_help (
-	char                            *help_type);
-
-char *
-acpi_db_get_next_token (
-	char                            *string,
-	char                            **next);
-
-u32
-acpi_db_get_line (
-	char                            *input_buffer);
-
-u32
-acpi_db_match_command (
-	char                            *user_command);
-
-void
-acpi_db_single_thread (
-	void);
-
-
-/*
- * dbstats - Generation and display of ACPI table statistics
- */
-
-void
-acpi_db_generate_statistics (
-	union acpi_parse_object         *root,
-	u8                              is_method);
-
-
-acpi_status
-acpi_db_display_statistics (
-	char                            *type_arg);
-
-acpi_status
-acpi_db_classify_one_object (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-void
-acpi_db_count_namespace_objects (
-	void);
-
-void
-acpi_db_enumerate_object (
-	union acpi_operand_object       *obj_desc);
-
-
-/*
- * dbutils - AML debugger utilities
- */
-
-void
-acpi_db_set_output_destination (
-	u32                             where);
-
-void
-acpi_db_dump_buffer (
-	u32                             address);
-
-void
-acpi_db_dump_object (
-	union acpi_object               *obj_desc,
-	u32                             level);
-
-void
-acpi_db_prep_namestring (
-	char                            *name);
-
-
-acpi_status
-acpi_db_second_pass_parse (
-	union acpi_parse_object         *root);
-
-struct acpi_namespace_node *
-acpi_db_local_ns_lookup (
-	char                            *name);
-
-
-#endif  /* __ACDEBUG_H__ */
diff -Nru a/drivers/acpi/include/acdispat.h b/drivers/acpi/include/acdispat.h
--- a/drivers/acpi/include/acdispat.h	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,494 +0,0 @@
-/******************************************************************************
- *
- * Name: acdispat.h - dispatcher (parser to interpreter interface)
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 _ACDISPAT_H_
-#define _ACDISPAT_H_
-
-
-#define NAMEOF_LOCAL_NTE    "__L0"
-#define NAMEOF_ARG_NTE      "__A0"
-
-
-/* Common interfaces */
-
-acpi_status
-acpi_ds_obj_stack_push (
-	void                            *object,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_obj_stack_pop (
-	u32                             pop_count,
-	struct acpi_walk_state          *walk_state);
-
-void *
-acpi_ds_obj_stack_get_value (
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_obj_stack_pop_object (
-	union acpi_operand_object       **object,
-	struct acpi_walk_state          *walk_state);
-
-
-/* dsopcode - support for late evaluation */
-
-acpi_status
-acpi_ds_execute_arguments (
-	struct acpi_namespace_node      *node,
-	struct acpi_namespace_node      *scope_node,
-	u32                             aml_length,
-	u8                              *aml_start);
-
-acpi_status
-acpi_ds_get_buffer_field_arguments (
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ds_get_region_arguments (
-	union acpi_operand_object       *rgn_desc);
-
-acpi_status
-acpi_ds_get_buffer_arguments (
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ds_get_package_arguments (
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ds_init_buffer_field (
-	u16                             aml_opcode,
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       *buffer_desc,
-	union acpi_operand_object       *offset_desc,
-	union acpi_operand_object       *length_desc,
-	union acpi_operand_object       *result_desc);
-
-acpi_status
-acpi_ds_eval_buffer_field_operands (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ds_eval_region_operands (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ds_eval_data_object_operands (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ds_initialize_region (
-	acpi_handle                     obj_handle);
-
-
-/* dsctrl - Parser/Interpreter interface, control stack routines */
-
-
-acpi_status
-acpi_ds_exec_begin_control_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ds_exec_end_control_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-
-/* dsexec - Parser/Interpreter interface, method execution callbacks */
-
-
-acpi_status
-acpi_ds_get_predicate_value (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       *result_obj);
-
-acpi_status
-acpi_ds_exec_begin_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         **out_op);
-
-acpi_status
-acpi_ds_exec_end_op (
-	struct acpi_walk_state          *state);
-
-
-/* dsfield - Parser/Interpreter interface for AML fields */
-
-acpi_status
-acpi_ds_get_field_names (
-	struct acpi_create_field_info   *info,
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *arg);
-
-acpi_status
-acpi_ds_create_field (
-	union acpi_parse_object         *op,
-	struct acpi_namespace_node      *region_node,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_create_bank_field (
-	union acpi_parse_object         *op,
-	struct acpi_namespace_node      *region_node,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_create_index_field (
-	union acpi_parse_object         *op,
-	struct acpi_namespace_node      *region_node,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_create_buffer_field (
-	union acpi_parse_object         *op,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_init_field_objects (
-	union acpi_parse_object         *op,
-	struct acpi_walk_state          *walk_state);
-
-
-/* dsload - Parser/Interpreter interface, namespace load callbacks */
-
-acpi_status
-acpi_ds_load1_begin_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         **out_op);
-
-acpi_status
-acpi_ds_load1_end_op (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_load2_begin_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         **out_op);
-
-acpi_status
-acpi_ds_load2_end_op (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_init_callbacks (
-	struct acpi_walk_state          *walk_state,
-	u32                             pass_number);
-
-
-/* dsmthdat - method data (locals/args) */
-
-
-acpi_status
-acpi_ds_store_object_to_local (
-	u16                             opcode,
-	u32                             index,
-	union acpi_operand_object       *src_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_method_data_get_entry (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       ***node);
-
-void
-acpi_ds_method_data_delete_all (
-	struct acpi_walk_state          *walk_state);
-
-u8
-acpi_ds_is_method_value (
-	union acpi_operand_object       *obj_desc);
-
-acpi_object_type
-acpi_ds_method_data_get_type (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_method_data_get_value (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       **dest_desc);
-
-void
-acpi_ds_method_data_delete_value (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_method_data_init_args (
-	union acpi_operand_object       **params,
-	u32                             max_param_count,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_method_data_get_node (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state,
-	struct acpi_namespace_node      **node);
-
-void
-acpi_ds_method_data_init (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_method_data_set_value (
-	u16                             opcode,
-	u32                             index,
-	union acpi_operand_object       *object,
-	struct acpi_walk_state          *walk_state);
-
-
-/* dsmethod - Parser/Interpreter interface - control method parsing */
-
-acpi_status
-acpi_ds_parse_method (
-	acpi_handle                     obj_handle);
-
-acpi_status
-acpi_ds_call_control_method (
-	struct acpi_thread_state        *thread,
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ds_restart_control_method (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       *return_desc);
-
-acpi_status
-acpi_ds_terminate_control_method (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_begin_method_execution (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       *obj_desc,
-	struct acpi_namespace_node      *calling_method_node);
-
-
-/* dsobj - Parser/Interpreter interface - object initialization and conversion */
-
-acpi_status
-acpi_ds_init_one_object (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_ds_initialize_objects (
-	struct acpi_table_desc          *table_desc,
-	struct acpi_namespace_node      *start_node);
-
-acpi_status
-acpi_ds_build_internal_buffer_obj (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	u32                             buffer_length,
-	union acpi_operand_object       **obj_desc_ptr);
-
-acpi_status
-acpi_ds_build_internal_package_obj (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	u32                             package_length,
-	union acpi_operand_object       **obj_desc);
-
-acpi_status
-acpi_ds_build_internal_object (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	union acpi_operand_object       **obj_desc_ptr);
-
-acpi_status
-acpi_ds_init_object_from_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	u16                             opcode,
-	union acpi_operand_object       **obj_desc);
-
-acpi_status
-acpi_ds_create_node (
-	struct acpi_walk_state          *walk_state,
-	struct acpi_namespace_node      *node,
-	union acpi_parse_object         *op);
-
-
-/* dsutils - Parser/Interpreter interface utility routines */
-
-u8
-acpi_ds_is_result_used (
-	union acpi_parse_object         *op,
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_ds_delete_result_if_not_used (
-	union acpi_parse_object         *op,
-	union acpi_operand_object       *result_obj,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_create_operand (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *arg,
-	u32                             args_remaining);
-
-acpi_status
-acpi_ds_create_operands (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *first_arg);
-
-acpi_status
-acpi_ds_resolve_operands (
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_ds_clear_operands (
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * dswscope - Scope Stack manipulation
- */
-
-acpi_status
-acpi_ds_scope_stack_push (
-	struct acpi_namespace_node      *node,
-	acpi_object_type                type,
-	struct acpi_walk_state          *walk_state);
-
-
-acpi_status
-acpi_ds_scope_stack_pop (
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_ds_scope_stack_clear (
-	struct acpi_walk_state          *walk_state);
-
-
-/* dswstate - parser WALK_STATE management routines */
-
-struct acpi_walk_state *
-acpi_ds_create_walk_state (
-	acpi_owner_id                   owner_id,
-	union acpi_parse_object         *origin,
-	union acpi_operand_object       *mth_desc,
-	struct acpi_thread_state        *thread);
-
-acpi_status
-acpi_ds_init_aml_walk (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	struct acpi_namespace_node      *method_node,
-	u8                              *aml_start,
-	u32                             aml_length,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc,
-	u32                             pass_number);
-
-acpi_status
-acpi_ds_obj_stack_delete_all (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_obj_stack_pop_and_delete (
-	u32                             pop_count,
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_ds_delete_walk_state (
-	struct acpi_walk_state          *walk_state);
-
-struct acpi_walk_state *
-acpi_ds_pop_walk_state (
-	struct acpi_thread_state        *thread);
-
-void
-acpi_ds_push_walk_state (
-	struct acpi_walk_state          *walk_state,
-	struct acpi_thread_state        *thread);
-
-acpi_status
-acpi_ds_result_stack_pop (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_stack_push (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_stack_clear (
-	struct acpi_walk_state          *walk_state);
-
-struct acpi_walk_state *
-acpi_ds_get_current_walk_state (
-	struct acpi_thread_state        *thread);
-
-void
-acpi_ds_delete_walk_state_cache (
-	void);
-
-acpi_status
-acpi_ds_result_insert (
-	void                            *object,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_remove (
-	union acpi_operand_object       **object,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_pop (
-	union acpi_operand_object       **object,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_push (
-	union acpi_operand_object       *object,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_result_pop_from_bottom (
-	union acpi_operand_object       **object,
-	struct acpi_walk_state          *walk_state);
-
-#endif /* _ACDISPAT_H_ */
diff -Nru a/drivers/acpi/include/acevents.h b/drivers/acpi/include/acevents.h
--- a/drivers/acpi/include/acevents.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,221 +0,0 @@
-/******************************************************************************
- *
- * Name: acevents.h - Event subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACEVENTS_H__
-#define __ACEVENTS_H__
-
-
-acpi_status
-acpi_ev_initialize (
-	void);
-
-acpi_status
-acpi_ev_handler_initialize (
-	void);
-
-
-/*
- * Evfixed - Fixed event handling
- */
-
-acpi_status
-acpi_ev_fixed_event_initialize (
-	void);
-
-u32
-acpi_ev_fixed_event_detect (
-	void);
-
-u32
-acpi_ev_fixed_event_dispatch (
-	u32                             event);
-
-
-/*
- * Evmisc
- */
-
-u8
-acpi_ev_is_notify_object (
-	struct acpi_namespace_node      *node);
-
-acpi_status
-acpi_ev_acquire_global_lock(
-	u16                             timeout);
-
-acpi_status
-acpi_ev_release_global_lock(
-	void);
-
-acpi_status
-acpi_ev_init_global_lock_handler (
-	void);
-
-u32
-acpi_ev_get_gpe_register_index (
-	u32                             gpe_number);
-
-u32
-acpi_ev_get_gpe_number_index (
-	u32                             gpe_number);
-
-acpi_status
-acpi_ev_queue_notify_request (
-	struct acpi_namespace_node      *node,
-	u32                             notify_value);
-
-void ACPI_SYSTEM_XFACE
-acpi_ev_notify_dispatch (
-	void                            *context);
-
-
-/*
- * Evgpe - GPE handling and dispatch
- */
-
-acpi_status
-acpi_ev_gpe_initialize (
-	void);
-
-acpi_status
-acpi_ev_init_gpe_control_methods (
-	void);
-
-u32
-acpi_ev_gpe_dispatch (
-	u32                             gpe_number);
-
-u32
-acpi_ev_gpe_detect (
-	void);
-
-/*
- * Evregion - Address Space handling
- */
-
-acpi_status
-acpi_ev_init_address_spaces (
-	void);
-
-acpi_status
-acpi_ev_address_space_dispatch (
-	union acpi_operand_object      *region_obj,
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	void                            *value);
-
-acpi_status
-acpi_ev_addr_handler_helper (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_ev_attach_region (
-	union acpi_operand_object       *handler_obj,
-	union acpi_operand_object       *region_obj,
-	u8                              acpi_ns_is_locked);
-
-void
-acpi_ev_detach_region (
-	union acpi_operand_object      *region_obj,
-	u8                              acpi_ns_is_locked);
-
-
-/*
- * Evregini - Region initialization and setup
- */
-
-acpi_status
-acpi_ev_system_memory_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_io_space_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_pci_config_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_cmos_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_pci_bar_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_default_region_setup (
-	acpi_handle                     handle,
-	u32                             function,
-	void                            *handler_context,
-	void                            **region_context);
-
-acpi_status
-acpi_ev_initialize_region (
-	union acpi_operand_object       *region_obj,
-	u8                              acpi_ns_locked);
-
-
-/*
- * Evsci - SCI (System Control Interrupt) handling/dispatch
- */
-
-u32
-acpi_ev_install_sci_handler (
-	void);
-
-acpi_status
-acpi_ev_remove_sci_handler (
-	void);
-
-u32
-acpi_ev_initialize_sCI (
-	u32                             program_sCI);
-
-void
-acpi_ev_terminate (
-	void);
-
-
-#endif  /* __ACEVENTS_H__  */
diff -Nru a/drivers/acpi/include/acexcep.h b/drivers/acpi/include/acexcep.h
--- a/drivers/acpi/include/acexcep.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,283 +0,0 @@
-/******************************************************************************
- *
- * Name: acexcep.h - Exception codes returned by the ACPI subsystem
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACEXCEP_H__
-#define __ACEXCEP_H__
-
-
-/*
- * Exceptions returned by external ACPI interfaces
- */
-
-#define AE_CODE_ENVIRONMENTAL           0x0000
-#define AE_CODE_PROGRAMMER              0x1000
-#define AE_CODE_ACPI_TABLES             0x2000
-#define AE_CODE_AML                     0x3000
-#define AE_CODE_CONTROL                 0x4000
-#define AE_CODE_MASK                    0xF000
-
-
-#define ACPI_SUCCESS(a)                 (!(a))
-#define ACPI_FAILURE(a)                 (a)
-
-
-#define AE_OK                           (acpi_status) 0x0000
-
-/*
- * Environmental exceptions
- */
-#define AE_ERROR                        (acpi_status) (0x0001 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_ACPI_TABLES               (acpi_status) (0x0002 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_NAMESPACE                 (acpi_status) (0x0003 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_MEMORY                    (acpi_status) (0x0004 | AE_CODE_ENVIRONMENTAL)
-#define AE_NOT_FOUND                    (acpi_status) (0x0005 | AE_CODE_ENVIRONMENTAL)
-#define AE_NOT_EXIST                    (acpi_status) (0x0006 | AE_CODE_ENVIRONMENTAL)
-#define AE_ALREADY_EXISTS               (acpi_status) (0x0007 | AE_CODE_ENVIRONMENTAL)
-#define AE_TYPE                         (acpi_status) (0x0008 | AE_CODE_ENVIRONMENTAL)
-#define AE_NULL_OBJECT                  (acpi_status) (0x0009 | AE_CODE_ENVIRONMENTAL)
-#define AE_NULL_ENTRY                   (acpi_status) (0x000A | AE_CODE_ENVIRONMENTAL)
-#define AE_BUFFER_OVERFLOW              (acpi_status) (0x000B | AE_CODE_ENVIRONMENTAL)
-#define AE_STACK_OVERFLOW               (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL)
-#define AE_STACK_UNDERFLOW              (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL)
-#define AE_NOT_IMPLEMENTED              (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL)
-#define AE_VERSION_MISMATCH             (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL)
-#define AE_SUPPORT                      (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL)
-#define AE_SHARE                        (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL)
-#define AE_LIMIT                        (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL)
-#define AE_TIME                         (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL)
-#define AE_UNKNOWN_STATUS               (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL)
-#define AE_ACQUIRE_DEADLOCK             (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL)
-#define AE_RELEASE_DEADLOCK             (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL)
-#define AE_NOT_ACQUIRED                 (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
-#define AE_ALREADY_ACQUIRED             (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_HARDWARE_RESPONSE         (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
-#define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
-#define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
-#define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
-
-#define AE_CODE_ENV_MAX                 0x001C
-
-/*
- * Programmer exceptions
- */
-#define AE_BAD_PARAMETER                (acpi_status) (0x0001 | AE_CODE_PROGRAMMER)
-#define AE_BAD_CHARACTER                (acpi_status) (0x0002 | AE_CODE_PROGRAMMER)
-#define AE_BAD_PATHNAME                 (acpi_status) (0x0003 | AE_CODE_PROGRAMMER)
-#define AE_BAD_DATA                     (acpi_status) (0x0004 | AE_CODE_PROGRAMMER)
-#define AE_BAD_ADDRESS                  (acpi_status) (0x0005 | AE_CODE_PROGRAMMER)
-#define AE_ALIGNMENT                    (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
-#define AE_BAD_HEX_CONSTANT             (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
-#define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
-#define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
-
-#define AE_CODE_PGM_MAX                 0x0009
-
-
-/*
- * Acpi table exceptions
- */
-#define AE_BAD_SIGNATURE                (acpi_status) (0x0001 | AE_CODE_ACPI_TABLES)
-#define AE_BAD_HEADER                   (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES)
-#define AE_BAD_CHECKSUM                 (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES)
-#define AE_BAD_VALUE                    (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES)
-#define AE_TABLE_NOT_SUPPORTED          (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES)
-#define AE_INVALID_TABLE_LENGTH         (acpi_status) (0x0006 | AE_CODE_ACPI_TABLES)
-
-#define AE_CODE_TBL_MAX                 0x0006
-
-
-/*
- * AML exceptions.  These are caused by problems with
- * the actual AML byte stream
- */
-#define AE_AML_ERROR                    (acpi_status) (0x0001 | AE_CODE_AML)
-#define AE_AML_PARSE                    (acpi_status) (0x0002 | AE_CODE_AML)
-#define AE_AML_BAD_OPCODE               (acpi_status) (0x0003 | AE_CODE_AML)
-#define AE_AML_NO_OPERAND               (acpi_status) (0x0004 | AE_CODE_AML)
-#define AE_AML_OPERAND_TYPE             (acpi_status) (0x0005 | AE_CODE_AML)
-#define AE_AML_OPERAND_VALUE            (acpi_status) (0x0006 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_LOCAL      (acpi_status) (0x0007 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_ARG        (acpi_status) (0x0008 | AE_CODE_AML)
-#define AE_AML_UNINITIALIZED_ELEMENT    (acpi_status) (0x0009 | AE_CODE_AML)
-#define AE_AML_NUMERIC_OVERFLOW         (acpi_status) (0x000A | AE_CODE_AML)
-#define AE_AML_REGION_LIMIT             (acpi_status) (0x000B | AE_CODE_AML)
-#define AE_AML_BUFFER_LIMIT             (acpi_status) (0x000C | AE_CODE_AML)
-#define AE_AML_PACKAGE_LIMIT            (acpi_status) (0x000D | AE_CODE_AML)
-#define AE_AML_DIVIDE_BY_ZERO           (acpi_status) (0x000E | AE_CODE_AML)
-#define AE_AML_BAD_NAME                 (acpi_status) (0x000F | AE_CODE_AML)
-#define AE_AML_NAME_NOT_FOUND           (acpi_status) (0x0010 | AE_CODE_AML)
-#define AE_AML_INTERNAL                 (acpi_status) (0x0011 | AE_CODE_AML)
-#define AE_AML_INVALID_SPACE_ID         (acpi_status) (0x0012 | AE_CODE_AML)
-#define AE_AML_STRING_LIMIT             (acpi_status) (0x0013 | AE_CODE_AML)
-#define AE_AML_NO_RETURN_VALUE          (acpi_status) (0x0014 | AE_CODE_AML)
-#define AE_AML_METHOD_LIMIT             (acpi_status) (0x0015 | AE_CODE_AML)
-#define AE_AML_NOT_OWNER                (acpi_status) (0x0016 | AE_CODE_AML)
-#define AE_AML_MUTEX_ORDER              (acpi_status) (0x0017 | AE_CODE_AML)
-#define AE_AML_MUTEX_NOT_ACQUIRED       (acpi_status) (0x0018 | AE_CODE_AML)
-#define AE_AML_INVALID_RESOURCE_TYPE    (acpi_status) (0x0019 | AE_CODE_AML)
-#define AE_AML_INVALID_INDEX            (acpi_status) (0x001A | AE_CODE_AML)
-#define AE_AML_REGISTER_LIMIT           (acpi_status) (0x001B | AE_CODE_AML)
-#define AE_AML_NO_WHILE                 (acpi_status) (0x001C | AE_CODE_AML)
-#define AE_AML_ALIGNMENT                (acpi_status) (0x001D | AE_CODE_AML)
-#define AE_AML_NO_RESOURCE_END_TAG      (acpi_status) (0x001E | AE_CODE_AML)
-#define AE_AML_BAD_RESOURCE_VALUE       (acpi_status) (0x001F | AE_CODE_AML)
-#define AE_AML_CIRCULAR_REFERENCE       (acpi_status) (0x0020 | AE_CODE_AML)
-
-#define AE_CODE_AML_MAX                 0x0020
-
-/*
- * Internal exceptions used for control
- */
-#define AE_CTRL_RETURN_VALUE            (acpi_status) (0x0001 | AE_CODE_CONTROL)
-#define AE_CTRL_PENDING                 (acpi_status) (0x0002 | AE_CODE_CONTROL)
-#define AE_CTRL_TERMINATE               (acpi_status) (0x0003 | AE_CODE_CONTROL)
-#define AE_CTRL_TRUE                    (acpi_status) (0x0004 | AE_CODE_CONTROL)
-#define AE_CTRL_FALSE                   (acpi_status) (0x0005 | AE_CODE_CONTROL)
-#define AE_CTRL_DEPTH                   (acpi_status) (0x0006 | AE_CODE_CONTROL)
-#define AE_CTRL_END                     (acpi_status) (0x0007 | AE_CODE_CONTROL)
-#define AE_CTRL_TRANSFER                (acpi_status) (0x0008 | AE_CODE_CONTROL)
-#define AE_CTRL_BREAK                   (acpi_status) (0x0009 | AE_CODE_CONTROL)
-#define AE_CTRL_CONTINUE                (acpi_status) (0x000A | AE_CODE_CONTROL)
-#define AE_CTRL_SKIP                    (acpi_status) (0x000B | AE_CODE_CONTROL)
-
-#define AE_CODE_CTRL_MAX                0x000B
-
-
-#ifdef DEFINE_ACPI_GLOBALS
-
-/*
- * String versions of the exception codes above
- * These strings must match the corresponding defines exactly
- */
-char const   *acpi_gbl_exception_names_env[] =
-{
-	"AE_OK",
-	"AE_ERROR",
-	"AE_NO_ACPI_TABLES",
-	"AE_NO_NAMESPACE",
-	"AE_NO_MEMORY",
-	"AE_NOT_FOUND",
-	"AE_NOT_EXIST",
-	"AE_ALREADY_EXISTS",
-	"AE_TYPE",
-	"AE_NULL_OBJECT",
-	"AE_NULL_ENTRY",
-	"AE_BUFFER_OVERFLOW",
-	"AE_STACK_OVERFLOW",
-	"AE_STACK_UNDERFLOW",
-	"AE_NOT_IMPLEMENTED",
-	"AE_VERSION_MISMATCH",
-	"AE_SUPPORT",
-	"AE_SHARE",
-	"AE_LIMIT",
-	"AE_TIME",
-	"AE_UNKNOWN_STATUS",
-	"AE_ACQUIRE_DEADLOCK",
-	"AE_RELEASE_DEADLOCK",
-	"AE_NOT_ACQUIRED",
-	"AE_ALREADY_ACQUIRED",
-	"AE_NO_HARDWARE_RESPONSE",
-	"AE_NO_GLOBAL_LOCK",
-	"AE_LOGICAL_ADDRESS",
-	"AE_ABORT_METHOD"
-};
-
-char const   *acpi_gbl_exception_names_pgm[] =
-{
-	"AE_BAD_PARAMETER",
-	"AE_BAD_CHARACTER",
-	"AE_BAD_PATHNAME",
-	"AE_BAD_DATA",
-	"AE_BAD_ADDRESS",
-	"AE_ALIGNMENT",
-	"AE_BAD_HEX_CONSTANT",
-	"AE_BAD_OCTAL_CONSTANT",
-	"AE_BAD_DECIMAL_CONSTANT"
-};
-
-char const   *acpi_gbl_exception_names_tbl[] =
-{
-	"AE_BAD_SIGNATURE",
-	"AE_BAD_HEADER",
-	"AE_BAD_CHECKSUM",
-	"AE_BAD_VALUE",
-	"AE_TABLE_NOT_SUPPORTED",
-	"AE_INVALID_TABLE_LENGTH"
-};
-
-char const   *acpi_gbl_exception_names_aml[] =
-{
-	"AE_AML_ERROR",
-	"AE_AML_PARSE",
-	"AE_AML_BAD_OPCODE",
-	"AE_AML_NO_OPERAND",
-	"AE_AML_OPERAND_TYPE",
-	"AE_AML_OPERAND_VALUE",
-	"AE_AML_UNINITIALIZED_LOCAL",
-	"AE_AML_UNINITIALIZED_ARG",
-	"AE_AML_UNINITIALIZED_ELEMENT",
-	"AE_AML_NUMERIC_OVERFLOW",
-	"AE_AML_REGION_LIMIT",
-	"AE_AML_BUFFER_LIMIT",
-	"AE_AML_PACKAGE_LIMIT",
-	"AE_AML_DIVIDE_BY_ZERO",
-	"AE_AML_BAD_NAME",
-	"AE_AML_NAME_NOT_FOUND",
-	"AE_AML_INTERNAL",
-	"AE_AML_INVALID_SPACE_ID",
-	"AE_AML_STRING_LIMIT",
-	"AE_AML_NO_RETURN_VALUE",
-	"AE_AML_METHOD_LIMIT",
-	"AE_AML_NOT_OWNER",
-	"AE_AML_MUTEX_ORDER",
-	"AE_AML_MUTEX_NOT_ACQUIRED",
-	"AE_AML_INVALID_RESOURCE_TYPE",
-	"AE_AML_INVALID_INDEX",
-	"AE_AML_REGISTER_LIMIT",
-	"AE_AML_NO_WHILE",
-	"AE_AML_ALIGNMENT",
-	"AE_AML_NO_RESOURCE_END_TAG",
-	"AE_AML_BAD_RESOURCE_VALUE",
-	"AE_AML_CIRCULAR_REFERENCE"
-};
-
-char const   *acpi_gbl_exception_names_ctrl[] =
-{
-	"AE_CTRL_RETURN_VALUE",
-	"AE_CTRL_PENDING",
-	"AE_CTRL_TERMINATE",
-	"AE_CTRL_TRUE",
-	"AE_CTRL_FALSE",
-	"AE_CTRL_DEPTH",
-	"AE_CTRL_END",
-	"AE_CTRL_TRANSFER",
-	"AE_CTRL_BREAK",
-	"AE_CTRL_CONTINUE",
-	"AE_CTRL_SKIP"
-};
-
-#endif /* ACPI GLOBALS */
-
-
-#endif /* __ACEXCEP_H__ */
diff -Nru a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h
--- a/drivers/acpi/include/acglobal.h	Mon Feb 10 10:39:22 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,298 +0,0 @@
-/******************************************************************************
- *
- * Name: acglobal.h - Declarations for global variables
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACGLOBAL_H__
-#define __ACGLOBAL_H__
-
-
-/*
- * Ensure that the globals are actually defined only once.
- *
- * The use of these defines allows a single list of globals (here) in order
- * to simplify maintenance of the code.
- */
-#ifdef DEFINE_ACPI_GLOBALS
-#define ACPI_EXTERN
-#else
-#define ACPI_EXTERN extern
-#endif
-
-
-/*****************************************************************************
- *
- * Debug support
- *
- ****************************************************************************/
-
-/* Runtime configuration of debug print levels */
-
-extern      u32                                 acpi_dbg_level;
-extern      u32                                 acpi_dbg_layer;
-
-/* Procedure nesting level for debug output */
-
-extern      u32                                 acpi_gbl_nesting_level;
-
-
-/*****************************************************************************
- *
- * ACPI Table globals
- *
- ****************************************************************************/
-
-/*
- * Table pointers.
- * Although these pointers are somewhat redundant with the global acpi_table,
- * they are convenient because they are typed pointers.
- *
- * These tables are single-table only; meaning that there can be at most one
- * of each in the system.  Each global points to the actual table.
- *
- */
-ACPI_EXTERN u32                                 acpi_gbl_table_flags;
-ACPI_EXTERN u32                                 acpi_gbl_rsdt_table_count;
-ACPI_EXTERN struct rsdp_descriptor             *acpi_gbl_RSDP;
-ACPI_EXTERN XSDT_DESCRIPTOR            *acpi_gbl_XSDT;
-ACPI_EXTERN FADT_DESCRIPTOR            *acpi_gbl_FADT;
-ACPI_EXTERN struct acpi_table_header           *acpi_gbl_DSDT;
-ACPI_EXTERN FACS_DESCRIPTOR            *acpi_gbl_FACS;
-ACPI_EXTERN struct acpi_common_facs             acpi_gbl_common_fACS;
-
-/*
- * Handle both ACPI 1.0 and ACPI 2.0 Integer widths
- * If we are running a method that exists in a 32-bit ACPI table.
- * Use only 32 bits of the Integer for conversion.
- */
-ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
-ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
-
-/*
- * Since there may be multiple SSDTs and PSDTS, a single pointer is not
- * sufficient; Therefore, there isn't one!
- */
-
-
-/*
- * ACPI Table info arrays
- */
-extern      struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
-extern      struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
-
-/*
- * Predefined mutex objects.  This array contains the
- * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
- * (The table maps local handles to the real OS handles)
- */
-ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_acpi_mutex_info [NUM_MTX];
-
-
-/*****************************************************************************
- *
- * Miscellaneous globals
- *
- ****************************************************************************/
-
-
-ACPI_EXTERN struct acpi_memory_list             acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_drv_notify;
-ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_sys_notify;
-ACPI_EXTERN acpi_init_handler                   acpi_gbl_init_handler;
-ACPI_EXTERN struct acpi_walk_state             *acpi_gbl_breakpoint_walk;
-ACPI_EXTERN acpi_handle                         acpi_gbl_global_lock_semaphore;
-
-ACPI_EXTERN u32                                 acpi_gbl_global_lock_thread_count;
-ACPI_EXTERN u32                                 acpi_gbl_original_mode;
-ACPI_EXTERN u32                                 acpi_gbl_rsdp_original_location;
-ACPI_EXTERN u32                                 acpi_gbl_ns_lookup_count;
-ACPI_EXTERN u32                                 acpi_gbl_ps_find_count;
-ACPI_EXTERN u16                                 acpi_gbl_pm1_enable_register_save;
-ACPI_EXTERN u16                                 acpi_gbl_next_table_owner_id;
-ACPI_EXTERN u16                                 acpi_gbl_next_method_owner_id;
-ACPI_EXTERN u16                                 acpi_gbl_global_lock_handle;
-ACPI_EXTERN u8                                  acpi_gbl_debugger_configuration;
-ACPI_EXTERN u8                                  acpi_gbl_global_lock_acquired;
-ACPI_EXTERN u8                                  acpi_gbl_step_to_next_call;
-ACPI_EXTERN u8                                  acpi_gbl_acpi_hardware_present;
-ACPI_EXTERN u8                                  acpi_gbl_global_lock_present;
-ACPI_EXTERN u8                                  acpi_gbl_events_initialized;
-
-extern u8                                       acpi_gbl_shutdown;
-extern u32                                      acpi_gbl_startup_flags;
-extern const u8                                 acpi_gbl_decode_to8bit[8];
-extern const char                              *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT];
-extern const struct acpi_opcode_info            acpi_gbl_aml_op_info[AML_NUM_OPCODES];
-extern const char                              *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
-
-
-/*****************************************************************************
- *
- * Namespace globals
- *
- ****************************************************************************/
-
-#define NUM_NS_TYPES                    ACPI_TYPE_INVALID+1
-
-#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
-#define NUM_PREDEFINED_NAMES            10
-#else
-#define NUM_PREDEFINED_NAMES            9
-#endif
-
-ACPI_EXTERN struct acpi_namespace_node          acpi_gbl_root_node_struct;
-ACPI_EXTERN struct acpi_namespace_node         *acpi_gbl_root_node;
-
-extern const u8                                 acpi_gbl_ns_properties[NUM_NS_TYPES];
-extern const struct acpi_predefined_names       acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
-
-#ifdef ACPI_DEBUG_OUTPUT
-ACPI_EXTERN u32                                 acpi_gbl_current_node_count;
-ACPI_EXTERN u32                                 acpi_gbl_current_node_size;
-ACPI_EXTERN u32                                 acpi_gbl_max_concurrent_node_count;
-ACPI_EXTERN acpi_size                           acpi_gbl_entry_stack_pointer;
-ACPI_EXTERN acpi_size                           acpi_gbl_lowest_stack_pointer;
-ACPI_EXTERN u32                                 acpi_gbl_deepest_nesting;
-#endif
-
-/*****************************************************************************
- *
- * Interpreter globals
- *
- ****************************************************************************/
-
-
-ACPI_EXTERN struct acpi_thread_state            *acpi_gbl_current_walk_list;
-
-/* Control method single step flag */
-
-ACPI_EXTERN u8                                  acpi_gbl_cm_single_step;
-
-
-/*****************************************************************************
- *
- * Parser globals
- *
- ****************************************************************************/
-
-ACPI_EXTERN union acpi_parse_object             *acpi_gbl_parsed_namespace_root;
-
-/*****************************************************************************
- *
- * Hardware globals
- *
- ****************************************************************************/
-
-extern      struct acpi_bit_register_info       acpi_gbl_bit_register_info[ACPI_NUM_BITREG];
-ACPI_EXTERN u8                                  acpi_gbl_sleep_type_a;
-ACPI_EXTERN u8                                  acpi_gbl_sleep_type_b;
-
-
-/*****************************************************************************
- *
- * Event and GPE globals
- *
- ****************************************************************************/
-
-extern      struct acpi_fixed_event_info        acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN struct acpi_fixed_event_handler     acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
-
-ACPI_EXTERN acpi_handle                         acpi_gbl_gpe_obj_handle;
-ACPI_EXTERN u32                                 acpi_gbl_gpe_register_count;
-ACPI_EXTERN u32                                 acpi_gbl_gpe_number_max;
-ACPI_EXTERN struct acpi_gpe_register_info      *acpi_gbl_gpe_register_info;
-ACPI_EXTERN struct acpi_gpe_number_info        *acpi_gbl_gpe_number_info;
-ACPI_EXTERN struct acpi_gpe_block_info          acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS];
-
-/*
- * GPE translation table
- * Indexed by the GPE number, returns a valid index into the global GPE tables.
- *
- * This table is needed because the GPE numbers supported by block 1 do not
- * have to be contiguous with the GPE numbers supported by block 0.
- */
-ACPI_EXTERN struct acpi_gpe_index_info         *acpi_gbl_gpe_number_to_index;
-
-
-/*****************************************************************************
- *
- * Debugger globals
- *
- ****************************************************************************/
-
-
-ACPI_EXTERN u8                                  acpi_gbl_db_output_flags;
-
-#ifdef ACPI_DISASSEMBLER
-
-ACPI_EXTERN u8                                  acpi_gbl_db_opt_disasm;
-ACPI_EXTERN u8                                  acpi_gbl_db_opt_verbose;
-#endif
-
-
-#ifdef ACPI_DEBUGGER
-
-extern      u8                                  acpi_gbl_method_executing;
-extern      u8                                  acpi_gbl_abort_method;
-extern      u8                                  acpi_gbl_db_terminate_threads;
-
-ACPI_EXTERN int                                 optind;
-ACPI_EXTERN char                               *optarg;
-
-ACPI_EXTERN u8                                  acpi_gbl_db_opt_tables;
-ACPI_EXTERN u8                                  acpi_gbl_db_opt_stats;
-ACPI_EXTERN u8                                  acpi_gbl_db_opt_ini_methods;
-
-
-ACPI_EXTERN char                               *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
-ACPI_EXTERN char                                acpi_gbl_db_line_buf[80];
-ACPI_EXTERN char                                acpi_gbl_db_parsed_buf[80];
-ACPI_EXTERN char                                acpi_gbl_db_scope_buf[40];
-ACPI_EXTERN char                                acpi_gbl_db_debug_filename[40];
-ACPI_EXTERN u8                                  acpi_gbl_db_output_to_file;
-ACPI_EXTERN char                               *acpi_gbl_db_buffer;
-ACPI_EXTERN char                               *acpi_gbl_db_filename;
-ACPI_EXTERN u32                                 acpi_gbl_db_debug_level;
-ACPI_EXTERN u32                                 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header           *acpi_gbl_db_table_ptr;
-ACPI_EXTERN struct acpi_namespace_node         *acpi_gbl_db_scope_node;
-
-/*
- * Statistic globals
- */
-ACPI_EXTERN u16                                 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX+1];
-ACPI_EXTERN u16                                 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX+1];
-ACPI_EXTERN u16                                 acpi_gbl_obj_type_count_misc;
-ACPI_EXTERN u16                                 acpi_gbl_node_type_count_misc;
-ACPI_EXTERN u32                                 acpi_gbl_num_nodes;
-ACPI_EXTERN u32                                 acpi_gbl_num_objects;
-
-
-ACPI_EXTERN u32                                 acpi_gbl_size_of_parse_tree;
-ACPI_EXTERN u32                                 acpi_gbl_size_of_method_trees;
-ACPI_EXTERN u32                                 acpi_gbl_size_of_node_entries;
-ACPI_EXTERN u32                                 acpi_gbl_size_of_acpi_objects;
-
-#endif /* ACPI_DEBUGGER */
-
-
-#endif /* __ACGLOBAL_H__ */
diff -Nru a/drivers/acpi/include/achware.h b/drivers/acpi/include/achware.h
--- a/drivers/acpi/include/achware.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,154 +0,0 @@
-/******************************************************************************
- *
- * Name: achware.h -- hardware specific interfaces
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACHWARE_H__
-#define __ACHWARE_H__
-
-
-/* PM Timer ticks per second (HZ) */
-#define PM_TIMER_FREQUENCY  3579545
-
-
-/* Prototypes */
-
-
-acpi_status
-acpi_hw_initialize (
-	void);
-
-acpi_status
-acpi_hw_shutdown (
-	void);
-
-acpi_status
-acpi_hw_initialize_system_info (
-	void);
-
-acpi_status
-acpi_hw_set_mode (
-	u32                             mode);
-
-u32
-acpi_hw_get_mode (
-	void);
-
-u32
-acpi_hw_get_mode_capabilities (
-	void);
-
-/* Register I/O Prototypes */
-
-struct acpi_bit_register_info *
-acpi_hw_get_bit_register_info (
-	u32                             register_id);
-
-acpi_status
-acpi_hw_register_read (
-	u8                              use_lock,
-	u32                             register_id,
-	u32                             *return_value);
-
-acpi_status
-acpi_hw_register_write (
-	u8                              use_lock,
-	u32                             register_id,
-	u32                             value);
-
-acpi_status
-acpi_hw_low_level_read (
-	u32                             width,
-	u32                             *value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
-
-acpi_status
-acpi_hw_low_level_write (
-	u32                             width,
-	u32                             value,
-	struct acpi_generic_address     *reg,
-	u32                             offset);
-
-acpi_status
-acpi_hw_clear_acpi_status (
-   void);
-
-
-/* GPE support */
-
-u8
-acpi_hw_get_gpe_bit_mask (
-	u32                             gpe_number);
-
-acpi_status
-acpi_hw_enable_gpe (
-	u32                             gpe_number);
-
-void
-acpi_hw_enable_gpe_for_wakeup (
-	u32                             gpe_number);
-
-acpi_status
-acpi_hw_disable_gpe (
-	u32                             gpe_number);
-
-void
-acpi_hw_disable_gpe_for_wakeup (
-	u32                             gpe_number);
-
-acpi_status
-acpi_hw_clear_gpe (
-	u32                             gpe_number);
-
-acpi_status
-acpi_hw_get_gpe_status (
-	u32                             gpe_number,
-	acpi_event_status               *event_status);
-
-acpi_status
-acpi_hw_disable_non_wakeup_gpes (
-	void);
-
-acpi_status
-acpi_hw_enable_non_wakeup_gpes (
-	void);
-
-
-/* ACPI Timer prototypes */
-
-acpi_status
-acpi_get_timer_resolution (
-	u32                             *resolution);
-
-acpi_status
-acpi_get_timer (
-	u32                             *ticks);
-
-acpi_status
-acpi_get_timer_duration (
-	u32                             start_ticks,
-	u32                             end_ticks,
-	u32                             *time_elapsed);
-
-
-#endif /* __ACHWARE_H__ */
diff -Nru a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h
--- a/drivers/acpi/include/acinterp.h	Mon Feb 10 10:39:31 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,717 +0,0 @@
-/******************************************************************************
- *
- * Name: acinterp.h - Interpreter subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACINTERP_H__
-#define __ACINTERP_H__
-
-
-#define ACPI_WALK_OPERANDS       (&(walk_state->operands [walk_state->num_operands -1]))
-
-
-acpi_status
-acpi_ex_resolve_operands (
-	u16                             opcode,
-	union acpi_operand_object       **stack_ptr,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_check_object_type (
-	acpi_object_type                type_needed,
-	acpi_object_type                this_type,
-	void                            *object);
-
-/*
- * exxface - External interpreter interfaces
- */
-
-acpi_status
-acpi_ex_load_table (
-	acpi_table_type                 table_id);
-
-acpi_status
-acpi_ex_execute_method (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
-
-
-/*
- * exconvrt - object conversion
- */
-
-acpi_status
-acpi_ex_convert_to_integer (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **result_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_convert_to_buffer (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **result_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_convert_to_string (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **result_desc,
-	u32                             base,
-	u32                             max_length,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_convert_to_target_type (
-	acpi_object_type                destination_type,
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       **result_desc,
-	struct acpi_walk_state          *walk_state);
-
-u32
-acpi_ex_convert_to_ascii (
-	acpi_integer                    integer,
-	u32                             base,
-	u8                              *string,
-	u8                              max_length);
-
-/*
- * exfield - ACPI AML (p-code) execution - field manipulation
- */
-
-acpi_status
-acpi_ex_extract_from_field (
-	union acpi_operand_object       *obj_desc,
-	void                            *buffer,
-	u32                             buffer_length);
-
-acpi_status
-acpi_ex_insert_into_field (
-	union acpi_operand_object       *obj_desc,
-	void                            *buffer,
-	u32                             buffer_length);
-
-acpi_status
-acpi_ex_setup_region (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset);
-
-acpi_status
-acpi_ex_access_region (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset,
-	acpi_integer                    *value,
-	u32                             read_write);
-
-u8
-acpi_ex_register_overflow (
-	union acpi_operand_object       *obj_desc,
-	acpi_integer                    value);
-
-acpi_status
-acpi_ex_field_datum_io (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset,
-	acpi_integer                    *value,
-	u32                             read_write);
-
-acpi_status
-acpi_ex_write_with_update_rule (
-	union acpi_operand_object       *obj_desc,
-	acpi_integer                    mask,
-	acpi_integer                    field_value,
-	u32                             field_datum_byte_offset);
-
-void
-acpi_ex_get_buffer_datum(
-	acpi_integer                    *datum,
-	void                            *buffer,
-	u32                             byte_granularity,
-	u32                             offset);
-
-void
-acpi_ex_set_buffer_datum (
-	acpi_integer                    merged_datum,
-	void                            *buffer,
-	u32                             byte_granularity,
-	u32                             offset);
-
-acpi_status
-acpi_ex_read_data_from_field (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **ret_buffer_desc);
-
-acpi_status
-acpi_ex_write_data_to_field (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **result_desc);
-
-/*
- * exmisc - ACPI AML (p-code) execution - specific opcodes
- */
-
-acpi_status
-acpi_ex_opcode_3A_0T_0R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_3A_1T_1R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_6A_0T_1R (
-	struct acpi_walk_state          *walk_state);
-
-u8
-acpi_ex_do_match (
-	u32                             match_op,
-	acpi_integer                    package_value,
-	acpi_integer                    match_value);
-
-acpi_status
-acpi_ex_get_object_reference (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       **return_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_resolve_multiple (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       *operand,
-	acpi_object_type                *return_type,
-	union acpi_operand_object       **return_desc);
-
-acpi_status
-acpi_ex_concat_template (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       *obj_desc2,
-	union acpi_operand_object       **actual_return_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_do_concatenate (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       *obj_desc2,
-	union acpi_operand_object       **actual_return_desc,
-	struct acpi_walk_state          *walk_state);
-
-u8
-acpi_ex_do_logical_op (
-	u16                             opcode,
-	acpi_integer                    operand0,
-	acpi_integer                    operand1);
-
-acpi_integer
-acpi_ex_do_math_op (
-	u16                             opcode,
-	acpi_integer                    operand0,
-	acpi_integer                    operand1);
-
-acpi_status
-acpi_ex_create_mutex (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_processor (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_power_resource (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_region (
-	u8                              *aml_start,
-	u32                             aml_length,
-	u8                              region_space,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_table_region (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_event (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_alias (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_create_method (
-	u8                              *aml_start,
-	u32                             aml_length,
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * exconfig - dynamic table load/unload
- */
-
-acpi_status
-acpi_ex_add_table (
-	struct acpi_table_header        *table,
-	struct acpi_namespace_node      *parent_node,
-	union acpi_operand_object       **ddb_handle);
-
-acpi_status
-acpi_ex_load_op (
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       *target,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_load_table_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       **return_desc);
-
-acpi_status
-acpi_ex_unload_table (
-	union acpi_operand_object       *ddb_handle);
-
-
-/*
- * exmutex - mutex support
- */
-
-acpi_status
-acpi_ex_acquire_mutex (
-	union acpi_operand_object       *time_desc,
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_release_mutex (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_walk_state          *walk_state);
-
-void
-acpi_ex_release_all_mutexes (
-	struct acpi_thread_state        *thread);
-
-void
-acpi_ex_unlink_mutex (
-	union acpi_operand_object       *obj_desc);
-
-void
-acpi_ex_link_mutex (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_thread_state        *thread);
-
-/*
- * exprep - ACPI AML (p-code) execution - prep utilities
- */
-
-acpi_status
-acpi_ex_prep_common_field_object (
-	union acpi_operand_object       *obj_desc,
-	u8                              field_flags,
-	u8                              field_attribute,
-	u32                             field_bit_position,
-	u32                             field_bit_length);
-
-acpi_status
-acpi_ex_prep_field_value (
-	struct acpi_create_field_info   *info);
-
-/*
- * exsystem - Interface to OS services
- */
-
-acpi_status
-acpi_ex_system_do_notify_op (
-	union acpi_operand_object       *value,
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_do_suspend(
-	u32                             time);
-
-acpi_status
-acpi_ex_system_do_stall (
-	u32                             time);
-
-acpi_status
-acpi_ex_system_acquire_mutex(
-	union acpi_operand_object       *time,
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_release_mutex(
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_signal_event(
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_wait_event(
-	union acpi_operand_object       *time,
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_reset_event(
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ex_system_wait_semaphore (
-	acpi_handle                     semaphore,
-	u16                             timeout);
-
-
-/*
- * exmonadic - ACPI AML (p-code) execution, monadic operators
- */
-
-acpi_status
-acpi_ex_opcode_1A_0T_0R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_1A_0T_1R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_1A_1T_1R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_1A_1T_0R (
-	struct acpi_walk_state          *walk_state);
-
-/*
- * exdyadic - ACPI AML (p-code) execution, dyadic operators
- */
-
-acpi_status
-acpi_ex_opcode_2A_0T_0R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_2A_0T_1R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_2A_1T_1R (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_opcode_2A_2T_1R (
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * exresolv  - Object resolution and get value functions
- */
-
-acpi_status
-acpi_ex_resolve_to_value (
-	union acpi_operand_object       **stack_ptr,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_resolve_node_to_value (
-	struct acpi_namespace_node      **stack_ptr,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_resolve_object_to_value (
-	union acpi_operand_object       **stack_ptr,
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * exdump - Scanner debug output routines
- */
-
-void
-acpi_ex_dump_operand (
-	union acpi_operand_object       *entry_desc);
-
-void
-acpi_ex_dump_operands (
-	union acpi_operand_object       **operands,
-	acpi_interpreter_mode           interpreter_mode,
-	char                            *ident,
-	u32                             num_levels,
-	char                            *note,
-	char                            *module_name,
-	u32                             line_number);
-
-void
-acpi_ex_dump_object_descriptor (
-	union acpi_operand_object       *object,
-	u32                             flags);
-
-void
-acpi_ex_dump_node (
-	struct acpi_namespace_node      *node,
-	u32                             flags);
-
-void
-acpi_ex_out_string (
-	char                            *title,
-	char                            *value);
-
-void
-acpi_ex_out_pointer (
-	char                            *title,
-	void                            *value);
-
-void
-acpi_ex_out_integer (
-	char                            *title,
-	u32                             value);
-
-void
-acpi_ex_out_address (
-	char                            *title,
-	acpi_physical_address           value);
-
-
-/*
- * exnames - interpreter/scanner name load/execute
- */
-
-char *
-acpi_ex_allocate_name_string (
-	u32                             prefix_count,
-	u32                             num_name_segs);
-
-u32
-acpi_ex_good_char (
-	u32                             character);
-
-acpi_status
-acpi_ex_name_segment (
-	u8                              **in_aml_address,
-	char                            *name_string);
-
-acpi_status
-acpi_ex_get_name_string (
-	acpi_object_type                data_type,
-	u8                              *in_aml_address,
-	char                            **out_name_string,
-	u32                             *out_name_length);
-
-acpi_status
-acpi_ex_do_name (
-	acpi_object_type                data_type,
-	acpi_interpreter_mode           load_exec_mode);
-
-
-/*
- * exstore - Object store support
- */
-
-acpi_status
-acpi_ex_store (
-	union acpi_operand_object       *val_desc,
-	union acpi_operand_object       *dest_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_store_object_to_index (
-	union acpi_operand_object       *val_desc,
-	union acpi_operand_object       *dest_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_store_object_to_node (
-	union acpi_operand_object       *source_desc,
-	struct acpi_namespace_node      *node,
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * exstoren
- */
-
-acpi_status
-acpi_ex_resolve_object (
-	union acpi_operand_object       **source_desc_ptr,
-	acpi_object_type                target_type,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_store_object_to_object (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *dest_desc,
-	union acpi_operand_object       **new_desc,
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * excopy - object copy
- */
-
-acpi_status
-acpi_ex_store_buffer_to_buffer (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *target_desc);
-
-acpi_status
-acpi_ex_store_string_to_string (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *target_desc);
-
-acpi_status
-acpi_ex_copy_integer_to_index_field (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *target_desc);
-
-acpi_status
-acpi_ex_copy_integer_to_bank_field (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *target_desc);
-
-acpi_status
-acpi_ex_copy_data_to_named_field (
-	union acpi_operand_object       *source_desc,
-	struct acpi_namespace_node      *node);
-
-acpi_status
-acpi_ex_copy_integer_to_buffer_field (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *target_desc);
-
-/*
- * exutils - interpreter/scanner utilities
- */
-
-acpi_status
-acpi_ex_enter_interpreter (
-	void);
-
-void
-acpi_ex_exit_interpreter (
-	void);
-
-void
-acpi_ex_truncate_for32bit_table (
-	union acpi_operand_object       *obj_desc);
-
-u8
-acpi_ex_acquire_global_lock (
-	u32                             rule);
-
-void
-acpi_ex_release_global_lock (
-	u8                              locked);
-
-u32
-acpi_ex_digits_needed (
-	acpi_integer                    value,
-	u32                             base);
-
-void
-acpi_ex_eisa_id_to_string (
-	u32                             numeric_id,
-	char                            *out_string);
-
-void
-acpi_ex_unsigned_integer_to_string (
-	acpi_integer                    value,
-	char                            *out_string);
-
-
-/*
- * exregion - default op_region handlers
- */
-
-acpi_status
-acpi_ex_system_memory_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_system_io_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_pci_config_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_cmos_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_pci_bar_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_embedded_controller_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-acpi_status
-acpi_ex_sm_bus_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-
-acpi_status
-acpi_ex_data_table_space_handler (
-	u32                             function,
-	acpi_physical_address           address,
-	u32                             bit_width,
-	acpi_integer                    *value,
-	void                            *handler_context,
-	void                            *region_context);
-
-#endif /* __INTERP_H__ */
diff -Nru a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h
--- a/drivers/acpi/include/aclocal.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,953 +0,0 @@
-/******************************************************************************
- *
- * Name: aclocal.h - Internal data types used across the ACPI subsystem
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACLOCAL_H__
-#define __ACLOCAL_H__
-
-
-#define ACPI_WAIT_FOREVER               0xFFFF  /* u16, as per ACPI spec */
-
-typedef void *                                  acpi_mutex;
-typedef u32                                     acpi_mutex_handle;
-
-
-/* Total number of aml opcodes defined */
-
-#define AML_NUM_OPCODES                 0x7E
-
-
-/*****************************************************************************
- *
- * Mutex typedefs and structs
- *
- ****************************************************************************/
-
-
-/*
- * Predefined handles for the mutex objects used within the subsystem
- * All mutex objects are automatically created by acpi_ut_mutex_initialize.
- *
- * The acquire/release ordering protocol is implied via this list.  Mutexes
- * with a lower value must be acquired before mutexes with a higher value.
- *
- * NOTE: any changes here must be reflected in the acpi_gbl_mutex_names table also!
- */
-
-#define ACPI_MTX_EXECUTE                0
-#define ACPI_MTX_INTERPRETER            1
-#define ACPI_MTX_PARSER                 2
-#define ACPI_MTX_DISPATCHER             3
-#define ACPI_MTX_TABLES                 4
-#define ACPI_MTX_OP_REGIONS             5
-#define ACPI_MTX_NAMESPACE              6
-#define ACPI_MTX_EVENTS                 7
-#define ACPI_MTX_HARDWARE               8
-#define ACPI_MTX_CACHES                 9
-#define ACPI_MTX_MEMORY                 10
-#define ACPI_MTX_DEBUG_CMD_COMPLETE     11
-#define ACPI_MTX_DEBUG_CMD_READY        12
-
-#define MAX_MTX                         12
-#define NUM_MTX                         MAX_MTX+1
-
-
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-#ifdef DEFINE_ACPI_GLOBALS
-
-/* Names for the mutexes used in the subsystem */
-
-static char                         *acpi_gbl_mutex_names[] =
-{
-	"ACPI_MTX_Execute",
-	"ACPI_MTX_Interpreter",
-	"ACPI_MTX_Parser",
-	"ACPI_MTX_Dispatcher",
-	"ACPI_MTX_Tables",
-	"ACPI_MTX_op_regions",
-	"ACPI_MTX_Namespace",
-	"ACPI_MTX_Events",
-	"ACPI_MTX_Hardware",
-	"ACPI_MTX_Caches",
-	"ACPI_MTX_Memory",
-	"ACPI_MTX_debug_cmd_complete",
-	"ACPI_MTX_debug_cmd_ready",
-};
-
-#endif
-#endif
-
-
-/* Table for the global mutexes */
-
-struct acpi_mutex_info
-{
-	acpi_mutex                          mutex;
-	u32                                 use_count;
-	u32                                 owner_id;
-};
-
-/* This owner ID means that the mutex is not in use (unlocked) */
-
-#define ACPI_MUTEX_NOT_ACQUIRED         (u32) (-1)
-
-
-/* Lock flag parameter for various interfaces */
-
-#define ACPI_MTX_DO_NOT_LOCK            0
-#define ACPI_MTX_LOCK                   1
-
-
-typedef u16                                     acpi_owner_id;
-#define ACPI_OWNER_TYPE_TABLE           0x0
-#define ACPI_OWNER_TYPE_METHOD          0x1
-#define ACPI_FIRST_METHOD_ID            0x0000
-#define ACPI_FIRST_TABLE_ID             0x8000
-
-/* TBD: [Restructure] get rid of the need for this! */
-
-#define TABLE_ID_DSDT                   (acpi_owner_id) 0x8000
-
-
-/* Field access granularities */
-
-#define ACPI_FIELD_BYTE_GRANULARITY     1
-#define ACPI_FIELD_WORD_GRANULARITY     2
-#define ACPI_FIELD_DWORD_GRANULARITY    4
-#define ACPI_FIELD_QWORD_GRANULARITY    8
-
-/*****************************************************************************
- *
- * Namespace typedefs and structs
- *
- ****************************************************************************/
-
-
-/* Operational modes of the AML interpreter/scanner */
-
-typedef enum
-{
-	ACPI_IMODE_LOAD_PASS1               = 0x01,
-	ACPI_IMODE_LOAD_PASS2               = 0x02,
-	ACPI_IMODE_EXECUTE                  = 0x0E
-
-} acpi_interpreter_mode;
-
-
-/*
- * The Node describes a named object that appears in the AML
- * An acpi_node is used to store Nodes.
- *
- * data_type is used to differentiate between internal descriptors, and MUST
- * be the first byte in this structure.
- */
-
-union acpi_name_union
-{
-	u32                                 integer;
-	char                                ascii[4];
-};
-
-struct acpi_namespace_node
-{
-	u8                                  descriptor;     /* Used to differentiate object descriptor types */
-	u8                                  type;           /* Type associated with this name */
-	u16                                 owner_id;
-	union acpi_name_union               name;           /* ACPI Name, always 4 chars per ACPI spec */
-
-
-	union acpi_operand_object           *object;        /* Pointer to attached ACPI object (optional) */
-	struct acpi_namespace_node          *child;         /* first child */
-	struct acpi_namespace_node          *peer;          /* Next peer*/
-	u16                                 reference_count; /* Current count of references and children */
-	u8                                  flags;
-};
-
-
-#define ACPI_ENTRY_NOT_FOUND            NULL
-
-
-/* Node flags */
-
-#define ANOBJ_RESERVED                  0x01
-#define ANOBJ_END_OF_PEER_LIST          0x02
-#define ANOBJ_DATA_WIDTH_32             0x04     /* Parent table is 64-bits */
-#define ANOBJ_METHOD_ARG                0x08
-#define ANOBJ_METHOD_LOCAL              0x10
-#define ANOBJ_METHOD_NO_RETVAL          0x20
-#define ANOBJ_METHOD_SOME_NO_RETVAL     0x40
-
-#define ANOBJ_IS_BIT_OFFSET             0x80
-
-
-/*
- * ACPI Table Descriptor.  One per ACPI table
- */
-struct acpi_table_desc
-{
-	struct acpi_table_desc          *prev;
-	struct acpi_table_desc          *next;
-	struct acpi_table_desc          *installed_desc;
-	struct acpi_table_header        *pointer;
-	u8                              *aml_start;
-	u64                             physical_address;
-	u32                             aml_length;
-	acpi_size                       length;
-	u32                             count;
-	acpi_owner_id                   table_id;
-	u8                              type;
-	u8                              allocation;
-	u8                              loaded_into_namespace;
-};
-
-
-struct acpi_find_context
-{
-	char                            *search_for;
-	acpi_handle                     *list;
-	u32                             *count;
-};
-
-
-struct acpi_ns_search_data
-{
-	struct acpi_namespace_node      *node;
-};
-
-
-/*
- * Predefined Namespace items
- */
-struct acpi_predefined_names
-{
-	char                            *name;
-	u8                              type;
-	char                            *val;
-};
-
-
-/* Object types used during package copies */
-
-
-#define ACPI_COPY_TYPE_SIMPLE           0
-#define ACPI_COPY_TYPE_PACKAGE          1
-
-/* Info structure used to convert external<->internal namestrings */
-
-struct acpi_namestring_info
-{
-	char                            *external_name;
-	char                            *next_external_char;
-	char                            *internal_name;
-	u32                             length;
-	u32                             num_segments;
-	u32                             num_carats;
-	u8                              fully_qualified;
-};
-
-
-/* Field creation info */
-
-struct acpi_create_field_info
-{
-	struct acpi_namespace_node      *region_node;
-	struct acpi_namespace_node      *field_node;
-	struct acpi_namespace_node      *register_node;
-	struct acpi_namespace_node      *data_register_node;
-	u32                             bank_value;
-	u32                             field_bit_position;
-	u32                             field_bit_length;
-	u8                              field_flags;
-	u8                              attribute;
-	u8                              field_type;
-};
-
-
-/*****************************************************************************
- *
- * Event typedefs and structs
- *
- ****************************************************************************/
-
-/* Information about each GPE register block */
-
-struct acpi_gpe_block_info
-{
-	struct acpi_generic_address     *block_address;
-	u16                             register_count;
-	u8                              block_base_number;
-};
-
-/* Information about a particular GPE register pair */
-
-struct acpi_gpe_register_info
-{
-	struct acpi_generic_address     status_address; /* Address of status reg */
-	struct acpi_generic_address     enable_address; /* Address of enable reg */
-	u8                              status;         /* Current value of status reg */
-	u8                              enable;         /* Current value of enable reg */
-	u8                              wake_enable;    /* Mask of bits to keep enabled when sleeping */
-	u8                              base_gpe_number; /* Base GPE number for this register */
-};
-
-
-#define ACPI_GPE_LEVEL_TRIGGERED        1
-#define ACPI_GPE_EDGE_TRIGGERED         2
-
-
-/* Information about each particular GPE level */
-
-struct acpi_gpe_number_info
-{
-	struct acpi_namespace_node      *method_node;   /* Method node for this GPE level */
-	acpi_gpe_handler                handler;        /* Address of handler, if any */
-	void                            *context;       /* Context to be passed to handler */
-	u8                              type;           /* Level or Edge */
-	u8                              bit_mask;
-};
-
-
-struct acpi_gpe_index_info
-{
-	u8                              number_index;
-};
-
-/* Information about each particular fixed event */
-
-struct acpi_fixed_event_handler
-{
-	acpi_event_handler              handler;        /* Address of handler. */
-	void                            *context;       /* Context to be passed to handler */
-};
-
-
-struct acpi_fixed_event_info
-{
-	u8                              status_register_id;
-	u8                              enable_register_id;
-	u16                             status_bit_mask;
-	u16                             enable_bit_mask;
-};
-
-/* Information used during field processing */
-
-struct acpi_field_info
-{
-	u8                              skip_field;
-	u8                              field_flag;
-	u32                             pkg_length;
-};
-
-
-/*****************************************************************************
- *
- * Generic "state" object for stacks
- *
- ****************************************************************************/
-
-
-#define ACPI_CONTROL_NORMAL                  0xC0
-#define ACPI_CONTROL_CONDITIONAL_EXECUTING   0xC1
-#define ACPI_CONTROL_PREDICATE_EXECUTING     0xC2
-#define ACPI_CONTROL_PREDICATE_FALSE         0xC3
-#define ACPI_CONTROL_PREDICATE_TRUE          0xC4
-
-
-/* Forward declarations */
-struct acpi_walk_state        ;
-struct acpi_obj_mutex;
-union acpi_parse_object        ;
-
-
-#define ACPI_STATE_COMMON                  /* Two 32-bit fields and a pointer */\
-	u8                                  data_type;          /* To differentiate various internal objs */\
-	u8                                  flags;      \
-	u16                                 value;      \
-	u16                                 state;      \
-	u16                                 reserved;   \
-	void                                *next;      \
-
-struct acpi_common_state
-{
-	ACPI_STATE_COMMON
-};
-
-
-/*
- * Update state - used to traverse complex objects such as packages
- */
-struct acpi_update_state
-{
-	ACPI_STATE_COMMON
-	union acpi_operand_object           *object;
-};
-
-
-/*
- * Pkg state - used to traverse nested package structures
- */
-struct acpi_pkg_state
-{
-	ACPI_STATE_COMMON
-	union acpi_operand_object           *source_object;
-	union acpi_operand_object           *dest_object;
-	struct acpi_walk_state              *walk_state;
-	void                                *this_target_obj;
-	u32                                 num_packages;
-	u16                                 index;
-};
-
-
-/*
- * Control state - one per if/else and while constructs.
- * Allows nesting of these constructs
- */
-struct acpi_control_state
-{
-	ACPI_STATE_COMMON
-	union acpi_parse_object             *predicate_op;
-	u8                                  *aml_predicate_start;   /* Start of if/while predicate */
-	u8                                  *package_end;           /* End of if/while block */
-	u16                                 opcode;
-};
-
-
-/*
- * Scope state - current scope during namespace lookups
- */
-struct acpi_scope_state
-{
-	ACPI_STATE_COMMON
-	struct acpi_namespace_node          *node;
-};
-
-
-struct acpi_pscope_state
-{
-	ACPI_STATE_COMMON
-	union acpi_parse_object             *op;                    /* current op being parsed */
-	u8                                  *arg_end;               /* current argument end */
-	u8                                  *pkg_end;               /* current package end */
-	u32                                 arg_list;               /* next argument to parse */
-	u32                                 arg_count;              /* Number of fixed arguments */
-};
-
-
-/*
- * Thread state - one per thread across multiple walk states.  Multiple walk
- * states are created when there are nested control methods executing.
- */
-struct acpi_thread_state
-{
-	ACPI_STATE_COMMON
-	struct acpi_walk_state              *walk_state_list;       /* Head of list of walk_states for this thread */
-	union acpi_operand_object           *acquired_mutex_list;   /* List of all currently acquired mutexes */
-	u32                                 thread_id;              /* Running thread ID */
-	u16                                 current_sync_level;     /* Mutex Sync (nested acquire) level */
-};
-
-
-/*
- * Result values - used to accumulate the results of nested
- * AML arguments
- */
-struct acpi_result_values
-{
-	ACPI_STATE_COMMON
-	union acpi_operand_object           *obj_desc [ACPI_OBJ_NUM_OPERANDS];
-	u8                                  num_results;
-	u8                                  last_insert;
-};
-
-
-typedef
-acpi_status (*acpi_parse_downwards) (
-	struct acpi_walk_state              *walk_state,
-	union acpi_parse_object             **out_op);
-
-typedef
-acpi_status (*acpi_parse_upwards) (
-	struct acpi_walk_state              *walk_state);
-
-
-/*
- * Notify info - used to pass info to the deferred notify
- * handler/dispatcher.
- */
-struct acpi_notify_info
-{
-	ACPI_STATE_COMMON
-	struct acpi_namespace_node          *node;
-	union acpi_operand_object           *handler_obj;
-};
-
-
-/* Generic state is union of structs above */
-
-union acpi_generic_state
-{
-	struct acpi_common_state            common;
-	struct acpi_control_state           control;
-	struct acpi_update_state            update;
-	struct acpi_scope_state             scope;
-	struct acpi_pscope_state            parse_scope;
-	struct acpi_pkg_state               pkg;
-	struct acpi_thread_state            thread;
-	struct acpi_result_values           results;
-	struct acpi_notify_info             notify;
-};
-
-
-/*****************************************************************************
- *
- * Interpreter typedefs and structs
- *
- ****************************************************************************/
-
-typedef
-acpi_status (*ACPI_EXECUTE_OP) (
-	struct acpi_walk_state              *walk_state);
-
-
-/*****************************************************************************
- *
- * Parser typedefs and structs
- *
- ****************************************************************************/
-
-/*
- * AML opcode, name, and argument layout
- */
-struct acpi_opcode_info
-{
-#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT)
-	char                                *name;          /* Opcode name (disassembler/debug only) */
-#endif
-	u32                                 parse_args;     /* Grammar/Parse time arguments */
-	u32                                 runtime_args;   /* Interpret time arguments */
-	u32                                 flags;          /* Misc flags */
-	u8                                  object_type;    /* Corresponding internal object type */
-	u8                                  class;          /* Opcode class */
-	u8                                  type;           /* Opcode type */
-};
-
-
-union acpi_parse_value
-{
-	acpi_integer                        integer;        /* integer constant (Up to 64 bits) */
-	struct uint64_struct                integer64;      /* Structure overlay for 2 32-bit Dwords */
-	u32                                 integer32;      /* integer constant, 32 bits only */
-	u16                                 integer16;      /* integer constant, 16 bits only */
-	u8                                  integer8;       /* integer constant, 8 bits only */
-	u32                                 size;           /* bytelist or field size */
-	char                                *string;        /* NULL terminated string */
-	u8                                  *buffer;        /* buffer or string */
-	char                                *name;          /* NULL terminated string */
-	union acpi_parse_object             *arg;           /* arguments and contained ops */
-};
-
-
-#define ACPI_PARSE_COMMON \
-	u8                                  data_type;      /* To differentiate various internal objs */\
-	u8                                  flags;          /* Type of Op */\
-	u16                                 aml_opcode;     /* AML opcode */\
-	u32                                 aml_offset;     /* offset of declaration in AML */\
-	union acpi_parse_object             *parent;        /* parent op */\
-	union acpi_parse_object             *next;          /* next op */\
-	ACPI_DISASM_ONLY_MEMBERS (\
-	u8                                  disasm_flags;   /* Used during AML disassembly */\
-	u8                                  disasm_opcode;  /* Subtype used for disassembly */\
-	char                                aml_op_name[16]) /* op name (debug only) */\
-			   /* NON-DEBUG members below: */\
-	struct acpi_namespace_node          *node;          /* for use by interpreter */\
-	union acpi_parse_value              value;          /* Value or args associated with the opcode */\
-
-
-#define ACPI_DASM_BUFFER        0x00
-#define ACPI_DASM_RESOURCE      0x01
-#define ACPI_DASM_STRING        0x02
-#define ACPI_DASM_UNICODE       0x03
-#define ACPI_DASM_EISAID        0x04
-#define ACPI_DASM_MATCHOP       0x05
-
-/*
- * generic operation (for example:  If, While, Store)
- */
-struct acpi_parse_obj_common
-{
-	ACPI_PARSE_COMMON
-};
-
-
-/*
- * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and op_regions),
- * and bytelists.
- */
-struct acpi_parse_obj_named
-{
-	ACPI_PARSE_COMMON
-	u8                                  *path;
-	u8                                  *data;          /* AML body or bytelist data */
-	u32                                 length;         /* AML length */
-	u32                                 name;           /* 4-byte name or zero if no name */
-};
-
-
-/* The parse node is the fundamental element of the parse tree */
-
-struct acpi_parse_obj_asl
-{
-	ACPI_PARSE_COMMON
-	union acpi_parse_object             *child;
-	union acpi_parse_object             *parent_method;
-	char                                *filename;
-	char                                *external_name;
-	char                                *namepath;
-	char                                name_seg[4];
-	u32                                 extra_value;
-	u32                                 column;
-	u32                                 line_number;
-	u32                                 logical_line_number;
-	u32                                 logical_byte_offset;
-	u32                                 end_line;
-	u32                                 end_logical_line;
-	u32                                 acpi_btype;
-	u32                                 aml_length;
-	u32                                 aml_subtree_length;
-	u32                                 final_aml_length;
-	u32                                 final_aml_offset;
-	u32                                 compile_flags;
-	u16                                 parse_opcode;
-	u8                                  aml_opcode_length;
-	u8                                  aml_pkg_len_bytes;
-	u8                                  extra;
-	char                                parse_op_name[12];
-};
-
-
-union acpi_parse_object
-{
-	struct acpi_parse_obj_common        common;
-	struct acpi_parse_obj_named         named;
-	struct acpi_parse_obj_asl           asl;
-};
-
-
-/*
- * Parse state - one state per parser invocation and each control
- * method.
- */
-struct acpi_parse_state
-{
-	u32                                 aml_size;
-	u8                                  *aml_start;     /* first AML byte */
-	u8                                  *aml;           /* next AML byte */
-	u8                                  *aml_end;       /* (last + 1) AML byte */
-	u8                                  *pkg_start;     /* current package begin */
-	u8                                  *pkg_end;       /* current package end */
-	union acpi_parse_object             *start_op;      /* root of parse tree */
-	struct acpi_namespace_node          *start_node;
-	union acpi_generic_state            *scope;         /* current scope */
-	union acpi_parse_object             *start_scope;
-};
-
-
-/* Parse object flags */
-
-#define ACPI_PARSEOP_GENERIC                    0x01
-#define ACPI_PARSEOP_NAMED                      0x02
-#define ACPI_PARSEOP_DEFERRED                   0x04
-#define ACPI_PARSEOP_BYTELIST                   0x08
-#define ACPI_PARSEOP_IN_CACHE                   0x80
-
-/* Parse object disasm_flags */
-
-#define ACPI_PARSEOP_IGNORE                     0x01
-#define ACPI_PARSEOP_PARAMLIST                  0x02
-#define ACPI_PARSEOP_EMPTY_TERMLIST             0x04
-#define ACPI_PARSEOP_SPECIAL                    0x10
-
-
-/*****************************************************************************
- *
- * Hardware (ACPI registers) and PNP
- *
- ****************************************************************************/
-
-#define PCI_ROOT_HID_STRING         "PNP0A03"
-
-struct acpi_bit_register_info
-{
-	u8                                  parent_register;
-	u8                                  bit_position;
-	u16                                 access_bit_mask;
-};
-
-
-/*
- * Register IDs
- * These are the full ACPI registers
- */
-#define ACPI_REGISTER_PM1_STATUS                0x01
-#define ACPI_REGISTER_PM1_ENABLE                0x02
-#define ACPI_REGISTER_PM1_CONTROL               0x03
-#define ACPI_REGISTER_PM1A_CONTROL              0x04
-#define ACPI_REGISTER_PM1B_CONTROL              0x05
-#define ACPI_REGISTER_PM2_CONTROL               0x06
-#define ACPI_REGISTER_PM_TIMER                  0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
-
-
-/* Masks used to access the bit_registers */
-
-#define ACPI_BITMASK_TIMER_STATUS               0x0001
-#define ACPI_BITMASK_BUS_MASTER_STATUS          0x0010
-#define ACPI_BITMASK_GLOBAL_LOCK_STATUS         0x0020
-#define ACPI_BITMASK_POWER_BUTTON_STATUS        0x0100
-#define ACPI_BITMASK_SLEEP_BUTTON_STATUS        0x0200
-#define ACPI_BITMASK_RT_CLOCK_STATUS            0x0400
-#define ACPI_BITMASK_WAKE_STATUS                0x8000
-
-#define ACPI_BITMASK_ALL_FIXED_STATUS           (ACPI_BITMASK_TIMER_STATUS          | \
-			 ACPI_BITMASK_BUS_MASTER_STATUS     | \
-			 ACPI_BITMASK_GLOBAL_LOCK_STATUS    | \
-			 ACPI_BITMASK_POWER_BUTTON_STATUS   | \
-			 ACPI_BITMASK_SLEEP_BUTTON_STATUS   | \
-			 ACPI_BITMASK_RT_CLOCK_STATUS       | \
-			 ACPI_BITMASK_WAKE_STATUS)
-
-#define ACPI_BITMASK_TIMER_ENABLE               0x0001
-#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE         0x0020
-#define ACPI_BITMASK_POWER_BUTTON_ENABLE        0x0100
-#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE        0x0200
-#define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
-
-#define ACPI_BITMASK_SCI_ENABLE                 0x0001
-#define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
-#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X               0x1C00
-#define ACPI_BITMASK_SLEEP_ENABLE               0x2000
-
-#define ACPI_BITMASK_ARB_DISABLE                0x0001
-
-
-/* Raw bit position of each bit_register */
-
-#define ACPI_BITPOSITION_TIMER_STATUS           0x00
-#define ACPI_BITPOSITION_BUS_MASTER_STATUS      0x04
-#define ACPI_BITPOSITION_GLOBAL_LOCK_STATUS     0x05
-#define ACPI_BITPOSITION_POWER_BUTTON_STATUS    0x08
-#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS    0x09
-#define ACPI_BITPOSITION_RT_CLOCK_STATUS        0x0A
-#define ACPI_BITPOSITION_WAKE_STATUS            0x0F
-
-#define ACPI_BITPOSITION_TIMER_ENABLE           0x00
-#define ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE     0x05
-#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE    0x08
-#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE    0x09
-#define ACPI_BITPOSITION_RT_CLOCK_ENABLE        0x0A
-
-#define ACPI_BITPOSITION_SCI_ENABLE             0x00
-#define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
-#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE    0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X           0x0A
-#define ACPI_BITPOSITION_SLEEP_ENABLE           0x0D
-
-#define ACPI_BITPOSITION_ARB_DISABLE            0x00
-
-
-/*****************************************************************************
- *
- * Resource descriptors
- *
- ****************************************************************************/
-
-
-/* resource_type values */
-
-#define ACPI_RESOURCE_TYPE_MEMORY_RANGE         0
-#define ACPI_RESOURCE_TYPE_IO_RANGE             1
-#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE     2
-
-/* Resource descriptor types and masks */
-
-#define ACPI_RDESC_TYPE_LARGE                   0x80
-#define ACPI_RDESC_TYPE_SMALL                   0x00
-
-#define ACPI_RDESC_TYPE_MASK                    0x80
-#define ACPI_RDESC_SMALL_MASK                   0x78 /* Only bits 6:3 contain the type */
-
-
-/*
- * Small resource descriptor types
- * Note: The 3 length bits (2:0) must be zero
- */
-#define ACPI_RDESC_TYPE_IRQ_FORMAT              0x20
-#define ACPI_RDESC_TYPE_DMA_FORMAT              0x28
-#define ACPI_RDESC_TYPE_START_DEPENDENT         0x30
-#define ACPI_RDESC_TYPE_END_DEPENDENT           0x38
-#define ACPI_RDESC_TYPE_IO_PORT                 0x40
-#define ACPI_RDESC_TYPE_FIXED_IO_PORT           0x48
-#define ACPI_RDESC_TYPE_SMALL_VENDOR            0x70
-#define ACPI_RDESC_TYPE_END_TAG                 0x78
-
-/*
- * Large resource descriptor types
- */
-
-#define ACPI_RDESC_TYPE_MEMORY_24               0x81
-#define ACPI_RDESC_TYPE_GENERAL_REGISTER        0x82
-#define ACPI_RDESC_TYPE_LARGE_VENDOR            0x84
-#define ACPI_RDESC_TYPE_MEMORY_32               0x85
-#define ACPI_RDESC_TYPE_FIXED_MEMORY_32         0x86
-#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE     0x87
-#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE      0x88
-#define ACPI_RDESC_TYPE_EXTENDED_XRUPT          0x89
-#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
-
-
-/* String version of device HIDs and UIDs */
-
-#define ACPI_DEVICE_ID_LENGTH                   0x09
-
-struct acpi_device_id
-{
-	char                    buffer[ACPI_DEVICE_ID_LENGTH];
-};
-
-
-/*****************************************************************************
- *
- * Miscellaneous
- *
- ****************************************************************************/
-
-#define ACPI_ASCII_ZERO                      0x30
-
-
-/*****************************************************************************
- *
- * Debugger
- *
- ****************************************************************************/
-
-struct acpi_db_method_info
-{
-	acpi_handle                     thread_gate;
-	char                            *name;
-	char                            **args;
-	u32                             flags;
-	u32                             num_loops;
-	char                            pathname[128];
-};
-
-struct acpi_integrity_info
-{
-	u32                         nodes;
-	u32                         objects;
-};
-
-
-#define ACPI_DB_REDIRECTABLE_OUTPUT  0x01
-#define ACPI_DB_CONSOLE_OUTPUT       0x02
-#define ACPI_DB_DUPLICATE_OUTPUT     0x03
-
-
-/*****************************************************************************
- *
- * Debug
- *
- ****************************************************************************/
-
-struct acpi_debug_print_info
-{
-	u32                             component_id;
-	char                            *proc_name;
-	char                            *module_name;
-};
-
-
-/* Entry for a memory allocation (debug only) */
-
-#define ACPI_MEM_MALLOC                      0
-#define ACPI_MEM_CALLOC                      1
-#define ACPI_MAX_MODULE_NAME                 16
-
-#define ACPI_COMMON_DEBUG_MEM_HEADER \
-	struct acpi_debug_mem_block         *previous; \
-	struct acpi_debug_mem_block         *next; \
-	u32                                 size; \
-	u32                                 component; \
-	u32                                 line; \
-	char                                module[ACPI_MAX_MODULE_NAME]; \
-	u8                                  alloc_type;
-
-struct acpi_debug_mem_header
-{
-	ACPI_COMMON_DEBUG_MEM_HEADER
-};
-
-struct acpi_debug_mem_block
-{
-	ACPI_COMMON_DEBUG_MEM_HEADER
-	u64                                 user_space;
-};
-
-
-#define ACPI_MEM_LIST_GLOBAL            0
-#define ACPI_MEM_LIST_NSNODE            1
-
-#define ACPI_MEM_LIST_FIRST_CACHE_LIST  2
-#define ACPI_MEM_LIST_STATE             2
-#define ACPI_MEM_LIST_PSNODE            3
-#define ACPI_MEM_LIST_PSNODE_EXT        4
-#define ACPI_MEM_LIST_OPERAND           5
-#define ACPI_MEM_LIST_WALK              6
-#define ACPI_MEM_LIST_MAX               6
-#define ACPI_NUM_MEM_LISTS              7
-
-
-struct acpi_memory_list
-{
-	void                                *list_head;
-	u16                                 link_offset;
-	u16                                 max_cache_depth;
-	u16                                 cache_depth;
-	u16                                 object_size;
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
-	/* Statistics for debug memory tracking only */
-
-	u32                                 total_allocated;
-	u32                                 total_freed;
-	u32                                 current_total_size;
-	u32                                 cache_requests;
-	u32                                 cache_hits;
-	char                                *list_name;
-#endif
-};
-
-
-#endif /* __ACLOCAL_H__ */
diff -Nru a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h
--- a/drivers/acpi/include/acmacros.h	Mon Feb 10 10:39:27 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,578 +0,0 @@
-/******************************************************************************
- *
- * Name: acmacros.h - C macros for the entire subsystem.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACMACROS_H__
-#define __ACMACROS_H__
-
-
-/*
- * Data manipulation macros
- */
-
-#define ACPI_LOWORD(l)                  ((u16)(u32)(l))
-#define ACPI_HIWORD(l)                  ((u16)((((u32)(l)) >> 16) & 0xFFFF))
-#define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
-#define ACPI_HIBYTE(l)                  ((u8)((((u16)(l)) >> 8) & 0xFF))
-
-
-#if ACPI_MACHINE_WIDTH == 16
-
-/*
- * For 16-bit addresses, we have to assume that the upper 32 bits
- * are zero.
- */
-#define ACPI_LODWORD(l)                 ((u32)(l))
-#define ACPI_HIDWORD(l)                 ((u32)(0))
-
-#define ACPI_GET_ADDRESS(a)             ((a).lo)
-#define ACPI_STORE_ADDRESS(a,b)         {(a).hi=0;(a).lo=(u32)(b);}
-#define ACPI_VALID_ADDRESS(a)           ((a).hi | (a).lo)
-
-#else
-#ifdef ACPI_NO_INTEGER64_SUPPORT
-/*
- * acpi_integer is 32-bits, no 64-bit support on this platform
- */
-#define ACPI_LODWORD(l)                 ((u32)(l))
-#define ACPI_HIDWORD(l)                 ((u32)(0))
-
-#define ACPI_GET_ADDRESS(a)             (a)
-#define ACPI_STORE_ADDRESS(a,b)         ((a)=(b))
-#define ACPI_VALID_ADDRESS(a)           (a)
-
-#else
-
-/*
- * Full 64-bit address/integer on both 32-bit and 64-bit platforms
- */
-#define ACPI_LODWORD(l)                 ((u32)(u64)(l))
-#define ACPI_HIDWORD(l)                 ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi))
-
-#define ACPI_GET_ADDRESS(a)             (a)
-#define ACPI_STORE_ADDRESS(a,b)         ((a)=(acpi_physical_address)(b))
-#define ACPI_VALID_ADDRESS(a)           (a)
-#endif
-#endif
-
- /*
-  * Extract a byte of data using a pointer.  Any more than a byte and we
-  * get into potential aligment issues -- see the STORE macros below
-  */
-#define ACPI_GET8(addr)                 (*(u8*)(addr))
-
-/* Pointer arithmetic */
-
-#define ACPI_PTR_ADD(t,a,b)             (t *) (void *)((char *)(a) + (acpi_native_uint)(b))
-#define ACPI_PTR_DIFF(a,b)              (acpi_native_uint) ((char *)(a) - (char *)(b))
-
-/* Pointer/Integer type conversions */
-
-#define ACPI_TO_POINTER(i)              ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i)
-#define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p,(void *) NULL)
-#define ACPI_OFFSET(d,f)                (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
-#define ACPI_FADT_OFFSET(f)             ACPI_OFFSET (FADT_DESCRIPTOR, f)
-
-#define ACPI_CAST_PTR(t, p)             ((t *)(void *)(p))
-#define ACPI_CAST_INDIRECT_PTR(t, p)    ((t **)(void *)(p))
-
-#if ACPI_MACHINE_WIDTH == 16
-#define ACPI_STORE_POINTER(d,s)         ACPI_MOVE_UNALIGNED32_TO_32(d,s)
-#define ACPI_PHYSADDR_TO_PTR(i)         (void *)(i)
-#define ACPI_PTR_TO_PHYSADDR(i)         (u32) (char *)(i)
-#else
-#define ACPI_PHYSADDR_TO_PTR(i)         ACPI_TO_POINTER(i)
-#define ACPI_PTR_TO_PHYSADDR(i)         ACPI_TO_INTEGER(i)
-#endif
-
-/*
- * Macros for moving data around to/from buffers that are possibly unaligned.
- * If the hardware supports the transfer of unaligned data, just do the store.
- * Otherwise, we have to move one byte at a time.
- */
-
-#ifdef _HW_ALIGNMENT_SUPPORT
-
-/* The hardware supports unaligned transfers, just do the move */
-
-#define ACPI_MOVE_UNALIGNED16_TO_16(d,s)    *(u16 *)(void *)(d) = *(u16 *)(void *)(s)
-#define ACPI_MOVE_UNALIGNED32_TO_32(d,s)    *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
-#define ACPI_MOVE_UNALIGNED16_TO_32(d,s)    *(u32 *)(void *)(d) = *(u16 *)(void *)(s)
-#define ACPI_MOVE_UNALIGNED64_TO_64(d,s)    *(u64 *)(void *)(d) = *(u64 *)(void *)(s)
-
-#else
-/*
- * The hardware does not support unaligned transfers.  We must move the
- * data one byte at a time.  These macros work whether the source or
- * the destination (or both) is/are unaligned.
- */
-
-#define ACPI_MOVE_UNALIGNED16_TO_16(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
-	  ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];}
-
-#define ACPI_MOVE_UNALIGNED32_TO_32(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
-			   ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
-			   ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
-			   ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];}
-
-#define ACPI_MOVE_UNALIGNED16_TO_32(d,s)    {(*(u32*)(void *)(d)) = 0; ACPI_MOVE_UNALIGNED16_TO_16(d,s);}
-
-#define ACPI_MOVE_UNALIGNED64_TO_64(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
-					 ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
-					 ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
-					 ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\
-					 ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[4];\
-					 ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[5];\
-					 ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[6];\
-					 ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[7];}
-
-#endif
-
-
-/*
- * Fast power-of-two math macros for non-optimized compilers
- */
-
-#define _ACPI_DIV(value,power_of2)      ((u32) ((value) >> (power_of2)))
-#define _ACPI_MUL(value,power_of2)      ((u32) ((value) << (power_of2)))
-#define _ACPI_MOD(value,divisor)        ((u32) ((value) & ((divisor) -1)))
-
-#define ACPI_DIV_2(a)                   _ACPI_DIV(a,1)
-#define ACPI_MUL_2(a)                   _ACPI_MUL(a,1)
-#define ACPI_MOD_2(a)                   _ACPI_MOD(a,2)
-
-#define ACPI_DIV_4(a)                   _ACPI_DIV(a,2)
-#define ACPI_MUL_4(a)                   _ACPI_MUL(a,2)
-#define ACPI_MOD_4(a)                   _ACPI_MOD(a,4)
-
-#define ACPI_DIV_8(a)                   _ACPI_DIV(a,3)
-#define ACPI_MUL_8(a)                   _ACPI_MUL(a,3)
-#define ACPI_MOD_8(a)                   _ACPI_MOD(a,8)
-
-#define ACPI_DIV_16(a)                  _ACPI_DIV(a,4)
-#define ACPI_MUL_16(a)                  _ACPI_MUL(a,4)
-#define ACPI_MOD_16(a)                  _ACPI_MOD(a,16)
-
-
-/*
- * Rounding macros (Power of two boundaries only)
- */
-#define ACPI_ROUND_DOWN(value,boundary)      (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1)))
-#define ACPI_ROUND_UP(value,boundary)        ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1)))
-
-#define ACPI_ROUND_DOWN_TO_32_BITS(a)        ACPI_ROUND_DOWN(a,4)
-#define ACPI_ROUND_DOWN_TO_64_BITS(a)        ACPI_ROUND_DOWN(a,8)
-#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a)    ACPI_ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY)
-
-#define ACPI_ROUND_UP_to_32_bITS(a)          ACPI_ROUND_UP(a,4)
-#define ACPI_ROUND_UP_to_64_bITS(a)          ACPI_ROUND_UP(a,8)
-#define ACPI_ROUND_UP_TO_NATIVE_WORD(a)      ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
-
-
-#define ACPI_ROUND_BITS_UP_TO_BYTES(a)       ACPI_DIV_8((a) + 7)
-#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a)     ACPI_DIV_8((a))
-
-#define ACPI_ROUND_UP_TO_1K(a)               (((a) + 1023) >> 10)
-
-/* Generic (non-power-of-two) rounding */
-
-#define ACPI_ROUND_UP_TO(value,boundary)     (((value) + ((boundary)-1)) / (boundary))
-
-/*
- * Bitmask creation
- * Bit positions start at zero.
- * MASK_BITS_ABOVE creates a mask starting AT the position and above
- * MASK_BITS_BELOW creates a mask starting one bit BELOW the position
- */
-#define ACPI_MASK_BITS_ABOVE(position)       (~((ACPI_INTEGER_MAX) << ((u32) (position))))
-#define ACPI_MASK_BITS_BELOW(position)       ((ACPI_INTEGER_MAX) << ((u32) (position)))
-
-#define ACPI_IS_OCTAL_DIGIT(d)               (((char)(d) >= '0') && ((char)(d) <= '7'))
-
-/* Macros for GAS addressing */
-
-#if ACPI_MACHINE_WIDTH != 16
-
-#define ACPI_PCI_DEVICE_MASK            (u64) 0x0000FFFF00000000
-#define ACPI_PCI_FUNCTION_MASK          (u64) 0x00000000FFFF0000
-#define ACPI_PCI_REGISTER_MASK          (u64) 0x000000000000FFFF
-
-/*
- * Obsolete
- */
-
-/*
-#define ACPI_PCI_FUNCTION(a)            (u16) ((((u64)((u64)(a) & ACPI_PCI_FUNCTION_MASK)) >> 16))
-#define ACPI_PCI_DEVICE(a)              (u16) ((((u64)((u64)(a) & ACPI_PCI_DEVICE_MASK)) >> 32))
-#define ACPI_PCI_REGISTER(a)            (u16) (((u64)((u64)(a) & ACPI_PCI_REGISTER_MASK)))
-*/
-
-
-#define ACPI_PCI_DEVICE(a)              (u16) ((ACPI_HIDWORD ((a))) & 0x0000FFFF)
-#define ACPI_PCI_FUNCTION(a)            (u16) ((ACPI_LODWORD ((a))) >> 16)
-#define ACPI_PCI_REGISTER(a)            (u16) ((ACPI_LODWORD ((a))) & 0x0000FFFF)
-
-#else
-
-/* No support for GAS and PCI IDs in 16-bit mode  */
-
-#define ACPI_PCI_FUNCTION(a)            (u16) ((a) & 0xFFFF0000)
-#define ACPI_PCI_DEVICE(a)              (u16) ((a) & 0x0000FFFF)
-#define ACPI_PCI_REGISTER(a)            (u16) ((a) & 0x0000FFFF)
-
-#endif
-
-
-/* Bitfields within ACPI registers */
-
-#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
-#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val)  reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
-
-/*
- * An struct acpi_namespace_node * can appear in some contexts,
- * where a pointer to an union acpi_operand_object    can also
- * appear.  This macro is used to distinguish them.
- *
- * The "Descriptor" field is the first field in both structures.
- */
-#define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->descriptor_id)
-#define ACPI_SET_DESCRIPTOR_TYPE(d,t)   (((union acpi_descriptor *)(void *)(d))->descriptor_id = t)
-
-
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
-
-/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */
-
-#define ACPI_IS_SINGLE_TABLE(x)         (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0)
-
-/*
- * Macros for the master AML opcode table
- */
-#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
-#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
-#else
-#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
-#endif
-
-#ifdef ACPI_DISASSEMBLER
-#define ACPI_DISASM_ONLY_MEMBERS(a)     a;
-#else
-#define ACPI_DISASM_ONLY_MEMBERS(a)
-#endif
-
-#define ARG_TYPE_WIDTH                  5
-#define ARG_1(x)                        ((u32)(x))
-#define ARG_2(x)                        ((u32)(x) << (1 * ARG_TYPE_WIDTH))
-#define ARG_3(x)                        ((u32)(x) << (2 * ARG_TYPE_WIDTH))
-#define ARG_4(x)                        ((u32)(x) << (3 * ARG_TYPE_WIDTH))
-#define ARG_5(x)                        ((u32)(x) << (4 * ARG_TYPE_WIDTH))
-#define ARG_6(x)                        ((u32)(x) << (5 * ARG_TYPE_WIDTH))
-
-#define ARGI_LIST1(a)                   (ARG_1(a))
-#define ARGI_LIST2(a,b)                 (ARG_1(b)|ARG_2(a))
-#define ARGI_LIST3(a,b,c)               (ARG_1(c)|ARG_2(b)|ARG_3(a))
-#define ARGI_LIST4(a,b,c,d)             (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
-#define ARGI_LIST5(a,b,c,d,e)           (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
-#define ARGI_LIST6(a,b,c,d,e,f)         (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
-
-#define ARGP_LIST1(a)                   (ARG_1(a))
-#define ARGP_LIST2(a,b)                 (ARG_1(a)|ARG_2(b))
-#define ARGP_LIST3(a,b,c)               (ARG_1(a)|ARG_2(b)|ARG_3(c))
-#define ARGP_LIST4(a,b,c,d)             (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
-#define ARGP_LIST5(a,b,c,d,e)           (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
-#define ARGP_LIST6(a,b,c,d,e,f)         (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
-
-#define GET_CURRENT_ARG_TYPE(list)      (list & ((u32) 0x1F))
-#define INCREMENT_ARG_LIST(list)        (list >>= ((u32) ARG_TYPE_WIDTH))
-
-
-/*
- * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
- *
- * 1) Address space
- * 2) Length in bytes -- convert to length in bits
- * 3) Bit offset is zero
- * 4) Reserved field is zero
- * 5) Expand address to 64 bits
- */
-#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   do {a.address_space_id = (u8) d;\
-							  a.register_bit_width = (u8) ACPI_MUL_8 (b);\
-							  a.register_bit_offset = 0;\
-							  a.reserved = 0;\
-							  ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0)
-
-/* ACPI V1.0 entries -- address space is always I/O */
-
-#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO)
-
-
-/*
- * Reporting macros that are never compiled out
- */
-
-#define ACPI_PARAM_LIST(pl)                  pl
-
-/*
- * Error reporting.  These versions add callers module and line#.  Since
- * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only
- * use it in debug mode.
- */
-
-#ifdef ACPI_DEBUG_OUTPUT
-
-#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
-									   acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \
-											 acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e);
-
-#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e);
-
-#else
-
-#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e);
-
-#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e);
-
-#endif
-
-/* Error reporting.  These versions pass thru the module and line# */
-
-#define _ACPI_REPORT_INFO(a,b,c,fp)         {acpi_ut_report_info(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define _ACPI_REPORT_ERROR(a,b,c,fp)        {acpi_ut_report_error(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-#define _ACPI_REPORT_WARNING(a,b,c,fp)      {acpi_ut_report_warning(a,b,c); \
-												acpi_os_printf ACPI_PARAM_LIST(fp);}
-
-/*
- * Debug macros that are conditionally compiled
- */
-
-#ifdef ACPI_DEBUG_OUTPUT
-
-#define ACPI_MODULE_NAME(name)               static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
-
-/*
- * Function entry tracing.
- * The first parameter should be the procedure name as a quoted string.  This is declared
- * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
- */
-
-#define ACPI_FUNCTION_NAME(a)           struct acpi_debug_print_info _dbg;     \
-										_dbg.component_id = _COMPONENT; \
-										_dbg.proc_name   = a;           \
-										_dbg.module_name = _THIS_MODULE;
-
-#define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a)\
-											acpi_ut_trace(__LINE__,&_dbg)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)    ACPI_FUNCTION_NAME(a)\
-											acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b)
-#define ACPI_FUNCTION_TRACE_U32(a,b)    ACPI_FUNCTION_NAME(a)\
-											acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b)
-#define ACPI_FUNCTION_TRACE_STR(a,b)    ACPI_FUNCTION_NAME(a)\
-											acpi_ut_trace_str(__LINE__,&_dbg,(char *)b)
-
-#define ACPI_FUNCTION_ENTRY()           acpi_ut_track_stack_ptr()
-
-/*
- * Function exit tracing.
- * WARNING: These macros include a return statement.  This is usually considered
- * bad form, but having a separate exit macro is very ugly and difficult to maintain.
- * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
- * so that "_proc_name" is defined.
- */
-#ifdef ACPI_USE_DO_WHILE_0
-#define ACPI_DO_WHILE0(a)               do a while(0)
-#else
-#define ACPI_DO_WHILE0(a)               a
-#endif
-
-#define return_VOID                     ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;})
-#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));})
-#define return_VALUE(s)                 ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));})
-#define return_PTR(s)                   ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));})
-
-/* Conditional execution */
-
-#define ACPI_DEBUG_EXEC(a)              a
-#define ACPI_NORMAL_EXEC(a)
-
-#define ACPI_DEBUG_DEFINE(a)            a;
-#define ACPI_DEBUG_ONLY_MEMBERS(a)      a;
-#define _VERBOSE_STRUCTURES
-
-
-/* Stack and buffer dumping */
-
-#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand(a)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e)   acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
-
-
-#define ACPI_DUMP_ENTRY(a,b)            acpi_ns_dump_entry (a,b)
-#define ACPI_DUMP_TABLES(a,b)           acpi_ns_dump_tables(a,b)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
-#define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
-#define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
-#define ACPI_BREAK_MSG(a)               acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a))
-
-
-/*
- * Generate INT3 on ACPI_ERROR (Debug only!)
- */
-
-#define ACPI_ERROR_BREAK
-#ifdef  ACPI_ERROR_BREAK
-#define ACPI_BREAK_ON_ERROR(lvl)        if ((lvl)&ACPI_ERROR) \
-											acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n")
-#else
-#define ACPI_BREAK_ON_ERROR(lvl)
-#endif
-
-/*
- * Master debug print macros
- * Print iff:
- *    1) Debug print for the current component is enabled
- *    2) Debug error level or trace level for the print statement is enabled
- */
-
-#define ACPI_DEBUG_PRINT(pl)            acpi_ut_debug_print ACPI_PARAM_LIST(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)        acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
-
-
-#else
-/*
- * This is the non-debug case -- make everything go away,
- * leaving no executable debug code!
- */
-
-#define ACPI_MODULE_NAME(name)
-#define _THIS_MODULE ""
-
-#define ACPI_DEBUG_EXEC(a)
-#define ACPI_NORMAL_EXEC(a)             a;
-
-#define ACPI_DEBUG_DEFINE(a)
-#define ACPI_DEBUG_ONLY_MEMBERS(a)
-#define ACPI_FUNCTION_NAME(a)
-#define ACPI_FUNCTION_TRACE(a)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)
-#define ACPI_FUNCTION_TRACE_U32(a,b)
-#define ACPI_FUNCTION_TRACE_STR(a,b)
-#define ACPI_FUNCTION_EXIT
-#define ACPI_FUNCTION_STATUS_EXIT(s)
-#define ACPI_FUNCTION_VALUE_EXIT(s)
-#define ACPI_FUNCTION_ENTRY()
-#define ACPI_DUMP_STACK_ENTRY(a)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e)
-#define ACPI_DUMP_ENTRY(a,b)
-#define ACPI_DUMP_TABLES(a,b)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)
-#define ACPI_DUMP_RESOURCE_LIST(a)
-#define ACPI_DUMP_BUFFER(a,b)
-#define ACPI_DEBUG_PRINT(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)
-#define ACPI_BREAK_MSG(a)
-
-#define return_VOID                     return
-#define return_ACPI_STATUS(s)           return(s)
-#define return_VALUE(s)                 return(s)
-#define return_PTR(s)                   return(s)
-
-#endif
-
-/*
- * Some code only gets executed when the debugger is built in.
- * Note that this is entirely independent of whether the
- * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
- */
-#ifdef ACPI_DEBUGGER
-#define ACPI_DEBUGGER_EXEC(a)           a
-#else
-#define ACPI_DEBUGGER_EXEC(a)
-#endif
-
-
-/*
- * For 16-bit code, we want to shrink some things even though
- * we are using ACPI_DEBUG_OUTPUT to get the debug output
- */
-#if ACPI_MACHINE_WIDTH == 16
-#undef ACPI_DEBUG_ONLY_MEMBERS
-#undef _VERBOSE_STRUCTURES
-#define ACPI_DEBUG_ONLY_MEMBERS(a)
-#endif
-
-
-#ifdef ACPI_DEBUG_OUTPUT
-/*
- * 1) Set name to blanks
- * 2) Copy the object name
- */
-#define ACPI_ADD_OBJECT_NAME(a,b)       ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\
-										ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name))
-#else
-
-#define ACPI_ADD_OBJECT_NAME(a,b)
-#endif
-
-
-/*
- * Memory allocation tracking (DEBUG ONLY)
- */
-
-#ifndef ACPI_DBG_TRACK_ALLOCATIONS
-
-/* Memory allocation */
-
-#define ACPI_MEM_ALLOCATE(a)            acpi_ut_allocate((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_CALLOCATE(a)           acpi_ut_callocate((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_FREE(a)                acpi_os_free(a)
-#define ACPI_MEM_TRACKING(a)
-
-
-#else
-
-/* Memory allocation */
-
-#define ACPI_MEM_ALLOCATE(a)            acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_CALLOCATE(a)           acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_FREE(a)                acpi_ut_free_and_track(a,_COMPONENT,_THIS_MODULE,__LINE__)
-#define ACPI_MEM_TRACKING(a)            a
-
-#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
-
-
-#define ACPI_GET_STACK_POINTER          _asm {mov eax, ebx}
-
-#endif /* ACMACROS_H */
diff -Nru a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h
--- a/drivers/acpi/include/acnamesp.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,489 +0,0 @@
-/******************************************************************************
- *
- * Name: acnamesp.h - Namespace subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACNAMESP_H__
-#define __ACNAMESP_H__
-
-
-/* To search the entire name space, pass this as search_base */
-
-#define ACPI_NS_ALL                 ((acpi_handle)0)
-
-/*
- * Elements of acpi_ns_properties are bit significant
- * and should be one-to-one with values of acpi_object_type
- */
-#define ACPI_NS_NORMAL              0
-#define ACPI_NS_NEWSCOPE            1   /* a definition of this type opens a name scope */
-#define ACPI_NS_LOCAL               2   /* suppress search of enclosing scopes */
-
-
-/* Definitions of the predefined namespace names  */
-
-#define ACPI_UNKNOWN_NAME           (u32) 0x3F3F3F3F     /* Unknown name is  "????" */
-#define ACPI_ROOT_NAME              (u32) 0x5F5F5F5C     /* Root name is     "\___" */
-#define ACPI_SYS_BUS_NAME           (u32) 0x5F53425F     /* Sys bus name is  "_SB_" */
-
-#define ACPI_NS_ROOT_PATH           "\\"
-#define ACPI_NS_SYSTEM_BUS          "_SB_"
-
-
-/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */
-
-#define ACPI_NS_NO_UPSEARCH         0
-#define ACPI_NS_SEARCH_PARENT       0x01
-#define ACPI_NS_DONT_OPEN_SCOPE     0x02
-#define ACPI_NS_NO_PEER_SEARCH      0x04
-#define ACPI_NS_ERROR_IF_FOUND      0x08
-
-#define ACPI_NS_WALK_UNLOCK         TRUE
-#define ACPI_NS_WALK_NO_UNLOCK      FALSE
-
-
-acpi_status
-acpi_ns_load_namespace (
-	void);
-
-acpi_status
-acpi_ns_initialize_objects (
-	void);
-
-acpi_status
-acpi_ns_initialize_devices (
-	void);
-
-
-/* Namespace init - nsxfinit */
-
-acpi_status
-acpi_ns_init_one_device (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_ns_init_one_object (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-
-acpi_status
-acpi_ns_walk_namespace (
-	acpi_object_type                type,
-	acpi_handle                     start_object,
-	u32                             max_depth,
-	u8                              unlock_before_callback,
-	acpi_walk_callback              user_function,
-	void                            *context,
-	void                            **return_value);
-
-struct acpi_namespace_node *
-acpi_ns_get_next_node (
-	acpi_object_type                type,
-	struct acpi_namespace_node      *parent,
-	struct acpi_namespace_node      *child);
-
-void
-acpi_ns_delete_namespace_by_owner (
-	u16                             table_id);
-
-
-/* Namespace loading - nsload */
-
-acpi_status
-acpi_ns_one_complete_parse (
-	u32                             pass_number,
-	struct acpi_table_desc          *table_desc);
-
-acpi_status
-acpi_ns_parse_table (
-	struct acpi_table_desc          *table_desc,
-	struct acpi_namespace_node      *scope);
-
-acpi_status
-acpi_ns_load_table (
-	struct acpi_table_desc          *table_desc,
-	struct acpi_namespace_node      *node);
-
-acpi_status
-acpi_ns_load_table_by_type (
-	acpi_table_type                 table_type);
-
-
-/*
- * Top-level namespace access - nsaccess
- */
-
-acpi_status
-acpi_ns_root_initialize (
-	void);
-
-acpi_status
-acpi_ns_lookup (
-	union acpi_generic_state        *scope_info,
-	char                            *name,
-	acpi_object_type                type,
-	acpi_interpreter_mode           interpreter_mode,
-	u32                             flags,
-	struct acpi_walk_state          *walk_state,
-	struct acpi_namespace_node      **ret_node);
-
-
-/*
- * Named object allocation/deallocation - nsalloc
- */
-
-struct acpi_namespace_node *
-acpi_ns_create_node (
-	u32                             name);
-
-void
-acpi_ns_delete_node (
-	struct acpi_namespace_node      *node);
-
-void
-acpi_ns_delete_namespace_subtree (
-	struct acpi_namespace_node      *parent_handle);
-
-void
-acpi_ns_detach_object (
-	struct acpi_namespace_node      *node);
-
-void
-acpi_ns_delete_children (
-	struct acpi_namespace_node      *parent);
-
-int
-acpi_ns_compare_names (
-	char                            *name1,
-	char                            *name2);
-
-/*
- * Namespace modification - nsmodify
- */
-
-acpi_status
-acpi_ns_unload_namespace (
-	acpi_handle                     handle);
-
-acpi_status
-acpi_ns_delete_subtree (
-	acpi_handle                     start_handle);
-
-
-/*
- * Namespace dump/print utilities - nsdump
- */
-
-void
-acpi_ns_dump_tables (
-	acpi_handle                     search_base,
-	u32                             max_depth);
-
-void
-acpi_ns_dump_entry (
-	acpi_handle                     handle,
-	u32                             debug_level);
-
-void
-acpi_ns_dump_pathname (
-	acpi_handle                     handle,
-	char                            *msg,
-	u32                             level,
-	u32                             component);
-
-void
-acpi_ns_print_pathname (
-	u32                             num_segments,
-	char                            *pathname);
-
-acpi_status
-acpi_ns_dump_one_device (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-void
-acpi_ns_dump_root_devices (
-	void);
-
-acpi_status
-acpi_ns_dump_one_object (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-void
-acpi_ns_dump_objects (
-	acpi_object_type                type,
-	u8                              display_type,
-	u32                             max_depth,
-	u32                             ownder_id,
-	acpi_handle                     start_handle);
-
-
-/*
- * Namespace evaluation functions - nseval
- */
-
-acpi_status
-acpi_ns_evaluate_by_handle (
-	struct acpi_namespace_node      *prefix_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
-
-acpi_status
-acpi_ns_evaluate_by_name (
-	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
-
-acpi_status
-acpi_ns_evaluate_relative (
-	struct acpi_namespace_node      *prefix_node,
-	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
-
-acpi_status
-acpi_ns_execute_control_method (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
-
-acpi_status
-acpi_ns_get_object_value (
-	struct acpi_namespace_node      *object_node,
-	union acpi_operand_object       **return_obj_desc);
-
-
-/*
- * Parent/Child/Peer utility functions
- */
-
-acpi_name
-acpi_ns_find_parent_name (
-	struct acpi_namespace_node      *node_to_search);
-
-
-/*
- * Name and Scope manipulation - nsnames
- */
-
-u32
-acpi_ns_opens_scope (
-	acpi_object_type                type);
-
-void
-acpi_ns_build_external_path (
-	struct acpi_namespace_node      *node,
-	acpi_size                       size,
-	char                            *name_buffer);
-
-char *
-acpi_ns_get_external_pathname (
-	struct acpi_namespace_node      *node);
-
-char *
-acpi_ns_name_of_current_scope (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ns_handle_to_pathname (
-	acpi_handle                     target_handle,
-	struct acpi_buffer              *buffer);
-
-u8
-acpi_ns_pattern_match (
-	struct acpi_namespace_node      *obj_node,
-	char                            *search_for);
-
-acpi_status
-acpi_ns_get_node_by_path (
-	char                            *external_pathname,
-	struct acpi_namespace_node      *in_prefix_node,
-	u32                             flags,
-	struct acpi_namespace_node      **out_node);
-
-acpi_size
-acpi_ns_get_pathname_length (
-	struct acpi_namespace_node      *node);
-
-
-/*
- * Object management for namespace nodes - nsobject
- */
-
-acpi_status
-acpi_ns_attach_object (
-	struct acpi_namespace_node      *node,
-	union acpi_operand_object       *object,
-	acpi_object_type                type);
-
-union acpi_operand_object *
-acpi_ns_get_attached_object (
-	struct acpi_namespace_node      *node);
-
-union acpi_operand_object *
-acpi_ns_get_secondary_object (
-	union acpi_operand_object       *obj_desc);
-
-acpi_status
-acpi_ns_attach_data (
-	struct acpi_namespace_node      *node,
-	acpi_object_handler             handler,
-	void                            *data);
-
-acpi_status
-acpi_ns_detach_data (
-	struct acpi_namespace_node      *node,
-	acpi_object_handler             handler);
-
-acpi_status
-acpi_ns_get_attached_data (
-	struct acpi_namespace_node      *node,
-	acpi_object_handler             handler,
-	void                            **data);
-
-
-/*
- * Namespace searching and entry - nssearch
- */
-
-acpi_status
-acpi_ns_search_and_enter (
-	u32                             entry_name,
-	struct acpi_walk_state          *walk_state,
-	struct acpi_namespace_node      *node,
-	acpi_interpreter_mode           interpreter_mode,
-	acpi_object_type                type,
-	u32                             flags,
-	struct acpi_namespace_node      **ret_node);
-
-acpi_status
-acpi_ns_search_node (
-	u32                             entry_name,
-	struct acpi_namespace_node      *node,
-	acpi_object_type                type,
-	struct acpi_namespace_node      **ret_node);
-
-void
-acpi_ns_install_node (
-	struct acpi_walk_state          *walk_state,
-	struct acpi_namespace_node      *parent_node,
-	struct acpi_namespace_node      *node,
-	acpi_object_type                type);
-
-
-/*
- * Utility functions - nsutils
- */
-
-u8
-acpi_ns_valid_root_prefix (
-	char                            prefix);
-
-u8
-acpi_ns_valid_path_separator (
-	char                            sep);
-
-acpi_object_type
-acpi_ns_get_type (
-	struct acpi_namespace_node      *node);
-
-u32
-acpi_ns_local (
-	acpi_object_type                type);
-
-void
-acpi_ns_report_error (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id,
-	char                            *internal_name,
-	acpi_status                     lookup_status);
-
-void
-acpi_ns_report_method_error (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id,
-	char                            *message,
-	struct acpi_namespace_node      *node,
-	char                            *path,
-	acpi_status                     lookup_status);
-
-void
-acpi_ns_print_node_pathname (
-	struct acpi_namespace_node      *node,
-	char                            *msg);
-
-acpi_status
-acpi_ns_build_internal_name (
-	struct acpi_namestring_info     *info);
-
-void
-acpi_ns_get_internal_name_length (
-	struct acpi_namestring_info     *info);
-
-acpi_status
-acpi_ns_internalize_name (
-	char                            *dotted_name,
-	char                            **converted_name);
-
-acpi_status
-acpi_ns_externalize_name (
-	u32                             internal_name_length,
-	char                            *internal_name,
-	u32                             *converted_name_length,
-	char                            **converted_name);
-
-struct acpi_namespace_node *
-acpi_ns_map_handle_to_node (
-	acpi_handle                     handle);
-
-acpi_handle
-acpi_ns_convert_entry_to_handle(
-	struct acpi_namespace_node      *node);
-
-void
-acpi_ns_terminate (
-	void);
-
-struct acpi_namespace_node *
-acpi_ns_get_parent_node (
-	struct acpi_namespace_node      *node);
-
-
-struct acpi_namespace_node *
-acpi_ns_get_next_valid_node (
-	struct acpi_namespace_node      *node);
-
-
-#endif /* __ACNAMESP_H__ */
diff -Nru a/drivers/acpi/include/acobject.h b/drivers/acpi/include/acobject.h
--- a/drivers/acpi/include/acobject.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,473 +0,0 @@
-
-/******************************************************************************
- *
- * Name: acobject.h - Definition of union acpi_operand_object    (Internal object only)
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 _ACOBJECT_H
-#define _ACOBJECT_H
-
-
-/*
- * The union acpi_operand_object    is used to pass AML operands from the dispatcher
- * to the interpreter, and to keep track of the various handlers such as
- * address space handlers and notify handlers.  The object is a constant
- * size in order to allow it to be cached and reused.
- */
-
-/*******************************************************************************
- *
- * Common Descriptors
- *
- ******************************************************************************/
-
-/*
- * Common area for all objects.
- *
- * data_type is used to differentiate between internal descriptors, and MUST
- * be the first byte in this structure.
- */
-#define ACPI_OBJECT_COMMON_HEADER   /* SIZE/ALIGNMENT: 32 bits, one ptr plus trailing 8-bit flag */\
-	u8                                      descriptor;         /* To differentiate various internal objs */\
-	u8                                      type;               /* acpi_object_type */\
-	u16                                     reference_count;    /* For object deletion management */\
-	union acpi_operand_object               *next_object;       /* Objects linked to parent NS node */\
-	u8                                      flags; \
-
-/* Values for flag byte above */
-
-#define AOPOBJ_AML_CONSTANT         0x01
-#define AOPOBJ_STATIC_POINTER       0x02
-#define AOPOBJ_DATA_VALID           0x04
-#define AOPOBJ_OBJECT_INITIALIZED   0x08
-#define AOPOBJ_SETUP_COMPLETE       0x10
-#define AOPOBJ_SINGLE_DATUM         0x20
-
-
-/*
- * Common bitfield for the field objects
- * "Field Datum"  -- a datum from the actual field object
- * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field
- */
-#define ACPI_COMMON_FIELD_INFO      /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\
-	u8                                      field_flags;        /* Access, update, and lock bits */\
-	u8                                      attribute;          /* From access_as keyword */\
-	u8                                      access_byte_width;  /* Read/Write size in bytes */\
-	u32                                     bit_length;         /* Length of field in bits */\
-	u32                                     base_byte_offset;   /* Byte offset within containing object */\
-	u8                                      start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
-	u8                                      datum_valid_bits;   /* Valid bit in first "Field datum" */\
-	u8                                      end_field_valid_bits; /* Valid bits in the last "field datum" */\
-	u8                                      end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\
-	u32                                     value;              /* Value to store into the Bank or Index register */\
-	struct acpi_namespace_node              *node;              /* Link back to parent node */
-
-
-/*
- * Fields common to both Strings and Buffers
- */
-#define ACPI_COMMON_BUFFER_INFO \
-	u32                                     length;
-
-
-/*
- * Common fields for objects that support ASL notifications
- */
-#define ACPI_COMMON_NOTIFY_INFO \
-	union acpi_operand_object               *sys_handler;        /* Handler for system notifies */\
-	union acpi_operand_object               *drv_handler;        /* Handler for driver notifies */\
-	union acpi_operand_object               *addr_handler;       /* Handler for Address space */
-
-
-/******************************************************************************
- *
- * Basic data types
- *
- *****************************************************************************/
-
-struct acpi_object_common
-{
-	ACPI_OBJECT_COMMON_HEADER
-};
-
-
-struct acpi_object_integer
-{
-	ACPI_OBJECT_COMMON_HEADER
-	acpi_integer                            value;
-};
-
-
-struct acpi_object_string           /* Null terminated, ASCII characters only */
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_BUFFER_INFO
-	char                                    *pointer;           /* String in AML stream or allocated string */
-};
-
-
-struct acpi_object_buffer
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_BUFFER_INFO
-	u8                                      *pointer;           /* Buffer in AML stream or allocated buffer */
-	struct acpi_namespace_node              *node;              /* Link back to parent node */
-	u8                                      *aml_start;
-	u32                                     aml_length;
-};
-
-
-struct acpi_object_package
-{
-	ACPI_OBJECT_COMMON_HEADER
-
-	u32                                     count;              /* # of elements in package */
-	u32                                     aml_length;
-	u8                                      *aml_start;
-	struct acpi_namespace_node              *node;              /* Link back to parent node */
-	union acpi_operand_object               **elements;         /* Array of pointers to acpi_objects */
-};
-
-
-/******************************************************************************
- *
- * Complex data types
- *
- *****************************************************************************/
-
-struct acpi_object_event
-{
-	ACPI_OBJECT_COMMON_HEADER
-	void                                    *semaphore;
-};
-
-
-#define INFINITE_CONCURRENCY        0xFF
-
-struct acpi_object_method
-{
-	ACPI_OBJECT_COMMON_HEADER
-	u8                                      method_flags;
-	u8                                      param_count;
-	u32                                     aml_length;
-	void                                    *semaphore;
-	u8                                      *aml_start;
-	u8                                      concurrency;
-	u8                                      thread_count;
-	acpi_owner_id                           owning_id;
-};
-
-
-struct acpi_object_mutex
-{
-	ACPI_OBJECT_COMMON_HEADER
-	u16                                     sync_level;
-	u16                                     acquisition_depth;
-	struct acpi_thread_state                *owner_thread;
-	void                                    *semaphore;
-	union acpi_operand_object               *prev;              /* Link for list of acquired mutexes */
-	union acpi_operand_object               *next;              /* Link for list of acquired mutexes */
-	struct acpi_namespace_node              *node;              /* containing object */
-};
-
-
-struct acpi_object_region
-{
-	ACPI_OBJECT_COMMON_HEADER
-
-	u8                                      space_id;
-	union acpi_operand_object               *addr_handler;      /* Handler for system notifies */
-	struct acpi_namespace_node              *node;              /* containing object */
-	union acpi_operand_object               *next;
-	u32                                     length;
-	acpi_physical_address                   address;
-};
-
-
-/******************************************************************************
- *
- * Objects that can be notified.  All share a common notify_info area.
- *
- *****************************************************************************/
-
-struct acpi_object_notify_common            /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_NOTIFY_INFO
-};
-
-
-struct acpi_object_device
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_NOTIFY_INFO
-};
-
-
-struct acpi_object_power_resource
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_NOTIFY_INFO
-	u32                                     system_level;
-	u32                                     resource_order;
-};
-
-
-struct acpi_object_processor
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_NOTIFY_INFO
-	u32                                     proc_id;
-	u32                                     length;
-	acpi_io_address                         address;
-};
-
-
-struct acpi_object_thermal_zone
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_NOTIFY_INFO
-};
-
-
-/******************************************************************************
- *
- * Fields.  All share a common header/info field.
- *
- *****************************************************************************/
-
-struct acpi_object_field_common                         /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_FIELD_INFO
-	union acpi_operand_object               *region_obj;        /* Containing Operation Region object */
-			  /* (REGION/BANK fields only) */
-};
-
-
-struct acpi_object_region_field
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_FIELD_INFO
-	union acpi_operand_object               *region_obj;        /* Containing op_region object */
-};
-
-
-struct acpi_object_bank_field
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_FIELD_INFO
-	union acpi_operand_object               *region_obj;        /* Containing op_region object */
-	union acpi_operand_object               *bank_obj;          /* bank_select Register object */
-};
-
-
-struct acpi_object_index_field
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_FIELD_INFO
-
-	/*
-	 * No "region_obj" pointer needed since the Index and Data registers
-	 * are each field definitions unto themselves.
-	 */
-	union acpi_operand_object               *index_obj;         /* Index register */
-	union acpi_operand_object               *data_obj;          /* Data register */
-};
-
-
-/* The buffer_field is different in that it is part of a Buffer, not an op_region */
-
-struct acpi_object_buffer_field
-{
-	ACPI_OBJECT_COMMON_HEADER
-	ACPI_COMMON_FIELD_INFO
-	union acpi_operand_object               *buffer_obj;        /* Containing Buffer object */
-};
-
-
-/******************************************************************************
- *
- * Objects for handlers
- *
- *****************************************************************************/
-
-struct acpi_object_notify_handler
-{
-	ACPI_OBJECT_COMMON_HEADER
-	struct acpi_namespace_node              *node;              /* Parent device */
-	acpi_notify_handler                     handler;
-	void                                    *context;
-};
-
-
-/* Flags for address handler */
-
-#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED  0x1
-
-
-struct acpi_object_addr_handler
-{
-	ACPI_OBJECT_COMMON_HEADER
-	u8                                      space_id;
-	u16                                     hflags;
-	acpi_adr_space_handler                  handler;
-	struct acpi_namespace_node              *node;              /* Parent device */
-	void                                    *context;
-	acpi_adr_space_setup                    setup;
-	union acpi_operand_object               *region_list;       /* regions using this handler */
-	union acpi_operand_object               *next;
-};
-
-
-/******************************************************************************
- *
- * Special internal objects
- *
- *****************************************************************************/
-
-/*
- * The Reference object type is used for these opcodes:
- * Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op
- */
-struct acpi_object_reference
-{
-	ACPI_OBJECT_COMMON_HEADER
-	u8                                      target_type;        /* Used for index_op */
-	u16                                     opcode;
-	u32                                     offset;             /* Used for arg_op, local_op, and index_op */
-	void                                    *object;            /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object  */
-	struct acpi_namespace_node              *node;
-	union acpi_operand_object               **where;
-};
-
-
-/*
- * Extra object is used as additional storage for types that
- * have AML code in their declarations (term_args) that must be
- * evaluated at run time.
- *
- * Currently: Region and field_unit types
- */
-struct acpi_object_extra
-{
-	ACPI_OBJECT_COMMON_HEADER
-	u8                                      byte_fill1;
-	u16                                     word_fill1;
-	u32                                     aml_length;
-	u8                                      *aml_start;
-	struct acpi_namespace_node              *method_REG;        /* _REG method for this region (if any) */
-	void                                    *region_context;    /* Region-specific data */
-};
-
-
-/* Additional data that can be attached to namespace nodes */
-
-struct acpi_object_data
-{
-	ACPI_OBJECT_COMMON_HEADER
-	acpi_object_handler                     handler;
-	void                                    *pointer;
-};
-
-
-/* Structure used when objects are cached for reuse */
-
-struct acpi_object_cache_list
-{
-	ACPI_OBJECT_COMMON_HEADER
-	union acpi_operand_object               *next;              /* Link for object cache and internal lists*/
-};
-
-
-/******************************************************************************
- *
- * union acpi_operand_object Descriptor - a giant union of all of the above
- *
- *****************************************************************************/
-
-union acpi_operand_object
-{
-	struct acpi_object_common               common;
-	struct acpi_object_integer              integer;
-	struct acpi_object_string               string;
-	struct acpi_object_buffer               buffer;
-	struct acpi_object_package              package;
-	struct acpi_object_event                event;
-	struct acpi_object_method               method;
-	struct acpi_object_mutex                mutex;
-	struct acpi_object_region               region;
-	struct acpi_object_notify_common        common_notify;
-	struct acpi_object_device               device;
-	struct acpi_object_power_resource       power_resource;
-	struct acpi_object_processor            processor;
-	struct acpi_object_thermal_zone         thermal_zone;
-	struct acpi_object_field_common         common_field;
-	struct acpi_object_region_field         field;
-	struct acpi_object_buffer_field         buffer_field;
-	struct acpi_object_bank_field           bank_field;
-	struct acpi_object_index_field          index_field;
-	struct acpi_object_notify_handler       notify_handler;
-	struct acpi_object_addr_handler         addr_handler;
-	struct acpi_object_reference            reference;
-	struct acpi_object_extra                extra;
-	struct acpi_object_data                 data;
-	struct acpi_object_cache_list           cache;
-};
-
-
-/******************************************************************************
- *
- * union acpi_descriptor - objects that share a common descriptor identifier
- *
- *****************************************************************************/
-
-
-/* Object descriptor types */
-
-#define ACPI_DESC_TYPE_CACHED           0x11        /* Used only when object is cached */
-#define ACPI_DESC_TYPE_STATE            0x20
-#define ACPI_DESC_TYPE_STATE_UPDATE     0x21
-#define ACPI_DESC_TYPE_STATE_PACKAGE    0x22
-#define ACPI_DESC_TYPE_STATE_CONTROL    0x23
-#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x24
-#define ACPI_DESC_TYPE_STATE_PSCOPE     0x25
-#define ACPI_DESC_TYPE_STATE_WSCOPE     0x26
-#define ACPI_DESC_TYPE_STATE_RESULT     0x27
-#define ACPI_DESC_TYPE_STATE_NOTIFY     0x28
-#define ACPI_DESC_TYPE_STATE_THREAD     0x29
-#define ACPI_DESC_TYPE_WALK             0x44
-#define ACPI_DESC_TYPE_PARSER           0x66
-#define ACPI_DESC_TYPE_OPERAND          0x88
-#define ACPI_DESC_TYPE_NAMED            0xAA
-
-
-union acpi_descriptor
-{
-	u8                                      descriptor_id;  /* To differentiate various internal objs */\
-	union acpi_operand_object               object;
-	struct acpi_namespace_node              node;
-	union acpi_parse_object                 op;
-};
-
-
-#endif /* _ACOBJECT_H */
diff -Nru a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h
--- a/drivers/acpi/include/acoutput.h	Mon Feb 10 10:39:24 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,166 +0,0 @@
-/******************************************************************************
- *
- * Name: acoutput.h -- debug output
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACOUTPUT_H__
-#define __ACOUTPUT_H__
-
-/*
- * Debug levels and component IDs.  These are used to control the
- * granularity of the output of the DEBUG_PRINT macro -- on a per-
- * component basis and a per-exception-type basis.
- */
-
-/* Component IDs are used in the global "debug_layer" */
-
-#define ACPI_UTILITIES              0x00000001
-#define ACPI_HARDWARE               0x00000002
-#define ACPI_EVENTS                 0x00000004
-#define ACPI_TABLES                 0x00000008
-#define ACPI_NAMESPACE              0x00000010
-#define ACPI_PARSER                 0x00000020
-#define ACPI_DISPATCHER             0x00000040
-#define ACPI_EXECUTER               0x00000080
-#define ACPI_RESOURCES              0x00000100
-#define ACPI_CA_DEBUGGER            0x00000200
-#define ACPI_OS_SERVICES            0x00000400
-#define ACPI_CA_DISASSEMBLER        0x00000800
-
-/* Component IDs for ACPI tools and utilities */
-
-#define ACPI_COMPILER               0x00001000
-#define ACPI_TOOLS                  0x00002000
-
-#define ACPI_ALL_COMPONENTS         0x00003FFF
-#define ACPI_COMPONENT_DEFAULT      (ACPI_ALL_COMPONENTS)
-
-
-/* Component IDs reserved for ACPI drivers */
-
-#define ACPI_ALL_DRIVERS            0xFFFF0000
-
-
-/*
- * Raw debug output levels, do not use these in the DEBUG_PRINT macros
- */
-#define ACPI_LV_ERROR               0x00000001
-#define ACPI_LV_WARN                0x00000002
-#define ACPI_LV_INIT                0x00000004
-#define ACPI_LV_DEBUG_OBJECT        0x00000008
-#define ACPI_LV_INFO                0x00000010
-#define ACPI_LV_ALL_EXCEPTIONS      0x0000001F
-
-/* Trace verbosity level 1 [Standard Trace Level] */
-
-#define ACPI_LV_INIT_NAMES          0x00000020
-#define ACPI_LV_PARSE               0x00000040
-#define ACPI_LV_LOAD                0x00000080
-#define ACPI_LV_DISPATCH            0x00000100
-#define ACPI_LV_EXEC                0x00000200
-#define ACPI_LV_NAMES               0x00000400
-#define ACPI_LV_OPREGION            0x00000800
-#define ACPI_LV_BFIELD              0x00001000
-#define ACPI_LV_TABLES              0x00002000
-#define ACPI_LV_VALUES              0x00004000
-#define ACPI_LV_OBJECTS             0x00008000
-#define ACPI_LV_RESOURCES           0x00010000
-#define ACPI_LV_USER_REQUESTS       0x00020000
-#define ACPI_LV_PACKAGE             0x00040000
-#define ACPI_LV_VERBOSITY1          0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS
-
-/* Trace verbosity level 2 [Function tracing and memory allocation] */
-
-#define ACPI_LV_ALLOCATIONS         0x00100000
-#define ACPI_LV_FUNCTIONS           0x00200000
-#define ACPI_LV_OPTIMIZATIONS       0x00400000
-#define ACPI_LV_VERBOSITY2          0x00700000 | ACPI_LV_VERBOSITY1
-#define ACPI_LV_ALL                 ACPI_LV_VERBOSITY2
-
-/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
-
-#define ACPI_LV_MUTEX               0x01000000
-#define ACPI_LV_THREADS             0x02000000
-#define ACPI_LV_IO                  0x04000000
-#define ACPI_LV_INTERRUPTS          0x08000000
-#define ACPI_LV_VERBOSITY3          0x0F000000 | ACPI_LV_VERBOSITY2
-
-/* Exceptionally verbose output -- also used in the global "debug_level" */
-
-#define ACPI_LV_AML_DISASSEMBLE     0x10000000
-#define ACPI_LV_VERBOSE_INFO        0x20000000
-#define ACPI_LV_FULL_TABLES         0x40000000
-#define ACPI_LV_EVENTS              0x80000000
-
-#define ACPI_LV_VERBOSE             0xF0000000
-
-
-/*
- * Debug level macros that are used in the DEBUG_PRINT macros
- */
-#define ACPI_DEBUG_LEVEL(dl)        (u32) dl,__LINE__,&_dbg
-
-/* Exception level -- used in the global "debug_level" */
-
-#define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
-#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
-#define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
-#define ACPI_DB_DEBUG_OBJECT        ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
-#define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
-#define ACPI_DB_ALL_EXCEPTIONS      ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
-
-
-/* Trace level -- also used in the global "debug_level" */
-
-#define ACPI_DB_INIT_NAMES          ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
-#define ACPI_DB_THREADS             ACPI_DEBUG_LEVEL (ACPI_LV_THREADS)
-#define ACPI_DB_PARSE               ACPI_DEBUG_LEVEL (ACPI_LV_PARSE)
-#define ACPI_DB_DISPATCH            ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH)
-#define ACPI_DB_LOAD                ACPI_DEBUG_LEVEL (ACPI_LV_LOAD)
-#define ACPI_DB_EXEC                ACPI_DEBUG_LEVEL (ACPI_LV_EXEC)
-#define ACPI_DB_NAMES               ACPI_DEBUG_LEVEL (ACPI_LV_NAMES)
-#define ACPI_DB_OPREGION            ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION)
-#define ACPI_DB_BFIELD              ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD)
-#define ACPI_DB_TABLES              ACPI_DEBUG_LEVEL (ACPI_LV_TABLES)
-#define ACPI_DB_FUNCTIONS           ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS)
-#define ACPI_DB_OPTIMIZATIONS       ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS)
-#define ACPI_DB_VALUES              ACPI_DEBUG_LEVEL (ACPI_LV_VALUES)
-#define ACPI_DB_OBJECTS             ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS)
-#define ACPI_DB_ALLOCATIONS         ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS)
-#define ACPI_DB_RESOURCES           ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES)
-#define ACPI_DB_IO                  ACPI_DEBUG_LEVEL (ACPI_LV_IO)
-#define ACPI_DB_INTERRUPTS          ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS)
-#define ACPI_DB_USER_REQUESTS       ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
-#define ACPI_DB_PACKAGE             ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
-#define ACPI_DB_MUTEX               ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
-
-#define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
-
-
-/* Defaults for debug_level, debug and normal */
-
-#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
-#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
-#define ACPI_DEBUG_ALL              (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
-
-
-#endif /* __ACOUTPUT_H__ */
diff -Nru a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h
--- a/drivers/acpi/include/acparser.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,328 +0,0 @@
-/******************************************************************************
- *
- * Module Name: acparser.h - AML Parser subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACPARSER_H__
-#define __ACPARSER_H__
-
-
-#define OP_HAS_RETURN_VALUE             1
-
-/* variable # arguments */
-
-#define ACPI_VAR_ARGS                   ACPI_UINT32_MAX
-
-
-#define ACPI_PARSE_DELETE_TREE          0x0001
-#define ACPI_PARSE_NO_TREE_DELETE       0x0000
-#define ACPI_PARSE_TREE_MASK            0x0001
-
-#define ACPI_PARSE_LOAD_PASS1           0x0010
-#define ACPI_PARSE_LOAD_PASS2           0x0020
-#define ACPI_PARSE_EXECUTE              0x0030
-#define ACPI_PARSE_MODE_MASK            0x0030
-
-#define ACPI_PARSE_DEFERRED_OP          0x0100
-
-/* Parser external interfaces */
-
-acpi_status
-acpi_psx_load_table (
-	u8                              *pcode_addr,
-	u32                             pcode_length);
-
-acpi_status
-acpi_psx_execute (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
-
-
-/******************************************************************************
- *
- * Parser interfaces
- *
- *****************************************************************************/
-
-
-/* psargs - Parse AML opcode arguments */
-
-u8 *
-acpi_ps_get_next_package_end (
-	struct acpi_parse_state         *parser_state);
-
-u32
-acpi_ps_get_next_package_length (
-	struct acpi_parse_state         *parser_state);
-
-char *
-acpi_ps_get_next_namestring (
-	struct acpi_parse_state         *parser_state);
-
-void
-acpi_ps_get_next_simple_arg (
-	struct acpi_parse_state         *parser_state,
-	u32                             arg_type,
-	union acpi_parse_object         *arg);
-
-acpi_status
-acpi_ps_get_next_namepath (
-	struct acpi_walk_state          *walk_state,
-	struct acpi_parse_state         *parser_state,
-	union acpi_parse_object         *arg,
-	u8                              method_call);
-
-union acpi_parse_object *
-acpi_ps_get_next_field (
-	struct acpi_parse_state         *parser_state);
-
-acpi_status
-acpi_ps_get_next_arg (
-	struct acpi_walk_state          *walk_state,
-	struct acpi_parse_state         *parser_state,
-	u32                             arg_type,
-	union acpi_parse_object         **return_arg);
-
-
-/* psfind */
-
-union acpi_parse_object *
-acpi_ps_find_name (
-	union acpi_parse_object         *scope,
-	u32                             name,
-	u32                             opcode);
-
-union acpi_parse_object*
-acpi_ps_get_parent (
-	union acpi_parse_object         *op);
-
-
-/* psopcode - AML Opcode information */
-
-const struct acpi_opcode_info *
-acpi_ps_get_opcode_info (
-	u16                             opcode);
-
-char *
-acpi_ps_get_opcode_name (
-	u16                             opcode);
-
-
-/* psparse - top level parsing routines */
-
-u32
-acpi_ps_get_opcode_size (
-	u32                             opcode);
-
-void
-acpi_ps_complete_this_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ps_next_parse_state (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	acpi_status                     callback_status);
-
-acpi_status
-acpi_ps_find_object (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         **out_op);
-
-void
-acpi_ps_delete_parse_tree (
-	union acpi_parse_object         *root);
-
-acpi_status
-acpi_ps_parse_loop (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ps_parse_aml (
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ps_parse_table (
-	u8                              *aml,
-	u32                             aml_size,
-	acpi_parse_downwards            descending_callback,
-	acpi_parse_upwards              ascending_callback,
-	union acpi_parse_object         **root_object);
-
-u16
-acpi_ps_peek_opcode (
-	struct acpi_parse_state         *state);
-
-
-/* psscope - Scope stack management routines */
-
-
-acpi_status
-acpi_ps_init_scope (
-	struct acpi_parse_state         *parser_state,
-	union acpi_parse_object         *root);
-
-union acpi_parse_object *
-acpi_ps_get_parent_scope (
-	struct acpi_parse_state         *state);
-
-u8
-acpi_ps_has_completed_scope (
-	struct acpi_parse_state         *parser_state);
-
-void
-acpi_ps_pop_scope (
-	struct acpi_parse_state         *parser_state,
-	union acpi_parse_object         **op,
-	u32                             *arg_list,
-	u32                             *arg_count);
-
-acpi_status
-acpi_ps_push_scope (
-	struct acpi_parse_state         *parser_state,
-	union acpi_parse_object         *op,
-	u32                             remaining_args,
-	u32                             arg_count);
-
-void
-acpi_ps_cleanup_scope (
-	struct acpi_parse_state         *state);
-
-
-/* pstree - parse tree manipulation routines */
-
-void
-acpi_ps_append_arg(
-	union acpi_parse_object         *op,
-	union acpi_parse_object         *arg);
-
-union acpi_parse_object*
-acpi_ps_find (
-	union acpi_parse_object         *scope,
-	char                            *path,
-	u16                             opcode,
-	u32                             create);
-
-union acpi_parse_object *
-acpi_ps_get_arg(
-	union acpi_parse_object         *op,
-	u32                              argn);
-
-union acpi_parse_object *
-acpi_ps_get_child (
-	union acpi_parse_object         *op);
-
-union acpi_parse_object *
-acpi_ps_get_depth_next (
-	union acpi_parse_object         *origin,
-	union acpi_parse_object         *op);
-
-
-/* pswalk - parse tree walk routines */
-
-acpi_status
-acpi_ps_walk_parsed_aml (
-	union acpi_parse_object         *start_op,
-	union acpi_parse_object         *end_op,
-	union acpi_operand_object       *mth_desc,
-	struct acpi_namespace_node      *start_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **caller_return_desc,
-	acpi_owner_id                   owner_id,
-	acpi_parse_downwards            descending_callback,
-	acpi_parse_upwards              ascending_callback);
-
-acpi_status
-acpi_ps_get_next_walk_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	acpi_parse_upwards              ascending_callback);
-
-acpi_status
-acpi_ps_delete_completed_op (
-	struct acpi_walk_state          *walk_state);
-
-
-/* psutils - parser utilities */
-
-union acpi_parse_object *
-acpi_ps_create_scope_op (
-	void);
-
-void
-acpi_ps_init_op (
-	union acpi_parse_object         *op,
-	u16                             opcode);
-
-union acpi_parse_object *
-acpi_ps_alloc_op (
-	u16                             opcode);
-
-void
-acpi_ps_free_op (
-	union acpi_parse_object         *op);
-
-void
-acpi_ps_delete_parse_cache (
-	void);
-
-u8
-acpi_ps_is_leading_char (
-	u32                             c);
-
-u8
-acpi_ps_is_prefix_char (
-	u32                             c);
-
-u32
-acpi_ps_get_name(
-	union acpi_parse_object         *op);
-
-void
-acpi_ps_set_name(
-	union acpi_parse_object         *op,
-	u32                             name);
-
-
-/* psdump - display parser tree */
-
-u32
-acpi_ps_sprint_path (
-	char                            *buffer_start,
-	u32                             buffer_size,
-	union acpi_parse_object         *op);
-
-u32
-acpi_ps_sprint_op (
-	char                            *buffer_start,
-	u32                             buffer_size,
-	union acpi_parse_object         *op);
-
-void
-acpi_ps_show (
-	union acpi_parse_object         *op);
-
-
-#endif /* __ACPARSER_H__ */
diff -Nru a/drivers/acpi/include/acpi.h b/drivers/acpi/include/acpi.h
--- a/drivers/acpi/include/acpi.h	Mon Feb 10 10:39:27 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,50 +0,0 @@
-/******************************************************************************
- *
- * Name: acpi.h - Master include file, Publics and external data.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACPI_H__
-#define __ACPI_H__
-
-/*
- * Common includes for all ACPI driver files
- * We put them here because we don't want to duplicate them
- * in the rest of the source code again and again.
- */
-#include "acconfig.h"           /* Configuration constants */
-#include "platform/acenv.h"     /* Target environment specific items */
-#include "actypes.h"            /* Fundamental common data types */
-#include "acexcep.h"            /* ACPI exception codes */
-#include "acmacros.h"           /* C macros */
-#include "actbl.h"              /* ACPI table definitions */
-#include "aclocal.h"            /* Internal data types */
-#include "acoutput.h"           /* Error output and Debug macros */
-#include "acpiosxf.h"           /* Interfaces to the ACPI-to-OS layer*/
-#include "acpixf.h"             /* ACPI core subsystem external interfaces */
-#include "acobject.h"           /* ACPI internal object */
-#include "acstruct.h"           /* Common structures */
-#include "acglobal.h"           /* All global variables */
-#include "achware.h"            /* Hardware defines and interfaces */
-#include "acutils.h"            /* Utility interfaces */
-
-
-#endif /* __ACPI_H__ */
diff -Nru a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h
--- a/drivers/acpi/include/acpiosxf.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,337 +0,0 @@
-
-/******************************************************************************
- *
- * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL).  These
- *                    interfaces must be implemented by OSL to interface the
- *                    ACPI components to the host operating system.
- *
- *****************************************************************************/
-
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACPIOSXF_H__
-#define __ACPIOSXF_H__
-
-#include "platform/acenv.h"
-#include "actypes.h"
-
-
-/* Priorities for acpi_os_queue_for_execution */
-
-#define OSD_PRIORITY_GPE            1
-#define OSD_PRIORITY_HIGH           2
-#define OSD_PRIORITY_MED            3
-#define OSD_PRIORITY_LO             4
-
-#define ACPI_NO_UNIT_LIMIT          ((u32) -1)
-#define ACPI_MUTEX_SEM              1
-
-
-/* Functions for acpi_os_signal */
-
-#define ACPI_SIGNAL_FATAL           0
-#define ACPI_SIGNAL_BREAKPOINT      1
-
-struct acpi_signal_fatal_info
-{
-	u32                             type;
-	u32                             code;
-	u32                             argument;
-};
-
-
-/*
- * Types specific to the OS service interfaces
- */
-
-typedef u32
-(ACPI_SYSTEM_XFACE *OSD_HANDLER) (
-	void                            *context);
-
-typedef void
-(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) (
-	void                            *context);
-
-
-/*
- * OSL Initialization and shutdown primitives
- */
-
-acpi_status
-acpi_os_initialize (
-	void);
-
-acpi_status
-acpi_os_terminate (
-	void);
-
-
-/*
- * ACPI Table interfaces
- */
-
-acpi_status
-acpi_os_get_root_pointer (
-	u32                             flags,
-	struct acpi_pointer             *address);
-
-acpi_status
-acpi_os_table_override (
-	struct acpi_table_header        *existing_table,
-	struct acpi_table_header        **new_table);
-
-
-/*
- * Synchronization primitives
- */
-
-acpi_status
-acpi_os_create_semaphore (
-	u32                             max_units,
-	u32                             initial_units,
-	acpi_handle                     *out_handle);
-
-acpi_status
-acpi_os_delete_semaphore (
-	acpi_handle                     handle);
-
-acpi_status
-acpi_os_wait_semaphore (
-	acpi_handle                     handle,
-	u32                             units,
-	u16                             timeout);
-
-acpi_status
-acpi_os_signal_semaphore (
-	acpi_handle                     handle,
-	u32                             units);
-
-
-/*
- * Memory allocation and mapping
- */
-
-void *
-acpi_os_allocate (
-	acpi_size                       size);
-
-void
-acpi_os_free (
-	void *                          memory);
-
-acpi_status
-acpi_os_map_memory (
-	acpi_physical_address           physical_address,
-	acpi_size                       size,
-	void                            **logical_address);
-
-void
-acpi_os_unmap_memory (
-	void                            *logical_address,
-	acpi_size                       size);
-
-acpi_status
-acpi_os_get_physical_address (
-	void                            *logical_address,
-	acpi_physical_address           *physical_address);
-
-
-/*
- * Interrupt handlers
- */
-
-acpi_status
-acpi_os_install_interrupt_handler (
-	u32                             interrupt_number,
-	OSD_HANDLER             service_routine,
-	void                            *context);
-
-acpi_status
-acpi_os_remove_interrupt_handler (
-	u32                             interrupt_number,
-	OSD_HANDLER             service_routine);
-
-
-/*
- * Threads and Scheduling
- */
-
-u32
-acpi_os_get_thread_id (
-	void);
-
-acpi_status
-acpi_os_queue_for_execution (
-	u32                             priority,
-	OSD_EXECUTION_CALLBACK  function,
-	void                            *context);
-
-void
-acpi_os_sleep (
-	u32                             seconds,
-	u32                             milliseconds);
-
-void
-acpi_os_stall (
-	u32                             microseconds);
-
-
-/*
- * Platform and hardware-independent I/O interfaces
- */
-
-acpi_status
-acpi_os_read_port (
-	acpi_io_address                 address,
-	void                            *value,
-	u32                             width);
-
-acpi_status
-acpi_os_write_port (
-	acpi_io_address                 address,
-	acpi_integer                    value,
-	u32                             width);
-
-
-/*
- * Platform and hardware-independent physical memory interfaces
- */
-
-acpi_status
-acpi_os_read_memory (
-	acpi_physical_address           address,
-	void                            *value,
-	u32                             width);
-
-acpi_status
-acpi_os_write_memory (
-	acpi_physical_address           address,
-	acpi_integer                    value,
-	u32                             width);
-
-
-/*
- * Platform and hardware-independent PCI configuration space access
- */
-
-acpi_status
-acpi_os_read_pci_configuration (
-	struct acpi_pci_id              *pci_id,
-	u32                             register,
-	void                            *value,
-	u32                             width);
-
-acpi_status
-acpi_os_write_pci_configuration (
-	struct acpi_pci_id              *pci_id,
-	u32                             register,
-	acpi_integer                    value,
-	u32                             width);
-
-/*
- * Interim function needed for PCI IRQ routing
- */
-void
-acpi_os_derive_pci_id(
-	acpi_handle                     rhandle,
-	acpi_handle                     chandle,
-	struct acpi_pci_id              **pci_id);
-
-/*
- * Miscellaneous
- */
-
-u8
-acpi_os_readable (
-	void                            *pointer,
-	u32                             length);
-
-u8
-acpi_os_writable (
-	void                            *pointer,
-	u32                             length);
-
-u32
-acpi_os_get_timer (
-	void);
-
-acpi_status
-acpi_os_signal (
-	u32                             function,
-	void                            *info);
-
-/*
- * Debug print routines
- */
-
-void ACPI_INTERNAL_VAR_XFACE
-acpi_os_printf (
-	const char                      *format,
-	...);
-
-void
-acpi_os_vprintf (
-	const char                      *format,
-	va_list                 args);
-
-void
-acpi_os_redirect_output (
-	void                            *destination);
-
-
-/*
- * Debug input
- */
-
-u32
-acpi_os_get_line (
-	char                            *buffer);
-
-
-/*
- * Directory manipulation
- */
-
-void *
-acpi_os_open_directory (
-	char                            *pathname,
-	char                            *wildcard_spec);
-
-char *
-acpi_os_get_next_filename (
-	void                            *dir_handle);
-
-void
-acpi_os_close_directory (
-	void                            *dir_handle);
-
-/*
- * Debug
- */
-
-void
-acpi_os_dbg_assert(
-	void                            *failed_assertion,
-	void                            *file_name,
-	u32                             line_number,
-	char                            *message);
-
-
-#endif /* __ACPIOSXF_H__ */
diff -Nru a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h
--- a/drivers/acpi/include/acpixf.h	Mon Feb 10 10:39:22 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,387 +0,0 @@
-
-/******************************************************************************
- *
- * Name: acpixf.h - External interfaces to the ACPI subsystem
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACXFACE_H__
-#define __ACXFACE_H__
-
-#include "actypes.h"
-#include "actbl.h"
-
-
- /*
- * Global interfaces
- */
-
-acpi_status
-acpi_initialize_subsystem (
-	void);
-
-acpi_status
-acpi_enable_subsystem (
-	u32                             flags);
-
-acpi_status
-acpi_initialize_objects (
-	u32                             flags);
-
-acpi_status
-acpi_terminate (
-	void);
-
-acpi_status
-acpi_subsystem_status (
-	void);
-
-acpi_status
-acpi_enable (
-	void);
-
-acpi_status
-acpi_disable (
-	void);
-
-acpi_status
-acpi_get_system_info (
-	struct acpi_buffer              *ret_buffer);
-
-const char *
-acpi_format_exception (
-	acpi_status                     exception);
-
-acpi_status
-acpi_purge_cached_objects (
-	void);
-
-acpi_status
-acpi_install_initialization_handler (
-	acpi_init_handler               handler,
-	u32                             function);
-
-/*
- * ACPI Memory manager
- */
-
-void *
-acpi_allocate (
-	u32                             size);
-
-void *
-acpi_callocate (
-	u32                             size);
-
-void
-acpi_free (
-	void                            *address);
-
-
-/*
- * ACPI table manipulation interfaces
- */
-
-acpi_status
-acpi_find_root_pointer (
-	u32                             flags,
-	struct acpi_pointer             *rsdp_address);
-
-acpi_status
-acpi_load_tables (
-	void);
-
-acpi_status
-acpi_load_table (
-	struct acpi_table_header        *table_ptr);
-
-acpi_status
-acpi_unload_table (
-	acpi_table_type                 table_type);
-
-acpi_status
-acpi_get_table_header (
-	acpi_table_type                 table_type,
-	u32                             instance,
-	struct acpi_table_header        *out_table_header);
-
-acpi_status
-acpi_get_table (
-	acpi_table_type                 table_type,
-	u32                             instance,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_get_firmware_table (
-	acpi_string                     signature,
-	u32                             instance,
-	u32                             flags,
-	struct acpi_table_header        **table_pointer);
-
-
-/*
- * Namespace and name interfaces
- */
-
-acpi_status
-acpi_walk_namespace (
-	acpi_object_type                type,
-	acpi_handle                     start_object,
-	u32                             max_depth,
-	acpi_walk_callback              user_function,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_get_devices (
-	char                            *HID,
-	acpi_walk_callback              user_function,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_get_name (
-	acpi_handle                     handle,
-	u32                             name_type,
-	struct acpi_buffer              *ret_path_ptr);
-
-acpi_status
-acpi_get_handle (
-	acpi_handle                     parent,
-	acpi_string                     pathname,
-	acpi_handle                     *ret_handle);
-
-acpi_status
-acpi_attach_data (
-	acpi_handle                     obj_handle,
-	acpi_object_handler             handler,
-	void                            *data);
-
-acpi_status
-acpi_detach_data (
-	acpi_handle                     obj_handle,
-	acpi_object_handler             handler);
-
-acpi_status
-acpi_get_data (
-	acpi_handle                     obj_handle,
-	acpi_object_handler             handler,
-	void                            **data);
-
-
-/*
- * Object manipulation and enumeration
- */
-
-acpi_status
-acpi_evaluate_object (
-	acpi_handle                     object,
-	acpi_string                     pathname,
-	struct acpi_object_list         *parameter_objects,
-	struct acpi_buffer              *return_object_buffer);
-
-acpi_status
-acpi_evaluate_object_typed (
-	acpi_handle                     object,
-	acpi_string                     pathname,
-	struct acpi_object_list         *external_params,
-	struct acpi_buffer              *return_buffer,
-	acpi_object_type                return_type);
-
-acpi_status
-acpi_get_object_info (
-	acpi_handle                     device,
-	struct acpi_device_info         *info);
-
-acpi_status
-acpi_get_next_object (
-	acpi_object_type                type,
-	acpi_handle                     parent,
-	acpi_handle                     child,
-	acpi_handle                     *out_handle);
-
-acpi_status
-acpi_get_type (
-	acpi_handle                     object,
-	acpi_object_type                *out_type);
-
-acpi_status
-acpi_get_parent (
-	acpi_handle                     object,
-	acpi_handle                     *out_handle);
-
-
-/*
- * Event handler interfaces
- */
-
-acpi_status
-acpi_install_fixed_event_handler (
-	u32                             acpi_event,
-	acpi_event_handler              handler,
-	void                            *context);
-
-acpi_status
-acpi_remove_fixed_event_handler (
-	u32                             acpi_event,
-	acpi_event_handler              handler);
-
-acpi_status
-acpi_install_notify_handler (
-	acpi_handle                     device,
-	u32                             handler_type,
-	acpi_notify_handler             handler,
-	void                            *context);
-
-acpi_status
-acpi_remove_notify_handler (
-	acpi_handle                     device,
-	u32                             handler_type,
-	acpi_notify_handler             handler);
-
-acpi_status
-acpi_install_address_space_handler (
-	acpi_handle                     device,
-	acpi_adr_space_type             space_id,
-	acpi_adr_space_handler          handler,
-	acpi_adr_space_setup            setup,
-	void                            *context);
-
-acpi_status
-acpi_remove_address_space_handler (
-	acpi_handle                     device,
-	acpi_adr_space_type             space_id,
-	acpi_adr_space_handler          handler);
-
-acpi_status
-acpi_install_gpe_handler (
-	u32                             gpe_number,
-	u32                             type,
-	acpi_gpe_handler                handler,
-	void                            *context);
-
-acpi_status
-acpi_acquire_global_lock (
-	u16                             timeout,
-	u32                             *handle);
-
-acpi_status
-acpi_release_global_lock (
-	u32                             handle);
-
-acpi_status
-acpi_remove_gpe_handler (
-	u32                             gpe_number,
-	acpi_gpe_handler                handler);
-
-acpi_status
-acpi_enable_event (
-	u32                             acpi_event,
-	u32                             type,
-	u32                             flags);
-
-acpi_status
-acpi_disable_event (
-	u32                             acpi_event,
-	u32                             type,
-	u32                             flags);
-
-acpi_status
-acpi_clear_event (
-	u32                             acpi_event,
-	u32                             type);
-
-acpi_status
-acpi_get_event_status (
-	u32                             acpi_event,
-	u32                             type,
-	acpi_event_status               *event_status);
-
-/*
- * Resource interfaces
- */
-
-acpi_status
-acpi_get_current_resources(
-	acpi_handle                     device_handle,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_get_possible_resources(
-	acpi_handle                     device_handle,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_set_current_resources (
-	acpi_handle                     device_handle,
-	struct acpi_buffer              *in_buffer);
-
-acpi_status
-acpi_get_irq_routing_table (
-	acpi_handle                     bus_device_handle,
-	struct acpi_buffer              *ret_buffer);
-
-
-/*
- * Hardware (ACPI device) interfaces
- */
-
-acpi_status
-acpi_get_register (
-	u32                             register_id,
-	u32                             *return_value,
-	u32                             flags);
-
-acpi_status
-acpi_set_register (
-	u32                             register_id,
-	u32                             value,
-	u32                             flags);
-
-acpi_status
-acpi_set_firmware_waking_vector (
-	acpi_physical_address           physical_address);
-
-acpi_status
-acpi_get_firmware_waking_vector (
-	acpi_physical_address           *physical_address);
-
-acpi_status
-acpi_get_sleep_type_data (
-	u8                              sleep_state,
-	u8                              *slp_typ_a,
-	u8                              *slp_typ_b);
-
-acpi_status
-acpi_enter_sleep_state_prep (
-	u8                              sleep_state);
-
-acpi_status
-acpi_enter_sleep_state (
-	u8                              sleep_state);
-
-acpi_status
-acpi_leave_sleep_state (
-	u8                              sleep_state);
-
-
-#endif /* __ACXFACE_H__ */
diff -Nru a/drivers/acpi/include/acresrc.h b/drivers/acpi/include/acresrc.h
--- a/drivers/acpi/include/acresrc.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,366 +0,0 @@
-/******************************************************************************
- *
- * Name: acresrc.h - Resource Manager function prototypes
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACRESRC_H__
-#define __ACRESRC_H__
-
-
-/*
- *  Function prototypes called from Acpi* APIs
- */
-
-acpi_status
-acpi_rs_get_prt_method_data (
-	acpi_handle                     handle,
-	struct acpi_buffer              *ret_buffer);
-
-
-acpi_status
-acpi_rs_get_crs_method_data (
-	acpi_handle                     handle,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_rs_get_prs_method_data (
-	acpi_handle                     handle,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_rs_set_srs_method_data (
-	acpi_handle                     handle,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_rs_create_resource_list (
-	union acpi_operand_object       *byte_stream_buffer,
-	struct acpi_buffer              *output_buffer);
-
-acpi_status
-acpi_rs_create_byte_stream (
-	struct acpi_resource            *linked_list_buffer,
-	struct acpi_buffer              *output_buffer);
-
-acpi_status
-acpi_rs_create_pci_routing_table (
-	union acpi_operand_object       *package_object,
-	struct acpi_buffer              *output_buffer);
-
-
-/*
- * Function prototypes called from acpi_rs_create*
- */
-void
-acpi_rs_dump_irq (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address16 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address64 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_dma (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_io (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_extended_irq (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_fixed_io (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_fixed_memory32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_memory24 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_memory32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_start_depend_fns (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_vendor_specific (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_resource_list (
-	struct acpi_resource            *resource);
-
-void
-acpi_rs_dump_irq_list (
-	u8                              *route_table);
-
-acpi_status
-acpi_rs_get_byte_stream_start (
-	u8                              *byte_stream_buffer,
-	u8                              **byte_stream_start,
-	u32                             *size);
-
-acpi_status
-acpi_rs_get_list_length (
-	u8                              *byte_stream_buffer,
-	u32                             byte_stream_buffer_length,
-	acpi_size                       *size_needed);
-
-acpi_status
-acpi_rs_get_byte_stream_length (
-	struct acpi_resource            *linked_list_buffer,
-	acpi_size                       *size_needed);
-
-acpi_status
-acpi_rs_get_pci_routing_table_length (
-	union acpi_operand_object       *package_object,
-	acpi_size                       *buffer_size_needed);
-
-acpi_status
-acpi_rs_byte_stream_to_list (
-	u8                              *byte_stream_buffer,
-	u32                             byte_stream_buffer_length,
-	u8                              *output_buffer);
-
-acpi_status
-acpi_rs_list_to_byte_stream (
-	struct acpi_resource            *linked_list,
-	acpi_size                       byte_stream_size_needed,
-	u8                              *output_buffer);
-
-acpi_status
-acpi_rs_io_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_fixed_io_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_io_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_fixed_io_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_irq_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_irq_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_dma_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_dma_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_address16_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_address16_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_address32_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_address32_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_address64_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_address64_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_start_depend_fns_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_end_depend_fns_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_start_depend_fns_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_end_depend_fns_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_memory24_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_memory24_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_memory32_range_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_fixed_memory32_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_memory32_range_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_fixed_memory32_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_extended_irq_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_extended_irq_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_end_tag_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_end_tag_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-acpi_status
-acpi_rs_vendor_resource (
-	u8                              *byte_stream_buffer,
-	acpi_size                       *bytes_consumed,
-	u8                              **output_buffer,
-	acpi_size                       *structure_size);
-
-acpi_status
-acpi_rs_vendor_stream (
-	struct acpi_resource            *linked_list,
-	u8                              **output_buffer,
-	acpi_size                       *bytes_consumed);
-
-u8
-acpi_rs_get_resource_type (
-	u8                              resource_start_byte);
-
-#endif  /* __ACRESRC_H__ */
diff -Nru a/drivers/acpi/include/acstruct.h b/drivers/acpi/include/acstruct.h
--- a/drivers/acpi/include/acstruct.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,183 +0,0 @@
-/******************************************************************************
- *
- * Name: acstruct.h - Internal structs
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACSTRUCT_H__
-#define __ACSTRUCT_H__
-
-
-/*****************************************************************************
- *
- * Tree walking typedefs and structs
- *
- ****************************************************************************/
-
-
-/*
- * Walk state - current state of a parse tree walk.  Used for both a leisurely stroll through
- * the tree (for whatever reason), and for control method execution.
- */
-
-#define ACPI_NEXT_OP_DOWNWARD       1
-#define ACPI_NEXT_OP_UPWARD         2
-
-#define ACPI_WALK_NON_METHOD        0
-#define ACPI_WALK_METHOD            1
-#define ACPI_WALK_METHOD_RESTART    2
-#define ACPI_WALK_CONST_REQUIRED    3
-#define ACPI_WALK_CONST_OPTIONAL    4
-
-struct acpi_walk_state
-{
-	u8                                  data_type;                          /* To differentiate various internal objs MUST BE FIRST!*/\
-	acpi_owner_id                       owner_id;                           /* Owner of objects created during the walk */
-	u8                                  last_predicate;                     /* Result of last predicate */
-	u8                                  current_result;                     /* */
-	u8                                  next_op_info;                       /* Info about next_op */
-	u8                                  num_operands;                       /* Stack pointer for Operands[] array */
-	u8                                  return_used;
-	u8                                  walk_type;
-	u16                                 opcode;                             /* Current AML opcode */
-	u8                                  scope_depth;
-	u8                                  reserved1;
-	u32                                 arg_count;                          /* push for fixed or var args */
-	u32                                 aml_offset;
-	u32                                 arg_types;
-	u32                                 method_breakpoint;                  /* For single stepping */
-	u32                                 user_breakpoint;                    /* User AML breakpoint */
-	u32                                 parse_flags;
-	u32                                 prev_arg_types;
-
-	u8                                  *aml_last_while;
-	struct acpi_namespace_node          arguments[ACPI_METHOD_NUM_ARGS];    /* Control method arguments */
-	union acpi_operand_object           **caller_return_desc;
-	union acpi_generic_state            *control_state;                     /* List of control states (nested IFs) */
-	struct acpi_namespace_node          local_variables[ACPI_METHOD_NUM_LOCALS];    /* Control method locals */
-	struct acpi_namespace_node          *method_call_node;                  /* Called method Node*/
-	union acpi_parse_object             *method_call_op;                    /* method_call Op if running a method */
-	union acpi_operand_object           *method_desc;                       /* Method descriptor if running a method */
-	struct acpi_namespace_node          *method_node;                       /* Method Node if running a method */
-	union acpi_parse_object             *op;                                /* Current parser op */
-	union acpi_operand_object           *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
-	const struct acpi_opcode_info       *op_info;                           /* Info on current opcode */
-	union acpi_parse_object             *origin;                            /* Start of walk [Obsolete] */
-	union acpi_operand_object           **params;
-	struct acpi_parse_state             parser_state;                       /* Current state of parser */
-	union acpi_operand_object           *result_obj;
-	union acpi_generic_state            *results;                           /* Stack of accumulated results */
-	union acpi_operand_object           *return_desc;                       /* Return object, if any */
-	union acpi_generic_state            *scope_info;                        /* Stack of nested scopes */
-
-	union acpi_parse_object             *prev_op;                           /* Last op that was processed */
-	union acpi_parse_object             *next_op;                           /* next op to be processed */
-	acpi_parse_downwards                descending_callback;
-	acpi_parse_upwards                  ascending_callback;
-	struct acpi_thread_state            *thread;
-	struct acpi_walk_state              *next;                              /* Next walk_state in list */
-};
-
-
-/* Info used by acpi_ps_init_objects */
-
-struct acpi_init_walk_info
-{
-	u16                             method_count;
-	u16                             device_count;
-	u16                             op_region_count;
-	u16                             field_count;
-	u16                             buffer_count;
-	u16                             package_count;
-	u16                             op_region_init;
-	u16                             field_init;
-	u16                             buffer_init;
-	u16                             package_init;
-	u16                             object_count;
-	struct acpi_table_desc          *table_desc;
-};
-
-
-/* Info used by acpi_ns_initialize_devices */
-
-struct acpi_device_walk_info
-{
-	u16                             device_count;
-	u16                             num_STA;
-	u16                             num_INI;
-	struct acpi_table_desc          *table_desc;
-};
-
-
-/* TBD: [Restructure] Merge with struct above */
-
-struct acpi_walk_info
-{
-	u32                             debug_level;
-	u32                             owner_id;
-	u8                              display_type;
-};
-
-/* Display Types */
-
-#define ACPI_DISPLAY_SUMMARY    0
-#define ACPI_DISPLAY_OBJECTS    1
-
-struct acpi_get_devices_info
-{
-	acpi_walk_callback              user_function;
-	void                            *context;
-	char                            *hid;
-};
-
-
-union acpi_aml_operands
-{
-	union acpi_operand_object           *operands[7];
-
-	struct
-	{
-		struct acpi_object_integer      *type;
-		struct acpi_object_integer      *code;
-		struct acpi_object_integer      *argument;
-
-	} fatal;
-
-	struct
-	{
-		union acpi_operand_object       *source;
-		struct acpi_object_integer      *index;
-		union acpi_operand_object       *target;
-
-	} index;
-
-	struct
-	{
-		union acpi_operand_object       *source;
-		struct acpi_object_integer      *index;
-		struct acpi_object_integer      *length;
-		union acpi_operand_object       *target;
-
-	} mid;
-};
-
-
-#endif
diff -Nru a/drivers/acpi/include/actables.h b/drivers/acpi/include/actables.h
--- a/drivers/acpi/include/actables.h	Mon Feb 10 10:39:24 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,218 +0,0 @@
-/******************************************************************************
- *
- * Name: actables.h - ACPI table management
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTABLES_H__
-#define __ACTABLES_H__
-
-
-/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */
-
-#define SIZE_IN_HEADER          0
-
-
-acpi_status
-acpi_tb_handle_to_object (
-	u16                             table_id,
-	struct acpi_table_desc          **table_desc);
-
-/*
- * tbconvrt - Table conversion routines
- */
-
-acpi_status
-acpi_tb_convert_to_xsdt (
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_convert_table_fadt (
-	void);
-
-acpi_status
-acpi_tb_build_common_facs (
-	struct acpi_table_desc          *table_info);
-
-u32
-acpi_tb_get_table_count (
-	struct rsdp_descriptor          *RSDP,
-	struct acpi_table_header        *RSDT);
-
-/*
- * tbget - Table "get" routines
- */
-
-acpi_status
-acpi_tb_get_table (
-	struct acpi_pointer             *address,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_get_table_header (
-	struct acpi_pointer             *address,
-	struct acpi_table_header        *return_header);
-
-acpi_status
-acpi_tb_get_table_body (
-	struct acpi_pointer             *address,
-	struct acpi_table_header        *header,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_get_this_table (
-	struct acpi_pointer             *address,
-	struct acpi_table_header        *header,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_table_override (
-	struct acpi_table_header        *header,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_get_table_ptr (
-	acpi_table_type                 table_type,
-	u32                             instance,
-	struct acpi_table_header        **table_ptr_loc);
-
-acpi_status
-acpi_tb_verify_rsdp (
-	struct acpi_pointer             *address);
-
-void
-acpi_tb_get_rsdt_address (
-	struct acpi_pointer             *out_address);
-
-acpi_status
-acpi_tb_validate_rsdt (
-	struct acpi_table_header        *table_ptr);
-
-acpi_status
-acpi_tb_get_required_tables (
-	void);
-
-acpi_status
-acpi_tb_get_primary_table (
-	struct acpi_pointer             *address,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_get_secondary_table (
-	struct acpi_pointer             *address,
-	acpi_string                     signature,
-	struct acpi_table_desc          *table_info);
-
-/*
- * tbinstall - Table installation
- */
-
-acpi_status
-acpi_tb_install_table (
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_match_signature (
-	char                            *signature,
-	struct acpi_table_desc          *table_info,
-	u8                              search_type);
-
-acpi_status
-acpi_tb_recognize_table (
-	struct acpi_table_desc          *table_info,
-	u8                             search_type);
-
-acpi_status
-acpi_tb_init_table_descriptor (
-	acpi_table_type                 table_type,
-	struct acpi_table_desc          *table_info);
-
-
-/*
- * tbremove - Table removal and deletion
- */
-
-void
-acpi_tb_delete_acpi_tables (
-	void);
-
-void
-acpi_tb_delete_acpi_table (
-	acpi_table_type                 type);
-
-void
-acpi_tb_delete_single_table (
-	struct acpi_table_desc          *table_desc);
-
-struct acpi_table_desc *
-acpi_tb_uninstall_table (
-	struct acpi_table_desc          *table_desc);
-
-void
-acpi_tb_free_acpi_tables_of_type (
-	struct acpi_table_desc          *table_info);
-
-
-/*
- * tbrsd - RSDP, RSDT utilities
- */
-
-acpi_status
-acpi_tb_get_table_rsdt (
-	void);
-
-u8 *
-acpi_tb_scan_memory_for_rsdp (
-	u8                              *start_address,
-	u32                             length);
-
-acpi_status
-acpi_tb_find_rsdp (
-	struct acpi_table_desc          *table_info,
-	u32                             flags);
-
-
-/*
- * tbutils - common table utilities
- */
-
-acpi_status
-acpi_tb_find_table (
-	char                            *signature,
-	char                            *oem_id,
-	char                            *oem_table_id,
-	struct acpi_table_header        **table_ptr);
-
-acpi_status
-acpi_tb_verify_table_checksum (
-	struct acpi_table_header        *table_header);
-
-u8
-acpi_tb_checksum (
-	void                            *buffer,
-	u32                             length);
-
-acpi_status
-acpi_tb_validate_table_header (
-	struct acpi_table_header        *table_header);
-
-
-#endif /* __ACTABLES_H__ */
diff -Nru a/drivers/acpi/include/actbl.h b/drivers/acpi/include/actbl.h
--- a/drivers/acpi/include/actbl.h	Mon Feb 10 10:39:27 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,208 +0,0 @@
-/******************************************************************************
- *
- * Name: actbl.h - Table data structures defined in ACPI specification
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTBL_H__
-#define __ACTBL_H__
-
-
-/*
- *  Values for description table header signatures
- */
-#define RSDP_NAME               "RSDP"
-#define RSDP_SIG                "RSD PTR "  /* RSDT Pointer signature */
-#define APIC_SIG                "APIC"      /* Multiple APIC Description Table */
-#define DSDT_SIG                "DSDT"      /* Differentiated System Description Table */
-#define FADT_SIG                "FACP"      /* Fixed ACPI Description Table */
-#define FACS_SIG                "FACS"      /* Firmware ACPI Control Structure */
-#define PSDT_SIG                "PSDT"      /* Persistent System Description Table */
-#define RSDT_SIG                "RSDT"      /* Root System Description Table */
-#define XSDT_SIG                "XSDT"      /* Extended  System Description Table */
-#define SSDT_SIG                "SSDT"      /* Secondary System Description Table */
-#define SBST_SIG                "SBST"      /* Smart Battery Specification Table */
-#define SPIC_SIG                "SPIC"      /* IOSAPIC table */
-#define BOOT_SIG                "BOOT"      /* Boot table */
-
-
-#define GL_OWNED                0x02        /* Ownership of global lock is bit 1 */
-
-/* values of Mapic.Model */
-
-#define DUAL_PIC                0
-#define MULTIPLE_APIC           1
-
-/* values of Type in struct apic_header */
-
-#define APIC_PROC               0
-#define APIC_IO                 1
-
-
-/*
- * Common table types.  The base code can remain
- * constant if the underlying tables are changed
- */
-#define RSDT_DESCRIPTOR         struct rsdt_descriptor_rev2
-#define XSDT_DESCRIPTOR         struct xsdt_descriptor_rev2
-#define FACS_DESCRIPTOR         struct facs_descriptor_rev2
-#define FADT_DESCRIPTOR         struct fadt_descriptor_rev2
-
-
-#pragma pack(1)
-
-/*
- * Architecture-independent tables
- * The architecture dependent tables are in separate files
- */
-struct rsdp_descriptor         /* Root System Descriptor Pointer */
-{
-	char                            signature [8];          /* ACPI signature, contains "RSD PTR " */
-	u8                              checksum;               /* To make sum of struct == 0 */
-	char                            oem_id [6];             /* OEM identification */
-	u8                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
-	u32                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
-	u32                             length;                 /* XSDT Length in bytes including hdr */
-	u64                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
-	u8                              extended_checksum;      /* Checksum of entire table */
-	char                            reserved [3];           /* Reserved field must be 0 */
-};
-
-
-struct acpi_table_header         /* ACPI common table header */
-{
-	char                            signature [4];          /* ACPI signature (4 ASCII characters) */
-	u32                             length;                 /* Length of table, in bytes, including header */
-	u8                              revision;               /* ACPI Specification minor version # */
-	u8                              checksum;               /* To make sum of entire table == 0 */
-	char                            oem_id [6];             /* OEM identification */
-	char                            oem_table_id [8];       /* OEM table identification */
-	u32                             oem_revision;           /* OEM revision number */
-	char                            asl_compiler_id [4];    /* ASL compiler vendor ID */
-	u32                             asl_compiler_revision;  /* ASL compiler revision number */
-};
-
-
-struct acpi_common_facs          /* Common FACS for internal use */
-{
-	u32                             *global_lock;
-	u64                             *firmware_waking_vector;
-	u8                              vector_width;
-};
-
-
-struct apic_table
-{
-	struct acpi_table_header        header;                 /* ACPI table header */
-	u32                             local_apic_address;     /* Physical address for accessing local APICs */
-	u32                             PCATcompat      : 1;    /* a one indicates system also has dual 8259s */
-	u32                             reserved1       : 31;
-};
-
-
-struct apic_header
-{
-	u8                              type;                   /* APIC type.  Either APIC_PROC or APIC_IO */
-	u8                              length;                 /* Length of APIC structure */
-};
-
-
-struct processor_apic
-{
-	struct apic_header              header;
-	u8                              processor_apic_id;      /* ACPI processor id */
-	u8                              local_apic_id;          /* Processor's local APIC id */
-	u32                             processor_enabled: 1;   /* Processor is usable if set */
-	u32                             reserved1       : 31;
-};
-
-
-struct io_apic
-{
-	struct apic_header              header;
-	u8                              io_apic_id;             /* I/O APIC ID */
-	u8                              reserved;               /* Reserved - must be zero */
-	u32                             io_apic_address;        /* APIC's physical address */
-	u32                             vector;                 /* Interrupt vector index where INTI
-			  * lines start */
-};
-
-
-/*
- *  IA64 TBD:  Add SAPIC Tables
- */
-
-/*
- *  IA64 TBD:   Modify Smart Battery Description to comply with ACPI IA64
- *              extensions.
- */
-struct smart_battery_description_table
-{
-	struct acpi_table_header        header;
-	u32                             warning_level;
-	u32                             low_level;
-	u32                             critical_level;
-};
-
-
-#pragma pack()
-
-
-/*
- * ACPI Table information.  We save the table address, length,
- * and type of memory allocation (mapped or allocated) for each
- * table for 1) when we exit, and 2) if a new table is installed
- */
-#define ACPI_MEM_NOT_ALLOCATED  0
-#define ACPI_MEM_ALLOCATED      1
-#define ACPI_MEM_MAPPED         2
-
-/* Definitions for the Flags bitfield member of struct acpi_table_support */
-
-#define ACPI_TABLE_SINGLE       0x00
-#define ACPI_TABLE_MULTIPLE     0x01
-#define ACPI_TABLE_EXECUTABLE   0x02
-
-#define ACPI_TABLE_ROOT         0x00
-#define ACPI_TABLE_PRIMARY      0x10
-#define ACPI_TABLE_SECONDARY    0x20
-#define ACPI_TABLE_OTHER        0x30
-#define ACPI_TABLE_TYPE_MASK    0x30
-
-/* Data about each known table type */
-
-struct acpi_table_support
-{
-	char                            *name;
-	char                            *signature;
-	void                            **global_ptr;
-	u8                              sig_length;
-	u8                              flags;
-};
-
-
-/*
- * Get the architecture-specific tables
- */
-#include "actbl1.h"   /* Acpi 1.0 table definitions */
-#include "actbl2.h"   /* Acpi 2.0 table definitions */
-
-#endif /* __ACTBL_H__ */
diff -Nru a/drivers/acpi/include/actbl1.h b/drivers/acpi/include/actbl1.h
--- a/drivers/acpi/include/actbl1.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,117 +0,0 @@
-/******************************************************************************
- *
- * Name: actbl1.h - ACPI 1.0 tables
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTBL1_H__
-#define __ACTBL1_H__
-
-#pragma pack(1)
-
-/*
- * ACPI 1.0 Root System Description Table (RSDT)
- */
-struct rsdt_descriptor_rev1
-{
-	struct acpi_table_header        header;                 /* ACPI Table header */
-	u32                             table_offset_entry [1]; /* Array of pointers to other */
-			 /* ACPI tables */
-};
-
-
-/*
- * ACPI 1.0 Firmware ACPI Control Structure (FACS)
- */
-struct facs_descriptor_rev1
-{
-	char                            signature[4];           /* ACPI Signature */
-	u32                             length;                 /* Length of structure, in bytes */
-	u32                             hardware_signature;     /* Hardware configuration signature */
-	u32                             firmware_waking_vector; /* ACPI OS waking vector */
-	u32                             global_lock;            /* Global Lock */
-	u32                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
-	u32                             reserved1       : 31;   /* Must be 0 */
-	u8                              resverved3 [40];        /* Reserved - must be zero */
-};
-
-
-/*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
- */
-struct fadt_descriptor_rev1
-{
-	struct acpi_table_header        header;                 /* ACPI Table header */
-	u32                             firmware_ctrl;          /* Physical address of FACS */
-	u32                             dsdt;                   /* Physical address of DSDT */
-	u8                              model;                  /* System Interrupt Model */
-	u8                              reserved1;              /* Reserved */
-	u16                             sci_int;                /* System vector of SCI interrupt */
-	u32                             smi_cmd;                /* Port address of SMI command port */
-	u8                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
-	u8                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
-	u8                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
-	u8                              reserved2;              /* Reserved - must be zero */
-	u32                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
-	u32                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
-	u32                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
-	u32                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
-	u32                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
-	u32                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
-	u32                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
-	u32                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
-	u8                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
-	u8                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
-	u8                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
-	u8                              pm_tm_len;              /* Byte Length of ports at pm_tm_blk */
-	u8                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
-	u8                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
-	u8                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
-	u8                              reserved3;              /* Reserved */
-	u16                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
-	u16                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
-	u16                             flush_size;             /* Size of area read to flush caches */
-	u16                             flush_stride;           /* Stride used in flushing caches */
-	u8                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
-	u8                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
-	u8                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
-	u8                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
-	u8                              century;                /* Index to century in RTC CMOS RAM */
-	u8                              reserved4;              /* Reserved */
-	u8                              reserved4a;             /* Reserved */
-	u8                              reserved4b;             /* Reserved */
-	u32                             wb_invd         : 1;    /* The wbinvd instruction works properly */
-	u32                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
-	u32                             proc_c1         : 1;    /* All processors support C1 state */
-	u32                             plvl2_up        : 1;    /* C2 state works on MP system */
-	u32                             pwr_button      : 1;    /* Power button is handled as a generic feature */
-	u32                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
-	u32                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
-	u32                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
-	u32                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
-	u32                             reserved5       : 23;   /* Reserved - must be zero */
-};
-
-#pragma pack()
-
-#endif /* __ACTBL1_H__ */
-
-
diff -Nru a/drivers/acpi/include/actbl2.h b/drivers/acpi/include/actbl2.h
--- a/drivers/acpi/include/actbl2.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,182 +0,0 @@
-/******************************************************************************
- *
- * Name: actbl2.h - ACPI Specification Revision 2.0 Tables
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTBL2_H__
-#define __ACTBL2_H__
-
-/*
- * Prefered Power Management Profiles
- */
-#define PM_UNSPECIFIED                  0
-#define PM_DESKTOP                      1
-#define PM_MOBILE                       2
-#define PM_WORKSTATION                  3
-#define PM_ENTERPRISE_SERVER            4
-#define PM_SOHO_SERVER                  5
-#define PM_APPLIANCE_PC                 6
-
-/*
- * ACPI Boot Arch Flags
- */
-#define BAF_LEGACY_DEVICES              0x0001
-#define BAF_8042_KEYBOARD_CONTROLLER    0x0002
-
-#define FADT2_REVISION_ID               3
-
-
-#pragma pack(1)
-
-/*
- * ACPI 2.0 Root System Description Table (RSDT)
- */
-struct rsdt_descriptor_rev2
-{
-	struct acpi_table_header        header;                 /* ACPI table header */
-	u32                             table_offset_entry [1]; /* Array of pointers to  */
-			 /* ACPI table headers */
-};
-
-
-/*
- * ACPI 2.0 Extended System Description Table (XSDT)
- */
-struct xsdt_descriptor_rev2
-{
-	struct acpi_table_header        header;                 /* ACPI table header */
-	u64                             table_offset_entry [1]; /* Array of pointers to  */
-			 /* ACPI table headers */
-};
-
-
-/*
- * ACPI 2.0 Firmware ACPI Control Structure (FACS)
- */
-struct facs_descriptor_rev2
-{
-	char                            signature[4];           /* ACPI signature */
-	u32                             length;                 /* Length of structure, in bytes */
-	u32                             hardware_signature;     /* Hardware configuration signature */
-	u32                             firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */
-	u32                             global_lock;            /* Global Lock used to synchronize access to shared hardware resources */
-	u32                             S4bios_f        : 1;    /* S4Bios_f - Indicates if S4BIOS support is present */
-	u32                             reserved1       : 31;   /* Must be 0 */
-	u64                             xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */
-	u8                              version;                /* Version of this table */
-	u8                              reserved3 [31];         /* Reserved - must be zero */
-};
-
-
-/*
- * ACPI 2.0 Generic Address Structure (GAS)
- */
-struct acpi_generic_address
-{
-	u8                              address_space_id;       /* Address space where struct or register exists. */
-	u8                              register_bit_width;     /* Size in bits of given register */
-	u8                              register_bit_offset;    /* Bit offset within the register */
-	u8                              reserved;               /* Must be 0 */
-	u64                             address;                /* 64-bit address of struct or register */
-};
-
-
-/*
- * ACPI 2.0 Fixed ACPI Description Table (FADT)
- */
-struct fadt_descriptor_rev2
-{
-	struct acpi_table_header        header;             /* ACPI table header */
-	u32                             V1_firmware_ctrl;   /* 32-bit physical address of FACS */
-	u32                             V1_dsdt;            /* 32-bit physical address of DSDT */
-	u8                              reserved1;          /* System Interrupt Model isn't used in ACPI 2.0*/
-	u8                              prefer_PM_profile;  /* Conveys preferred power management profile to OSPM. */
-	u16                             sci_int;            /* System vector of SCI interrupt */
-	u32                             smi_cmd;            /* Port address of SMI command port */
-	u8                              acpi_enable;        /* Value to write to smi_cmd to enable ACPI */
-	u8                              acpi_disable;       /* Value to write to smi_cmd to disable ACPI */
-	u8                              S4bios_req;         /* Value to write to SMI CMD to enter S4BIOS state */
-	u8                              pstate_cnt;         /* Processor performance state control*/
-	u32                             V1_pm1a_evt_blk;    /* Port address of Power Mgt 1a acpi_event Reg Blk */
-	u32                             V1_pm1b_evt_blk;    /* Port address of Power Mgt 1b acpi_event Reg Blk */
-	u32                             V1_pm1a_cnt_blk;    /* Port address of Power Mgt 1a Control Reg Blk */
-	u32                             V1_pm1b_cnt_blk;    /* Port address of Power Mgt 1b Control Reg Blk */
-	u32                             V1_pm2_cnt_blk;     /* Port address of Power Mgt 2 Control Reg Blk */
-	u32                             V1_pm_tmr_blk;      /* Port address of Power Mgt Timer Ctrl Reg Blk */
-	u32                             V1_gpe0_blk;        /* Port addr of General Purpose acpi_event 0 Reg Blk */
-	u32                             V1_gpe1_blk;        /* Port addr of General Purpose acpi_event 1 Reg Blk */
-	u8                              pm1_evt_len;        /* Byte length of ports at pm1_x_evt_blk */
-	u8                              pm1_cnt_len;        /* Byte length of ports at pm1_x_cnt_blk */
-	u8                              pm2_cnt_len;        /* Byte Length of ports at pm2_cnt_blk */
-	u8                              pm_tm_len;          /* Byte Length of ports at pm_tm_blk */
-	u8                              gpe0_blk_len;       /* Byte Length of ports at gpe0_blk */
-	u8                              gpe1_blk_len;       /* Byte Length of ports at gpe1_blk */
-	u8                              gpe1_base;          /* Offset in gpe model where gpe1 events start */
-	u8                              cst_cnt;            /* Support for the _CST object and C States change notification.*/
-	u16                             plvl2_lat;          /* Worst case HW latency to enter/exit C2 state */
-	u16                             plvl3_lat;          /* Worst case HW latency to enter/exit C3 state */
-	u16                             flush_size;         /* Number of flush strides that need to be read */
-	u16                             flush_stride;       /* Processor's memory cache line width, in bytes */
-	u8                              duty_offset;        /* Processor's duty cycle index in processor's P_CNT reg*/
-	u8                              duty_width;         /* Processor's duty cycle value bit width in P_CNT register.*/
-	u8                              day_alrm;           /* Index to day-of-month alarm in RTC CMOS RAM */
-	u8                              mon_alrm;           /* Index to month-of-year alarm in RTC CMOS RAM */
-	u8                              century;            /* Index to century in RTC CMOS RAM */
-	u16                             iapc_boot_arch;     /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
-	u8                              reserved2;          /* Reserved */
-	u32                             wb_invd     : 1;    /* The wbinvd instruction works properly */
-	u32                             wb_invd_flush : 1;  /* The wbinvd flushes but does not invalidate */
-	u32                             proc_c1     : 1;    /* All processors support C1 state */
-	u32                             plvl2_up    : 1;    /* C2 state works on MP system */
-	u32                             pwr_button  : 1;    /* Power button is handled as a generic feature */
-	u32                             sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
-	u32                             fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
-	u32                             rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
-	u32                             tmr_val_ext : 1;    /* Indicates tmr_val is 32 bits 0=24-bits*/
-	u32                             dock_cap    : 1;    /* Supports Docking */
-	u32                             reset_reg_sup : 1;  /* Indicates system supports system reset via the FADT RESET_REG*/
-	u32                             sealed_case : 1;    /* Indicates system has no internal expansion capabilities and case is sealed. */
-	u32                             headless    : 1;    /* Indicates system does not have local video capabilities or local input devices.*/
-	u32                             cpu_sw_sleep : 1;   /* Indicates to OSPM that a processor native instruction */
-			   /* Must be executed after writing the SLP_TYPx register. */
-	u32                             reserved6   : 18;   /* Reserved - must be zero */
-
-	struct acpi_generic_address     reset_register;     /* Reset register address in GAS format */
-	u8                              reset_value;        /* Value to write to the reset_register port to reset the system. */
-	u8                              reserved7[3];       /* These three bytes must be zero */
-	u64                             xfirmware_ctrl;     /* 64-bit physical address of FACS */
-	u64                             Xdsdt;              /* 64-bit physical address of DSDT */
-	struct acpi_generic_address     xpm1a_evt_blk;      /* Extended Power Mgt 1a acpi_event Reg Blk address */
-	struct acpi_generic_address     xpm1b_evt_blk;      /* Extended Power Mgt 1b acpi_event Reg Blk address */
-	struct acpi_generic_address     xpm1a_cnt_blk;      /* Extended Power Mgt 1a Control Reg Blk address */
-	struct acpi_generic_address     xpm1b_cnt_blk;      /* Extended Power Mgt 1b Control Reg Blk address */
-	struct acpi_generic_address     xpm2_cnt_blk;       /* Extended Power Mgt 2 Control Reg Blk address */
-	struct acpi_generic_address     xpm_tmr_blk;        /* Extended Power Mgt Timer Ctrl Reg Blk address */
-	struct acpi_generic_address     xgpe0_blk;          /* Extended General Purpose acpi_event 0 Reg Blk address */
-	struct acpi_generic_address     xgpe1_blk;          /* Extended General Purpose acpi_event 1 Reg Blk address */
-};
-
-
-#pragma pack()
-
-#endif /* __ACTBL2_H__ */
-
diff -Nru a/drivers/acpi/include/actbl71.h b/drivers/acpi/include/actbl71.h
--- a/drivers/acpi/include/actbl71.h	Mon Feb 10 10:39:26 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,144 +0,0 @@
-/******************************************************************************
- *
- * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71
- *                   This file includes tables specific to this
- *                   specification revision.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTBL71_H__
-#define __ACTBL71_H__
-
-
-/* 0.71 FADT address_space data item bitmasks defines */
-/* If the associated bit is zero then it is in memory space else in io space */
-
-#define SMI_CMD_ADDRESS_SPACE       0x01
-#define PM1_BLK_ADDRESS_SPACE       0x02
-#define PM2_CNT_BLK_ADDRESS_SPACE   0x04
-#define PM_TMR_BLK_ADDRESS_SPACE    0x08
-#define GPE0_BLK_ADDRESS_SPACE      0x10
-#define GPE1_BLK_ADDRESS_SPACE      0x20
-
-/* Only for clarity in declarations */
-
-typedef u64                         IO_ADDRESS;
-
-
-#pragma pack(1)
-struct  /* Root System Descriptor Pointer */
-{
-	NATIVE_CHAR             signature [8];          /* contains "RSD PTR " */
-	u8                              checksum;               /* to make sum of struct == 0 */
-	NATIVE_CHAR             oem_id [6];             /* OEM identification */
-	u8                              reserved;               /* Must be 0 for 1.0, 2 for 2.0 */
-	u64                             rsdt_physical_address;  /* 64-bit physical address of RSDT */
-};
-
-
-/*****************************************/
-/* IA64 Extensions to ACPI Spec Rev 0.71 */
-/* for the Root System Description Table */
-/*****************************************/
-struct
-{
-	struct acpi_table_header    header;                 /* Table header */
-	u32                         reserved_pad;           /* IA64 alignment, must be 0 */
-	u64                         table_offset_entry [1]; /* Array of pointers to other */
-			   /* tables' headers */
-};
-
-
-/*******************************************/
-/* IA64 Extensions to ACPI Spec Rev 0.71   */
-/* for the Firmware ACPI Control Structure */
-/*******************************************/
-struct
-{
-	NATIVE_CHAR         signature[4];         /* signature "FACS" */
-	u32                         length;               /* length of structure, in bytes */
-	u32                         hardware_signature;   /* hardware configuration signature */
-	u32                         reserved4;            /* must be 0 */
-	u64                         firmware_waking_vector; /* ACPI OS waking vector */
-	u64                         global_lock;          /* Global Lock */
-	u32                         S4bios_f      : 1;    /* Indicates if S4BIOS support is present */
-	u32                         reserved1     : 31;   /* must be 0 */
-	u8                          reserved3 [28];       /* reserved - must be zero */
-};
-
-
-/******************************************/
-/* IA64 Extensions to ACPI Spec Rev 0.71  */
-/* for the Fixed ACPI Description Table   */
-/******************************************/
-struct
-{
-	struct acpi_table_header    header;             /* table header */
-	u32                         reserved_pad;       /* IA64 alignment, must be 0 */
-	u64                         firmware_ctrl;      /* 64-bit Physical address of FACS */
-	u64                         dsdt;               /* 64-bit Physical address of DSDT */
-	u8                          model;              /* System Interrupt Model */
-	u8                          address_space;      /* Address Space Bitmask */
-	u16                         sci_int;            /* System vector of SCI interrupt */
-	u8                          acpi_enable;        /* value to write to smi_cmd to enable ACPI */
-	u8                          acpi_disable;       /* value to write to smi_cmd to disable ACPI */
-	u8                          S4bios_req;         /* Value to write to SMI CMD to enter S4BIOS state */
-	u8                          reserved2;          /* reserved - must be zero */
-	u64                         smi_cmd;            /* Port address of SMI command port */
-	u64                         pm1a_evt_blk;       /* Port address of Power Mgt 1a acpi_event Reg Blk */
-	u64                         pm1b_evt_blk;       /* Port address of Power Mgt 1b acpi_event Reg Blk */
-	u64                         pm1a_cnt_blk;       /* Port address of Power Mgt 1a Control Reg Blk */
-	u64                         pm1b_cnt_blk;       /* Port address of Power Mgt 1b Control Reg Blk */
-	u64                         pm2_cnt_blk;        /* Port address of Power Mgt 2 Control Reg Blk */
-	u64                         pm_tmr_blk;         /* Port address of Power Mgt Timer Ctrl Reg Blk */
-	u64                         gpe0_blk;           /* Port addr of General Purpose acpi_event 0 Reg Blk */
-	u64                         gpe1_blk;           /* Port addr of General Purpose acpi_event 1 Reg Blk */
-	u8                          pm1_evt_len;        /* Byte length of ports at pm1_x_evt_blk */
-	u8                          pm1_cnt_len;        /* Byte length of ports at pm1_x_cnt_blk */
-	u8                          pm2_cnt_len;        /* Byte Length of ports at pm2_cnt_blk */
-	u8                          pm_tm_len;          /* Byte Length of ports at pm_tm_blk */
-	u8                          gpe0_blk_len;       /* Byte Length of ports at gpe0_blk */
-	u8                          gpe1_blk_len;       /* Byte Length of ports at gpe1_blk */
-	u8                          gpe1_base;          /* offset in gpe model where gpe1 events start */
-	u8                          reserved3;          /* reserved */
-	u16                         plvl2_lat;          /* worst case HW latency to enter/exit C2 state */
-	u16                         plvl3_lat;          /* worst case HW latency to enter/exit C3 state */
-	u8                          day_alrm;           /* index to day-of-month alarm in RTC CMOS RAM */
-	u8                          mon_alrm;           /* index to month-of-year alarm in RTC CMOS RAM */
-	u8                          century;            /* index to century in RTC CMOS RAM */
-	u8                          reserved4;          /* reserved */
-	u32                         flush_cash  : 1;    /* PAL_FLUSH_CACHE is correctly supported */
-	u32                         reserved5   : 1;    /* reserved - must be zero */
-	u32                         proc_c1     : 1;    /* all processors support C1 state */
-	u32                         plvl2_up    : 1;    /* C2 state works on MP system */
-	u32                         pwr_button  : 1;    /* Power button is handled as a generic feature */
-	u32                         sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
-	u32                         fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
-	u32                         rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
-	u32                         tmr_val_ext : 1;    /* tmr_val is 32 bits */
-	u32                         dock_cap    : 1;    /* Supports Docking */
-	u32                         reserved6   : 22;    /* reserved - must be zero */
-};
-
-#pragma pack()
-
-#endif /* __ACTBL71_H__ */
-
diff -Nru a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h
--- a/drivers/acpi/include/actypes.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1189 +0,0 @@
-/******************************************************************************
- *
- * Name: actypes.h - Common data types for the entire ACPI subsystem
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACTYPES_H__
-#define __ACTYPES_H__
-
-/*! [Begin] no source code translation (keep the typedefs) */
-
-
-
-/*
- * Data type ranges
- */
-#define ACPI_UINT8_MAX                  (UINT8)  0xFF
-#define ACPI_UINT16_MAX                 (UINT16) 0xFFFF
-#define ACPI_UINT32_MAX                 (UINT32) 0xFFFFFFFF
-#define ACPI_UINT64_MAX                 (UINT64) 0xFFFFFFFFFFFFFFFF
-#define ACPI_ASCII_MAX                  0x7F
-
-
-#ifdef DEFINE_ALTERNATE_TYPES
-/*
- * Types used only in translated source, defined here to enable
- * cross-platform compilation only.
- */
-typedef int                             s32;
-typedef unsigned char                   u8;
-typedef unsigned short                  u16;
-typedef unsigned int                    u32;
-typedef COMPILER_DEPENDENT_UINT64       u64;
-
-#endif
-
-
-/*
- * Data types - Fixed across all compilation models (16/32/64)
- *
- * BOOLEAN          Logical Boolean.
- * INT8             8-bit  (1 byte) signed value
- * UINT8            8-bit  (1 byte) unsigned value
- * INT16            16-bit (2 byte) signed value
- * UINT16           16-bit (2 byte) unsigned value
- * INT32            32-bit (4 byte) signed value
- * UINT32           32-bit (4 byte) unsigned value
- * INT64            64-bit (8 byte) signed value
- * UINT64           64-bit (8 byte) unsigned value
- * ACPI_NATIVE_INT  32-bit on IA-32, 64-bit on IA-64 signed value
- * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value
- */
-
-#ifndef ACPI_MACHINE_WIDTH
-#error ACPI_MACHINE_WIDTH not defined
-#endif
-
-#if ACPI_MACHINE_WIDTH == 64
-
-/*! [Begin] no source code translation (keep the typedefs) */
-
-/*
- * 64-bit type definitions
- */
-typedef unsigned char                   UINT8;
-typedef unsigned char                   BOOLEAN;
-typedef unsigned short                  UINT16;
-typedef int                             INT32;
-typedef unsigned int                    UINT32;
-typedef COMPILER_DEPENDENT_INT64        INT64;
-typedef COMPILER_DEPENDENT_UINT64       UINT64;
-
-/*! [End] no source code translation !*/
-
-typedef s64                                     acpi_native_int;
-typedef u64                                     acpi_native_uint;
-
-typedef u64                                     acpi_table_ptr;
-typedef u64                                     acpi_io_address;
-typedef u64                                     acpi_physical_address;
-typedef u64                                     acpi_size;
-
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000008      /* No hardware alignment support in IA64 */
-#define ACPI_USE_NATIVE_DIVIDE                          /* Native 64-bit integer support */
-#define ACPI_MAX_PTR                    ACPI_UINT64_MAX
-#define ACPI_SIZE_MAX                   ACPI_UINT64_MAX
-
-
-#elif ACPI_MACHINE_WIDTH == 16
-
-/*! [Begin] no source code translation (keep the typedefs) */
-
-/*
- * 16-bit type definitions
- */
-typedef unsigned char                   UINT8;
-typedef unsigned char                   BOOLEAN;
-typedef unsigned int                    UINT16;
-typedef long                            INT32;
-typedef int                             INT16;
-typedef unsigned long                   UINT32;
-
-struct
-{
-	UINT32                                  Lo;
-	UINT32                                  Hi;
-};
-
-/*! [End] no source code translation !*/
-
-typedef u16                                     acpi_native_uint;
-typedef s16                                     acpi_native_int;
-
-typedef u32                                     acpi_table_ptr;
-typedef u32                                     acpi_io_address;
-typedef char                                    *acpi_physical_address;
-typedef u16                                     acpi_size;
-
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000002
-#define _HW_ALIGNMENT_SUPPORT
-#define ACPI_USE_NATIVE_DIVIDE                          /* No 64-bit integers, ok to use native divide */
-#define ACPI_MAX_PTR                    ACPI_UINT16_MAX
-#define ACPI_SIZE_MAX                   ACPI_UINT16_MAX
-
-/*
- * (16-bit only) internal integers must be 32-bits, so
- * 64-bit integers cannot be supported
- */
-#define ACPI_NO_INTEGER64_SUPPORT
-
-
-#elif ACPI_MACHINE_WIDTH == 32
-
-/*! [Begin] no source code translation (keep the typedefs) */
-
-/*
- * 32-bit type definitions (default)
- */
-typedef unsigned char                   UINT8;
-typedef unsigned char                   BOOLEAN;
-typedef unsigned short                  UINT16;
-typedef int                             INT32;
-typedef unsigned int                    UINT32;
-typedef COMPILER_DEPENDENT_INT64        INT64;
-typedef COMPILER_DEPENDENT_UINT64       UINT64;
-
-/*! [End] no source code translation !*/
-
-typedef s32                                     acpi_native_int;
-typedef u32                                     acpi_native_uint;
-
-typedef u64                                     acpi_table_ptr;
-typedef u32                                     acpi_io_address;
-typedef u64                                     acpi_physical_address;
-typedef u32                                     acpi_size;
-
-#define ALIGNED_ADDRESS_BOUNDARY        0x00000004
-#define _HW_ALIGNMENT_SUPPORT
-#define ACPI_MAX_PTR                    ACPI_UINT32_MAX
-#define ACPI_SIZE_MAX                   ACPI_UINT32_MAX
-
-#else
-#error unknown ACPI_MACHINE_WIDTH
-#endif
-
-
-/*
- * Miscellaneous common types
- */
-typedef u32                                     UINT32_BIT;
-typedef acpi_native_uint                        ACPI_PTRDIFF;
-
-/*
- * Pointer overlays to avoid lots of typecasting for
- * code that accepts both physical and logical pointers.
- */
-union acpi_pointers
-{
-	acpi_physical_address               physical;
-	void                                *logical;
-	acpi_table_ptr                      value;
-};
-
-struct acpi_pointer
-{
-	u32                                 pointer_type;
-	union acpi_pointers                 pointer;
-};
-
-/* pointer_types for above */
-
-#define ACPI_PHYSICAL_POINTER           0x01
-#define ACPI_LOGICAL_POINTER            0x02
-
-/* Processor mode */
-
-#define ACPI_PHYSICAL_ADDRESSING        0x04
-#define ACPI_LOGICAL_ADDRESSING         0x08
-#define ACPI_MEMORY_MODE                0x0C
-
-#define ACPI_PHYSMODE_PHYSPTR           ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
-#define ACPI_LOGMODE_PHYSPTR            ACPI_LOGICAL_ADDRESSING  | ACPI_PHYSICAL_POINTER
-#define ACPI_LOGMODE_LOGPTR             ACPI_LOGICAL_ADDRESSING  | ACPI_LOGICAL_POINTER
-
-
-/*
- * Useful defines
- */
-#ifdef FALSE
-#undef FALSE
-#endif
-#define FALSE                           (1 == 0)
-
-#ifdef TRUE
-#undef TRUE
-#endif
-#define TRUE                            (1 == 1)
-
-#ifndef NULL
-#define NULL                            (void *) 0
-#endif
-
-
-/*
- * Local datatypes
- */
-typedef u32                                     acpi_status;    /* All ACPI Exceptions */
-typedef u32                                     acpi_name;      /* 4-byte ACPI name */
-typedef char *                                  acpi_string;    /* Null terminated ASCII string */
-typedef void *                                  acpi_handle;    /* Actually a ptr to an Node */
-
-struct uint64_struct
-{
-	u32                                 lo;
-	u32                                 hi;
-};
-
-union uint64_overlay
-{
-	u64                                 full;
-	struct uint64_struct                part;
-};
-
-struct uint32_struct
-{
-	u32                                 lo;
-	u32                                 hi;
-};
-
-
-/*
- * Acpi integer width. In ACPI version 1, integers are
- * 32 bits.  In ACPI version 2, integers are 64 bits.
- * Note that this pertains to the ACPI integer type only, not
- * other integers used in the implementation of the ACPI CA
- * subsystem.
- */
-#ifdef ACPI_NO_INTEGER64_SUPPORT
-
-/* 32-bit integers only, no 64-bit support */
-
-typedef u32                                     acpi_integer;
-#define ACPI_INTEGER_MAX                ACPI_UINT32_MAX
-#define ACPI_INTEGER_BIT_SIZE           32
-#define ACPI_MAX_BCD_VALUE              99999999
-#define ACPI_MAX_BCD_DIGITS             8
-#define ACPI_MAX_DECIMAL_DIGITS         10
-
-#define ACPI_USE_NATIVE_DIVIDE          /* Use compiler native 32-bit divide */
-
-
-#else
-
-/* 64-bit integers */
-
-typedef u64                                     acpi_integer;
-#define ACPI_INTEGER_MAX                ACPI_UINT64_MAX
-#define ACPI_INTEGER_BIT_SIZE           64
-#define ACPI_MAX_BCD_VALUE              9999999999999999
-#define ACPI_MAX_BCD_DIGITS             16
-#define ACPI_MAX_DECIMAL_DIGITS         19
-
-#if ACPI_MACHINE_WIDTH == 64
-#define ACPI_USE_NATIVE_DIVIDE          /* Use compiler native 64-bit divide */
-#endif
-#endif
-
-
-/*
- * Constants with special meanings
- */
-#define ACPI_ROOT_OBJECT                (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR)
-
-
-/*
- * Initialization sequence
- */
-#define ACPI_FULL_INITIALIZATION        0x00
-#define ACPI_NO_ADDRESS_SPACE_INIT      0x01
-#define ACPI_NO_HARDWARE_INIT           0x02
-#define ACPI_NO_EVENT_INIT              0x04
-#define ACPI_NO_HANDLER_INIT            0x08
-#define ACPI_NO_ACPI_ENABLE             0x10
-#define ACPI_NO_DEVICE_INIT             0x20
-#define ACPI_NO_OBJECT_INIT             0x40
-
-/*
- * Initialization state
- */
-#define ACPI_INITIALIZED_OK             0x01
-
-/*
- * Power state values
- */
-
-#define ACPI_STATE_UNKNOWN              (u8) 0xFF
-
-#define ACPI_STATE_S0                   (u8) 0
-#define ACPI_STATE_S1                   (u8) 1
-#define ACPI_STATE_S2                   (u8) 2
-#define ACPI_STATE_S3                   (u8) 3
-#define ACPI_STATE_S4                   (u8) 4
-#define ACPI_STATE_S5                   (u8) 5
-#define ACPI_S_STATES_MAX               ACPI_STATE_S5
-#define ACPI_S_STATE_COUNT              6
-
-#define ACPI_STATE_D0                   (u8) 0
-#define ACPI_STATE_D1                   (u8) 1
-#define ACPI_STATE_D2                   (u8) 2
-#define ACPI_STATE_D3                   (u8) 3
-#define ACPI_D_STATES_MAX               ACPI_STATE_D3
-#define ACPI_D_STATE_COUNT              4
-
-#define ACPI_STATE_C0                   (u8) 0
-#define ACPI_STATE_C1                   (u8) 1
-#define ACPI_STATE_C2                   (u8) 2
-#define ACPI_STATE_C3                   (u8) 3
-#define ACPI_C_STATES_MAX               ACPI_STATE_C3
-#define ACPI_C_STATE_COUNT              4
-
-/*
- * Sleep type invalid value
- */
-#define ACPI_SLEEP_TYPE_MAX             0x7
-#define ACPI_SLEEP_TYPE_INVALID         0xFF
-
-/*
- * Standard notify values
- */
-#define ACPI_NOTIFY_BUS_CHECK           (u8) 0
-#define ACPI_NOTIFY_DEVICE_CHECK        (u8) 1
-#define ACPI_NOTIFY_DEVICE_WAKE         (u8) 2
-#define ACPI_NOTIFY_EJECT_REQUEST       (u8) 3
-#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT  (u8) 4
-#define ACPI_NOTIFY_FREQUENCY_MISMATCH  (u8) 5
-#define ACPI_NOTIFY_BUS_MODE_MISMATCH   (u8) 6
-#define ACPI_NOTIFY_POWER_FAULT         (u8) 7
-
-
-/*
- *  Table types.  These values are passed to the table related APIs
- */
-typedef u32                                     acpi_table_type;
-
-#define ACPI_TABLE_RSDP                 (acpi_table_type) 0
-#define ACPI_TABLE_DSDT                 (acpi_table_type) 1
-#define ACPI_TABLE_FADT                 (acpi_table_type) 2
-#define ACPI_TABLE_FACS                 (acpi_table_type) 3
-#define ACPI_TABLE_PSDT                 (acpi_table_type) 4
-#define ACPI_TABLE_SSDT                 (acpi_table_type) 5
-#define ACPI_TABLE_XSDT                 (acpi_table_type) 6
-#define ACPI_TABLE_MAX                  6
-#define NUM_ACPI_TABLES                 (ACPI_TABLE_MAX+1)
-
-
-/*
- * Types associated with ACPI names and objects.  The first group of
- * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
- * of the ACPI object_type() operator (See the ACPI Spec). Therefore,
- * only add to the first group if the spec changes.
- *
- * Types must be kept in sync with the global acpi_ns_properties
- * and acpi_ns_type_names arrays.
- */
-typedef u32                                     acpi_object_type;
-
-#define ACPI_TYPE_ANY                   0x00
-#define ACPI_TYPE_INTEGER               0x01  /* Byte/Word/Dword/Zero/One/Ones */
-#define ACPI_TYPE_STRING                0x02
-#define ACPI_TYPE_BUFFER                0x03
-#define ACPI_TYPE_PACKAGE               0x04  /* byte_const, multiple data_term/Constant/super_name */
-#define ACPI_TYPE_FIELD_UNIT            0x05
-#define ACPI_TYPE_DEVICE                0x06  /* Name, multiple Node */
-#define ACPI_TYPE_EVENT                 0x07
-#define ACPI_TYPE_METHOD                0x08  /* Name, byte_const, multiple Code */
-#define ACPI_TYPE_MUTEX                 0x09
-#define ACPI_TYPE_REGION                0x0A
-#define ACPI_TYPE_POWER                 0x0B  /* Name,byte_const,word_const,multi Node */
-#define ACPI_TYPE_PROCESSOR             0x0C  /* Name,byte_const,Dword_const,byte_const,multi nm_o */
-#define ACPI_TYPE_THERMAL               0x0D  /* Name, multiple Node */
-#define ACPI_TYPE_BUFFER_FIELD          0x0E
-#define ACPI_TYPE_DDB_HANDLE            0x0F
-#define ACPI_TYPE_DEBUG_OBJECT          0x10
-
-#define ACPI_TYPE_EXTERNAL_MAX          0x10
-
-/*
- * These are object types that do not map directly to the ACPI
- * object_type() operator. They are used for various internal purposes only.
- * If new predefined ACPI_TYPEs are added (via the ACPI specification), these
- * internal types must move upwards. (There is code that depends on these
- * values being contiguous with the external types above.)
- */
-#define ACPI_TYPE_LOCAL_REGION_FIELD    0x11
-#define ACPI_TYPE_LOCAL_BANK_FIELD      0x12
-#define ACPI_TYPE_LOCAL_INDEX_FIELD     0x13
-#define ACPI_TYPE_LOCAL_REFERENCE       0x14  /* Arg#, Local#, Name, Debug, ref_of, Index */
-#define ACPI_TYPE_LOCAL_ALIAS           0x15
-#define ACPI_TYPE_LOCAL_NOTIFY          0x16
-#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x17
-#define ACPI_TYPE_LOCAL_RESOURCE        0x18
-#define ACPI_TYPE_LOCAL_RESOURCE_FIELD  0x19
-#define ACPI_TYPE_LOCAL_SCOPE           0x1A  /* 1 Name, multiple object_list Nodes */
-
-#define ACPI_TYPE_NS_NODE_MAX           0x1A  /* Last typecode used within a NS Node */
-
-/*
- * These are special object types that never appear in
- * a Namespace node, only in an union acpi_operand_object
- */
-#define ACPI_TYPE_LOCAL_EXTRA           0x1B
-#define ACPI_TYPE_LOCAL_DATA            0x1C
-
-#define ACPI_TYPE_LOCAL_MAX             0x1C
-
-/* All types above here are invalid */
-
-#define ACPI_TYPE_INVALID               0x1D
-#define ACPI_TYPE_NOT_FOUND             0xFF
-
-
-/*
- * Bitmapped ACPI types.  Used internally only
- */
-#define ACPI_BTYPE_ANY                  0x00000000
-#define ACPI_BTYPE_INTEGER              0x00000001
-#define ACPI_BTYPE_STRING               0x00000002
-#define ACPI_BTYPE_BUFFER               0x00000004
-#define ACPI_BTYPE_PACKAGE              0x00000008
-#define ACPI_BTYPE_FIELD_UNIT           0x00000010
-#define ACPI_BTYPE_DEVICE               0x00000020
-#define ACPI_BTYPE_EVENT                0x00000040
-#define ACPI_BTYPE_METHOD               0x00000080
-#define ACPI_BTYPE_MUTEX                0x00000100
-#define ACPI_BTYPE_REGION               0x00000200
-#define ACPI_BTYPE_POWER                0x00000400
-#define ACPI_BTYPE_PROCESSOR            0x00000800
-#define ACPI_BTYPE_THERMAL              0x00001000
-#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
-#define ACPI_BTYPE_DDB_HANDLE           0x00004000
-#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
-#define ACPI_BTYPE_REFERENCE            0x00010000
-#define ACPI_BTYPE_RESOURCE             0x00020000
-
-#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
-
-#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
-#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
-#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
-#define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF  /* ARG or LOCAL */
-#define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
-
-/*
- * All I/O
- */
-#define ACPI_READ                       0
-#define ACPI_WRITE                      1
-#define ACPI_IO_MASK                    1
-
-
-/*
- * acpi_event Types: Fixed & General Purpose
- */
-typedef u32                                     acpi_event_type;
-
-#define ACPI_EVENT_FIXED                0
-#define ACPI_EVENT_GPE                  1
-
-/*
- * Fixed events
- */
-#define ACPI_EVENT_PMTIMER              0
-#define ACPI_EVENT_GLOBAL               1
-#define ACPI_EVENT_POWER_BUTTON         2
-#define ACPI_EVENT_SLEEP_BUTTON         3
-#define ACPI_EVENT_RTC                  4
-#define ACPI_EVENT_MAX                  4
-#define ACPI_NUM_FIXED_EVENTS           ACPI_EVENT_MAX + 1
-
-#define ACPI_GPE_INVALID                0xFF
-#define ACPI_GPE_MAX                    0xFF
-#define ACPI_NUM_GPE                    256
-
-#define ACPI_EVENT_LEVEL_TRIGGERED      1
-#define ACPI_EVENT_EDGE_TRIGGERED       2
-
-/*
- * GPEs
- */
-#define ACPI_EVENT_WAKE_ENABLE          0x1
-#define ACPI_EVENT_WAKE_DISABLE         0x1
-
-
-/*
- * acpi_event Status:
- * -------------
- * The encoding of acpi_event_status is illustrated below.
- * Note that a set bit (1) indicates the property is TRUE
- * (e.g. if bit 0 is set then the event is enabled).
- * +-------------+-+-+-+
- * |   Bits 31:3 |2|1|0|
- * +-------------+-+-+-+
- *          |     | | |
- *          |     | | +- Enabled?
- *          |     | +--- Enabled for wake?
- *          |     +----- Set?
- *          +----------- <Reserved>
- */
-typedef u32                                     acpi_event_status;
-
-#define ACPI_EVENT_FLAG_DISABLED        (acpi_event_status) 0x00
-#define ACPI_EVENT_FLAG_ENABLED         (acpi_event_status) 0x01
-#define ACPI_EVENT_FLAG_WAKE_ENABLED    (acpi_event_status) 0x02
-#define ACPI_EVENT_FLAG_SET             (acpi_event_status) 0x04
-
-
-/* Notify types */
-
-#define ACPI_SYSTEM_NOTIFY              0
-#define ACPI_DEVICE_NOTIFY              1
-#define ACPI_MAX_NOTIFY_HANDLER_TYPE    1
-
-#define ACPI_MAX_SYS_NOTIFY             0x7f
-
-
-/* Address Space (Operation Region) Types */
-
-typedef u8                                      acpi_adr_space_type;
-
-#define ACPI_ADR_SPACE_SYSTEM_MEMORY    (acpi_adr_space_type) 0
-#define ACPI_ADR_SPACE_SYSTEM_IO        (acpi_adr_space_type) 1
-#define ACPI_ADR_SPACE_PCI_CONFIG       (acpi_adr_space_type) 2
-#define ACPI_ADR_SPACE_EC               (acpi_adr_space_type) 3
-#define ACPI_ADR_SPACE_SMBUS            (acpi_adr_space_type) 4
-#define ACPI_ADR_SPACE_CMOS             (acpi_adr_space_type) 5
-#define ACPI_ADR_SPACE_PCI_BAR_TARGET   (acpi_adr_space_type) 6
-#define ACPI_ADR_SPACE_DATA_TABLE       (acpi_adr_space_type) 7
-#define ACPI_ADR_SPACE_FIXED_HARDWARE   (acpi_adr_space_type) 127
-
-
-/*
- * bit_register IDs
- * These are bitfields defined within the full ACPI registers
- */
-#define ACPI_BITREG_TIMER_STATUS                0x00
-#define ACPI_BITREG_BUS_MASTER_STATUS           0x01
-#define ACPI_BITREG_GLOBAL_LOCK_STATUS          0x02
-#define ACPI_BITREG_POWER_BUTTON_STATUS         0x03
-#define ACPI_BITREG_SLEEP_BUTTON_STATUS         0x04
-#define ACPI_BITREG_RT_CLOCK_STATUS             0x05
-#define ACPI_BITREG_WAKE_STATUS                 0x06
-
-#define ACPI_BITREG_TIMER_ENABLE                0x07
-#define ACPI_BITREG_GLOBAL_LOCK_ENABLE          0x08
-#define ACPI_BITREG_POWER_BUTTON_ENABLE         0x09
-#define ACPI_BITREG_SLEEP_BUTTON_ENABLE         0x0A
-#define ACPI_BITREG_RT_CLOCK_ENABLE             0x0B
-#define ACPI_BITREG_WAKE_ENABLE                 0x0C
-
-#define ACPI_BITREG_SCI_ENABLE                  0x0D
-#define ACPI_BITREG_BUS_MASTER_RLD              0x0E
-#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x0F
-#define ACPI_BITREG_SLEEP_TYPE_A                0x10
-#define ACPI_BITREG_SLEEP_TYPE_B                0x11
-#define ACPI_BITREG_SLEEP_ENABLE                0x12
-
-#define ACPI_BITREG_ARB_DISABLE                 0x13
-
-#define ACPI_BITREG_MAX                         0x13
-#define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
-
-
-/*
- * External ACPI object definition
- */
-union acpi_object
-{
-	acpi_object_type                    type;   /* See definition of acpi_ns_type for values */
-	struct
-	{
-		acpi_object_type                    type;
-		acpi_integer                        value;      /* The actual number */
-	} integer;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 length;     /* # of bytes in string, excluding trailing null */
-		char                                *pointer;   /* points to the string value */
-	} string;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 length;     /* # of bytes in buffer */
-		u8                                  *pointer;   /* points to the buffer */
-	} buffer;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 fill1;
-		acpi_handle                         handle;     /* object reference */
-	} reference;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 count;      /* # of elements in package */
-		union acpi_object                   *elements;  /* Pointer to an array of ACPI_OBJECTs */
-	} package;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 proc_id;
-		acpi_io_address                     pblk_address;
-		u32                                 pblk_length;
-	} processor;
-
-	struct
-	{
-		acpi_object_type                    type;
-		u32                                 system_level;
-		u32                                 resource_order;
-	} power_resource;
-};
-
-
-/*
- * List of objects, used as a parameter list for control method evaluation
- */
-struct acpi_object_list
-{
-	u32                                 count;
-	union acpi_object                   *pointer;
-};
-
-
-/*
- * Miscellaneous common Data Structures used by the interfaces
- */
-#define ACPI_NO_BUFFER              0
-#define ACPI_ALLOCATE_BUFFER        (acpi_size) (-1)
-#define ACPI_ALLOCATE_LOCAL_BUFFER  (acpi_size) (-2)
-
-struct acpi_buffer
-{
-	acpi_size                           length;         /* Length in bytes of the buffer */
-	void                                *pointer;       /* pointer to buffer */
-};
-
-
-/*
- * name_type for acpi_get_name
- */
-#define ACPI_FULL_PATHNAME              0
-#define ACPI_SINGLE_NAME                1
-#define ACPI_NAME_TYPE_MAX              1
-
-
-/*
- * Structure and flags for acpi_get_system_info
- */
-#define ACPI_SYS_MODE_UNKNOWN           0x0000
-#define ACPI_SYS_MODE_ACPI              0x0001
-#define ACPI_SYS_MODE_LEGACY            0x0002
-#define ACPI_SYS_MODES_MASK             0x0003
-
-
-/*
- * ACPI Table Info.  One per ACPI table _type_
- */
-struct acpi_table_info
-{
-	u32                                 count;
-};
-
-
-/*
- * System info returned by acpi_get_system_info()
- */
-struct acpi_system_info
-{
-	u32                                 acpi_ca_version;
-	u32                                 flags;
-	u32                                 timer_resolution;
-	u32                                 reserved1;
-	u32                                 reserved2;
-	u32                                 debug_level;
-	u32                                 debug_layer;
-	u32                                 num_table_types;
-	struct acpi_table_info              table_info [NUM_ACPI_TABLES];
-};
-
-
-/*
- * Various handlers and callback procedures
- */
-typedef
-u32 (*acpi_event_handler) (
-	void                                *context);
-
-typedef
-void (*acpi_gpe_handler) (
-	void                                *context);
-
-typedef
-void (*acpi_notify_handler) (
-	acpi_handle                         device,
-	u32                                 value,
-	void                                *context);
-
-typedef
-void (*acpi_object_handler) (
-	acpi_handle                         object,
-	u32                                 function,
-	void                                *data);
-
-typedef
-acpi_status (*acpi_init_handler) (
-	acpi_handle                         object,
-	u32                                 function);
-
-#define ACPI_INIT_DEVICE_INI        1
-
-
-/* Address Spaces (Operation Regions */
-
-typedef
-acpi_status (*acpi_adr_space_handler) (
-	u32                                 function,
-	acpi_physical_address               address,
-	u32                                 bit_width,
-	acpi_integer                        *value,
-	void                                *handler_context,
-	void                                *region_context);
-
-#define ACPI_DEFAULT_HANDLER        NULL
-
-
-typedef
-acpi_status (*acpi_adr_space_setup) (
-	acpi_handle                         region_handle,
-	u32                                 function,
-	void                                *handler_context,
-	void                                **region_context);
-
-#define ACPI_REGION_ACTIVATE    0
-#define ACPI_REGION_DEACTIVATE  1
-
-typedef
-acpi_status (*acpi_walk_callback) (
-	acpi_handle                         obj_handle,
-	u32                                 nesting_level,
-	void                                *context,
-	void                                **return_value);
-
-
-/* Interrupt handler return values */
-
-#define ACPI_INTERRUPT_NOT_HANDLED      0x00
-#define ACPI_INTERRUPT_HANDLED          0x01
-
-
-/* Structure and flags for acpi_get_device_info */
-
-#define ACPI_VALID_HID                  0x1
-#define ACPI_VALID_UID                  0x2
-#define ACPI_VALID_ADR                  0x4
-#define ACPI_VALID_STA                  0x8
-
-
-#define ACPI_COMMON_OBJ_INFO \
-	acpi_object_type                    type;           /* ACPI object type */ \
-	acpi_name                           name            /* ACPI object Name */
-
-
-struct acpi_obj_info_header
-{
-	ACPI_COMMON_OBJ_INFO;
-};
-
-
-struct acpi_device_info
-{
-	ACPI_COMMON_OBJ_INFO;
-
-	u32                                 valid;              /*  Are the next bits legit? */
-	char                                hardware_id[9];     /*  _HID value if any */
-	char                                unique_id[9];       /*  _UID value if any */
-	acpi_integer                        address;            /*  _ADR value if any */
-	u32                                 current_status;     /*  _STA value */
-};
-
-
-/* Context structs for address space handlers */
-
-struct acpi_pci_id
-{
-	u16                                 segment;
-	u16                                 bus;
-	u16                                 device;
-	u16                                 function;
-};
-
-
-struct acpi_mem_space_context
-{
-	u32                                 length;
-	acpi_physical_address               address;
-	acpi_physical_address               mapped_physical_address;
-	u8                                  *mapped_logical_address;
-	acpi_size                           mapped_length;
-};
-
-
-/*
- * Definitions for Resource Attributes
- */
-
-/*
- *  Memory Attributes
- */
-#define ACPI_READ_ONLY_MEMORY           (u8) 0x00
-#define ACPI_READ_WRITE_MEMORY          (u8) 0x01
-
-#define ACPI_NON_CACHEABLE_MEMORY       (u8) 0x00
-#define ACPI_CACHABLE_MEMORY            (u8) 0x01
-#define ACPI_WRITE_COMBINING_MEMORY     (u8) 0x02
-#define ACPI_PREFETCHABLE_MEMORY        (u8) 0x03
-
-/*
- *  IO Attributes
- *  The ISA Io ranges are:     n000-n0_ffh, n400-n4_ffh, n800-n8_ffh, n_c00-n_cFFh.
- *  The non-ISA Io ranges are: n100-n3_ffh, n500-n7_ffh, n900-n_bFfh, n_cd0-n_fFFh.
- */
-#define ACPI_NON_ISA_ONLY_RANGES        (u8) 0x01
-#define ACPI_ISA_ONLY_RANGES            (u8) 0x02
-#define ACPI_ENTIRE_RANGE               (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES)
-
-/*
- *  IO Port Descriptor Decode
- */
-#define ACPI_DECODE_10                  (u8) 0x00    /* 10-bit IO address decode */
-#define ACPI_DECODE_16                  (u8) 0x01    /* 16-bit IO address decode */
-
-/*
- *  IRQ Attributes
- */
-#define ACPI_EDGE_SENSITIVE             (u8) 0x00
-#define ACPI_LEVEL_SENSITIVE            (u8) 0x01
-
-#define ACPI_ACTIVE_HIGH                (u8) 0x00
-#define ACPI_ACTIVE_LOW                 (u8) 0x01
-
-#define ACPI_EXCLUSIVE                  (u8) 0x00
-#define ACPI_SHARED                     (u8) 0x01
-
-/*
- *  DMA Attributes
- */
-#define ACPI_COMPATIBILITY              (u8) 0x00
-#define ACPI_TYPE_A                     (u8) 0x01
-#define ACPI_TYPE_B                     (u8) 0x02
-#define ACPI_TYPE_F                     (u8) 0x03
-
-#define ACPI_NOT_BUS_MASTER             (u8) 0x00
-#define ACPI_BUS_MASTER                 (u8) 0x01
-
-#define ACPI_TRANSFER_8                 (u8) 0x00
-#define ACPI_TRANSFER_8_16              (u8) 0x01
-#define ACPI_TRANSFER_16                (u8) 0x02
-
-/*
- * Start Dependent Functions Priority definitions
- */
-#define ACPI_GOOD_CONFIGURATION         (u8) 0x00
-#define ACPI_ACCEPTABLE_CONFIGURATION   (u8) 0x01
-#define ACPI_SUB_OPTIMAL_CONFIGURATION  (u8) 0x02
-
-/*
- *  16, 32 and 64-bit Address Descriptor resource types
- */
-#define ACPI_MEMORY_RANGE               (u8) 0x00
-#define ACPI_IO_RANGE                   (u8) 0x01
-#define ACPI_BUS_NUMBER_RANGE           (u8) 0x02
-
-#define ACPI_ADDRESS_NOT_FIXED          (u8) 0x00
-#define ACPI_ADDRESS_FIXED              (u8) 0x01
-
-#define ACPI_POS_DECODE                 (u8) 0x00
-#define ACPI_SUB_DECODE                 (u8) 0x01
-
-#define ACPI_PRODUCER                   (u8) 0x00
-#define ACPI_CONSUMER                   (u8) 0x01
-
-
-/*
- *  Structures used to describe device resources
- */
-struct acpi_resource_irq
-{
-	u32                                 edge_level;
-	u32                                 active_high_low;
-	u32                                 shared_exclusive;
-	u32                                 number_of_interrupts;
-	u32                                 interrupts[1];
-};
-
-struct acpi_resource_dma
-{
-	u32                                 type;
-	u32                                 bus_master;
-	u32                                 transfer;
-	u32                                 number_of_channels;
-	u32                                 channels[1];
-};
-
-struct acpi_resource_start_dpf
-{
-	u32                                 compatibility_priority;
-	u32                                 performance_robustness;
-};
-
-/*
- * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not
- * needed because it has no fields
- */
-
-struct acpi_resource_io
-{
-	u32                                 io_decode;
-	u32                                 min_base_address;
-	u32                                 max_base_address;
-	u32                                 alignment;
-	u32                                 range_length;
-};
-
-struct acpi_resource_fixed_io
-{
-	u32                                 base_address;
-	u32                                 range_length;
-};
-
-struct acpi_resource_vendor
-{
-	u32                                 length;
-	u8                                  reserved[1];
-};
-
-struct acpi_resource_end_tag
-{
-	u8                                  checksum;
-};
-
-struct acpi_resource_mem24
-{
-	u32                                 read_write_attribute;
-	u32                                 min_base_address;
-	u32                                 max_base_address;
-	u32                                 alignment;
-	u32                                 range_length;
-};
-
-struct acpi_resource_mem32
-{
-	u32                                 read_write_attribute;
-	u32                                 min_base_address;
-	u32                                 max_base_address;
-	u32                                 alignment;
-	u32                                 range_length;
-};
-
-struct acpi_resource_fixed_mem32
-{
-	u32                                 read_write_attribute;
-	u32                                 range_base_address;
-	u32                                 range_length;
-};
-
-struct acpi_memory_attribute
-{
-	u16                                 cache_attribute;
-	u16                                 read_write_attribute;
-};
-
-struct acpi_io_attribute
-{
-	u16                                 range_attribute;
-	u16                                 reserved;
-};
-
-struct acpi_bus_attribute
-{
-	u16                                 reserved1;
-	u16                                 reserved2;
-};
-
-union acpi_resource_attribute
-{
-	struct acpi_memory_attribute        memory;
-	struct acpi_io_attribute            io;
-	struct acpi_bus_attribute           bus;
-};
-
-struct acpi_resource_source
-{
-	u32                                 index;
-	u32                                 string_length;
-	char                                *string_ptr;
-};
-
-struct acpi_resource_address16
-{
-	u32                                 resource_type;
-	u32                                 producer_consumer;
-	u32                                 decode;
-	u32                                 min_address_fixed;
-	u32                                 max_address_fixed;
-	union acpi_resource_attribute       attribute;
-	u32                                 granularity;
-	u32                                 min_address_range;
-	u32                                 max_address_range;
-	u32                                 address_translation_offset;
-	u32                                 address_length;
-	struct acpi_resource_source         resource_source;
-};
-
-struct acpi_resource_address32
-{
-	u32                                 resource_type;
-	u32                                 producer_consumer;
-	u32                                 decode;
-	u32                                 min_address_fixed;
-	u32                                 max_address_fixed;
-	union acpi_resource_attribute       attribute;
-	u32                                 granularity;
-	u32                                 min_address_range;
-	u32                                 max_address_range;
-	u32                                 address_translation_offset;
-	u32                                 address_length;
-	struct acpi_resource_source         resource_source;
-};
-
-struct acpi_resource_address64
-{
-	u32                                 resource_type;
-	u32                                 producer_consumer;
-	u32                                 decode;
-	u32                                 min_address_fixed;
-	u32                                 max_address_fixed;
-	union acpi_resource_attribute       attribute;
-	u64                                 granularity;
-	u64                                 min_address_range;
-	u64                                 max_address_range;
-	u64                                 address_translation_offset;
-	u64                                 address_length;
-	struct acpi_resource_source         resource_source;
-};
-
-struct acpi_resource_ext_irq
-{
-	u32                                 producer_consumer;
-	u32                                 edge_level;
-	u32                                 active_high_low;
-	u32                                 shared_exclusive;
-	u32                                 number_of_interrupts;
-	struct acpi_resource_source         resource_source;
-	u32                                 interrupts[1];
-};
-
-
-/* ACPI_RESOURCE_TYPEs */
-
-#define ACPI_RSTYPE_IRQ                 0
-#define ACPI_RSTYPE_DMA                 1
-#define ACPI_RSTYPE_START_DPF           2
-#define ACPI_RSTYPE_END_DPF             3
-#define ACPI_RSTYPE_IO                  4
-#define ACPI_RSTYPE_FIXED_IO            5
-#define ACPI_RSTYPE_VENDOR              6
-#define ACPI_RSTYPE_END_TAG             7
-#define ACPI_RSTYPE_MEM24               8
-#define ACPI_RSTYPE_MEM32               9
-#define ACPI_RSTYPE_FIXED_MEM32         10
-#define ACPI_RSTYPE_ADDRESS16           11
-#define ACPI_RSTYPE_ADDRESS32           12
-#define ACPI_RSTYPE_ADDRESS64           13
-#define ACPI_RSTYPE_EXT_IRQ             14
-
-typedef u32                                     acpi_resource_type;
-
-union acpi_resource_data
-{
-	struct acpi_resource_irq            irq;
-	struct acpi_resource_dma            dma;
-	struct acpi_resource_start_dpf      start_dpf;
-	struct acpi_resource_io             io;
-	struct acpi_resource_fixed_io       fixed_io;
-	struct acpi_resource_vendor         vendor_specific;
-	struct acpi_resource_end_tag        end_tag;
-	struct acpi_resource_mem24          memory24;
-	struct acpi_resource_mem32          memory32;
-	struct acpi_resource_fixed_mem32    fixed_memory32;
-	struct acpi_resource_address16      address16;
-	struct acpi_resource_address32      address32;
-	struct acpi_resource_address64      address64;
-	struct acpi_resource_ext_irq        extended_irq;
-};
-
-struct acpi_resource
-{
-	acpi_resource_type                  id;
-	u32                                 length;
-	union acpi_resource_data            data;
-};
-
-#define ACPI_RESOURCE_LENGTH                12
-#define ACPI_RESOURCE_LENGTH_NO_DATA        8       /* Id + Length fields */
-
-#define ACPI_SIZEOF_RESOURCE(type)          (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type))
-
-#define ACPI_NEXT_RESOURCE(res)             (struct acpi_resource *)((u8 *) res + res->length)
-
-#ifdef _HW_ALIGNMENT_SUPPORT
-#define ACPI_ALIGN_RESOURCE_SIZE(length)    (length)
-#else
-#define ACPI_ALIGN_RESOURCE_SIZE(length)    ACPI_ROUND_UP_TO_NATIVE_WORD(length)
-#endif
-
-/*
- * END: of definitions for Resource Attributes
- */
-
-
-struct acpi_pci_routing_table
-{
-	u32                                 length;
-	u32                                 pin;
-	acpi_integer                        address;        /* here for 64-bit alignment */
-	u32                                 source_index;
-	char                                source[4];      /* pad to 64 bits so sizeof() works in all cases */
-};
-
-/*
- * END: of definitions for PCI Routing tables
- */
-
-
-#endif /* __ACTYPES_H__ */
diff -Nru a/drivers/acpi/include/acutils.h b/drivers/acpi/include/acutils.h
--- a/drivers/acpi/include/acutils.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,815 +0,0 @@
-/******************************************************************************
- *
- * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 _ACUTILS_H
-#define _ACUTILS_H
-
-
-typedef
-acpi_status (*acpi_pkg_callback) (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-
-acpi_status
-acpi_ut_walk_package_tree (
-	union acpi_operand_object       *source_object,
-	void                            *target_object,
-	acpi_pkg_callback               walk_callback,
-	void                            *context);
-
-
-struct acpi_pkg_info
-{
-	u8                              *free_space;
-	acpi_size                       length;
-	u32                             object_space;
-	u32                             num_packages;
-};
-
-#define REF_INCREMENT       (u16) 0
-#define REF_DECREMENT       (u16) 1
-#define REF_FORCE_DELETE    (u16) 2
-
-/* acpi_ut_dump_buffer */
-
-#define DB_BYTE_DISPLAY     1
-#define DB_WORD_DISPLAY     2
-#define DB_DWORD_DISPLAY    4
-#define DB_QWORD_DISPLAY    8
-
-
-/* Global initialization interfaces */
-
-void
-acpi_ut_init_globals (
-	void);
-
-void
-acpi_ut_terminate (
-	void);
-
-
-/*
- * ut_init - miscellaneous initialization and shutdown
- */
-
-acpi_status
-acpi_ut_hardware_initialize (
-	void);
-
-void
-acpi_ut_subsystem_shutdown (
-	void);
-
-acpi_status
-acpi_ut_validate_fadt (
-	void);
-
-/*
- * ut_global - Global data structures and procedures
- */
-
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
-
-char *
-acpi_ut_get_mutex_name (
-	u32                             mutex_id);
-
-#endif
-
-char *
-acpi_ut_get_type_name (
-	acpi_object_type                type);
-
-char *
-acpi_ut_get_object_type_name (
-	union acpi_operand_object       *obj_desc);
-
-char *
-acpi_ut_get_region_name (
-	u8                              space_id);
-
-char *
-acpi_ut_get_event_name (
-	u32                             event_id);
-
-char
-acpi_ut_hex_to_ascii_char (
-	acpi_integer                    integer,
-	u32                             position);
-
-u8
-acpi_ut_valid_object_type (
-	acpi_object_type                type);
-
-acpi_owner_id
-acpi_ut_allocate_owner_id (
-	u32                             id_type);
-
-
-/*
- * ut_clib - Local implementations of C library functions
- */
-
-#ifndef ACPI_USE_SYSTEM_CLIBRARY
-
-acpi_size
-acpi_ut_strlen (
-	const char                      *string);
-
-char *
-acpi_ut_strcpy (
-	char                            *dst_string,
-	const char                      *src_string);
-
-char *
-acpi_ut_strncpy (
-	char                            *dst_string,
-	const char                      *src_string,
-	acpi_size                       count);
-
-int
-acpi_ut_strncmp (
-	const char                      *string1,
-	const char                      *string2,
-	acpi_size                       count);
-
-int
-acpi_ut_strcmp (
-	const char                      *string1,
-	const char                      *string2);
-
-char *
-acpi_ut_strcat (
-	char                            *dst_string,
-	const char                      *src_string);
-
-char *
-acpi_ut_strncat (
-	char                            *dst_string,
-	const char                      *src_string,
-	acpi_size                       count);
-
-u32
-acpi_ut_strtoul (
-	const char                      *string,
-	char                            **terminator,
-	u32                             base);
-
-char *
-acpi_ut_strstr (
-	char                            *string1,
-	char                            *string2);
-
-void *
-acpi_ut_memcpy (
-	void                            *dest,
-	const void                      *src,
-	acpi_size                       count);
-
-void *
-acpi_ut_memset (
-	void                            *dest,
-	acpi_native_uint                value,
-	acpi_size                       count);
-
-int
-acpi_ut_to_upper (
-	int                             c);
-
-int
-acpi_ut_to_lower (
-	int                             c);
-
-extern const u8 _acpi_ctype[];
-
-#define _ACPI_XA     0x00    /* extra alphabetic - not supported */
-#define _ACPI_XS     0x40    /* extra space */
-#define _ACPI_BB     0x00    /* BEL, BS, etc. - not supported */
-#define _ACPI_CN     0x20    /* CR, FF, HT, NL, VT */
-#define _ACPI_DI     0x04    /* '0'-'9' */
-#define _ACPI_LO     0x02    /* 'a'-'z' */
-#define _ACPI_PU     0x10    /* punctuation */
-#define _ACPI_SP     0x08    /* space */
-#define _ACPI_UP     0x01    /* 'A'-'Z' */
-#define _ACPI_XD     0x80    /* '0'-'9', 'A'-'F', 'a'-'f' */
-
-#define ACPI_IS_DIGIT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI))
-#define ACPI_IS_SPACE(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP))
-#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
-#define ACPI_IS_UPPER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
-#define ACPI_IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
-#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
-#define ACPI_IS_ALPHA(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
-#define ACPI_IS_ASCII(c)  ((c) < 0x80)
-
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
-/*
- * ut_copy - Object construction and conversion interfaces
- */
-
-acpi_status
-acpi_ut_build_simple_object(
-	union acpi_operand_object       *obj,
-	union acpi_object               *user_obj,
-	u8                              *data_space,
-	u32                             *buffer_space_used);
-
-acpi_status
-acpi_ut_build_package_object (
-	union acpi_operand_object       *obj,
-	u8                              *buffer,
-	u32                             *space_used);
-
-acpi_status
-acpi_ut_copy_ielement_to_eelement (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-acpi_status
-acpi_ut_copy_ielement_to_ielement (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-acpi_status
-acpi_ut_copy_iobject_to_eobject (
-	union acpi_operand_object       *obj,
-	struct acpi_buffer              *ret_buffer);
-
-acpi_status
-acpi_ut_copy_esimple_to_isimple(
-	union acpi_object               *user_obj,
-	union acpi_operand_object       **return_obj);
-
-acpi_status
-acpi_ut_copy_eobject_to_iobject (
-	union acpi_object               *obj,
-	union acpi_operand_object       **internal_obj);
-
-acpi_status
-acpi_ut_copy_isimple_to_isimple (
-	union acpi_operand_object       *source_obj,
-	union acpi_operand_object       *dest_obj);
-
-acpi_status
-acpi_ut_copy_ipackage_to_ipackage (
-	union acpi_operand_object       *source_obj,
-	union acpi_operand_object       *dest_obj,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ut_copy_simple_object (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *dest_desc);
-
-acpi_status
-acpi_ut_copy_iobject_to_iobject (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       **dest_desc,
-	struct acpi_walk_state          *walk_state);
-
-
-/*
- * ut_create - Object creation
- */
-
-acpi_status
-acpi_ut_update_object_reference (
-	union acpi_operand_object       *object,
-	u16                             action);
-
-
-/*
- * ut_debug - Debug interfaces
- */
-
-void
-acpi_ut_init_stack_ptr_trace (
-	void);
-
-void
-acpi_ut_track_stack_ptr (
-	void);
-
-void
-acpi_ut_trace (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info);
-
-void
-acpi_ut_trace_ptr (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	void                            *pointer);
-
-void
-acpi_ut_trace_u32 (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	u32                             integer);
-
-void
-acpi_ut_trace_str (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	char                            *string);
-
-void
-acpi_ut_exit (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info);
-
-void
-acpi_ut_status_exit (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	acpi_status                     status);
-
-void
-acpi_ut_value_exit (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	acpi_integer                    value);
-
-void
-acpi_ut_ptr_exit (
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	u8                              *ptr);
-
-void
-acpi_ut_report_info (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id);
-
-void
-acpi_ut_report_error (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id);
-
-void
-acpi_ut_report_warning (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id);
-
-void
-acpi_ut_dump_buffer (
-	u8                              *buffer,
-	u32                             count,
-	u32                             display,
-	u32                             component_id);
-
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print (
-	u32                             requested_debug_level,
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	char                            *format,
-	...) ACPI_PRINTF_LIKE_FUNC;
-
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_debug_print_raw (
-	u32                             requested_debug_level,
-	u32                             line_number,
-	struct acpi_debug_print_info    *dbg_info,
-	char                            *format,
-	...) ACPI_PRINTF_LIKE_FUNC;
-
-
-/*
- * ut_delete - Object deletion
- */
-
-void
-acpi_ut_delete_internal_obj (
-	union acpi_operand_object       *object);
-
-void
-acpi_ut_delete_internal_package_object (
-	union acpi_operand_object       *object);
-
-void
-acpi_ut_delete_internal_simple_object (
-	union acpi_operand_object       *object);
-
-void
-acpi_ut_delete_internal_object_list (
-	union acpi_operand_object       **obj_list);
-
-
-/*
- * ut_eval - object evaluation
- */
-
-/* Method name strings */
-
-#define METHOD_NAME__HID        "_HID"
-#define METHOD_NAME__CID        "_CID"
-#define METHOD_NAME__UID        "_UID"
-#define METHOD_NAME__ADR        "_ADR"
-#define METHOD_NAME__STA        "_STA"
-#define METHOD_NAME__REG        "_REG"
-#define METHOD_NAME__SEG        "_SEG"
-#define METHOD_NAME__BBN        "_BBN"
-#define METHOD_NAME__PRT        "_PRT"
-
-
-acpi_status
-acpi_ut_evaluate_object (
-	struct acpi_namespace_node      *prefix_node,
-	char                            *path,
-	u32                             expected_return_btypes,
-	union acpi_operand_object       **return_desc);
-
-acpi_status
-acpi_ut_evaluate_numeric_object (
-	char                            *object_name,
-	struct acpi_namespace_node      *device_node,
-	acpi_integer                    *address);
-
-acpi_status
-acpi_ut_execute_HID (
-	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *hid);
-
-acpi_status
-acpi_ut_execute_CID (
-	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *cid);
-
-acpi_status
-acpi_ut_execute_STA (
-	struct acpi_namespace_node      *device_node,
-	u32                             *status_flags);
-
-acpi_status
-acpi_ut_execute_UID (
-	struct acpi_namespace_node      *device_node,
-	struct acpi_device_id           *uid);
-
-
-/*
- * ut_mutex - mutual exclusion interfaces
- */
-
-acpi_status
-acpi_ut_mutex_initialize (
-	void);
-
-void
-acpi_ut_mutex_terminate (
-	void);
-
-acpi_status
-acpi_ut_create_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_delete_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_acquire_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_release_mutex (
-	acpi_mutex_handle               mutex_id);
-
-
-/*
- * ut_object - internal object create/delete/cache routines
- */
-
-union acpi_operand_object    *
-acpi_ut_create_internal_object_dbg (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id,
-	acpi_object_type                type);
-
-void *
-acpi_ut_allocate_object_desc_dbg (
-	char                            *module_name,
-	u32                             line_number,
-	u32                             component_id);
-
-#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t)
-#define acpi_ut_allocate_object_desc()  acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT)
-
-void
-acpi_ut_delete_object_desc (
-	union acpi_operand_object       *object);
-
-u8
-acpi_ut_valid_internal_object (
-	void                            *object);
-
-union acpi_operand_object *
-acpi_ut_create_buffer_object (
-	acpi_size                       buffer_size);
-
-
-/*
- * ut_ref_cnt - Object reference count management
- */
-
-void
-acpi_ut_add_reference (
-	union acpi_operand_object       *object);
-
-void
-acpi_ut_remove_reference (
-	union acpi_operand_object       *object);
-
-/*
- * ut_size - Object size routines
- */
-
-acpi_status
-acpi_ut_get_simple_object_size (
-	union acpi_operand_object       *obj,
-	acpi_size                       *obj_length);
-
-acpi_status
-acpi_ut_get_package_object_size (
-	union acpi_operand_object       *obj,
-	acpi_size                       *obj_length);
-
-acpi_status
-acpi_ut_get_object_size(
-	union acpi_operand_object       *obj,
-	acpi_size                       *obj_length);
-
-acpi_status
-acpi_ut_get_element_length (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-
-/*
- * ut_state - Generic state creation/cache routines
- */
-
-void
-acpi_ut_push_generic_state (
-	union acpi_generic_state        **list_head,
-	union acpi_generic_state        *state);
-
-union acpi_generic_state *
-acpi_ut_pop_generic_state (
-	union acpi_generic_state        **list_head);
-
-
-union acpi_generic_state *
-acpi_ut_create_generic_state (
-	void);
-
-struct acpi_thread_state *
-acpi_ut_create_thread_state (
-	void);
-
-union acpi_generic_state *
-acpi_ut_create_update_state (
-	union acpi_operand_object       *object,
-	u16                             action);
-
-union acpi_generic_state *
-acpi_ut_create_pkg_state (
-	void                            *internal_object,
-	void                            *external_object,
-	u16                             index);
-
-acpi_status
-acpi_ut_create_update_state_and_push (
-	union acpi_operand_object       *object,
-	u16                             action,
-	union acpi_generic_state        **state_list);
-
-acpi_status
-acpi_ut_create_pkg_state_and_push (
-	void                            *internal_object,
-	void                            *external_object,
-	u16                             index,
-	union acpi_generic_state        **state_list);
-
-union acpi_generic_state *
-acpi_ut_create_control_state (
-	void);
-
-void
-acpi_ut_delete_generic_state (
-	union acpi_generic_state        *state);
-
-void
-acpi_ut_delete_generic_state_cache (
-	void);
-
-void
-acpi_ut_delete_object_cache (
-	void);
-
-/*
- * utmisc
- */
-
-void
-acpi_ut_print_string (
-	char                            *string,
-	u8                              max_length);
-
-acpi_status
-acpi_ut_divide (
-	acpi_integer                    *in_dividend,
-	acpi_integer                    *in_divisor,
-	acpi_integer                    *out_quotient,
-	acpi_integer                    *out_remainder);
-
-acpi_status
-acpi_ut_short_divide (
-	acpi_integer                    *in_dividend,
-	u32                             divisor,
-	acpi_integer                    *out_quotient,
-	u32                             *out_remainder);
-
-u8
-acpi_ut_valid_acpi_name (
-	u32                             name);
-
-u8
-acpi_ut_valid_acpi_character (
-	char                            character);
-
-acpi_status
-acpi_ut_strtoul64 (
-	char                            *string,
-	u32                             base,
-	acpi_integer                    *ret_integer);
-
-char *
-acpi_ut_strupr (
-	char                            *src_string);
-
-u8 *
-acpi_ut_get_resource_end_tag (
-	union acpi_operand_object       *obj_desc);
-
-u8
-acpi_ut_generate_checksum (
-	u8                              *buffer,
-	u32                             length);
-
-u32
-acpi_ut_dword_byte_swap (
-	u32                             value);
-
-void
-acpi_ut_set_integer_width (
-	u8                              revision);
-
-#ifdef ACPI_DEBUG_OUTPUT
-void
-acpi_ut_display_init_pathname (
-	u8                              type,
-	struct acpi_namespace_node      *obj_handle,
-	char                            *path);
-
-#endif
-
-
-/*
- * Utalloc - memory allocation and object caching
- */
-
-void *
-acpi_ut_acquire_from_cache (
-	u32                             list_id);
-
-void
-acpi_ut_release_to_cache (
-	u32                             list_id,
-	void                            *object);
-
-void
-acpi_ut_delete_generic_cache (
-	u32                             list_id);
-
-acpi_status
-acpi_ut_validate_buffer (
-	struct acpi_buffer              *buffer);
-
-acpi_status
-acpi_ut_initialize_buffer (
-	struct acpi_buffer              *buffer,
-	acpi_size                       required_length);
-
-
-/* Memory allocation functions */
-
-void *
-acpi_ut_allocate (
-	acpi_size                       size,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-void *
-acpi_ut_callocate (
-	acpi_size                       size,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
-void *
-acpi_ut_allocate_and_track (
-	acpi_size                       size,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-void *
-acpi_ut_callocate_and_track (
-	acpi_size                       size,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-void
-acpi_ut_free_and_track (
-	void                            *address,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-struct acpi_debug_mem_block *
-acpi_ut_find_allocation (
-	u32                             list_id,
-	void                            *allocation);
-
-acpi_status
-acpi_ut_track_allocation (
-	u32                             list_id,
-	struct acpi_debug_mem_block     *address,
-	acpi_size                       size,
-	u8                              alloc_type,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-acpi_status
-acpi_ut_remove_allocation (
-	u32                             list_id,
-	struct acpi_debug_mem_block     *address,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-void
-acpi_ut_dump_allocation_info (
-	void);
-
-void
-acpi_ut_dump_allocations (
-	u32                             component,
-	char                            *module);
-#endif
-
-
-#endif /* _ACUTILS_H */
diff -Nru a/drivers/acpi/include/amlcode.h b/drivers/acpi/include/amlcode.h
--- a/drivers/acpi/include/amlcode.h	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,477 +0,0 @@
-/******************************************************************************
- *
- * Name: amlcode.h - Definitions for AML, as included in "definition blocks"
- *                   Declarations and definitions contained herein are derived
- *                   directly from the ACPI specification.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __AMLCODE_H__
-#define __AMLCODE_H__
-
-/* primary opcodes */
-
-#define AML_NULL_CHAR               (u16) 0x00
-
-#define AML_ZERO_OP                 (u16) 0x00
-#define AML_ONE_OP                  (u16) 0x01
-#define AML_UNASSIGNED              (u16) 0x02
-#define AML_ALIAS_OP                (u16) 0x06
-#define AML_NAME_OP                 (u16) 0x08
-#define AML_BYTE_OP                 (u16) 0x0a
-#define AML_WORD_OP                 (u16) 0x0b
-#define AML_DWORD_OP                (u16) 0x0c
-#define AML_STRING_OP               (u16) 0x0d
-#define AML_QWORD_OP                (u16) 0x0e     /* ACPI 2.0 */
-#define AML_SCOPE_OP                (u16) 0x10
-#define AML_BUFFER_OP               (u16) 0x11
-#define AML_PACKAGE_OP              (u16) 0x12
-#define AML_VAR_PACKAGE_OP          (u16) 0x13     /* ACPI 2.0 */
-#define AML_METHOD_OP               (u16) 0x14
-#define AML_DUAL_NAME_PREFIX        (u16) 0x2e
-#define AML_MULTI_NAME_PREFIX_OP    (u16) 0x2f
-#define AML_NAME_CHAR_SUBSEQ        (u16) 0x30
-#define AML_NAME_CHAR_FIRST         (u16) 0x41
-#define AML_OP_PREFIX               (u16) 0x5b
-#define AML_ROOT_PREFIX             (u16) 0x5c
-#define AML_PARENT_PREFIX           (u16) 0x5e
-#define AML_LOCAL_OP                (u16) 0x60
-#define AML_LOCAL0                  (u16) 0x60
-#define AML_LOCAL1                  (u16) 0x61
-#define AML_LOCAL2                  (u16) 0x62
-#define AML_LOCAL3                  (u16) 0x63
-#define AML_LOCAL4                  (u16) 0x64
-#define AML_LOCAL5                  (u16) 0x65
-#define AML_LOCAL6                  (u16) 0x66
-#define AML_LOCAL7                  (u16) 0x67
-#define AML_ARG_OP                  (u16) 0x68
-#define AML_ARG0                    (u16) 0x68
-#define AML_ARG1                    (u16) 0x69
-#define AML_ARG2                    (u16) 0x6a
-#define AML_ARG3                    (u16) 0x6b
-#define AML_ARG4                    (u16) 0x6c
-#define AML_ARG5                    (u16) 0x6d
-#define AML_ARG6                    (u16) 0x6e
-#define AML_STORE_OP                (u16) 0x70
-#define AML_REF_OF_OP               (u16) 0x71
-#define AML_ADD_OP                  (u16) 0x72
-#define AML_CONCAT_OP               (u16) 0x73
-#define AML_SUBTRACT_OP             (u16) 0x74
-#define AML_INCREMENT_OP            (u16) 0x75
-#define AML_DECREMENT_OP            (u16) 0x76
-#define AML_MULTIPLY_OP             (u16) 0x77
-#define AML_DIVIDE_OP               (u16) 0x78
-#define AML_SHIFT_LEFT_OP           (u16) 0x79
-#define AML_SHIFT_RIGHT_OP          (u16) 0x7a
-#define AML_BIT_AND_OP              (u16) 0x7b
-#define AML_BIT_NAND_OP             (u16) 0x7c
-#define AML_BIT_OR_OP               (u16) 0x7d
-#define AML_BIT_NOR_OP              (u16) 0x7e
-#define AML_BIT_XOR_OP              (u16) 0x7f
-#define AML_BIT_NOT_OP              (u16) 0x80
-#define AML_FIND_SET_LEFT_BIT_OP    (u16) 0x81
-#define AML_FIND_SET_RIGHT_BIT_OP   (u16) 0x82
-#define AML_DEREF_OF_OP             (u16) 0x83
-#define AML_CONCAT_RES_OP           (u16) 0x84     /* ACPI 2.0 */
-#define AML_MOD_OP                  (u16) 0x85     /* ACPI 2.0 */
-#define AML_NOTIFY_OP               (u16) 0x86
-#define AML_SIZE_OF_OP              (u16) 0x87
-#define AML_INDEX_OP                (u16) 0x88
-#define AML_MATCH_OP                (u16) 0x89
-#define AML_CREATE_DWORD_FIELD_OP   (u16) 0x8a
-#define AML_CREATE_WORD_FIELD_OP    (u16) 0x8b
-#define AML_CREATE_BYTE_FIELD_OP    (u16) 0x8c
-#define AML_CREATE_BIT_FIELD_OP     (u16) 0x8d
-#define AML_TYPE_OP                 (u16) 0x8e
-#define AML_CREATE_QWORD_FIELD_OP   (u16) 0x8f     /* ACPI 2.0 */
-#define AML_LAND_OP                 (u16) 0x90
-#define AML_LOR_OP                  (u16) 0x91
-#define AML_LNOT_OP                 (u16) 0x92
-#define AML_LEQUAL_OP               (u16) 0x93
-#define AML_LGREATER_OP             (u16) 0x94
-#define AML_LLESS_OP                (u16) 0x95
-#define AML_TO_BUFFER_OP            (u16) 0x96     /* ACPI 2.0 */
-#define AML_TO_DECSTRING_OP         (u16) 0x97     /* ACPI 2.0 */
-#define AML_TO_HEXSTRING_OP         (u16) 0x98     /* ACPI 2.0 */
-#define AML_TO_INTEGER_OP           (u16) 0x99     /* ACPI 2.0 */
-#define AML_TO_STRING_OP            (u16) 0x9c     /* ACPI 2.0 */
-#define AML_COPY_OP                 (u16) 0x9d     /* ACPI 2.0 */
-#define AML_MID_OP                  (u16) 0x9e     /* ACPI 2.0 */
-#define AML_CONTINUE_OP             (u16) 0x9f     /* ACPI 2.0 */
-#define AML_IF_OP                   (u16) 0xa0
-#define AML_ELSE_OP                 (u16) 0xa1
-#define AML_WHILE_OP                (u16) 0xa2
-#define AML_NOOP_OP                 (u16) 0xa3
-#define AML_RETURN_OP               (u16) 0xa4
-#define AML_BREAK_OP                (u16) 0xa5
-#define AML_BREAK_POINT_OP          (u16) 0xcc
-#define AML_ONES_OP                 (u16) 0xff
-
-/* prefixed opcodes */
-
-#define AML_EXTOP                   (u16) 0x005b
-
-
-#define AML_MUTEX_OP                (u16) 0x5b01
-#define AML_EVENT_OP                (u16) 0x5b02
-#define AML_SHIFT_RIGHT_BIT_OP      (u16) 0x5b10
-#define AML_SHIFT_LEFT_BIT_OP       (u16) 0x5b11
-#define AML_COND_REF_OF_OP          (u16) 0x5b12
-#define AML_CREATE_FIELD_OP         (u16) 0x5b13
-#define AML_LOAD_TABLE_OP           (u16) 0x5b1f     /* ACPI 2.0 */
-#define AML_LOAD_OP                 (u16) 0x5b20
-#define AML_STALL_OP                (u16) 0x5b21
-#define AML_SLEEP_OP                (u16) 0x5b22
-#define AML_ACQUIRE_OP              (u16) 0x5b23
-#define AML_SIGNAL_OP               (u16) 0x5b24
-#define AML_WAIT_OP                 (u16) 0x5b25
-#define AML_RESET_OP                (u16) 0x5b26
-#define AML_RELEASE_OP              (u16) 0x5b27
-#define AML_FROM_BCD_OP             (u16) 0x5b28
-#define AML_TO_BCD_OP               (u16) 0x5b29
-#define AML_UNLOAD_OP               (u16) 0x5b2a
-#define AML_REVISION_OP             (u16) 0x5b30
-#define AML_DEBUG_OP                (u16) 0x5b31
-#define AML_FATAL_OP                (u16) 0x5b32
-#define AML_REGION_OP               (u16) 0x5b80
-#define AML_FIELD_OP                (u16) 0x5b81
-#define AML_DEVICE_OP               (u16) 0x5b82
-#define AML_PROCESSOR_OP            (u16) 0x5b83
-#define AML_POWER_RES_OP            (u16) 0x5b84
-#define AML_THERMAL_ZONE_OP         (u16) 0x5b85
-#define AML_INDEX_FIELD_OP          (u16) 0x5b86
-#define AML_BANK_FIELD_OP           (u16) 0x5b87
-#define AML_DATA_REGION_OP          (u16) 0x5b88     /* ACPI 2.0 */
-
-
-/* Bogus opcodes (they are actually two separate opcodes) */
-
-#define AML_LGREATEREQUAL_OP        (u16) 0x9295
-#define AML_LLESSEQUAL_OP           (u16) 0x9294
-#define AML_LNOTEQUAL_OP            (u16) 0x9293
-
-
-/*
- * Internal opcodes
- * Use only "Unknown" AML opcodes, don't attempt to use
- * any valid ACPI ASCII values (A-Z, 0-9, '-')
- */
-
-#define AML_INT_NAMEPATH_OP         (u16) 0x002d
-#define AML_INT_NAMEDFIELD_OP       (u16) 0x0030
-#define AML_INT_RESERVEDFIELD_OP    (u16) 0x0031
-#define AML_INT_ACCESSFIELD_OP      (u16) 0x0032
-#define AML_INT_BYTELIST_OP         (u16) 0x0033
-#define AML_INT_STATICSTRING_OP     (u16) 0x0034
-#define AML_INT_METHODCALL_OP       (u16) 0x0035
-#define AML_INT_RETURN_VALUE_OP     (u16) 0x0036
-#define AML_INT_EVAL_SUBTREE_OP     (u16) 0x0037
-
-
-#define ARG_NONE                    0x0
-
-/*
- * Argument types for the AML Parser
- * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments.
- * There can be up to 31 unique argument types
- */
-
-#define ARGP_BYTEDATA               0x01
-#define ARGP_BYTELIST               0x02
-#define ARGP_CHARLIST               0x03
-#define ARGP_DATAOBJ                0x04
-#define ARGP_DATAOBJLIST            0x05
-#define ARGP_DWORDDATA              0x06
-#define ARGP_FIELDLIST              0x07
-#define ARGP_NAME                   0x08
-#define ARGP_NAMESTRING             0x09
-#define ARGP_OBJLIST                0x0A
-#define ARGP_PKGLENGTH              0x0B
-#define ARGP_SUPERNAME              0x0C
-#define ARGP_TARGET                 0x0D
-#define ARGP_TERMARG                0x0E
-#define ARGP_TERMLIST               0x0F
-#define ARGP_WORDDATA               0x10
-#define ARGP_QWORDDATA              0x11
-#define ARGP_SIMPLENAME             0x12
-
-/*
- * Resolved argument types for the AML Interpreter
- * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments.
- * There can be up to 31 unique argument types (0 is end-of-arg-list indicator)
- *
- * Note: If and when 5 bits becomes insufficient, it would probably be best
- * to convert to a 6-byte array of argument types, allowing 8 bits per argument.
- */
-
-/* "Standard" ACPI types are 1-15 (0x0F) */
-
-#define ARGI_INTEGER                ACPI_TYPE_INTEGER       /* 1 */
-#define ARGI_STRING                 ACPI_TYPE_STRING        /* 2 */
-#define ARGI_BUFFER                 ACPI_TYPE_BUFFER        /* 3 */
-#define ARGI_PACKAGE                ACPI_TYPE_PACKAGE       /* 4 */
-#define ARGI_EVENT                  ACPI_TYPE_EVENT
-#define ARGI_MUTEX                  ACPI_TYPE_MUTEX
-#define ARGI_REGION                 ACPI_TYPE_REGION
-#define ARGI_DDBHANDLE              ACPI_TYPE_DDB_HANDLE
-
-/* Custom types are 0x10 through 0x1F */
-
-#define ARGI_IF                     0x10
-#define ARGI_ANYOBJECT              0x11
-#define ARGI_ANYTYPE                0x12
-#define ARGI_COMPUTEDATA            0x13     /* Buffer, String, or Integer */
-#define ARGI_DATAOBJECT             0x14     /* Buffer, String, package or reference to a Node - Used only by size_of operator*/
-#define ARGI_COMPLEXOBJ             0x15     /* Buffer, String, or package (Used by INDEX op only) */
-#define ARGI_INTEGER_REF            0x16
-#define ARGI_OBJECT_REF             0x17
-#define ARGI_DEVICE_REF             0x18
-#define ARGI_REFERENCE              0x19
-#define ARGI_TARGETREF              0x1A     /* Target, subject to implicit conversion */
-#define ARGI_FIXED_TARGET           0x1B     /* Target, no implicit conversion */
-#define ARGI_SIMPLE_TARGET          0x1C     /* Name, Local, Arg -- no implicit conversion */
-#define ARGI_BUFFERSTRING           0x1D
-#define ARGI_REF_OR_STRING          0x1E     /* Reference or String (Used by DEREFOF op only) */
-
-#define ARGI_INVALID_OPCODE         0xFFFFFFFF
-
-
-/*
- * hash offsets
- */
-#define AML_EXTOP_HASH_OFFSET       22
-#define AML_LNOT_HASH_OFFSET        19
-
-
-/*
- * opcode groups and types
- */
-
-#define OPGRP_NAMED                 0x01
-#define OPGRP_FIELD                 0x02
-#define OPGRP_BYTELIST              0x04
-
-
-/*
- * Opcode information
- */
-
-/* Opcode flags */
-
-#define AML_HAS_ARGS                0x0800
-#define AML_HAS_TARGET              0x0400
-#define AML_HAS_RETVAL              0x0200
-#define AML_NSOBJECT                0x0100
-#define AML_NSOPCODE                0x0080
-#define AML_NSNODE                  0x0040
-#define AML_NAMED                   0x0020
-#define AML_DEFER                   0x0010
-#define AML_FIELD                   0x0008
-#define AML_CREATE                  0x0004
-#define AML_MATH                    0x0002
-#define AML_LOGICAL                 0x0001
-#define AML_CONSTANT                0x1000
-
-/* Convenient flag groupings */
-
-#define AML_FLAGS_EXEC_1A_0T_0R     AML_HAS_ARGS                                   /* Monadic1  */
-#define AML_FLAGS_EXEC_1A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL /* Monadic2  */
-#define AML_FLAGS_EXEC_1A_1T_0R     AML_HAS_ARGS | AML_HAS_TARGET
-#define AML_FLAGS_EXEC_1A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */
-#define AML_FLAGS_EXEC_2A_0T_0R     AML_HAS_ARGS                                   /* Dyadic1   */
-#define AML_FLAGS_EXEC_2A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL /* Dyadic2   */
-#define AML_FLAGS_EXEC_2A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r  */
-#define AML_FLAGS_EXEC_2A_2T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
-#define AML_FLAGS_EXEC_3A_0T_0R     AML_HAS_ARGS
-#define AML_FLAGS_EXEC_3A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
-#define AML_FLAGS_EXEC_6A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL
-
-
-/*
- * The opcode Type is used in a dispatch table, do not change
- * without updating the table.
- */
-#define AML_TYPE_EXEC_1A_0T_0R      0x00 /* Monadic1  */
-#define AML_TYPE_EXEC_1A_0T_1R      0x01 /* Monadic2  */
-#define AML_TYPE_EXEC_1A_1T_0R      0x02
-#define AML_TYPE_EXEC_1A_1T_1R      0x03 /* monadic2_r */
-#define AML_TYPE_EXEC_2A_0T_0R      0x04 /* Dyadic1   */
-#define AML_TYPE_EXEC_2A_0T_1R      0x05 /* Dyadic2   */
-#define AML_TYPE_EXEC_2A_1T_1R      0x06 /* dyadic2_r  */
-#define AML_TYPE_EXEC_2A_2T_1R      0x07
-#define AML_TYPE_EXEC_3A_0T_0R      0x08
-#define AML_TYPE_EXEC_3A_1T_1R      0x09
-#define AML_TYPE_EXEC_6A_0T_1R      0x0A
-/* End of types used in dispatch table */
-
-#define AML_TYPE_LITERAL            0x0B
-#define AML_TYPE_CONSTANT           0x0C
-#define AML_TYPE_METHOD_ARGUMENT    0x0D
-#define AML_TYPE_LOCAL_VARIABLE     0x0E
-#define AML_TYPE_DATA_TERM          0x0F
-
-/* Generic for an op that returns a value */
-
-#define AML_TYPE_METHOD_CALL        0x10
-
-/* Misc */
-
-#define AML_TYPE_CREATE_FIELD       0x11
-#define AML_TYPE_CREATE_OBJECT      0x12
-#define AML_TYPE_CONTROL            0x13
-#define AML_TYPE_NAMED_NO_OBJ       0x14
-#define AML_TYPE_NAMED_FIELD        0x15
-#define AML_TYPE_NAMED_SIMPLE       0x16
-#define AML_TYPE_NAMED_COMPLEX      0x17
-#define AML_TYPE_RETURN             0x18
-
-#define AML_TYPE_UNDEFINED          0x19
-#define AML_TYPE_BOGUS              0x1A
-
-
-/*
- * Opcode classes
- */
-#define AML_CLASS_EXECUTE           0x00
-#define AML_CLASS_CREATE            0x01
-#define AML_CLASS_ARGUMENT          0x02
-#define AML_CLASS_NAMED_OBJECT      0x03
-#define AML_CLASS_CONTROL           0x04
-#define AML_CLASS_ASCII             0x05
-#define AML_CLASS_PREFIX            0x06
-#define AML_CLASS_INTERNAL          0x07
-#define AML_CLASS_RETURN_VALUE      0x08
-#define AML_CLASS_METHOD_CALL       0x09
-#define AML_CLASS_UNKNOWN           0x0A
-
-
-/* Predefined Operation Region space_iDs */
-
-typedef enum
-{
-	REGION_MEMORY                   = 0,
-	REGION_IO,
-	REGION_PCI_CONFIG,
-	REGION_EC,
-	REGION_SMBUS,
-	REGION_CMOS,
-	REGION_PCI_BAR,
-	REGION_DATA_TABLE,              /* Internal use only */
-	REGION_FIXED_HW                 = 0x7F
-
-} AML_REGION_TYPES;
-
-
-/* Comparison operation codes for match_op operator */
-
-typedef enum
-{
-	MATCH_MTR                       = 0,
-	MATCH_MEQ                       = 1,
-	MATCH_MLE                       = 2,
-	MATCH_MLT                       = 3,
-	MATCH_MGE                       = 4,
-	MATCH_MGT                       = 5
-
-} AML_MATCH_OPERATOR;
-
-#define MAX_MATCH_OPERATOR          5
-
-
-/*
- * field_flags
- *
- * This byte is extracted from the AML and includes three separate
- * pieces of information about the field:
- * 1) The field access type
- * 2) The field update rule
- * 3) The lock rule for the field
- *
- * Bits 00 - 03 : access_type (any_acc, byte_acc, etc.)
- *      04      : lock_rule (1 == Lock)
- *      05 - 06 : update_rule
- */
-#define AML_FIELD_ACCESS_TYPE_MASK  0x0F
-#define AML_FIELD_LOCK_RULE_MASK    0x10
-#define AML_FIELD_UPDATE_RULE_MASK  0x60
-
-
-/* 1) Field Access Types */
-
-typedef enum
-{
-	AML_FIELD_ACCESS_ANY            = 0x00,
-	AML_FIELD_ACCESS_BYTE           = 0x01,
-	AML_FIELD_ACCESS_WORD           = 0x02,
-	AML_FIELD_ACCESS_DWORD          = 0x03,
-	AML_FIELD_ACCESS_QWORD          = 0x04,    /* ACPI 2.0 */
-	AML_FIELD_ACCESS_BUFFER         = 0x05     /* ACPI 2.0 */
-
-} AML_ACCESS_TYPE;
-
-
-/* 2) Field Lock Rules */
-
-typedef enum
-{
-	AML_FIELD_LOCK_NEVER            = 0x00,
-	AML_FIELD_LOCK_ALWAYS           = 0x10
-
-} AML_LOCK_RULE;
-
-
-/* 3) Field Update Rules */
-
-typedef enum
-{
-	AML_FIELD_UPDATE_PRESERVE       = 0x00,
-	AML_FIELD_UPDATE_WRITE_AS_ONES  = 0x20,
-	AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40
-
-} AML_UPDATE_RULE;
-
-
-/*
- * Field Access Attributes.
- * This byte is extracted from the AML via the
- * access_as keyword
- */
-typedef enum
-{
-	AML_FIELD_ATTRIB_SMB_QUICK      = 0x02,
-	AML_FIELD_ATTRIB_SMB_SEND_RCV   = 0x04,
-	AML_FIELD_ATTRIB_SMB_BYTE       = 0x06,
-	AML_FIELD_ATTRIB_SMB_WORD       = 0x08,
-	AML_FIELD_ATTRIB_SMB_BLOCK      = 0x0A,
-	AML_FIELD_ATTRIB_SMB_WORD_CALL  = 0x0C,
-	AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D
-
-} AML_ACCESS_ATTRIBUTE;
-
-
-/* bit fields in method_flags byte */
-
-#define METHOD_FLAGS_ARG_COUNT      0x07
-#define METHOD_FLAGS_SERIALIZED     0x08
-#define METHOD_FLAGS_SYNCH_LEVEL    0xF0
-
-
-#endif /* __AMLCODE_H__ */
diff -Nru a/drivers/acpi/include/amlresrc.h b/drivers/acpi/include/amlresrc.h
--- a/drivers/acpi/include/amlresrc.h	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,310 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: amlresrc.h - AML resource descriptors
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __AMLRESRC_H
-#define __AMLRESRC_H
-
-
-#define ASL_RESNAME_ADDRESS                     "_ADR"
-#define ASL_RESNAME_ALIGNMENT                   "_ALN"
-#define ASL_RESNAME_ADDRESSSPACE                "_ASI"
-#define ASL_RESNAME_BASEADDRESS                 "_BAS"
-#define ASL_RESNAME_BUSMASTER                   "_BM_"  /* Master(1), Slave(0) */
-#define ASL_RESNAME_DECODE                      "_DEC"
-#define ASL_RESNAME_DMA                         "_DMA"
-#define ASL_RESNAME_DMATYPE                     "_TYP"  /* Compatible(0), A(1), B(2), F(3) */
-#define ASL_RESNAME_GRANULARITY                 "_GRA"
-#define ASL_RESNAME_INTERRUPT                   "_INT"
-#define ASL_RESNAME_INTERRUPTLEVEL              "_LL_"  /* active_lo(1), active_hi(0) */
-#define ASL_RESNAME_INTERRUPTSHARE              "_SHR"  /* Shareable(1), no_share(0) */
-#define ASL_RESNAME_INTERRUPTTYPE               "_HE_"  /* Edge(1), Level(0) */
-#define ASL_RESNAME_LENGTH                      "_LEN"
-#define ASL_RESNAME_MEMATTRIBUTES               "_MTP"  /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
-#define ASL_RESNAME_MEMTYPE                     "_MEM"  /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
-#define ASL_RESNAME_MAXADDR                     "_MAX"
-#define ASL_RESNAME_MINADDR                     "_MIN"
-#define ASL_RESNAME_MAXTYPE                     "_MAF"
-#define ASL_RESNAME_MINTYPE                     "_MIF"
-#define ASL_RESNAME_REGISTERBITOFFSET           "_RBO"
-#define ASL_RESNAME_REGISTERBITWIDTH            "_RBW"
-#define ASL_RESNAME_RANGETYPE                   "_RNG"
-#define ASL_RESNAME_READWRITETYPE               "_RW_"  /* read_only(0), Writeable (1) */
-#define ASL_RESNAME_TRANSLATION                 "_TRA"
-#define ASL_RESNAME_TRANSTYPE                   "_TRS"  /* Sparse(1), Dense(0) */
-#define ASL_RESNAME_TYPE                        "_TTP"  /* Translation(1), Static (0) */
-#define ASL_RESNAME_XFERTYPE                    "_SIz"  /* 8(0), 8_and16(1), 16(2) */
-
-
-/* Default sizes for "small" resource descriptors */
-
-#define ASL_RDESC_IRQ_SIZE                      0x02
-#define ASL_RDESC_DMA_SIZE                      0x02
-#define ASL_RDESC_ST_DEPEND_SIZE                0x00
-#define ASL_RDESC_END_DEPEND_SIZE               0x00
-#define ASL_RDESC_IO_SIZE                       0x07
-#define ASL_RDESC_FIXED_IO_SIZE                 0x03
-#define ASL_RDESC_END_TAG_SIZE                  0x01
-
-
-struct asl_resource_node
-{
-	u32                                 buffer_length;
-	void                                *buffer;
-	struct asl_resource_node            *next;
-};
-
-
-/*
- * Resource descriptors defined in the ACPI specification.
- *
- * Alignment must be BYTE because these descriptors
- * are used to overlay the AML byte stream.
- */
-#pragma pack(1)
-
-struct asl_irq_format_desc
-{
-	u8                                  descriptor_type;
-	u16                                 irq_mask;
-	u8                                  flags;
-};
-
-
-struct asl_irq_noflags_desc
-{
-	u8                                  descriptor_type;
-	u16                                 irq_mask;
-};
-
-
-struct asl_dma_format_desc
-{
-	u8                                  descriptor_type;
-	u8                                  dma_channel_mask;
-	u8                                  flags;
-};
-
-
-struct asl_start_dependent_desc
-{
-	u8                                  descriptor_type;
-	u8                                  flags;
-};
-
-
-struct asl_start_dependent_noprio_desc
-{
-	u8                                  descriptor_type;
-};
-
-
-struct asl_end_dependent_desc
-{
-	u8                                  descriptor_type;
-};
-
-
-struct asl_io_port_desc
-{
-	u8                                  descriptor_type;
-	u8                                  information;
-	u16                                 address_min;
-	u16                                 address_max;
-	u8                                  alignment;
-	u8                                  length;
-};
-
-
-struct asl_fixed_io_port_desc
-{
-	u8                                  descriptor_type;
-	u16                                 base_address;
-	u8                                  length;
-};
-
-
-struct asl_small_vendor_desc
-{
-	u8                                  descriptor_type;
-	u8                                  vendor_defined[7];
-};
-
-
-struct asl_end_tag_desc
-{
-	u8                                  descriptor_type;
-	u8                                  checksum;
-};
-
-
-/* LARGE descriptors */
-
-struct asl_memory_24_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  information;
-	u16                                 address_min;
-	u16                                 address_max;
-	u16                                 alignment;
-	u16                                 range_length;
-};
-
-
-struct asl_large_vendor_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  vendor_defined[1];
-};
-
-
-struct asl_memory_32_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  information;
-	u32                                 address_min;
-	u32                                 address_max;
-	u32                                 alignment;
-	u32                                 range_length;
-};
-
-
-struct asl_fixed_memory_32_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  information;
-	u32                                 base_address;
-	u32                                 range_length;
-};
-
-
-struct asl_qword_address_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  resource_type;
-	u8                                  flags;
-	u8                                  specific_flags;
-	u64                                 granularity;
-	u64                                 address_min;
-	u64                                 address_max;
-	u64                                 translation_offset;
-	u64                                 address_length;
-	u8                                  optional_fields[2];
-};
-
-
-struct asl_dword_address_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  resource_type;
-	u8                                  flags;
-	u8                                  specific_flags;
-	u32                                 granularity;
-	u32                                 address_min;
-	u32                                 address_max;
-	u32                                 translation_offset;
-	u32                                 address_length;
-	u8                                  optional_fields[2];
-};
-
-
-struct asl_word_address_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  resource_type;
-	u8                                  flags;
-	u8                                  specific_flags;
-	u16                                 granularity;
-	u16                                 address_min;
-	u16                                 address_max;
-	u16                                 translation_offset;
-	u16                                 address_length;
-	u8                                  optional_fields[2];
-};
-
-
-struct asl_extended_xrupt_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  flags;
-	u8                                  table_length;
-	u32                                 interrupt_number[1];
-	/* res_source_index, res_source optional fields follow */
-};
-
-
-struct asl_general_register_desc
-{
-	u8                                  descriptor_type;
-	u16                                 length;
-	u8                                  address_space_id;
-	u8                                  bit_width;
-	u8                                  bit_offset;
-	u8                                  reserved;
-	u64                                 address;
-};
-
-/* restore default alignment */
-
-#pragma pack()
-
-/* Union of all resource descriptors, sow we can allocate the worst case */
-
-union asl_resource_desc
-{
-	struct asl_irq_format_desc          irq;
-	struct asl_dma_format_desc          dma;
-	struct asl_start_dependent_desc     std;
-	struct asl_end_dependent_desc       end;
-	struct asl_io_port_desc             iop;
-	struct asl_fixed_io_port_desc       fio;
-	struct asl_small_vendor_desc        smv;
-	struct asl_end_tag_desc             et;
-
-	struct asl_memory_24_desc           M24;
-	struct asl_large_vendor_desc        lgv;
-	struct asl_memory_32_desc           M32;
-	struct asl_fixed_memory_32_desc     F32;
-	struct asl_qword_address_desc       qas;
-	struct asl_dword_address_desc       das;
-	struct asl_word_address_desc        was;
-	struct asl_extended_xrupt_desc      exx;
-	struct asl_general_register_desc    grg;
-	u32                                 u32_item;
-	u16                                 u16_item;
-	u8                                  U8item;
-};
-
-
-#endif
-
diff -Nru a/drivers/acpi/include/platform/acenv.h b/drivers/acpi/include/platform/acenv.h
--- a/drivers/acpi/include/platform/acenv.h	Mon Feb 10 10:39:24 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,344 +0,0 @@
-/******************************************************************************
- *
- * Name: acenv.h - Generation environment specific items
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACENV_H__
-#define __ACENV_H__
-
-
-/*
- * Configuration for ACPI tools and utilities
- */
-
-#ifdef _ACPI_DUMP_APP
-#ifndef MSDOS
-#define ACPI_DEBUG_OUTPUT
-#endif
-#define ACPI_APPLICATION
-#define ACPI_DISASSEMBLER
-#define ACPI_NO_METHOD_EXECUTION
-#define ACPI_USE_SYSTEM_CLIBRARY
-#endif
-
-#ifdef _ACPI_EXEC_APP
-#undef DEBUGGER_THREADING
-#define DEBUGGER_THREADING      DEBUGGER_SINGLE_THREADED
-#define ACPI_DEBUG_OUTPUT
-#define ACPI_APPLICATION
-#define ACPI_DEBUGGER
-#define ACPI_DISASSEMBLER
-#define ACPI_USE_SYSTEM_CLIBRARY
-#endif
-
-#ifdef _ACPI_ASL_COMPILER
-#define ACPI_DEBUG_OUTPUT
-#define ACPI_APPLICATION
-#define ACPI_DISASSEMBLER
-#define ACPI_CONSTANT_EVAL_ONLY
-#define ACPI_USE_SYSTEM_CLIBRARY
-#endif
-
-/*
- * Environment configuration.  The purpose of this file is to interface to the
- * local generation environment.
- *
- * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
- *      Otherwise, local versions of string/memory functions will be used.
- * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
- *      the standard header files may be used.
- *
- * The ACPI subsystem only uses low level C library functions that do not call
- * operating system services and may therefore be inlined in the code.
- *
- * It may be necessary to tailor these include files to the target
- * generation environment.
- *
- *
- * Functions and constants used from each header:
- *
- * string.h:    memcpy
- *              memset
- *              strcat
- *              strcmp
- *              strcpy
- *              strlen
- *              strncmp
- *              strncat
- *              strncpy
- *
- * stdlib.h:    strtoul
- *
- * stdarg.h:    va_list
- *              va_arg
- *              va_start
- *              va_end
- *
- */
-
-/*! [Begin] no source code translation */
-
-#if defined(_LINUX)
-#include "aclinux.h"
-
-#elif defined(_AED_EFI)
-#include "acefi.h"
-
-#elif defined(WIN32)
-#include "acwin.h"
-
-#elif defined(WIN64)
-#include "acwin64.h"
-
-#elif defined(MSDOS)        /* Must appear after WIN32 and WIN64 check */
-#include "acdos16.h"
-
-#elif defined(__FreeBSD__)
-#include "acfreebsd.h"
-
-#elif defined(MODESTO)
-#include "acmodesto.h"
-
-#elif defined(NETWARE)
-#include "acnetware.h"
-
-#else
-
-/* All other environments */
-
-#define ACPI_USE_STANDARD_HEADERS
-
-#define COMPILER_DEPENDENT_INT64   long long
-#define COMPILER_DEPENDENT_UINT64  unsigned long long
-
-
-/* Name of host operating system (returned by the _OS_ namespace object) */
-
-#define ACPI_OS_NAME         "Intel ACPI/CA Core Subsystem"
-
-/* This macro is used to tag functions as "printf-like" because
- * some compilers can catch printf format string problems. MSVC
- * doesn't, so this is proprocessed away.
- */
-#define ACPI_PRINTF_LIKE_FUNC
-
-#endif
-
-/*
- * Memory allocation tracking.  Used only if
- * 1) This is the debug version
- * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
- */
-#ifdef ACPI_DEBUG_OUTPUT
-#if ACPI_MACHINE_WIDTH != 16
-#define ACPI_DBG_TRACK_ALLOCATIONS
-#endif
-#endif
-
-/*! [End] no source code translation !*/
-
-
-/*
- * Debugger threading model
- * Use single threaded if the entire subsystem is contained in an application
- * Use multiple threaded when the subsystem is running in the kernel.
- *
- * By default the model is single threaded if ACPI_APPLICATION is set,
- * multi-threaded if ACPI_APPLICATION is not set.
- */
-#define DEBUGGER_SINGLE_THREADED    0
-#define DEBUGGER_MULTI_THREADED     1
-
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
-
-#else
-#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
-#endif
-
-
-/******************************************************************************
- *
- * C library configuration
- *
- *****************************************************************************/
-
-#ifdef ACPI_USE_SYSTEM_CLIBRARY
-/*
- * Use the standard C library headers.
- * We want to keep these to a minimum.
- */
-
-#ifdef ACPI_USE_STANDARD_HEADERS
-/*
- * Use the standard headers from the standard locations
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#endif /* ACPI_USE_STANDARD_HEADERS */
-
-/*
- * We will be linking to the standard Clib functions
- */
-
-#define ACPI_STRSTR(s1,s2)      strstr((s1), (s2))
-#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
-#define ACPI_STRLEN(s)          (acpi_size) strlen((s))
-#define ACPI_STRCPY(d,s)        (void) strcpy((d), (s))
-#define ACPI_STRNCPY(d,s,n)     (void) strncpy((d), (s), (acpi_size)(n))
-#define ACPI_STRNCMP(d,s,n)     strncmp((d), (s), (acpi_size)(n))
-#define ACPI_STRCMP(d,s)        strcmp((d), (s))
-#define ACPI_STRCAT(d,s)        (void) strcat((d), (s))
-#define ACPI_STRNCAT(d,s,n)     strncat((d), (s), (acpi_size)(n))
-#define ACPI_STRTOUL(d,s,n)     strtoul((d), (s), (acpi_size)(n))
-#define ACPI_MEMCPY(d,s,n)      (void) memcpy((d), (s), (acpi_size)(n))
-#define ACPI_MEMSET(d,s,n)      (void) memset((d), (s), (acpi_size)(n))
-
-#define ACPI_TOUPPER            toupper
-#define ACPI_TOLOWER            tolower
-#define ACPI_IS_XDIGIT          isxdigit
-#define ACPI_IS_DIGIT           isdigit
-#define ACPI_IS_SPACE           isspace
-#define ACPI_IS_UPPER           isupper
-#define ACPI_IS_PRINT           isprint
-#define ACPI_IS_ALPHA           isalpha
-#define ACPI_IS_ASCII           isascii
-
-/******************************************************************************
- *
- * Not using native C library, use local implementations
- *
- *****************************************************************************/
-#else
-
-/*
- * Use local definitions of C library macros and functions
- * NOTE: The function implementations may not be as efficient
- * as an inline or assembly code implementation provided by a
- * native C library.
- */
-
-#ifndef va_arg
-
-#ifndef _VALIST
-#define _VALIST
-typedef char *va_list;
-#endif /* _VALIST */
-
-/*
- * Storage alignment properties
- */
-
-#define  _AUPBND                (sizeof (acpi_native_int) - 1)
-#define  _ADNBND                (sizeof (acpi_native_int) - 1)
-
-/*
- * Variable argument list macro definitions
- */
-
-#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))
-#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
-#define va_end(ap)              (void) 0
-#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
-
-#endif /* va_arg */
-
-
-#define ACPI_STRSTR(s1,s2)      acpi_ut_strstr ((s1), (s2))
-#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
-#define ACPI_STRLEN(s)          (acpi_size) acpi_ut_strlen ((s))
-#define ACPI_STRCPY(d,s)        (void) acpi_ut_strcpy ((d), (s))
-#define ACPI_STRNCPY(d,s,n)     (void) acpi_ut_strncpy ((d), (s), (acpi_size)(n))
-#define ACPI_STRNCMP(d,s,n)     acpi_ut_strncmp ((d), (s), (acpi_size)(n))
-#define ACPI_STRCMP(d,s)        acpi_ut_strcmp ((d), (s))
-#define ACPI_STRCAT(d,s)        (void) acpi_ut_strcat ((d), (s))
-#define ACPI_STRNCAT(d,s,n)     acpi_ut_strncat ((d), (s), (acpi_size)(n))
-#define ACPI_STRTOUL(d,s,n)     acpi_ut_strtoul ((d), (s), (acpi_size)(n))
-#define ACPI_MEMCPY(d,s,n)      (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n))
-#define ACPI_MEMSET(d,v,n)      (void) acpi_ut_memset ((d), (v), (acpi_size)(n))
-#define ACPI_TOUPPER            acpi_ut_to_upper
-#define ACPI_TOLOWER            acpi_ut_to_lower
-
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
-
-
-/******************************************************************************
- *
- * Assembly code macros
- *
- *****************************************************************************/
-
-/*
- * Handle platform- and compiler-specific assembly language differences.
- * These should already have been defined by the platform includes above.
- *
- * Notes:
- * 1) Interrupt 3 is used to break into a debugger
- * 2) Interrupts are turned off during ACPI register setup
- */
-
-/* Unrecognized compiler, use defaults */
-
-#ifndef ACPI_ASM_MACROS
-
-/*
- * Calling conventions:
- *
- * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
- * ACPI_EXTERNAL_XFACE      - External ACPI interfaces
- * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
- * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
- */
-#define ACPI_SYSTEM_XFACE
-#define ACPI_EXTERNAL_XFACE
-#define ACPI_INTERNAL_XFACE
-#define ACPI_INTERNAL_VAR_XFACE
-
-#define ACPI_ASM_MACROS
-#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS()
-#define ACPI_ENABLE_IRQS()
-#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
-#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
-
-#endif /* ACPI_ASM_MACROS */
-
-
-#ifdef ACPI_APPLICATION
-
-/* Don't want software interrupts within a ring3 application */
-
-#undef BREAKPOINT3
-#define BREAKPOINT3
-#endif
-
-
-/******************************************************************************
- *
- * Compiler-specific information is contained in the compiler-specific
- * headers.
- *
- *****************************************************************************/
-#endif /* __ACENV_H__ */
diff -Nru a/drivers/acpi/include/platform/acgcc.h b/drivers/acpi/include/platform/acgcc.h
--- a/drivers/acpi/include/platform/acgcc.h	Mon Feb 10 10:39:33 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,40 +0,0 @@
-/******************************************************************************
- *
- * Name: acgcc.h - GCC specific defines, etc.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACGCC_H__
-#define __ACGCC_H__
-
-/* This macro is used to tag functions as "printf-like" because
- * some compilers (like GCC) can catch printf format string problems.
- */
-#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5)))
-
-/* Some compilers complain about unused variables. Sometimes we don't want to
- * use all the variables (most specifically for _THIS_MODULE). This allow us
- * to to tell the compiler warning in a per-variable manner that a variable
- * is unused.
- */
-#define ACPI_UNUSED_VAR __attribute__ ((unused))
-
-#endif /* __ACGCC_H__ */
diff -Nru a/drivers/acpi/include/platform/aclinux.h b/drivers/acpi/include/platform/aclinux.h
--- a/drivers/acpi/include/platform/aclinux.h	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,72 +0,0 @@
-/******************************************************************************
- *
- * Name: aclinux.h - OS specific defines, etc.
- *
- *****************************************************************************/
-
-/*
- *  Copyright (C) 2000 - 2003, R. Byron Moore
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU 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 __ACLINUX_H__
-#define __ACLINUX_H__
-
-#define ACPI_OS_NAME                "Linux"
-
-#define ACPI_USE_SYSTEM_CLIBRARY
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <asm/system.h>
-#include <asm/atomic.h>
-#include <asm/div64.h>
-#include <asm/acpi.h>
-
-#define strtoul simple_strtoul
-
-#define ACPI_MACHINE_WIDTH  BITS_PER_LONG
-
-#else /* !__KERNEL__ */
-
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#if defined(__ia64__) || defined(__x86_64__)
-#define ACPI_MACHINE_WIDTH	    64
-#define COMPILER_DEPENDENT_INT64    long
-#define COMPILER_DEPENDENT_UINT64   unsigned long
-#else
-#define ACPI_MACHINE_WIDTH	    32
-#define COMPILER_DEPENDENT_INT64    long long
-#define COMPILER_DEPENDENT_UINT64   unsigned long long
-#define ACPI_USE_NATIVE_DIVIDE
-#endif
-
-#endif /* __KERNEL__ */
-
-/* Linux uses GCC */
-
-#include "acgcc.h"
-
-#endif /* __ACLINUX_H__ */
diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
--- a/drivers/acpi/namespace/nsload.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/acpi/namespace/nsload.c	Mon Feb 10 10:39:32 2003
@@ -75,9 +75,11 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", table_desc->aml_start));
 
+	/* Ignore table if there is no AML contained within */
+
 	if (!table_desc->aml_length) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Zero-length AML block\n"));
-		return_ACPI_STATUS (AE_BAD_PARAMETER);
+		ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", table_desc->pointer->signature));
+		return_ACPI_STATUS (AE_OK);
 	}
 
 	/*
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/acpi/osl.c	Mon Feb 10 10:39:31 2003
@@ -35,9 +35,9 @@
 #include <linux/kmod.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
+#include <acpi/acpi.h>
 #include <asm/io.h>
 #include "acpi_bus.h"
-#include "acpi.h"
 
 #ifdef CONFIG_ACPI_EFI
 #include <linux/efi.h>
diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c
--- a/drivers/acpi/power.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/acpi/power.c	Mon Feb 10 10:39:27 2003
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include "acpi_bus.h"
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/acpi/processor.c	Mon Feb 10 10:39:29 2003
@@ -35,18 +35,19 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/delay.h>
+#include <linux/cpufreq.h>
 #include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/delay.h>
+
 #include "acpi_bus.h"
 #include "acpi_drivers.h"
+#include "processor.h"
 
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-#include <linux/cpufreq.h>
-#endif
 
 #define ACPI_PROCESSOR_COMPONENT	0x01000000
 #define ACPI_PROCESSOR_CLASS		"processor"
@@ -64,17 +65,6 @@
 #define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
 #define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
 
-#define ACPI_PROCESSOR_BUSY_METRIC	10
-
-#define ACPI_PROCESSOR_MAX_POWER	ACPI_C_STATE_COUNT
-#define ACPI_PROCESSOR_MAX_C2_LATENCY	100
-#define ACPI_PROCESSOR_MAX_C3_LATENCY	1000
-
-#define ACPI_PROCESSOR_MAX_PERFORMANCE	8
-
-#define ACPI_PROCESSOR_MAX_THROTTLING	16
-#define ACPI_PROCESSOR_MAX_THROTTLE	250	/* 25% */
-#define ACPI_PROCESSOR_MAX_DUTY_WIDTH	4
 
 const u32 POWER_OF_2[] = {1,2,4,8,16,32,64};
 
@@ -107,118 +97,6 @@
 			},
 };
 
-/* Power Management */
-
-struct acpi_processor_cx_policy {
-	u32			count;
-	int			state;
-	struct {
-		u32			time;
-		u32			ticks;
-		u32			count;
-		u32			bm;
-	}			threshold;
-};
-
-struct acpi_processor_cx {
-	u8			valid;
-	u32			address;
-	u32			latency;
-	u32			latency_ticks;
-	u32			power;
-	u32			usage;
-	struct acpi_processor_cx_policy promotion;
-	struct acpi_processor_cx_policy demotion;
-};
-
-struct acpi_processor_power {
-	int			state;
-	int			default_state;
-	u32			bm_activity;
-	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
-};
-
-/* Performance Management */
-
-struct acpi_pct_register {
-	u8			descriptor;
-	u16			length;
-	u8			space_id;
-	u8			bit_width;
-	u8			bit_offset;
-	u8			reserved;
-	u64			address;
-} __attribute__ ((packed));
-
-struct acpi_processor_px {
-	acpi_integer		core_frequency;		/* megahertz */
-	acpi_integer		power;			/* milliWatts */
-	acpi_integer		transition_latency;	/* microseconds */
-	acpi_integer		bus_master_latency;	/* microseconds */
-	acpi_integer		control;		/* control value */
-	acpi_integer		status;			/* success indicator */
-};
-
-struct acpi_processor_performance {
-	int			state;
-	int			platform_limit;
-	u16			control_register;
-	u16			status_register;
-	int			state_count;
-	struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE];
-};
-
-
-/* Throttling Control */
-
-struct acpi_processor_tx {
-	u16			power;
-	u16			performance;
-};
-
-struct acpi_processor_throttling {
-	int			state;
-	u32			address;
-	u8			duty_offset;
-	u8			duty_width;
-	int			state_count;
-	struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING];
-};
-
-/* Limit Interface */
-
-struct acpi_processor_lx {
-	int			px;		/* performace state */	
-	int			tx;		/* throttle level */
-};
-
-struct acpi_processor_limit {
-	struct acpi_processor_lx state;		/* current limit */
-	struct acpi_processor_lx thermal;	/* thermal limit */
-	struct acpi_processor_lx user;		/* user limit */
-};
-
-
-struct acpi_processor_flags {
-	u8			power:1;
-	u8			performance:1;
-	u8			throttling:1;
-	u8			limit:1;
-	u8			bm_control:1;
-	u8			bm_check:1;
-	u8			reserved:2;
-};
-
-struct acpi_processor {
-	acpi_handle		handle;
-	u32			acpi_id;
-	u32			id;
-	struct acpi_processor_flags flags;
-	struct acpi_processor_power power;
-	struct acpi_processor_performance performance;
-	struct acpi_processor_throttling throttling;
-	struct acpi_processor_limit limit;
-};
 
 struct acpi_processor_errata {
 	u8			smp;
@@ -262,18 +140,6 @@
 static struct acpi_processor_errata errata;
 static void (*pm_idle_save)(void) = NULL;
 
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-static unsigned int cpufreq_usage_count = 0;
-static struct cpufreq_driver *acpi_cpufreq_driver;
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-	.open 		= acpi_processor_perf_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif
-
 
 /* --------------------------------------------------------------------------
                                 Errata Handling
@@ -880,8 +746,7 @@
 /* --------------------------------------------------------------------------
                               Performance Management
    -------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-static int 
+int 
 acpi_processor_get_platform_limit (
 	struct acpi_processor*	pr)
 {
@@ -898,347 +763,38 @@
 	 * (e.g. 0 = states 0..n; 1 = states 1..n; etc.
 	 */
 	status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
-	if(ACPI_FAILURE(status)) {
+	if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n"));
 		return_VALUE(-ENODEV);
 	}
 
-	pr->performance.platform_limit = (int) ppc;
+	pr->performance_platform_limit = (int) ppc;
 
 	return_VALUE(0);
 }
+EXPORT_SYMBOL(acpi_processor_get_platform_limit);
 
-
-static int 
-acpi_processor_get_performance_control (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	acpi_status		status = 0;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	union acpi_object	*pct = NULL;
-	union acpi_object	obj = {0};
-	struct acpi_pct_register *reg = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
-
-	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
-	if(ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	pct = (union acpi_object *) buffer.pointer;
-	if (!pct || (pct->type != ACPI_TYPE_PACKAGE) 
-		|| (pct->package.count != 2)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	/*
-	 * control_register
-	 */
-
-	obj = pct->package.elements[0];
-
-	if ((obj.type != ACPI_TYPE_BUFFER) 
-		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-		|| (obj.buffer.pointer == NULL)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Invalid _PCT data (control_register)\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	reg = (struct acpi_pct_register *) (obj.buffer.pointer);
-
-	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unsupported address space [%d] (control_register)\n",
-			(u32) reg->space_id));
-		result = -EFAULT;
-		goto end;
-	}
-
-	pr->performance.control_register = (u16) reg->address;
-
-	/*
-	 * status_register
-	 */
-
-	obj = pct->package.elements[1];
-
-	if ((obj.type != ACPI_TYPE_BUFFER) 
-		|| (obj.buffer.length < sizeof(struct acpi_pct_register)) 
-		|| (obj.buffer.pointer == NULL)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Invalid _PCT data (status_register)\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	reg = (struct acpi_pct_register *) (obj.buffer.pointer);
-
-	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unsupported address space [%d] (status_register)\n",
-			(u32) reg->space_id));
-		result = -EFAULT;
-		goto end;
-	}
-
-	pr->performance.status_register = (u16) reg->address;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"control_register[0x%04x] status_register[0x%04x]\n",
-		pr->performance.control_register,
-		pr->performance.status_register));
-
-end:
-	acpi_os_free(buffer.pointer);
-
-	return_VALUE(result);
-}
-
-
-static int 
-acpi_processor_get_performance_states (
-	struct acpi_processor*	pr)
-{
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_buffer	format = {sizeof("NNNNNN"), "NNNNNN"};
-	struct acpi_buffer	state = {0, NULL};
-	union acpi_object 	*pss = NULL;
-	int			i = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
-
-	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
-	if(ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
-		return_VALUE(-ENODEV);
-	}
-
-	pss = (union acpi_object *) buffer.pointer;
-	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-		result = -EFAULT;
-		goto end;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", 
-		pss->package.count));
-
-	if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
-		pr->performance.state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Limiting number of states to max (%d)\n", 
-			ACPI_PROCESSOR_MAX_PERFORMANCE));
-	}
-	else
-		pr->performance.state_count = pss->package.count;
-
-	if (pr->performance.state_count > 1)
-		pr->flags.performance = 1;
-
-	for (i = 0; i < pr->performance.state_count; i++) {
-
-		struct acpi_processor_px *px = &(pr->performance.states[i]);
-
-		state.length = sizeof(struct acpi_processor_px);
-		state.pointer = px;
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
-
-		status = acpi_extract_package(&(pss->package.elements[i]), 
-			&format, &state);
-		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n"));
-			result = -EFAULT;
-			goto end;
-		}
-
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
-			i, 
-			(u32) px->core_frequency, 
-			(u32) px->power, 
-			(u32) px->transition_latency, 
-			(u32) px->bus_master_latency,
-			(u32) px->control, 
-			(u32) px->status));
-	}
-
-end:
-	acpi_os_free(buffer.pointer);
-
-	return_VALUE(result);
-}
-
-
-static int
-acpi_processor_set_performance (
-	struct acpi_processor	*pr,
-	int			state)
+int 
+acpi_processor_register_performance (
+	struct acpi_processor_performance * performance,
+	struct acpi_processor ** pr,
+	unsigned int cpu)
 {
-	u16			port = 0;
-	u8			value = 0;
-	int			i = 0;
-	struct cpufreq_freqs    cpufreq_freqs;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (!pr->flags.performance)
-		return_VALUE(-ENODEV);
-
-	if (state >= pr->performance.state_count) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
-			"Invalid target state (P%d)\n", state));
-		return_VALUE(-ENODEV);
-	}
-
-	if (state < pr->performance.platform_limit) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
-			"Platform limit (P%d) overrides target state (P%d)\n",
-			pr->performance.platform_limit, state));
-		return_VALUE(-ENODEV);
-	}
-
-	if (state == pr->performance.state) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Already at target state (P%d)\n", state));
-		return_VALUE(0);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
-		pr->performance.state, state));
-
-	/* cpufreq frequency struct */
-	cpufreq_freqs.cpu = pr->id;
-	cpufreq_freqs.old = pr->performance.states[pr->performance.state].core_frequency;
-	cpufreq_freqs.new = pr->performance.states[state].core_frequency;
-
-	/* notify cpufreq */
-	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
-
-	/*
-	 * First we write the target state's 'control' value to the
-	 * control_register.
-	 */
+	ACPI_FUNCTION_TRACE("acpi_processor_register_performance");
 
-	port = pr->performance.control_register;
-	value = (u16) pr->performance.states[state].control;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Writing 0x%02x to port 0x%04x\n", value, port));
-
-	outb(value, port); 
-
-	/*
-	 * Then we read the 'status_register' and compare the value with the
-	 * target state's 'status' to make sure the transition was successful.
-	 * Note that we'll poll for up to 1ms (100 cycles of 10us) before
-	 * giving up.
-	 */
-
-	port = pr->performance.status_register;
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Looking for 0x%02x from port 0x%04x\n",
-		(u8) pr->performance.states[state].status, port));
-
-	for (i=0; i<100; i++) {
-		value = inb(port);
-		if (value == (u8) pr->performance.states[state].status)
-			break;
-		udelay(10);
-	}
-
-	/* notify cpufreq */
-	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
-
-	if (value != pr->performance.states[state].status) {
-		unsigned int tmp = cpufreq_freqs.new;
-		cpufreq_freqs.new = cpufreq_freqs.old;
-		cpufreq_freqs.old = tmp;
-		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
-		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n"));
+	*pr = processors[cpu];
+	if (!*pr)
 		return_VALUE(-ENODEV);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Transition successful after %d microseconds\n",
-		i * 10));
-
-	pr->performance.state = state;
-
-	return_VALUE(0);
-}
-
-
-static int
-acpi_processor_get_performance_info (
-	struct acpi_processor	*pr)
-{
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	acpi_handle		handle = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
+	if ((*pr)->performance)
+		return_VALUE(-EBUSY);
 
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	status = acpi_get_handle(pr->handle, "_PCT", &handle);
-	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"ACPI-based processor performance control unavailable\n"));
-		return_VALUE(0);
-	}
-
-	result = acpi_processor_get_performance_control(pr);
-	if (result)
-		return_VALUE(result);
-
-	result = acpi_processor_get_performance_states(pr);
-	if (result)
-		return_VALUE(result);
-
-	result = acpi_processor_get_platform_limit(pr);
-	if (result)
-		return_VALUE(result);
-
-	/* 
-	 * TBD: Don't trust the latency values we get from BIOS, but rather
-	 *      measure the latencies during run-time (e.g. get_latencies).
-	 */
-
-	return_VALUE(0);
-}
-#else
-
-
-static int
-acpi_processor_get_performance_info (
-	struct acpi_processor	*pr)
-{
-	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info_dummy");
-	if (!pr)
-		return_VALUE(-EINVAL);
-	pr->flags.performance = 0;
-	return_VALUE(0);
+	(*pr)->performance = performance;
+	return 0;
 }
-#endif
-
-
+EXPORT_SYMBOL(acpi_processor_register_performance);
 
+/* for the rest of it, check cpufreq/acpi.c */
 
 
 /* --------------------------------------------------------------------------
@@ -1484,9 +1040,9 @@
 	if (!pr->flags.limit)
 		return_VALUE(-ENODEV);
 
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
+#ifdef CONFIG_CPU_FREQ
 	if (pr->flags.performance) {
-		px = pr->performance.platform_limit;
+		px = pr->performance_platform_limit;
 		if (pr->limit.user.px > px)
 			px = pr->limit.user.px;
 		if (pr->limit.thermal.px > px)
@@ -1495,11 +1051,13 @@
 			struct cpufreq_policy policy;
 			policy.cpu = pr->id;
 			cpufreq_get_policy(&policy, pr->id);
-			policy.max = pr->performance.states[px].core_frequency * 1000;
+			policy.max = pr->performance->states[px].core_frequency * 1000; /* racy */
 			result = cpufreq_set_policy(&policy);
 		}
 		if (result)
 			goto end;
+	} else if (pr->performance_platform_limit) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Platform limit event detected. Consider using ACPI P-States CPUfreq driver\n"));
 	}
 #endif
 
@@ -1560,7 +1118,7 @@
 
 	/* Thermal limits are always relative to the current Px/Tx state. */
 	if (pr->flags.performance)
-		pr->limit.thermal.px = pr->performance.state;
+		pr->limit.thermal.px = pr->performance->state;
 	if (pr->flags.throttling)
 		pr->limit.thermal.tx = pr->throttling.state;
 
@@ -1581,7 +1139,7 @@
 
 	case ACPI_PROCESSOR_LIMIT_INCREMENT:
 		if (pr->flags.performance) {
-			if (px == (pr->performance.state_count - 1))
+			if (px == (pr->performance->state_count - 1))
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 					"At maximum performance state\n"));
 			else {
@@ -1600,7 +1158,7 @@
 
 	case ACPI_PROCESSOR_LIMIT_DECREMENT:
 		if (pr->flags.performance) {
-			if (px == pr->performance.platform_limit)
+			if (px == pr->performance_platform_limit)
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 					"At minimum performance state\n"));
 			else  {
@@ -1650,247 +1208,6 @@
 	return_VALUE(0);
 }
 
-/* --------------------------------------------------------------------------
-                               cpufreq interface
-   -------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-static int
-acpi_cpufreq_setpolicy (
-	struct cpufreq_policy   *policy)
-{
-	unsigned int i = 0;
-	struct acpi_processor *pr = NULL;
-	unsigned int next_state = 0;
-	unsigned int result = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
-
-	if (!policy)
-		return_VALUE(-EINVAL);
-
-	pr = processors[policy->cpu];
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/* select appropriate P-State */
-	if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
-	{
-		for (i=(pr->performance.state_count - 1); i>= pr->limit.state.px; i--)
-		{
-			unsigned int state_freq = pr->performance.states[i].core_frequency * 1000;
-			if ((policy->min <= state_freq) &&
-			    (policy->max >= state_freq)) 
-			{
-				next_state = i;
-				break;
-			}
-		}
-	} else {
-		for (i=pr->limit.state.px; i < pr->performance.state_count; i++)
-		{
-			unsigned int state_freq = pr->performance.states[i].core_frequency * 1000;
-			if ((policy->min <= state_freq) &&
-			    (policy->max >= state_freq)) 
-			{
-				next_state = i;
-				break;
-			}
-		}
-	}
-
-	/* set one or all CPUs to the new state */
-	result = acpi_processor_set_performance (pr, next_state);
-
-	return_VALUE(result);
-}
-
-
-static int
-acpi_cpufreq_verify (
-	struct cpufreq_policy   *policy)
-{
-	unsigned int i = 0;
-	struct acpi_processor *pr = NULL;
-	unsigned int number_states = 0;
-	unsigned int next_larger_state = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
-
-	if (!policy)
-		return_VALUE(-EINVAL);
-
-	pr = processors[policy->cpu];
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	/* first check if min and max are within valid limits */
-	cpufreq_verify_within_limits(
-		policy, 
-		pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000,
-		pr->performance.states[pr->limit.state.px].core_frequency * 1000);
-
-	/* now check if at least one value is within this limit */
-	for (i=pr->limit.state.px; i < pr->performance.state_count; i++)
-	{
-		unsigned int state_freq = pr->performance.states[i].core_frequency * 1000;
-		if ((policy->min <= state_freq) &&
-		    (policy->max >= state_freq))
-			number_states++;
-		if (state_freq > policy->max)
-			next_larger_state = i;
-	}
-
-	if (!number_states) {
-		/* round up now */
-		policy->max = pr->performance.states[next_larger_state].core_frequency * 1000;
-	}
-
-	cpufreq_verify_within_limits(
-		policy, 
-		pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000,
-		pr->performance.states[pr->limit.state.px].core_frequency * 1000);
-
-	return_VALUE(0);
-}
-
-static int
-acpi_cpufreq_init (
-	struct acpi_processor   *pr)
-{
-	int                     result = 0;
-	int                     i = 0;
-	int                     current_state = 0;
-	struct cpufreq_driver   *driver;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
-
-	if (!pr->flags.performance)
-		return_VALUE(0);
-
-	if (cpufreq_usage_count) {
-		if (pr->flags.performance == 1)
-			cpufreq_usage_count++;
-		return_VALUE(0);
-	}
-
-	/* test if it works */
-	current_state = pr->performance.state;
-
-	if (current_state == pr->limit.state.px) {
-		result = acpi_processor_set_performance(pr, (pr->performance.state_count - 1));
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-			pr->flags.performance = 0;
-			return_VALUE(-ENODEV);
-		}
-	}
-
-	result = acpi_processor_set_performance(pr, pr->limit.state.px);
-	if (result) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-		pr->flags.performance = 0;
-		return_VALUE(-ENODEV);
-	}
-	
-	if (current_state != 0) {
-		result = acpi_processor_set_performance(pr, current_state);
-		if (result) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
-			pr->flags.performance = 0;
-			return_VALUE(-ENODEV);
-		}
-	}
-
-	/* initialization of main "cpufreq" code*/
-	driver = kmalloc(sizeof(struct cpufreq_driver) + 
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver)
-		return_VALUE(-ENOMEM);
-
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
-
-#ifdef CONFIG_CPU_FREQ_24_API
-	for (i=0;i<NR_CPUS;i++) {
-		driver->cpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000;
-	}
-#endif
-
-	/* detect highest transition latency */
-	for (i=0;i<pr->performance.state_count;i++) {
-		if (pr->performance.states[i].transition_latency > driver->policy[0].cpuinfo.transition_latency)
-			driver->policy[0].cpuinfo.transition_latency = pr->performance.states[i].transition_latency;
-	}
-
-	driver->verify      = &acpi_cpufreq_verify;
-	driver->setpolicy   = &acpi_cpufreq_setpolicy;
-	driver->init        = NULL;
-	driver->exit        = NULL;
-	strncpy(driver->name, "acpi-processor", CPUFREQ_NAME_LEN);
-
-	for (i=0;i<NR_CPUS;i++) {
-		driver->policy[i].cpu    = pr->id;
-		driver->policy[i].min    = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000;
-		driver->policy[i].max    = pr->performance.states[pr->limit.state.px].core_frequency * 1000;
-		driver->policy[i].cpuinfo.max_freq = pr->performance.states[0].core_frequency * 1000;
-		driver->policy[i].cpuinfo.min_freq = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000;
-		driver->policy[i].cpuinfo.transition_latency = driver->policy[0].cpuinfo.transition_latency;
-		driver->policy[i].policy = ( pr->performance.states[current_state].core_frequency * 1000 == driver->policy[i].max) ? 
-			CPUFREQ_POLICY_PERFORMANCE : CPUFREQ_POLICY_POWERSAVE;
-	}
-
-	acpi_cpufreq_driver = driver;
-	result = cpufreq_register(driver);
-	if (result) {
-		kfree(driver);
-		acpi_cpufreq_driver = NULL;
-		return_VALUE(result);
-	}
-
-	cpufreq_usage_count++;
-
-	return_VALUE(0);
-}
-
-static int
-acpi_cpufreq_exit (
-	struct acpi_processor   *pr)
-{
-	int                     result = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_exit");
-
-	if (!pr)
-		return_VALUE(-EINVAL);
-
-	if (pr->flags.performance)
-		cpufreq_usage_count--;
-
-	if (!cpufreq_usage_count) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-			"Removing cpufreq driver\n"));
-		result = cpufreq_unregister();
-	}
-
-	return_VALUE(result);
-}
-#else
-static int
-acpi_cpufreq_init (
-	struct acpi_processor   *pr)
-{
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_init_dummy");
-	return_VALUE(0);
-}
-
-
-static int
-acpi_cpufreq_exit (
-	struct acpi_processor   *pr)
-{
-	ACPI_FUNCTION_TRACE("acpi_cpufreq_exit_dummy");
-	return_VALUE(0);
-}
-#endif
 
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
@@ -1987,82 +1304,6 @@
 						PDE(inode)->data);
 }
 
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
-	int			i = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show");
-
-	if (!pr)
-		goto end;
-
-	if (!pr->flags.performance) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
-	}
-
-	seq_printf(seq, "state count:             %d\n"
-			"active state:            P%d\n",
-			pr->performance.state_count,
-			pr->performance.state);
-
-	seq_puts(seq, "states:\n");
-	for (i = 0; i < pr->performance.state_count; i++)
-		seq_printf(seq, "   %cP%d:                  %d MHz, %d mW, %d uS\n",
-			(i == pr->performance.state?'*':' '), i,
-			(u32) pr->performance.states[i].core_frequency,
-			(u32) pr->performance.states[i].power,
-			(u32) pr->performance.states[i].transition_latency);
-
-end:
-	return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_processor_perf_seq_show,
-						PDE(inode)->data);
-}
-
-static int
-acpi_processor_write_performance (
-        struct file		*file,
-        const char		*buffer,
-        unsigned long		count,
-        void			*data)
-{
-	int			result = 0;
-	struct acpi_processor	*pr = (struct acpi_processor *) data;
-	char			state_string[12] = {'\0'};
-	unsigned int            new_state = 0;
-	struct cpufreq_policy   policy;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_write_performance");
-
-	if (!pr || (count > sizeof(state_string) - 1))
-		return_VALUE(-EINVAL);
-	
-	if (copy_from_user(state_string, buffer, count))
-		return_VALUE(-EFAULT);
-	
-	state_string[count] = '\0';
-	new_state = simple_strtoul(state_string, NULL, 0);
-
-	cpufreq_get_policy(&policy, pr->id);
-
-	policy.cpu = pr->id;
-	policy.max = pr->performance.states[new_state].core_frequency * 1000;
-
-	result = cpufreq_set_policy(&policy);
-	if (result)
-		return_VALUE(result);
-
-	return_VALUE(count);
-}
-#endif
-
 static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
@@ -2111,8 +1352,8 @@
 acpi_processor_write_throttling (
         struct file		*file,
         const char		*buffer,
-        unsigned long		count,
-        void			*data)
+        size_t			count,
+        loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_processor	*pr = (struct acpi_processor *) data;
@@ -2155,7 +1396,7 @@
 			"user limit:              P%d:T%d\n"
 			"thermal limit:           P%d:T%d\n",
 			pr->limit.state.px, pr->limit.state.tx,
-			pr->flags.performance?pr->performance.platform_limit:0,
+			pr->flags.performance?pr->performance_platform_limit:0,
 			pr->limit.user.px, pr->limit.user.tx,
 			pr->limit.thermal.px, pr->limit.thermal.tx);
 
@@ -2171,10 +1412,10 @@
 
 static int
 acpi_processor_write_limit (
-        struct file		*file,
-        const char		*buffer,
-        unsigned long		count,
-        void			*data)
+	struct file		*file,
+	const char		*buffer,
+	size_t			count,
+	loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_processor	*pr = (struct acpi_processor *) data;
@@ -2202,8 +1443,8 @@
 	}
 
 	if (pr->flags.performance) {
-		if ((px < pr->performance.platform_limit) 
-			|| (px > (pr->performance.state_count - 1))) {
+		if ((px < pr->performance_platform_limit) 
+			|| (px > (pr->performance->state_count - 1))) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid px\n"));
 			return_VALUE(-EINVAL);
 		}
@@ -2263,21 +1504,6 @@
 		entry->data = acpi_driver_data(device);
 	}
 
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
-	/* 'performance' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_PERFORMANCE));
-	else {
-		entry->proc_fops = &acpi_processor_perf_fops;
-		entry->write_proc = acpi_processor_write_performance;
-		entry->data = acpi_driver_data(device);
-	}
-#endif
-
 	/* 'throttling' [R/W] */
 	entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
 		S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
@@ -2287,7 +1513,7 @@
 			ACPI_PROCESSOR_FILE_THROTTLING));
 	else {
 		entry->proc_fops = &acpi_processor_throttling_fops;
-		entry->write_proc = acpi_processor_write_throttling;
+		entry->proc_fops->write = acpi_processor_write_throttling;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -2300,7 +1526,7 @@
 			ACPI_PROCESSOR_FILE_LIMIT));
 	else {
 		entry->proc_fops = &acpi_processor_limit_fops;
-		entry->write_proc = acpi_processor_write_limit;
+		entry->proc_fops->write = acpi_processor_write_limit;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -2383,22 +1609,27 @@
 
 	if (!object.processor.pblk_address)
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
-	else if (object.processor.pblk_length < 6)
+	else if (object.processor.pblk_length < 4)
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n",
 			object.processor.pblk_length));
 	else {
 		pr->throttling.address = object.processor.pblk_address;
 		pr->throttling.duty_offset = acpi_fadt.duty_offset;
 		pr->throttling.duty_width = acpi_fadt.duty_width;
-		pr->power.states[ACPI_STATE_C2].address =
-			object.processor.pblk_address + 4;
-		pr->power.states[ACPI_STATE_C3].address =
-			object.processor.pblk_address + 5;
+
+		if (object.processor.pblk_length >= 5)
+			pr->power.states[ACPI_STATE_C2].address =
+				object.processor.pblk_address + 4;
+
+		if (object.processor.pblk_length >= 6)
+			pr->power.states[ACPI_STATE_C3].address =
+				object.processor.pblk_address + 5;
 	}
 
 	acpi_processor_get_power_info(pr);
-	acpi_processor_get_performance_info(pr);
-	acpi_cpufreq_init(pr);
+	pr->flags.performance = 0;
+	pr->performance_platform_limit = 0;
+	acpi_processor_get_platform_limit(pr);
 	acpi_processor_get_throttling_info(pr);
 	acpi_processor_get_limit_info(pr);
 
@@ -2426,18 +1657,11 @@
 
 	switch (event) {
 	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
-#ifdef CONFIG_ACPI_PROCESSOR_PERF
 		result = acpi_processor_get_platform_limit(pr);
 		if (!result)
 			acpi_processor_apply_limit(pr);
-#else
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Please use kernel with Processor Performance States support included!\n"));
-		result = 0;
-#endif
-
 		acpi_bus_generate_event(device, event, 
-			pr->performance.platform_limit);
+			pr->performance_platform_limit);
 		break;
 	case ACPI_PROCESSOR_NOTIFY_POWER:
 		/* TBD */
@@ -2511,8 +1735,6 @@
 	for (i=1; i<ACPI_C_STATE_COUNT; i++)
 		if (pr->power.states[i].valid)
 			printk(" C%d", i);
-	if (pr->flags.performance)
-		printk(", %d performance states", pr->performance.state_count);
 	if (pr->flags.throttling)
 		printk(", %d throttling states", pr->throttling.state_count);
 	printk(")\n");
@@ -2554,7 +1776,6 @@
 		return_VALUE(-ENODEV);
 	}
 
-	acpi_cpufreq_exit(pr);
 	acpi_processor_remove_fs(device);
 
 	processors[pr->id] = NULL;
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/acpi/resources/rscalc.c	Mon Feb 10 10:39:27 2003
@@ -793,7 +793,7 @@
 				 * The length String.Length field does not include the
 				 * terminating NULL, add 1
 				 */
-				temp_size_needed += ((*sub_object_list)->string.length + 1);
+				temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1);
 			}
 			else {
 				temp_size_needed += acpi_ns_get_pathname_length (
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/acpi/scan.c	Mon Feb 10 10:39:26 2003
@@ -6,7 +6,7 @@
 #include <linux/acpi.h>
 
 #include "acpi_drivers.h"
-#include "include/acinterp.h"	/* for acpi_ex_eisa_id_to_string() */
+#include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */
 
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
--- a/drivers/acpi/tables/tbinstal.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/acpi/tables/tbinstal.c	Mon Feb 10 10:39:24 2003
@@ -61,7 +61,7 @@
 	 * Search for a signature match among the known table types
 	 */
 	for (i = 0; i < NUM_ACPI_TABLES; i++) {
-		if ((acpi_gbl_acpi_table_data[i].flags & ACPI_TABLE_TYPE_MASK) != search_type) {
+		if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) {
 			continue;
 		}
 
@@ -74,7 +74,7 @@
 			}
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-				"Table [%4.4s] matched and is a required ACPI table\n",
+				"Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
 				(char *) acpi_gbl_acpi_table_data[i].signature));
 
 			return_ACPI_STATUS (AE_OK);
@@ -82,7 +82,7 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-		"Table [%4.4s] is not a required ACPI table - ignored\n",
+		"Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n",
 		(char *) signature));
 
 	return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
@@ -125,7 +125,7 @@
 
 	status = acpi_tb_init_table_descriptor (table_info->type, table_info);
 	if (ACPI_FAILURE (status)) {
-		ACPI_REPORT_ERROR (("Could not install ACPI table [%s], %s\n",
+		ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n",
 			table_info->pointer->signature, acpi_format_exception (status)));
 	}
 
diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c
--- a/drivers/acpi/tables.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/acpi/tables.c	Mon Feb 10 10:39:25 2003
@@ -509,8 +509,7 @@
 
 
 int __init
-acpi_table_init (
-	char			*cmdline)
+acpi_table_init (void)
 {
 	struct acpi_table_rsdp	*rsdp = NULL;
 	unsigned long		rsdp_phys = 0;
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/acpi/thermal.c	Mon Feb 10 10:39:31 2003
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/compatmac.h>
 #include <linux/proc_fs.h>
 #include <linux/sched.h>
 #include <linux/kmod.h>
@@ -878,10 +877,12 @@
 acpi_thermal_write_trip_points (
         struct file		*file,
         const char		*buffer,
-        unsigned long		count,
-        void			*data)
+        size_t			count,
+        loff_t			*ppos)
 {
-	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
+
 	char			limit_string[25] = {'\0'};
 	int			critical, hot, passive, active0, active1;
 
@@ -945,8 +946,8 @@
 acpi_thermal_write_cooling_mode (
 	struct file		*file,
 	const char		*buffer,
-	unsigned long		count,
-	void			*data)
+	size_t			count,
+	loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
@@ -1005,8 +1006,8 @@
 acpi_thermal_write_polling (
 	struct file		*file,
 	const char		*buffer,
-	unsigned long		count,
-	void			*data)
+	size_t			count,
+	loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
@@ -1080,10 +1081,10 @@
 	if (!entry)
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 			"Unable to create '%s' fs entry\n",
-			ACPI_THERMAL_FILE_POLLING_FREQ));
+			ACPI_THERMAL_FILE_TRIP_POINTS));
 	else {
 		entry->proc_fops = &acpi_thermal_trip_fops;
-		entry->write_proc = acpi_thermal_write_trip_points;
+		entry->proc_fops->write = acpi_thermal_write_trip_points;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -1096,7 +1097,7 @@
 			ACPI_THERMAL_FILE_COOLING_MODE));
 	else {
 		entry->proc_fops = &acpi_thermal_cooling_fops;
-		entry->write_proc = acpi_thermal_write_cooling_mode;
+		entry->proc_fops->write = acpi_thermal_write_cooling_mode;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -1109,7 +1110,7 @@
 			ACPI_THERMAL_FILE_POLLING_FREQ));
 	else {
 		entry->proc_fops = &acpi_thermal_polling_fops;
-		entry->write_proc = acpi_thermal_write_polling;
+		entry->proc_fops->write = acpi_thermal_write_polling;
 		entry->data = acpi_driver_data(device);
 	}
 
diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/acpi/toshiba_acpi.c	Mon Feb 10 10:39:23 2003
@@ -309,8 +309,8 @@
 }
 
 static int
-proc_write_lcd(struct file* file, const char* buffer, unsigned long count,
-	void* data)
+proc_write_lcd(struct file* file, const char* buffer, size_t count,
+	loff_t* data)
 {
 	int value;
 	/*int byte_count;*/
@@ -358,8 +358,8 @@
 }
 
 static int
-proc_write_video(struct file* file, const char* buffer, unsigned long count,
-	void* data)
+proc_write_video(struct file* file, const char* buffer, size_t count,
+	loff_t* data)
 {
 	int value;
 	const char* buffer_end = buffer + count;
@@ -423,8 +423,8 @@
 }
 
 static int
-proc_write_fan(struct file* file, const char* buffer, unsigned long count,
-	void* data)
+proc_write_fan(struct file* file, const char* buffer, size_t count,
+	loff_t* data)
 {
 	int value;
 	u32 hci_result;
@@ -476,8 +476,8 @@
 }
 
 static int
-proc_write_keys(struct file* file, const char* buffer, unsigned long count,
-	void* data)
+proc_write_keys(struct file* file, const char* buffer, size_t count,
+	loff_t* data)
 {
 	int value;
 
@@ -518,28 +518,28 @@
 		toshiba_proc_dir);
 	if (proc) {
 		proc->proc_fops = &toshiba_lcd_fops;
-		proc->write_proc = proc_write_lcd;
+		proc->proc_fops->write = proc_write_lcd;
 	}
 
 	proc = create_proc_entry(PROC_VIDEO, S_IFREG | S_IRUGO | S_IWUSR,
 		toshiba_proc_dir);
 	if (proc) {
 		proc->proc_fops = &toshiba_video_fops;
-		proc->write_proc = proc_write_video;
+		proc->proc_fops->write = proc_write_video;
 	}
 
 	proc = create_proc_entry(PROC_FAN, S_IFREG | S_IRUGO | S_IWUSR,
 		toshiba_proc_dir);
 	if (proc) {
 		proc->proc_fops = &toshiba_fan_fops;
-		proc->write_proc = proc_write_fan;
+		proc->proc_fops->write = proc_write_fan;
 	}
 
 	proc = create_proc_entry(PROC_KEYS, S_IFREG | S_IRUGO | S_IWUSR,
 		toshiba_proc_dir);
 	if (proc) {
 		proc->proc_fops = &toshiba_keys_fops;
-		proc->write_proc = proc_write_keys;
+		proc->proc_fops->write = proc_write_keys;
 	}
 
 	proc = create_proc_entry(PROC_VERSION, S_IFREG | S_IRUGO | S_IWUSR,
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/acpi/utilities/utcopy.c	Mon Feb 10 10:39:26 2003
@@ -652,13 +652,13 @@
 		 */
 		if ((source_desc->string.length) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			dest_desc->string.pointer = ACPI_MEM_ALLOCATE (source_desc->string.length + 1);
+			dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
 			if (!dest_desc->string.pointer) {
 				return (AE_NO_MEMORY);
 			}
 
 			ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
-					  source_desc->string.length + 1);
+					  (acpi_size) source_desc->string.length + 1);
 		}
 		break;
 
diff -Nru a/drivers/atm/Kconfig b/drivers/atm/Kconfig
--- a/drivers/atm/Kconfig	Mon Feb 10 10:39:26 2003
+++ b/drivers/atm/Kconfig	Mon Feb 10 10:39:26 2003
@@ -15,6 +15,11 @@
 config ATM_LANAI
 	tristate "Efficient Networks Speedstream 3010"
 	depends on PCI
+	help
+	  Supports ATM cards based on the Efficient Networks "Lanai"
+	  chipset such as the Speedstream 3010 and the ENI-25p.  The
+	  Speedstream 3060 is currently not supported since we don't
+	  have the code to drive the on-board Alcatel DSL chipset (yet).
 
 config ATM_ENI
 	tristate "Efficient Networks ENI155P"
@@ -29,7 +34,7 @@
 
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called eni.o.
+	  <file:Documentation/modules.txt>.  The module will be called eni.
 
 config ATM_ENI_DEBUG
 	bool "Enable extended debugging"
@@ -136,7 +141,7 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  firestream.o.
+	  firestream.
 
 config ATM_ZATM
 	tristate "ZeitNet ZN1221/ZN1225"
@@ -147,7 +152,7 @@
 
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called zatm.o.
+	  <file:Documentation/modules.txt>.  The module will be called zatm.
 
 config ATM_ZATM_DEBUG
 	bool "Enable extended debugging"
@@ -186,7 +191,7 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  nicstar.o.
+	  nicstar.
 
 config ATM_NICSTAR_USE_SUNI
 	bool "Use suni PHY driver (155Mbps)"
@@ -218,7 +223,7 @@
 
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>. The module will be called idt77252.o
+	  <file:Documentation/modules.txt>. The module will be called idt77252
 
 config ATM_IDT77252_DEBUG
 	bool "Enable debugging messages"
@@ -251,7 +256,7 @@
 	depends on PCI
 	help
 	  This is a driver for ATMizer based ATM card produced by Madge
-	  Networks Ltd. Say Y (or M to compile as a module named ambassador.o)
+	  Networks Ltd. Say Y (or M to compile as a module named ambassador)
 	  here if you have one of these cards.
 
 config ATM_AMBASSADOR_DEBUG
@@ -276,7 +281,7 @@
 	help
 	  This is a driver for the Horizon chipset ATM adapter cards once
 	  produced by Madge Networks Ltd. Say Y (or M to compile as a module
-	  named horizon.o) here if you have one of these cards.
+	  named horizon) here if you have one of these cards.
 
 config ATM_HORIZON_DEBUG
 	bool "Enable debugging messages"
@@ -305,7 +310,7 @@
 	  UTP155, UTP25, DS3 and E3). Go to:
 	  	<http://www.iphase.com/products/ClassSheet.cfm?ClassID=ATM>
 	  for more info about the cards. Say Y (or M to compile as a module
-	  named iphase.o) here if you have one of these cards.
+	  named iphase) here if you have one of these cards.
 
 	  See the file <file:Documentation/networking/iphase.txt> for further
 	  details.
@@ -334,7 +339,7 @@
 	  This is a driver for the FORE Systems 200E-series ATM adapter
 	  cards. It simultaneously supports PCA-200E and SBA-200E models
 	  on PCI and SBUS hosts. Say Y (or M to compile as a module
-	  named fore_200e.o) here if you have one of these ATM adapters.
+	  named fore_200e) here if you have one of these ATM adapters.
 
 	  Note that the driver will actually be compiled only if you
 	  additionally enable the support for PCA-200E and/or SBA-200E
diff -Nru a/drivers/atm/Makefile b/drivers/atm/Makefile
--- a/drivers/atm/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/atm/Makefile	Mon Feb 10 10:39:23 2003
@@ -4,7 +4,6 @@
 
 EXTRA_CFLAGS := -g
 
-export-objs	:= uPD98402.o suni.o idt77105.o
 fore_200e-objs	:= fore200e.o
 host-progs	:= fore200e_mkfirm
 
diff -Nru a/drivers/atm/lanai.c b/drivers/atm/lanai.c
--- a/drivers/atm/lanai.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/atm/lanai.c	Mon Feb 10 10:39:24 2003
@@ -632,7 +632,7 @@
  * anytime it wants to consult its table of vccs - for instance
  * when handling an incoming PDU.  This also explains why we would
  * probably want the write_lock while in _change_qos - to prevent
- * handling of PDUs while possibly in an inconsistant state.
+ * handling of PDUs while possibly in an inconsistent state.
  * Also, _send would grab the lock for reading.
  *
  * One problem with this is that _open and _close could no longer
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/base/Makefile	Mon Feb 10 10:39:31 2003
@@ -1,14 +1,8 @@
 # Makefile for the Linux device tree
 
-obj-y		:= core.o sys.o interface.o power.o bus.o \
-			driver.o class.o intf.o platform.o \
-			cpu.o firmware.o
-
+obj-y			:= core.o sys.o interface.o power.o bus.o \
+			   driver.o class.o intf.o platform.o \
+			   cpu.o firmware.o
 obj-$(CONFIG_NUMA)	+= node.o  memblk.o
-
-obj-y		+= fs/
-
+obj-y			+= fs/
 obj-$(CONFIG_HOTPLUG)	+= hotplug.o
-
-export-objs	:= core.o power.o sys.o bus.o driver.o \
-			class.o intf.o platform.o firmware.o
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/base/cpu.c	Mon Feb 10 10:39:24 2003
@@ -35,7 +35,7 @@
  */
 int __init register_cpu(struct cpu *cpu, int num, struct node *root)
 {
-	cpu->node_id = __cpu_to_node(num);
+	cpu->node_id = cpu_to_node(num);
 	cpu->sysdev.name = "cpu";
 	cpu->sysdev.id = num;
 	if (root)
diff -Nru a/drivers/base/fs/Makefile b/drivers/base/fs/Makefile
--- a/drivers/base/fs/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/base/fs/Makefile	Mon Feb 10 10:39:27 2003
@@ -1,3 +1,2 @@
 obj-y		:= device.o
 
-export-objs	:= device.o
diff -Nru a/drivers/base/memblk.c b/drivers/base/memblk.c
--- a/drivers/base/memblk.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/base/memblk.c	Mon Feb 10 10:39:33 2003
@@ -36,7 +36,7 @@
  */
 int __init register_memblk(struct memblk *memblk, int num, struct node *root)
 {
-	memblk->node_id = __memblk_to_node(num);
+	memblk->node_id = memblk_to_node(num);
 	memblk->sysdev.name = "memblk";
 	memblk->sysdev.id = num;
 	if (root)
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/base/node.c	Mon Feb 10 10:39:23 2003
@@ -72,7 +72,7 @@
 {
 	int error;
 
-	node->cpumap = __node_to_cpu_mask(num);
+	node->cpumap = node_to_cpumask(num);
 	node->sysroot.id = num;
 	if (parent)
 		node->sysroot.dev.parent = &parent->sysroot.sysdev;
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/block/DAC960.c	Mon Feb 10 10:39:30 2003
@@ -267,10 +267,12 @@
 	  }
         }
      if (Controller->FirmwareType == DAC960_V1_Controller) {
+        Command->cmd_sglist = Command->V1.ScatterList;
 	Command->V1.ScatterGatherList =
 		(DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
 	Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
       } else {
+        Command->cmd_sglist = Command->V2.ScatterList;
 	Command->V2.ScatterGatherList =
 		(DAC960_V2_ScatterGatherSegment_T *)ScatterGatherCPU;
 	Command->V2.ScatterGatherListDMA = ScatterGatherDMA;
@@ -3046,25 +3048,12 @@
   DAC960_V1_ScatterGatherSegment_T *ScatterGatherList =
 					Command->V1.ScatterGatherList;
   struct scatterlist *ScatterList = Command->V1.ScatterList;
-  int DmaDirection, SegCount;
 
   DAC960_V1_ClearCommand(Command);
 
-  if (Command->CommandType == DAC960_ReadCommand)
-        DmaDirection = PCI_DMA_FROMDEVICE;
-  else
-        DmaDirection = PCI_DMA_TODEVICE;
-
-  SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request,
-								ScatterList);
-  /* pci_map_sg MAY change the value of SegCount */
-  SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount,
-								DmaDirection);
-  Command->SegmentCount = SegCount;
-
-  if (SegCount == 1)
+  if (Command->SegmentCount == 1)
     {
-      if (Command->CommandType == DAC960_ReadCommand)
+      if (Command->DmaDirection == PCI_DMA_FROMDEVICE)
 	CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
       else 
         CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
@@ -3079,7 +3068,7 @@
     {
       int i;
 
-      if (Command->CommandType == DAC960_ReadCommand)
+      if (Command->DmaDirection == PCI_DMA_FROMDEVICE)
 	CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
       else
 	CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
@@ -3089,9 +3078,9 @@
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
       CommandMailbox->Type5.BusAddress = Command->V1.ScatterGatherListDMA;
 
-      CommandMailbox->Type5.ScatterGatherCount = SegCount;
+      CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
 
-      for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) {
+      for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) {
 		ScatterGatherList->SegmentDataPointer =
 			(DAC960_BusAddress32_T)sg_dma_address(ScatterList);
 		ScatterGatherList->SegmentByteCount =
@@ -3112,25 +3101,12 @@
   DAC960_Controller_T *Controller = Command->Controller;
   DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
   struct scatterlist *ScatterList = Command->V2.ScatterList;
-  int DmaDirection, SegCount;
 
   DAC960_V2_ClearCommand(Command);
 
-  if (Command->CommandType == DAC960_ReadCommand)
-        DmaDirection = PCI_DMA_FROMDEVICE;
-  else
-        DmaDirection = PCI_DMA_TODEVICE;
-
-  SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request,
-								ScatterList);
-  /* pci_map_sg MAY change the value of SegCount */
-  SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount,
-								DmaDirection);
-  Command->SegmentCount = SegCount;
-
   CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
   CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
-    (Command->CommandType == DAC960_ReadCommand);
+    (Command->DmaDirection == PCI_DMA_FROMDEVICE);
   CommandMailbox->SCSI_10.DataTransferSize =
     Command->BlockCount << DAC960_BlockSizeBits;
   CommandMailbox->SCSI_10.RequestSenseBusAddress = Command->V2.RequestSenseDMA;
@@ -3139,7 +3115,7 @@
   CommandMailbox->SCSI_10.RequestSenseSize = sizeof(DAC960_SCSI_RequestSense_T);
   CommandMailbox->SCSI_10.CDBLength = 10;
   CommandMailbox->SCSI_10.SCSI_CDB[0] =
-    (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
+    (Command->DmaDirection == PCI_DMA_FROMDEVICE ? 0x28 : 0x2A);
   CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
   CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
   CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
@@ -3147,7 +3123,7 @@
   CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
   CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
 
-  if (SegCount == 1)
+  if (Command->SegmentCount == 1)
     {
       CommandMailbox->SCSI_10.DataTransferMemoryAddress
 			     .ScatterGatherSegments[0]
@@ -3163,13 +3139,13 @@
       DAC960_V2_ScatterGatherSegment_T *ScatterGatherList;
       int i;
 
-      if (SegCount > 2)
+      if (Command->SegmentCount > 2)
 	{
           ScatterGatherList = Command->V2.ScatterGatherList;
 	  CommandMailbox->SCSI_10.CommandControlBits
 			 .AdditionalScatterGatherListMemory = true;
 	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
-		.ExtendedScatterGather.ScatterGatherList0Length = SegCount;
+		.ExtendedScatterGather.ScatterGatherList0Length = Command->SegmentCount;
 	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
 			 .ExtendedScatterGather.ScatterGatherList0Address =
 	    Command->V2.ScatterGatherListDMA;
@@ -3178,7 +3154,7 @@
 	ScatterGatherList = CommandMailbox->SCSI_10.DataTransferMemoryAddress
 				 .ScatterGatherSegments;
 
-      for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) {
+      for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) {
 		ScatterGatherList->SegmentDataPointer =
 			(DAC960_BusAddress64_T)sg_dma_address(ScatterList);
 		ScatterGatherList->SegmentByteCount =
@@ -3220,22 +3196,75 @@
 
       DAC960_WaitForCommand(Controller);
   }
-  if (rq_data_dir(Request) == READ)
+  if (rq_data_dir(Request) == READ) {
+    Command->DmaDirection = PCI_DMA_FROMDEVICE;
     Command->CommandType = DAC960_ReadCommand;
-  else
+  } else {
+    Command->DmaDirection = PCI_DMA_TODEVICE;
     Command->CommandType = DAC960_WriteCommand;
+  }
   Command->Completion = Request->waiting;
   Command->LogicalDriveNumber = (int)Request->rq_disk->private_data;
   Command->BlockNumber = Request->sector;
   Command->BlockCount = Request->nr_sectors;
   Command->Request = Request;
   blkdev_dequeue_request(Request);
+  Command->SegmentCount = blk_rq_map_sg(&Controller->RequestQueue,
+		  Command->Request, Command->cmd_sglist);
+  /* pci_map_sg MAY change the value of SegCount */
+  Command->SegmentCount = pci_map_sg(Command->PciDevice, Command->cmd_sglist,
+		 Command->SegmentCount, Command->DmaDirection);
+
   DAC960_QueueReadWriteCommand(Command);
   return true;
 }
 
 
 /*
+  DAC960_queue_partial_rw extracts one bio from the request already
+  associated with argument command, and construct a new command block to retry I/O
+  only on that bio.  Queue that command to the controller.
+
+  This function re-uses a previously-allocated Command,
+  	there is no failure mode from trying to allocate a command.
+*/
+
+static void DAC960_queue_partial_rw(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  IO_Request_T *Request = Command->Request;
+
+  if (Command->DmaDirection == PCI_DMA_FROMDEVICE)
+    Command->CommandType = DAC960_ReadRetryCommand;
+  else
+    Command->CommandType = DAC960_WriteRetryCommand;
+
+  /*
+   * We could be more efficient with these mapping requests
+   * and map only the portions that we need.  But since this
+   * code should almost never be called, just go with a
+   * simple coding.
+   */
+  (void)blk_rq_map_sg(&Controller->RequestQueue, Command->Request,
+                                        Command->cmd_sglist);
+
+  (void)pci_map_sg(Command->PciDevice, Command->cmd_sglist, 1,
+		                        Command->DmaDirection);
+  /*
+   * Resubmitting the request sector at a time is really tedious.
+   * But, this should almost never happen.  So, we're willing to pay
+   * this price so that in the end, as much of the transfer is completed
+   * successfully as possible.
+   */
+  Command->SegmentCount = 1;
+  Command->BlockNumber = Request->sector;
+  Command->BlockCount = 1;
+  DAC960_QueueReadWriteCommand(Command);
+  return;
+}
+
+
+/*
   DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
   from Controller's I/O Request Queue and queue them to the Controller.
 */
@@ -3276,43 +3305,30 @@
   individual Buffer.
 */
 
-static inline void DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
+static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
 						 boolean SuccessfulIO)
 {
-	DAC960_CommandType_T CommandType = Command->CommandType;
 	IO_Request_T *Request = Command->Request;
-	int DmaDirection, UpToDate;
+	int UpToDate;
 
 	UpToDate = 0;
 	if (SuccessfulIO)
 		UpToDate = 1;
 
-	/*
-	 * We could save DmaDirection in the command structure
-	 * and just reuse that information here.
-	 */
-	if (CommandType == DAC960_ReadCommand ||
-		CommandType == DAC960_ReadRetryCommand)
-		DmaDirection = PCI_DMA_FROMDEVICE;
-	else
-		DmaDirection = PCI_DMA_TODEVICE;
-
-	pci_unmap_sg(Command->PciDevice, Command->V1.ScatterList,
-		Command->SegmentCount, DmaDirection);
-	/*
-	 * BlockCount is redundant with nr_sectors in the request
-	 * structure.  Consider eliminating BlockCount from the
-	 * command structure now that Command includes a pointer to
-	 * the request.
-	 */
-	 while (end_that_request_first(Request, UpToDate, Command->BlockCount))
-		 ;
- 	 end_that_request_last(Request);
-
-	if (Command->Completion) {
-		complete(Command->Completion);
-		Command->Completion = NULL;
+	pci_unmap_sg(Command->PciDevice, Command->cmd_sglist,
+		Command->SegmentCount, Command->DmaDirection);
+
+	 if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
+
+ 	 	end_that_request_last(Request);
+
+		if (Command->Completion) {
+			complete(Command->Completion);
+			Command->Completion = NULL;
+		}
+		return true;
 	}
+	return false;
 }
 
 /*
@@ -3384,46 +3400,65 @@
   if (CommandType == DAC960_ReadCommand ||
       CommandType == DAC960_WriteCommand)
     {
-      if (CommandStatus == DAC960_V1_NormalCompletion)
 
-		DAC960_ProcessCompletedRequest(Command, true);
+#ifdef FORCE_RETRY_DEBUG
+      CommandStatus = DAC960_V1_IrrecoverableDataError;
+#endif
+
+      if (CommandStatus == DAC960_V1_NormalCompletion) {
 
-      else if (CommandStatus == DAC960_V1_IrrecoverableDataError ||
+		if (!DAC960_ProcessCompletedRequest(Command, true))
+			BUG();
+
+      } else if (CommandStatus == DAC960_V1_IrrecoverableDataError ||
 		CommandStatus == DAC960_V1_BadDataEncountered)
 	{
-
 	  /*
-	   * Finish this later.
-	   *
-	   * We should call "complete_that_request_first()"
-	   * to remove the first part of the request.  Then, if there
-	   * is still more I/O to be done, resubmit the request.
-	   *
-	   * We want to recalculate scatter/gather list,
-	   * and requeue the command.
-	   *
-	   * For now, print a message on the console, and clone
-	   * the code for "normal" completion.
+	   * break the command down into pieces and resubmit each
+	   * piece, hoping that some of them will succeed.
 	   */
-	  printk("V1_ProcessCompletedCommand: I/O error on read/write\n");
-
-	  DAC960_ProcessCompletedRequest(Command, false);
+	   DAC960_queue_partial_rw(Command);
+	   return;
 	}
       else
 	{
 	  if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
 	    DAC960_V1_ReadWriteError(Command);
 
-	  DAC960_ProcessCompletedRequest(Command, false);
+	 if (!DAC960_ProcessCompletedRequest(Command, false))
+		BUG();
 	}
     }
   else if (CommandType == DAC960_ReadRetryCommand ||
 	   CommandType == DAC960_WriteRetryCommand)
     {
-	/*
-	 * We're not doing retry commands yet.
-	 */
-	printk("DAC960_ProcessCompletedCommand: RetryCommand not done yet\n");
+      boolean normal_completion;
+#ifdef FORCE_RETRY_FAILURE_DEBUG
+      static int retry_count = 1;
+#endif
+      /*
+        Perform completion processing for the portion that was
+        retried, and submit the next portion, if any.
+      */
+      normal_completion = true;
+      if (CommandStatus != DAC960_V1_NormalCompletion) {
+        normal_completion = false;
+        if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+            DAC960_V1_ReadWriteError(Command);
+      }
+
+#ifdef FORCE_RETRY_FAILURE_DEBUG
+      if (!(++retry_count % 10000)) {
+	      printk("V1 error retry failure test\n");
+	      normal_completion = false;
+              DAC960_V1_ReadWriteError(Command);
+      }
+#endif
+
+      if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) {
+        DAC960_queue_partial_rw(Command);
+        return;
+      }
     }
 
   else if (CommandType == DAC960_MonitoringCommand)
@@ -4451,23 +4486,25 @@
   if (CommandType == DAC960_ReadCommand ||
       CommandType == DAC960_WriteCommand)
     {
-      if (CommandStatus == DAC960_V2_NormalCompletion)
 
-		DAC960_ProcessCompletedRequest(Command, true);
+#ifdef FORCE_RETRY_DEBUG
+      CommandStatus = DAC960_V2_AbormalCompletion;
+#endif
+      Command->V2.RequestSense->SenseKey = DAC960_SenseKey_MediumError;
+
+      if (CommandStatus == DAC960_V2_NormalCompletion) {
+
+		if (!DAC960_ProcessCompletedRequest(Command, true))
+			BUG();
 
-      else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError)
+      } else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError)
 	{
-	  
 	  /*
-	   * Don't know yet how to handle this case.  
-	   * See comments in DAC960_V1_ProcessCompletedCommand()
-	   *
-	   * For now, print a message on the console, and clone
-	   * the code for "normal" completion.
+	   * break the command down into pieces and resubmit each
+	   * piece, hoping that some of them will succeed.
 	   */
-	  printk("V1_ProcessCompletedCommand: I/O error on read/write\n");
-
-	  DAC960_ProcessCompletedRequest(Command, false);
+	   DAC960_queue_partial_rw(Command);
+	   return;
 	}
       else
 	{
@@ -4476,13 +4513,40 @@
 	  /*
 	    Perform completion processing for all buffers in this I/O Request.
 	  */
-          DAC960_ProcessCompletedRequest(Command, false);
+          (void)DAC960_ProcessCompletedRequest(Command, false);
 	}
     }
   else if (CommandType == DAC960_ReadRetryCommand ||
 	   CommandType == DAC960_WriteRetryCommand)
     {
-	printk("DAC960_V2_ProcessCompletedCommand: retries not coded yet\n");
+      boolean normal_completion;
+
+#ifdef FORCE_RETRY_FAILURE_DEBUG
+      static int retry_count = 1;
+#endif
+      /*
+        Perform completion processing for the portion that was
+	retried, and submit the next portion, if any.
+      */
+      normal_completion = true;
+      if (CommandStatus != DAC960_V2_NormalCompletion) {
+	normal_completion = false;
+	if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady)
+	    DAC960_V2_ReadWriteError(Command);
+      }
+
+#ifdef FORCE_RETRY_FAILURE_DEBUG
+      if (!(++retry_count % 10000)) {
+	      printk("V2 error retry failure test\n");
+	      normal_completion = false;
+	      DAC960_V2_ReadWriteError(Command);
+      }
+#endif
+
+      if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) {
+		DAC960_queue_partial_rw(Command);
+        	return;
+      }
     }
   else if (CommandType == DAC960_MonitoringCommand)
     {
diff -Nru a/drivers/block/DAC960.h b/drivers/block/DAC960.h
--- a/drivers/block/DAC960.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/block/DAC960.h	Mon Feb 10 10:39:30 2003
@@ -2305,6 +2305,8 @@
   unsigned int BlockNumber;
   unsigned int BlockCount;
   unsigned int SegmentCount;
+  int	DmaDirection;
+  struct scatterlist *cmd_sglist;
   IO_Request_T *Request;
   struct pci_dev *PciDevice;
   union {
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/block/Kconfig	Mon Feb 10 10:39:24 2003
@@ -16,7 +16,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called floppy.o. If you want to compile it as a
+	  The module will be called floppy. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config AMIGA_FLOPPY
@@ -44,7 +44,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ps2esdi.o.
+	  will be called ps2esdi.
 
 config AMIGA_Z2RAM
 	tristate "Amiga Zorro II ramdisk support"
@@ -54,7 +54,7 @@
 	  ramdisk or as a swap partition. Say Y if you want to include this
 	  driver in the kernel. This driver is also available as a module
 	  ( = code which can be inserted in and removed from the running
-	  kernel whenever you want). The module is called z2ram.o. If you want
+	  kernel whenever you want). The module is called z2ram. If you want
 	  to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -74,7 +74,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called acsi.o.
+	  The module will be called acsi.
 
 comment "Some devices (e.g. CD jukebox) support multiple LUNs"
 	depends on ATARI && ATARI_ACSI
@@ -98,7 +98,7 @@
 	  it in the kernel. Otherwise, say N. This driver is also available as
 	  a module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want). The module will be called
-	  acsi_slm.o. Be warned: the driver needs much ST-RAM and can cause
+	  acsi_slm. Be warned: the driver needs much ST-RAM and can cause
 	  problems due to that fact!
 
 config BLK_DEV_XD
@@ -111,7 +111,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called xd.o.
+	  will be called xd.
 
 	  It's pretty unlikely that you have one of these: say N.
 
@@ -133,7 +133,7 @@
 	  PARIDE as a module. If you built PARIDE support into your kernel,
 	  you may still build the individual protocol modules and high-level
 	  drivers as loadable modules. If you build this support as a module,
-	  it will be called paride.o.
+	  it will be called paride.
 
 	  To use the PARIDE support, you must say Y or M here and also to at
 	  least one high-level driver (e.g. "Parallel port IDE disks",
@@ -190,7 +190,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called DAC960.o.
+	  will be called DAC960.
 
 config BLK_DEV_UMEM
 	tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)"
@@ -206,7 +206,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read Documentation/modules.txt. The module will be
-	  called umem.o.
+	  called umem.
 
 	  The umem driver has not yet been allocated a MAJOR number, so
 	  one is chosen dynamically.  Use "devfs" or look in /proc/devices
@@ -259,7 +259,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called loop.o.
+	  will be called loop.
 
 	  Most users will answer N here.
 
@@ -288,7 +288,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called nbd.o.
+	  will be called nbd.
 
 	  If unsure, say N.
 
@@ -308,7 +308,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M and read <file:Documentation/modules.txt>. The module will be
-	  called rd.o.
+	  called rd.
 
 	  Most normal users won't need the RAM disk functionality, and can
 	  thus say N here.
diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile
--- a/drivers/block/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/block/Makefile	Mon Feb 10 10:39:31 2003
@@ -8,9 +8,6 @@
 # In the future, some of these should be built conditionally.
 #
 
-export-objs	:= elevator.o ll_rw_blk.o loop.o genhd.o acsi.o \
-		   scsi_ioctl.o deadline-iosched.o
-
 obj-y	:= elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o deadline-iosched.o
 
 obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/block/cpqarray.c	Mon Feb 10 10:39:23 2003
@@ -607,7 +607,7 @@
 #ifndef MODULE
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
 /*
- * Config string is a comma seperated set of i/o addresses of EISA cards.
+ * Config string is a comma separated set of i/o addresses of EISA cards.
  */
 static int cpqarray_setup(char *str)
 {
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/block/floppy.c	Mon Feb 10 10:39:23 2003
@@ -2298,7 +2298,7 @@
 	if (end_that_request_first(req, uptodate, current_count_sectors))
 		return;
 	add_disk_randomness(req->rq_disk);
-	floppy_off((int)req->rq_disk->private_data);
+	floppy_off((long)req->rq_disk->private_data);
 	blkdev_dequeue_request(req);
 	end_that_request_last(req);
 
@@ -2631,7 +2631,7 @@
 		return 0;
 	}
 
-	set_fdc((int)current_req->rq_disk->private_data);
+	set_fdc((long)current_req->rq_disk->private_data);
 
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
@@ -2911,7 +2911,11 @@
 
 	for (;;) {
 		if (!current_req) {
-			struct request *req = elv_next_request(&floppy_queue);
+			struct request *req;
+
+			spin_lock_irq(floppy_queue.queue_lock);
+			req = elv_next_request(&floppy_queue);
+			spin_unlock_irq(floppy_queue.queue_lock);
 			if (!req) {
 				do_floppy = NULL;
 				unlock_fdc();
@@ -2919,7 +2923,7 @@
 			}
 			current_req = req;
 		}
-		drive = (int)current_req->rq_disk->private_data;
+		drive = (long)current_req->rq_disk->private_data;
 		set_fdc(drive);
 		reschedule_timeout(current_reqD, "redo fd request", 0);
 
@@ -3298,7 +3302,7 @@
 static int invalidate_drive(struct block_device *bdev)
 {
 	/* invalidate the buffer track to force a reread */
-	set_bit((int)bdev->bd_disk->private_data, &fake_change);
+	set_bit((long)bdev->bd_disk->private_data, &fake_change);
 	process_fd_request();
 	check_disk_change(bdev);
 	return 0;
@@ -3793,7 +3797,7 @@
  */
 static int check_floppy_change(struct gendisk *disk)
 {
-	int drive = (int)disk->private_data;
+	int drive = (long)disk->private_data;
 
 	if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
 		return 1;
@@ -3896,7 +3900,7 @@
  * geometry formats */
 static int floppy_revalidate(struct gendisk *disk)
 {
-	int drive=(int)disk->private_data;
+	int drive=(long)disk->private_data;
 #define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device))
 	int cf;
 	int res = 0;
@@ -4354,7 +4358,7 @@
 		if (fdc_state[FDC(drive)].version == FDC_NONE)
 			continue;
 		/* to be cleaned up... */
-		disks[drive]->private_data = (void*)drive;
+		disks[drive]->private_data = (void*)(long)drive;
 		disks[drive]->queue = &floppy_queue;
 		add_disk(disks[drive]);
 	}
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/block/ll_rw_blk.c	Mon Feb 10 10:39:23 2003
@@ -27,6 +27,8 @@
 #include <linux/completion.h>
 #include <linux/slab.h>
 
+static void blk_unplug_work(void *data);
+
 /*
  * For the allocated request tables
  */
@@ -237,6 +239,14 @@
 	blk_queue_hardsect_size(q, 512);
 	blk_queue_dma_alignment(q, 511);
 
+	q->unplug_thresh = 4;		/* hmm */
+	q->unplug_delay = (3 * HZ) / 1000;	/* 3 milliseconds */
+	if (q->unplug_delay == 0)
+		q->unplug_delay = 1;
+
+	init_timer(&q->unplug_timer);
+	INIT_WORK(&q->unplug_work, blk_unplug_work, q);
+
 	/*
 	 * by default assume old behaviour and bounce for any highmem page
 	 */
@@ -274,7 +284,7 @@
 		init_emergency_isa_pool();
 		q->bounce_gfp = GFP_NOIO | GFP_DMA;
 	} else
-		q->bounce_gfp = GFP_NOHIGHIO;
+		q->bounce_gfp = GFP_NOIO;
 
 	/*
 	 * keep this for debugging for now...
@@ -960,6 +970,7 @@
 	if (!blk_queue_plugged(q)) {
 		spin_lock(&blk_plug_lock);
 		list_add_tail(&q->plug_list, &blk_plug_list);
+		mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
 		spin_unlock(&blk_plug_lock);
 	}
 }
@@ -974,6 +985,7 @@
 	if (blk_queue_plugged(q)) {
 		spin_lock(&blk_plug_lock);
 		list_del_init(&q->plug_list);
+		del_timer(&q->unplug_timer);
 		spin_unlock(&blk_plug_lock);
 		return 1;
 	}
@@ -992,6 +1004,8 @@
 	if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
 		return;
 
+	del_timer(&q->unplug_timer);
+
 	/*
 	 * was plugged, fire request_fn if queue has stuff to do
 	 */
@@ -1020,6 +1034,18 @@
 	spin_unlock_irq(q->queue_lock);
 }
 
+static void blk_unplug_work(void *data)
+{
+	generic_unplug_device(data);
+}
+
+static void blk_unplug_timeout(unsigned long data)
+{
+	request_queue_t *q = (request_queue_t *)data;
+
+	schedule_work(&q->unplug_work);
+}
+
 /**
  * blk_start_queue - restart a previously stopped queue
  * @q:    The &request_queue_t in question
@@ -1164,6 +1190,9 @@
 	count -= __blk_cleanup_queue(&q->rq[READ]);
 	count -= __blk_cleanup_queue(&q->rq[WRITE]);
 
+	del_timer_sync(&q->unplug_timer);
+	flush_scheduled_work();
+
 	if (count)
 		printk("blk_cleanup_queue: leaked requests (%d)\n", count);
 
@@ -1269,6 +1298,9 @@
 	blk_queue_make_request(q, __make_request);
 	blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
 
+	q->unplug_timer.function = blk_unplug_timeout;
+	q->unplug_timer.data = (unsigned long)q;
+
 	blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
 	blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
 
@@ -1811,7 +1843,15 @@
 out:
 	if (freereq)
 		__blk_put_request(q, freereq);
+
+	if (blk_queue_plugged(q)) {
+		int nr_queued = (queue_nr_requests - q->rq[0].count) +
+				(queue_nr_requests - q->rq[1].count);
+		if (nr_queued == q->unplug_thresh)
+			__generic_unplug_device(q);
+	}
 	spin_unlock_irq(q->queue_lock);
+
 	return 0;
 
 end_io:
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/block/loop.c	Mon Feb 10 10:39:28 2003
@@ -350,15 +350,10 @@
 	int ret;
 
 	pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
-
-	do {
-		if (bio_rw(bio) == WRITE)
-			ret = lo_send(lo, bio, lo->lo_blocksize, pos);
-		else
-			ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
-
-	} while (++bio->bi_idx < bio->bi_vcnt);
-
+	if (bio_rw(bio) == WRITE)
+		ret = lo_send(lo, bio, lo->lo_blocksize, pos);
+	else
+		ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
 	return ret;
 }
 
@@ -589,10 +584,10 @@
 					   hence, it mustn't be stopped at all because it could
 					   be indirectly used during suspension */
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	flush_signals(current);
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	set_user_nice(current, -20);
 
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/block/nbd.c	Mon Feb 10 10:39:24 2003
@@ -24,7 +24,7 @@
  * 01-3-11 Make nbd work with new Linux block layer code. It now supports
  *   plugging like all the other block devices. Also added in MSG_MORE to
  *   reduce number of partial TCP segments sent. <steve@chygwyn.com>
- * 01-12-6 Fix deadlock condition by making queue locks independant of
+ * 01-12-6 Fix deadlock condition by making queue locks independent of
  *   the transmit lock. <steve@chygwyn.com>
  * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes.
  *   <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com>
@@ -118,12 +118,12 @@
 	set_fs(get_ds());
 	/* Allow interception of SIGKILL only
 	 * Don't allow other signals to interrupt the transmission */
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	oldset = current->blocked;
 	sigfillset(&current->blocked);
 	sigdelsetmask(&current->blocked, sigmask(SIGKILL));
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 
 	do {
@@ -146,11 +146,11 @@
 
 		if (signal_pending(current)) {
 			siginfo_t info;
-			spin_lock_irqsave(&current->sig->siglock, flags);
+			spin_lock_irqsave(&current->sighand->siglock, flags);
 			printk(KERN_WARNING "NBD (pid %d: %s) got signal %d\n",
 				current->pid, current->comm, 
 				dequeue_signal(&current->blocked, &info));
-			spin_unlock_irqrestore(&current->sig->siglock, flags);
+			spin_unlock_irqrestore(&current->sighand->siglock, flags);
 			result = -EINTR;
 			break;
 		}
@@ -166,10 +166,10 @@
 		buf += result;
 	} while (size > 0);
 
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	current->blocked = oldset;
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 	set_fs(oldfs);
 	return result;
diff -Nru a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
--- a/drivers/block/paride/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/block/paride/Kconfig	Mon Feb 10 10:39:23 2003
@@ -21,7 +21,7 @@
 	  connected through a parallel port. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  parallel port IDE driver, otherwise you should answer M to build
-	  it as a loadable module. The module will be called pd.o. You
+	  it as a loadable module. The module will be called pd. You
 	  must also have at least one parallel port protocol driver in your
 	  system. Among the devices supported by this driver are the SyQuest
 	  EZ-135, EZ-230 and SparQ drives, the Avatar Shark and the backpack
@@ -35,7 +35,7 @@
 	  connected through a parallel port. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  parallel port ATAPI CD-ROM driver, otherwise you should answer M to
-	  build it as a loadable module. The module will be called pcd.o. You
+	  build it as a loadable module. The module will be called pcd. You
 	  must also have at least one parallel port protocol driver in your
 	  system. Among the devices supported by this driver are the
 	  MicroSolutions backpack CD-ROM drives and the Freecom Power CD. If
@@ -51,7 +51,7 @@
 	  connected through a parallel port. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  parallel port ATAPI disk driver, otherwise you should answer M
-	  to build it as a loadable module. The module will be called pf.o.
+	  to build it as a loadable module. The module will be called pf.
 	  You must also have at least one parallel port protocol driver in
 	  your system. Among the devices supported by this driver are the
 	  MicroSolutions backpack PD/CD drive and the Imation Superdisk
@@ -65,7 +65,7 @@
 	  connected through a parallel port. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  parallel port ATAPI disk driver, otherwise you should answer M
-	  to build it as a loadable module. The module will be called pt.o.
+	  to build it as a loadable module. The module will be called pt.
 	  You must also have at least one parallel port protocol driver in
 	  your system. Among the devices supported by this driver is the
 	  parallel port version of the HP 5GB drive.
@@ -82,7 +82,7 @@
 	  If you chose to build PARIDE support into your kernel, you may
 	  answer Y here to build in the parallel port generic ATAPI driver,
 	  otherwise you should answer M to build it as a loadable module. The
-	  module will be called pg.o.
+	  module will be called pg.
 
 	  You must also have at least one parallel port protocol driver in
 	  your system.
@@ -106,7 +106,7 @@
 	  parallel port kits made in Hong Kong. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  protocol driver, otherwise you should answer M to build it as a
-	  loadable module. The module will be called aten.o. You must also
+	  loadable module. The module will be called aten. You must also
 	  have a high-level driver for the type of device that you want to
 	  support.
 
@@ -125,7 +125,7 @@
 	  If you chose to build PARIDE support into your kernel, you may
 	  answer Y here to build in the protocol driver, otherwise you should
 	  answer M to build it as a loadable module.  The module will be
-	  called bpck.o.  You must also have a high-level driver for the type
+	  called bpck.  You must also have a high-level driver for the type
 	  of device that you want to support.
 
 config PARIDE_BPCK6
@@ -144,7 +144,7 @@
 	  If you chose to build PARIDE support into your kernel, you may
 	  answer Y here to build in the protocol driver, otherwise you should
 	  answer M to build it as a loadable module.  The module will be
-	  called bpck6.o.  You must also have a high-level driver for the type
+	  called bpck6.  You must also have a high-level driver for the type
 	  of device that you want to support.
 
 config PARIDE_COMM
@@ -155,7 +155,7 @@
 	  protocol from DataStor. If you chose to build PARIDE support
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
-	  module. The module will be called comm.o. You must also have
+	  module. The module will be called comm. You must also have
 	  a high-level driver for the type of device that you want to support.
 
 config PARIDE_DSTR
@@ -166,7 +166,7 @@
 	  protocol from DataStor. If you chose to build PARIDE support
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
-	  module. The module will be called dstr.o. You must also have
+	  module. The module will be called dstr. You must also have
 	  a high-level driver for the type of device that you want to support.
 
 config PARIDE_FIT2
@@ -178,7 +178,7 @@
 	  (low speed) adapter that is used in some portable hard drives. If
 	  you chose to build PARIDE support into your kernel, you may answer Y
 	  here to build in the protocol driver, otherwise you should answer M
-	  to build it as a loadable module. The module will be called ktti.o.
+	  to build it as a loadable module. The module will be called ktti.
 	  You must also have a high-level driver for the type of device that
 	  you want to support.
 
@@ -192,7 +192,7 @@
 	  devices. If you chose to build PARIDE support into your kernel, you
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
-	  called fit3.o. You must also have a high-level driver for the type
+	  called fit3. You must also have a high-level driver for the type
 	  of device that you want to support.
 
 config PARIDE_EPAT
@@ -205,7 +205,7 @@
 	  Hewlett-Packard, SyQuest, Imation and Avatar. If you chose to build
 	  PARIDE support into your kernel, you may answer Y here to build in
 	  the protocol driver, otherwise you should answer M to build it as a
-	  loadable module. The module will be called epat.o. You must also
+	  loadable module. The module will be called epat. You must also
 	  have a high-level driver for the type of device that you want to
 	  support.
 
@@ -226,7 +226,7 @@
 	  found in some no-name kits. If you chose to build PARIDE support
 	  into your kernel, you may answer Y here to build in the protocol
 	  driver, otherwise you should answer M to build it as a loadable
-	  module. The module will be called epia.o. You must also have a
+	  module. The module will be called epia. You must also have a
 	  high-level driver for the type of device that you want to support.
 
 config PARIDE_FRIQ
@@ -238,7 +238,7 @@
 	  drive.  If you chose to build PARIDE support into your kernel, you
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
-	  called friq.o. You must also have a high-level driver for the type
+	  called friq. You must also have a high-level driver for the type
 	  of device that you want to support.
 
 config PARIDE_FRPW
@@ -249,7 +249,7 @@
 	  protocol. If you chose to build PARIDE support into your kernel, you
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
-	  called frpw.o. You must also have a high-level driver for the type
+	  called frpw. You must also have a high-level driver for the type
 	  of device that you want to support.
 
 config PARIDE_KBIC
@@ -262,7 +262,7 @@
 	  especially in Europe. If you chose to build PARIDE support into your
 	  kernel, you may answer Y here to build in the protocol driver,
 	  otherwise you should answer M to build it as a loadable module. The
-	  module will be called kbic.o. You must also have a high-level driver
+	  module will be called kbic. You must also have a high-level driver
 	  for the type of device that you want to support.
 
 config PARIDE_KTTI
@@ -274,7 +274,7 @@
 	  used in some 2.5" portable hard drives. If you chose to build PARIDE
 	  support into your kernel, you may answer Y here to build in the
 	  protocol driver, otherwise you should answer M to build it as a
-	  loadable module. The module will be called ktti.o. You must also
+	  loadable module. The module will be called ktti. You must also
 	  have a high-level driver for the type of device that you want to
 	  support.
 
@@ -287,7 +287,7 @@
 	  name). If you chose to build PARIDE support into your kernel, you
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will
-	  be called on20.o. You must also have a high-level driver for the
+	  be called on20. You must also have a high-level driver for the
 	  type of device that you want to support.
 
 config PARIDE_ON26
@@ -299,7 +299,7 @@
 	  name). If you chose to build PARIDE support into your kernel, you
 	  may answer Y here to build in the protocol driver, otherwise you
 	  should answer M to build it as a loadable module. The module will be
-	  called on26.o. You must also have a high-level driver for the type
+	  called on26. You must also have a high-level driver for the type
 	  of device that you want to support.
 
 #
diff -Nru a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile
--- a/drivers/block/paride/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/block/paride/Makefile	Mon Feb 10 10:39:32 2003
@@ -5,8 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs := paride.o
-
 obj-$(CONFIG_PARIDE)		+= paride.o
 obj-$(CONFIG_PARIDE_ATEN)	+= aten.o
 obj-$(CONFIG_PARIDE_BPCK)	+= bpck.o
diff -Nru a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
--- a/drivers/bluetooth/Kconfig	Mon Feb 10 10:39:25 2003
+++ b/drivers/bluetooth/Kconfig	Mon Feb 10 10:39:26 2003
@@ -11,7 +11,7 @@
 	  USB interface.
 
 	  Say Y here to compile support for Bluetooth USB devices into the
-	  kernel or say M to compile it as module (hci_usb.o).
+	  kernel or say M to compile it as module (hci_usb).
 
 config BT_USB_ZERO_PACKET
 	bool "USB zero packet support"
@@ -34,7 +34,7 @@
 	  adapter and BrainBoxes Bluetooth PC Card.
 
 	  Say Y here to compile support for Bluetooth UART devices into the
-	  kernel or say M to compile it as module (hci_uart.o).
+	  kernel or say M to compile it as module (hci_uart).
 
 config BT_HCIUART_H4
 	bool "UART (H4) protocol support"
@@ -68,7 +68,7 @@
 	  Socket Bluetooth CF Card
 
 	  Say Y here to compile support for HCI DTL1 devices into the
-	  kernel or say M to compile it as module (dtl1_cs.o).
+	  kernel or say M to compile it as module (dtl1_cs).
 
 config BT_HCIBT3C
 	tristate "HCI BT3C (PC Card) driver"
@@ -84,7 +84,7 @@
 	  the BlueFW package. For more information, see <http://bluez.sf.net>.
 
 	  Say Y here to compile support for HCI BT3C devices into the
-	  kernel or say M to compile it as module (bt3c_cs.o).
+	  kernel or say M to compile it as module (bt3c_cs).
 
 config BT_HCIBLUECARD
 	tristate "HCI BlueCard (PC Card) driver"
@@ -97,7 +97,7 @@
 	  Anycom Bluetooth CF Card
 
 	  Say Y here to compile support for HCI BlueCard devices into the
-	  kernel or say M to compile it as module (bluecard_cs.o).
+	  kernel or say M to compile it as module (bluecard_cs).
 
 config BT_HCIVHCI
 	tristate "HCI VHCI (Virtual HCI device) driver"
@@ -107,7 +107,7 @@
 	  This driver is required if you want to use HCI Emulation software.
 
 	  Say Y here to compile support for virtual HCI devices into the
-	  kernel or say M to compile it as module (hci_vhci.o).
+	  kernel or say M to compile it as module (hci_vhci).
 
 endmenu
 
diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
--- a/drivers/bluetooth/bt3c_cs.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/bluetooth/bt3c_cs.c	Mon Feb 10 10:39:33 2003
@@ -528,19 +528,19 @@
 	}
 
 	/* Block signals, everything but SIGKILL/SIGSTOP */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	tmpsig = current->blocked;
 	siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	result = waitpid(pid, NULL, __WCLONE);
 
 	/* Allow signals again */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = tmpsig;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (result != pid) {
 		printk(KERN_WARNING "bt3c_cs: Waiting for pid %d failed (errno=%d).\n", pid, -result);
diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
--- a/drivers/cdrom/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/cdrom/Kconfig	Mon Feb 10 10:39:31 2003
@@ -18,7 +18,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aztcd.o.  If you want to compile it as a
+	  The module will be called aztcd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config GSCD
@@ -36,7 +36,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gscd.o.  If you want to compile it as a
+	  The module will be called gscd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SBPCD
@@ -76,7 +76,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sbpcd.o.  If you want to compile it as a
+	  The module will be called sbpcd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config MCD
@@ -101,7 +101,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mcd.o. If you want to compile it as a
+	  The module will be called mcd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config MCD_IRQ
@@ -142,7 +142,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mcdx.o. If you want to compile it as a
+	  The module will be called mcdx. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config OPTCD
@@ -161,7 +161,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called optcd.o. If you want to compile it as a
+	  The module will be called optcd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config CM206
@@ -178,7 +178,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cm206.o. If you want to compile it as a
+	  The module will be called cm206. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SJCD
@@ -192,7 +192,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sjcd.o. If you want to compile it as a
+	  The module will be called sjcd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ISP16_CDI
@@ -207,7 +207,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called isp16.o. If you want to compile it as a
+	  The module will be called isp16. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config CDU31A
@@ -229,7 +229,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cdu31a.o.  If you want to compile it as a
+	  The module will be called cdu31a.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config CDU535
@@ -245,6 +245,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sonycd535.o. If you want to compile it as
+	  The module will be called sonycd535. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile
--- a/drivers/cdrom/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/cdrom/Makefile	Mon Feb 10 10:39:27 2003
@@ -3,22 +3,6 @@
 # 30 Jan 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
 # Rewritten to use lists instead of if-statements.
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs	:= cdrom.o
-
-
-
-# Object file lists.
-
-obj-y		:=
-obj-m		:=
-obj-n		:=
-obj-		:=
-
-
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_BLK_DEV_IDECD)	+=              cdrom.o
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/char/Kconfig	Mon Feb 10 10:39:23 2003
@@ -91,7 +91,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. You will get
-	  two modules called ip2.o and ip2main.o.
+	  two modules called ip2 and ip2main.
 
 config ROCKETPORT
 	tristate "Comtrol Rocketport support"
@@ -104,7 +104,7 @@
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  rocket.o.
+	  rocket.
 
 config CYCLADES
 	tristate "Cyclades async mux support"
@@ -122,7 +122,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called cyclades.o.
+	  will be called cyclades.
 
 	  If you haven't heard about it, it's safe to say N.
 
@@ -155,7 +155,7 @@
 	  one of the two drivers.
 
 	  If you want to compile this driver as a module, say M here and read
-	  <file:Documentation/modules.txt>. The module will be called epca.o.
+	  <file:Documentation/modules.txt>. The module will be called epca.
 
 config DIGI
 	tristate "Digiboard PC/Xx Support"
@@ -168,7 +168,7 @@
 	  Y here and read the file <file:Documentation/digiboard.txt>.
 
 	  If you want to compile this driver as a module, say M here and read
-	  <file:Documentation/modules.txt>. The module will be called pcxx.o.
+	  <file:Documentation/modules.txt>. The module will be called pcxx.
 
 config ESPSERIAL
 	tristate "Hayes ESP serial port support"
@@ -181,7 +181,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>.  The module will be
-	  called esp.o.  If unsure, say N.
+	  called esp.  If unsure, say N.
 
 config MOXA_INTELLIO
 	tristate "Moxa Intellio support"
@@ -191,7 +191,7 @@
 
 	  This driver can also be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called moxa.o. If you want to do that, say M
+	  The module will be called moxa. If you want to do that, say M
 	  here.
 
 config MOXA_SMARTIO
@@ -202,7 +202,7 @@
 
 	  This driver can also be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mxser.o. If you want to do that, say M
+	  The module will be called mxser. If you want to do that, say M
 	  here.
 
 config ISI
@@ -214,7 +214,7 @@
 	  built as a module ( = code which can be inserted in and removed from
 	  the running kernel whenever you want).  Please read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  isicom.o.
+	  isicom.
 
 config SYNCLINK
 	tristate "Microgate SyncLink card support"
@@ -226,7 +226,7 @@
 
 	  This driver can only be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called synclink.o.  If you want to do that, say M
+	  The module will be called synclink.  If you want to do that, say M
 	  here.
 
 config SYNCLINKMP
@@ -240,7 +240,7 @@
 
 	  This driver may be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called synclinkmp.o.  If you want to do that, say M
+	  The module will be called synclinkmp.  If you want to do that, say M
 	  here.
 
 config N_HDLC
@@ -252,7 +252,7 @@
 
 	  This driver can only be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called n_hdlc.o. If you want to do that, say M
+	  The module will be called n_hdlc. If you want to do that, say M
 	  here.
 
 config RISCOM8
@@ -266,7 +266,7 @@
 	  say Y here and read the file <file:Documentation/riscom8.txt>.
 
 	  Also it's possible to say M here and compile this driver as kernel
-	  loadable module; the module will be called riscom8.o.
+	  loadable module; the module will be called riscom8.
 
 config SPECIALIX
 	tristate "Specialix IO8+ card support"
@@ -280,7 +280,7 @@
 	  If you have a card like that, say Y here and read the file
 	  <file:Documentation/specialix.txt>. Also it's possible to say M here
 	  and compile this driver as kernel loadable module which will be
-	  called specialix.o.
+	  called specialix.
 
 config SPECIALIX_RTSCTS
 	bool "Specialix DTR/RTS pin is RTS"
@@ -301,7 +301,7 @@
 
 	  This driver can only be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sx.o. If you want to do that, say M here.
+	  The module will be called sx. If you want to do that, say M here.
 
 config RIO
 	tristate "Specialix RIO system support"
@@ -343,7 +343,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called stallion.o.
+	  will be called stallion.
 
 config ISTALLION
 	tristate "Stallion EC8/64, ONboard, Brumby support"
@@ -356,7 +356,7 @@
 	  To compile it as a module ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt>. The module will be called
-	  istallion.o.
+	  istallion.
 
 config SERIAL_TX3912
 	bool "TMPTX3912/PR31700 serial port support"
@@ -430,9 +430,9 @@
 	  for which 8 pin to DB25 adapters were supplied. The card also had
 	  jumpers internally to toggle various pinning configurations.
 
-	  This driver can be built as a module; but then "generic_serial.o"
+	  This driver can be built as a module; but then "generic_serial"
 	  will also be built as a module. This has to be loaded before
-	  "ser_a2232.o". If you want to do this, answer M here and read
+	  "ser_a2232". If you want to do this, answer M here and read
 	  "<file:Documentation/modules.txt>".
 
 source "drivers/serial/Kconfig"
@@ -495,7 +495,7 @@
 	  driver as a module however ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt> and
-	  <file:Documentation/parport.txt>.  The module will be called lp.o.
+	  <file:Documentation/parport.txt>.  The module will be called lp.
 
 	  If you have several parallel ports, you can specify which ports to
 	  use with the "lp" kernel command line option.  (Try "man bootparam"
@@ -539,7 +539,7 @@
 	  This support is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  ppdev.o.
+	  ppdev.
 
 	  If unsure, say N.
 
@@ -558,7 +558,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tipar.o. If you want to compile it as a
+	  The module will be called tipar. If you want to compile it as a
 	  module, say M here and read Documentation/modules.txt.
 
 	  If you don't know what a parallel link cable is or what a Texas
@@ -598,7 +598,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called busmouse.o. If you want to compile it as a
+	  The module will be called busmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 endmenu
@@ -610,7 +610,7 @@
 	  to compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  tpqic02.o.
+	  tpqic02.
 
 config QIC02_DYNCONF
 	bool "Do you want runtime configuration for QIC-02"
@@ -649,7 +649,7 @@
 	  found in the NetWinder. This driver allows the user to control the
 	  temperature set points and to read the current temperature.
 
-	  It is also possible to say M here to build it as a module (ds1620.o)
+	  It is also possible to say M here to build it as a module (ds1620)
 	  It is recommended to be used on a NetWinder, but it is not a
 	  necessity.
 
@@ -675,7 +675,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  nwbutton.o.
+	  nwbutton.
 
 	  Most people will answer Y to this question and "Reboot Using Button"
 	  below to be able to initiate a system shutdown from the button.
@@ -704,7 +704,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called nwflash.o. If you want to compile it as a
+	  The module will be called nwflash. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you're not sure, say N.
@@ -723,7 +723,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  i810_rng.o.
+	  i810_rng.
 
 	  If unsure, say N.
 
@@ -741,7 +741,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  amd768_rng.o.
+	  amd768_rng.
 
 	  If unsure, say N.
 
@@ -769,7 +769,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called nvram.o. If you want to compile it as a
+	  The module will be called nvram. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config RTC
@@ -797,7 +797,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called rtc.o. If you want to compile it as a module,
+	  The module is called rtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 config GEN_RTC
@@ -817,7 +817,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called genrtc.o. If you want to compile it as a module,
+	  The module is called genrtc. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>. To load the
 	  module automatically add 'alias char-major-10-135 genrtc' to your
 	  /etc/modules.conf
@@ -851,7 +851,7 @@
 	  called the `internal DoubleTalk'.  If you want to compile this as a
 	  module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want), say M here and read
-	  <file:Documentation/modules.txt>. The module will be called dtlk.o.
+	  <file:Documentation/modules.txt>. The module will be called dtlk.
 
 config R3964
 	tristate "Siemens R3964 line discipline"
@@ -863,7 +863,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  n_r3964.o.
+	  n_r3964.
 
 	  If unsure, say N.
 
@@ -879,7 +879,7 @@
 	  To compile this driver as a module ( = code which can be inserted in
 	  and removed from the running kernel whenever you want), say M here
 	  and read <file:Documentation/modules.txt>. The module will be called
-	  applicom.o.
+	  applicom.
 
 	  If unsure, say N.
 
@@ -896,7 +896,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called sonypi.o.
+	  will be called sonypi.
 
 
 menu "Ftape, the floppy tape device driver"
@@ -927,7 +927,7 @@
 	  module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want). If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>. The
-	  module will be called ftape.o.
+	  module will be called ftape.
 
 	  Note that the Ftape-HOWTO is out of date (sorry) and documents the
 	  older version 2.08 of this software but still contains useful
@@ -973,7 +973,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mwave.o. If you want to compile it as
+	  The module will be called mwave. If you want to compile it as
 	  a module, say M here and read Documentation/modules.txt.
 
 config SCx200_GPIO
@@ -983,7 +983,7 @@
 	  Give userspace access to the GPIO pins on the National
 	  Semiconductor SCx200 processors.
 
-	  If compiled as a module, it will be called scx200_gpio.o.
+	  If compiled as a module, it will be called scx200_gpio.
 
 config RAW_DRIVER
 	tristate "RAW driver (/dev/raw/rawN)"
@@ -991,6 +991,13 @@
 	  The raw driver permits block devices to be bound to /dev/raw/rawN. 
 	  Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 
 	  See the raw(8) manpage for more details.
+
+config HANGCHECK_TIMER
+	tristate "Hangcheck timer"
+	help
+	  The hangcheck-timer module detects when the system has gone
+	  out to lunch past a certain margin.  It can reboot the system
+	  or merely print a warning.
 
 endmenu
 
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/char/Makefile	Mon Feb 10 10:39:33 2003
@@ -9,13 +9,6 @@
 
 obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs     :=	busmouse.o vt.o generic_serial.o ip2main.o consolemap.o\
-			ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \
-			selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o
-
 obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o
 obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
 obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
@@ -84,6 +77,7 @@
 obj-$(CONFIG_PCMCIA) += pcmcia/
 obj-$(CONFIG_IPMI_HANDLER) += ipmi/
 
+obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
 
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	Mon Feb 10 10:39:28 2003
+++ b/drivers/char/agp/Kconfig	Mon Feb 10 10:39:28 2003
@@ -23,7 +23,7 @@
 
 	  This driver is available as a module.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called agpgart.o.
+	  module will be called agpgart.
 
 config AGP_GART
 	bool "/dev/agpgart (AGP Support)"
diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
--- a/drivers/char/agp/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/agp/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,8 +3,6 @@
 # space ioctl interface to use agp memory.  It also adds a kernel interface
 # that other drivers could use to manipulate agp memory.
 
-export-objs := backend.o
-
 agpgart-y := backend.o frontend.o generic.o
 agpgart-$(CONFIG_AGP3) += generic-3.0.o
 agpgart-objs := $(agpgart-y)
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Mon Feb 10 10:39:26 2003
+++ b/drivers/char/agp/agp.h	Mon Feb 10 10:39:26 2003
@@ -47,7 +47,7 @@
 	flush_agp_cache();
 }
 #else
-static void global_cache_flush(void)
+static inline void global_cache_flush(void)
 {
 	flush_agp_cache();
 }
diff -Nru a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
--- a/drivers/char/drm/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/char/drm/Kconfig	Mon Feb 10 10:39:31 2003
@@ -20,7 +20,7 @@
 	depends on DRM
 	help
 	  Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
-	  graphics card.  If M is selected, the module will be called tdfx.o.
+	  graphics card.  If M is selected, the module will be called tdfx.
 
 #    tristate '  3dlabs GMX 2000' CONFIG_DRM_GAMMA
 config DRM_R128
@@ -28,7 +28,7 @@
 	depends on DRM
 	help
 	  Choose this option if you have an ATI Rage 128 graphics card.  If M
-	  is selected, the module will be called r128.o.  AGP support for
+	  is selected, the module will be called r128.  AGP support for
 	  this card is strongly suggested (unless you have a PCI version).
 
 config DRM_RADEON
@@ -39,14 +39,14 @@
 	  are both PCI and AGP versions.  You don't need to choose this to
 	  run the Radeon in plain VGA mode.  There is a product page at
 	  <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
-	  If M is selected, the module will be called radeon.o.
+	  If M is selected, the module will be called radeon.
 
 config DRM_I810
 	tristate "Intel I810"
 	depends on DRM && AGP
 	help
 	  Choose this option if you have an Intel I810 graphics card.  If M is
-	  selected, the module will be called i810.o.  AGP support is required
+	  selected, the module will be called i810.  AGP support is required
 	  for this driver to work.
 
 config DRM_I830
@@ -58,6 +58,6 @@
 	depends on DRM && AGP
 	help
 	  Choose this option if you have a Matrox G200, G400 or G450 graphics
-	  card.  If M is selected, the module will be called mga.o.  AGP
+	  card.  If M is selected, the module will be called mga.  AGP
 	  support is required for this driver to work.
 
diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/char/drm/i830_dma.c	Mon Feb 10 10:39:23 2003
@@ -454,7 +454,7 @@
 	DRM_DEBUG("pitch_bits %x\n",    init->pitch_bits);
 
 	dev_priv->cpp = init->cpp;
-	/* We are using seperate values as placeholders for mechanisms for
+	/* We are using separate values as placeholders for mechanisms for
 	 * private backbuffer/depthbuffer usage.
 	 */
 
diff -Nru a/drivers/char/ftape/Kconfig b/drivers/char/ftape/Kconfig
--- a/drivers/char/ftape/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/char/ftape/Kconfig	Mon Feb 10 10:39:23 2003
@@ -18,14 +18,14 @@
 	  module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want).  In this case you should read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  zftape.o.
+	  zftape.
 
 	  Regardless of whether you say Y or M here, an additional runtime
-	  loadable module called `zft-compressor.o' which contains code to
+	  loadable module called `zft-compressor' which contains code to
 	  support user transparent on-the-fly compression based on Ross
 	  William's lzrw3 algorithm will be produced.  If you have enabled the
 	  kernel module loader (i.e. have said Y to "Kernel module loader
-	  support", above) then `zft-compressor.o' will be loaded
+	  support", above) then `zft-compressor' will be loaded
 	  automatically by zftape when needed.
 
 	  Despite its name, zftape does NOT use compression by default.  The
diff -Nru a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
--- a/drivers/char/ftape/compressor/zftape-compress.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/char/ftape/compressor/zftape-compress.c	Mon Feb 10 10:39:31 2003
@@ -1196,11 +1196,7 @@
 		printk(
 KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
 KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n"
-KERN_INFO "Compiled for kernel version %s"
-#ifdef MODVERSIONS
-		" with versioned symbols"
-#endif
-		"\n", UTS_RELEASE);
+KERN_INFO "Compiled for kernel version %s\n", UTS_RELEASE);
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
diff -Nru a/drivers/char/ftape/lowlevel/Makefile b/drivers/char/ftape/lowlevel/Makefile
--- a/drivers/char/ftape/lowlevel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/ftape/lowlevel/Makefile	Mon Feb 10 10:39:24 2003
@@ -23,8 +23,6 @@
 #      driver for Linux.
 #
 
-export-objs := ftape_syms.o
-
 obj-$(CONFIG_FTAPE) += ftape.o
 
 ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \
diff -Nru a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
--- a/drivers/char/ftape/lowlevel/fdc-io.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/ftape/lowlevel/fdc-io.c	Mon Feb 10 10:39:24 2003
@@ -386,11 +386,11 @@
 	/* timeout time will be up to USPT microseconds too long ! */
 	timeout = (1000 * time + FT_USPT - 1) / FT_USPT;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	old_sigmask = current->blocked;
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	current->state = TASK_INTERRUPTIBLE;
 	add_wait_queue(&ftape_wait_intr, &wait);
@@ -398,10 +398,10 @@
 		timeout = schedule_timeout(timeout);
         }
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = old_sigmask;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	
 	remove_wait_queue(&ftape_wait_intr, &wait);
 	/*  the following IS necessary. True: as well
diff -Nru a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c
--- a/drivers/char/ftape/lowlevel/ftape-init.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/char/ftape/lowlevel/ftape-init.c	Mon Feb 10 10:39:31 2003
@@ -70,11 +70,7 @@
 KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n"
 KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
 KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n"
-KERN_INFO "Compiled for Linux version %s"
-#ifdef MODVERSIONS
-	       " with versioned symbols"
-#endif
-	       "\n", UTS_RELEASE);
+KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE);
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
diff -Nru a/drivers/char/ftape/zftape/Makefile b/drivers/char/ftape/zftape/Makefile
--- a/drivers/char/ftape/zftape/Makefile	Mon Feb 10 10:39:30 2003
+++ b/drivers/char/ftape/zftape/Makefile	Mon Feb 10 10:39:30 2003
@@ -27,8 +27,6 @@
 # ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should
 #                leave this enabled for compatibility with taper.
 
-export-objs := zftape_syms.o
-
 obj-$(CONFIG_ZFTAPE) += zftape.o
 
 zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \
diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
--- a/drivers/char/ftape/zftape/zftape-init.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/char/ftape/zftape/zftape-init.c	Mon Feb 10 10:39:25 2003
@@ -331,11 +331,7 @@
 KERN_INFO
 "and builtin compression (lzrw3 algorithm).\n"
 KERN_INFO
-"Compiled for Linux version %s"
-#ifdef MODVERSIONS
-		       " with versioned symbols"
-#endif
-		       "\n", UTS_RELEASE);
+"Compiled for Linux version %s\n", UTS_RELEASE);
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
diff -Nru a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/hangcheck-timer.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,127 @@
+/*
+ * hangcheck-timer.c
+ *
+ * Driver for a little io fencing timer.
+ *
+ * Copyright (C) 2002 Oracle Corporation.  All rights reserved.
+ *
+ * Author: Joel Becker <joel.becker@oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have recieved 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.
+ */
+
+/*
+ * The hangcheck-timer driver uses the TSC to catch delays that
+ * jiffies does not notice.  A timer is set.  When the timer fires, it
+ * checks whether it was delayed and if that delay exceeds a given
+ * margin of error.  The hangcheck_tick module paramter takes the timer
+ * duration in seconds.  The hangcheck_margin parameter defines the
+ * margin of error, in seconds.  The defaults are 60 seconds for the
+ * timer and 180 seconds for the margin of error.  IOW, a timer is set
+ * for 60 seconds.  When the timer fires, the callback checks the
+ * actual duration that the timer waited.  If the duration exceeds the
+ * alloted time and margin (here 60 + 180, or 240 seconds), the machine
+ * is restarted.  A healthy machine will have the duration match the
+ * expected timeout very closely.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+
+
+#define VERSION_STR "0.5.0"
+
+#define DEFAULT_IOFENCE_MARGIN 60	/* Default fudge factor, in seconds */
+#define DEFAULT_IOFENCE_TICK 180	/* Default timer timeout, in seconds */
+
+static int hangcheck_tick = DEFAULT_IOFENCE_TICK;
+static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN;
+static int hangcheck_reboot;  /* Defaults to not reboot */
+
+/* Driver options */
+module_param(hangcheck_tick, int, 0);
+MODULE_PARM_DESC(hangcheck_tick, "Timer delay.");
+module_param(hangcheck_margin, int, 0);
+MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire.");
+module_param(hangcheck_reboot, int, 0);
+MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded.");
+
+MODULE_AUTHOR("Joel Becker");
+MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin.");
+MODULE_LICENSE("GPL");
+
+
+/* Last time scheduled */
+static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;
+
+static void hangcheck_fire(unsigned long);
+
+static struct timer_list hangcheck_ticktock =
+		TIMER_INITIALIZER(hangcheck_fire, 0, 0);
+
+static void hangcheck_fire(unsigned long data)
+{
+	unsigned long long cur_tsc, tsc_diff;
+
+	cur_tsc = get_cycles();
+
+	if (cur_tsc > hangcheck_tsc)
+		tsc_diff = cur_tsc - hangcheck_tsc;
+	else
+		tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */
+
+	if (tsc_diff > hangcheck_tsc_margin) {
+		if (hangcheck_reboot) {
+			printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n");
+			machine_restart(NULL);
+		} else {
+			printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n");
+		}
+	}
+	mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ));
+	hangcheck_tsc = get_cycles();
+}
+
+
+static int __init hangcheck_init(void)
+{
+	printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n",
+	       VERSION_STR, hangcheck_tick, hangcheck_margin);
+
+	hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick;
+	hangcheck_tsc_margin *= HZ;
+	hangcheck_tsc_margin *= current_cpu_data.loops_per_jiffy;
+
+	hangcheck_tsc = get_cycles();
+	mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ));
+
+	return 0;
+}
+
+
+static void __exit hangcheck_exit(void)
+{
+	del_timer_sync(&hangcheck_ticktock);
+}
+
+module_init(hangcheck_init);
+module_exit(hangcheck_exit);
diff -Nru a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
--- a/drivers/char/ip2/i2ellis.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/char/ip2/i2ellis.c	Mon Feb 10 10:39:23 2003
@@ -773,7 +773,7 @@
 //
 // Writes 'count' bytes from 'address' to the data fifo specified by the board
 // structure pointer pB. Should count happen to be odd, an extra pad byte is
-// sent (identity unknown...). This is to be consistant with the 16-bit version.
+// sent (identity unknown...). This is to be consistent with the 16-bit version.
 // Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf.
 //
 //******************************************************************************
diff -Nru a/drivers/char/ip2/i2os.h b/drivers/char/ip2/i2os.h
--- a/drivers/char/ip2/i2os.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/char/ip2/i2os.h	Mon Feb 10 10:39:27 2003
@@ -8,7 +8,7 @@
 *   PACKAGE:     Linux tty Device Driver for IntelliPort II family of multiport
 *                serial I/O controllers.
 *
-*   DESCRIPTION: Defines, definitions and includes which are heavily dependant
+*   DESCRIPTION: Defines, definitions and includes which are heavily dependent
 *                on O/S, host, compiler, etc. This file is tailored for:
 *                 Linux v2.0.0 and later
 *                 Gnu gcc c2.7.2
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/char/ip2main.c	Mon Feb 10 10:39:33 2003
@@ -21,7 +21,7 @@
 //
 // 1.2.14	/\/\|=mhw=|\/\/
 // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
-// Changed the definition of ip2trace to be more consistant with kernel style
+// Changed the definition of ip2trace to be more consistent with kernel style
 //	Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
 //
 // 1.2.13	/\/\|=mhw=|\/\/
@@ -1466,7 +1466,7 @@
 		}
 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
 	// and can't work because we don't know the_char
-	// as the_char is reported on a seperate path
+	// as the_char is reported on a separate path
 	// The intelligent board does this stuff as setup
 	{
 	char brkf = TTY_NORMAL;
diff -Nru a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
--- a/drivers/char/ipmi/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/char/ipmi/Makefile	Mon Feb 10 10:39:32 2003
@@ -2,8 +2,6 @@
 # Makefile for the ipmi drivers.
 #
 
-export-objs	:= ipmi_msghandler.o ipmi_watchdog.o
-
 ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o
 
 obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/char/keyboard.c	Mon Feb 10 10:39:25 2003
@@ -918,7 +918,7 @@
 
 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
 
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+#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)
 
 static unsigned short x86_keycodes[256] =
 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
--- a/drivers/char/n_hdlc.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/n_hdlc.c	Mon Feb 10 10:39:24 2003
@@ -35,7 +35,7 @@
  *    callback directly to avoid fragmenting or concatenating
  *    multiple frames into a single receive callback.
  *
- *    The HDLC line discipline queues the receive frames in seperate
+ *    The HDLC line discipline queues the receive frames in separate
  *    buffers so complete receive frames can be returned by the
  *    tty read calls.
  *
diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/char/n_tty.c	Mon Feb 10 10:39:23 2003
@@ -787,7 +787,7 @@
 int is_ignored(int sig)
 {
 	return (sigismember(&current->blocked, sig) ||
-	        current->sig->action[sig-1].sa.sa_handler == SIG_IGN);
+	        current->sighand->action[sig-1].sa.sa_handler == SIG_IGN);
 }
 
 static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/char/nvram.c	Mon Feb 10 10:39:25 2003
@@ -11,7 +11,7 @@
  * "NVRAM" (NV stands for non-volatile).
  *
  * The data are supplied as a (seekable) character device, /dev/nvram. The
- * size of this file is dependant on the controller.  The usual size is 114,
+ * size of this file is dependent on the controller.  The usual size is 114,
  * the number of freely available bytes in the memory (i.e., not used by the
  * RTC itself).
  *
diff -Nru a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
--- a/drivers/char/pcmcia/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/char/pcmcia/Kconfig	Mon Feb 10 10:39:31 2003
@@ -15,7 +15,7 @@
 
 	  This driver may be built as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called synclinkmp.o.  If you want to do that, say M
+	  The module will be called synclinkmp.  If you want to do that, say M
 	  here.
 
 endmenu
diff -Nru a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h
--- a/drivers/char/rio/cmdpkt.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/rio/cmdpkt.h	Mon Feb 10 10:39:24 2003
@@ -41,7 +41,7 @@
 /*
 ** overlays for the data area of a packet. Used in both directions
 ** (to build a packet to send, and to interpret a packet that arrives)
-** and is very inconvenient for MIPS, so they appear as two seperate
+** and is very inconvenient for MIPS, so they appear as two separate
 ** structures - those used for modifying/reading packets on the card
 ** and those for modifying/reading packets in real memory, which have an _M
 ** suffix.
diff -Nru a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
--- a/drivers/char/rio/riotty.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/char/rio/riotty.c	Mon Feb 10 10:39:25 2003
@@ -1287,7 +1287,7 @@
 }
 
 /*
-	ttyseth -- set hardware dependant tty settings
+	ttyseth -- set hardware dependent tty settings
 */
 void
 ttyseth(PortP, s, sg)
@@ -1342,7 +1342,7 @@
 }
 
 /*
-	ttyseth_pv -- set hardware dependant tty settings using either the
+	ttyseth_pv -- set hardware dependent tty settings using either the
 			POSIX termios structure or the System V termio structure.
 				sysv = 0 => (POSIX):	 struct termios *sg
 				sysv != 0 => (System V): struct termio *sg
diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/char/rtc.c	Mon Feb 10 10:39:25 2003
@@ -171,7 +171,7 @@
  *	A very tiny interrupt handler. It runs with SA_INTERRUPT set,
  *	but there is possibility of conflicting with the set_rtc_mmss()
  *	call (the rtc irq and the timer irq can easily run at the same
- *	time in two different CPUs). So we need to serializes
+ *	time in two different CPUs). So we need to serialize
  *	accesses to the chip with the rtc_lock spinlock that each
  *	architecture should implement in the timer code.
  *	(See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
@@ -401,22 +401,18 @@
 		min = alm_tm.tm_min;
 		sec = alm_tm.tm_sec;
 
-		if (hrs >= 24)
-			hrs = 0xff;
-
-		if (min >= 60)
-			min = 0xff;
-
-		if (sec >= 60)
-			sec = 0xff;
-
 		spin_lock_irq(&rtc_lock);
 		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
 		    RTC_ALWAYS_BCD)
 		{
-			BIN_TO_BCD(sec);
-			BIN_TO_BCD(min);
-			BIN_TO_BCD(hrs);
+			if (sec < 60) BIN_TO_BCD(sec);
+			else sec = 0xff;
+
+			if (min < 60) BIN_TO_BCD(min);
+			else min = 0xff;
+
+			if (hrs < 24) BIN_TO_BCD(hrs);
+			else hrs = 0xff;
 		}
 		CMOS_WRITE(hrs, RTC_HOURS_ALARM);
 		CMOS_WRITE(min, RTC_MINUTES_ALARM);
@@ -486,7 +482,7 @@
 			yrs = 73;
 		}
 #endif
-		/* These limits and adjustments are independant of
+		/* These limits and adjustments are independent of
 		 * whether the chip is in binary mode or not.
 		 */
 		if (yrs > 169) {
diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c
--- a/drivers/char/synclink.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/char/synclink.c	Mon Feb 10 10:39:24 2003
@@ -6098,7 +6098,7 @@
 	/*
 	 * Program the Bus Configuration Register (BCR)
 	 *
-	 * <15>		0	Don't use seperate address
+	 * <15>		0	Don't use separate address
 	 * <14..6>	0	reserved
 	 * <5..4>	00	IAckmode = Default, don't care
 	 * <3>		1	Bus Request Totem Pole output
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/char/tty_io.c	Mon Feb 10 10:39:29 2003
@@ -442,6 +442,13 @@
 	file_list_lock();
 	for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
 		struct file * filp = list_entry(l, struct file, f_list);
+		/*
+		 * If this file descriptor has been closed, ignore it; it
+		 * will be going away shortly. (We don't test filp->f_count
+		 * for zero since that could open another race.) --rmk
+		 */
+		if (filp->private_data == NULL)
+			continue;
 		if (IS_CONSOLE_DEV(filp->f_dentry->d_inode->i_rdev) ||
 		    IS_SYSCONS_DEV(filp->f_dentry->d_inode->i_rdev)) {
 			cons_filp = filp;
diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/drivers/char/watchdog/Kconfig	Mon Feb 10 10:39:29 2003
@@ -50,7 +50,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  softdog.o.
+	  softdog.
 
 config WDT
 	tristate "WDT Watchdog timer"
@@ -66,7 +66,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called wdt.o.
+	  will be called wdt.
 
 config WDTPCI
 	tristate "WDT PCI Watchdog timer"
@@ -82,7 +82,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called wdt_pci.o.
+	  will be called wdt_pci.
 
 config WDT_501
 	bool "WDT501 features"
@@ -115,7 +115,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called pcwd.o. If you want to compile it as a module,
+	  The module is called pcwd. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 	  Most people will say N.
@@ -132,7 +132,7 @@
 	  This driver is like the WDT501 driver but for different hardware.
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called pscwdt.o.  If you want to compile it as a
+	  The module is called pscwdt.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  Most
 	  people will say N.
 
@@ -150,7 +150,7 @@
 	help
 	  The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
 	  here if you wish to use this. Alternatively say M to compile the
-	  driver as a module, which will be called wdt285.o.
+	  driver as a module, which will be called wdt285.
 
 	  This driver does not work on all machines. In particular, early CATS
 	  boards have hardware problems that will cause the machine to simply
@@ -164,7 +164,7 @@
 	help
 	  Say Y here to include support for the WB977 watchdog included in
 	  NetWinder machines. Alternatively say M to compile the driver as
-	  a module, which will be called wdt977.o.
+	  a module, which will be called wdt977.
 
 	  Not sure? It's safe to say N.
 
@@ -179,7 +179,7 @@
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt. The module will be called sa1100_wdt.o.
+	  Documentation/modules.txt. The module will be called sa1100_wdt.
 
 config EUROTECH_WDT
 	tristate "Eurotech CPU-1220/1410 Watchdog Timer"
@@ -202,7 +202,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called ib700wdt.o. If you want to compile it as a
+	  The module is called ib700wdt. If you want to compile it as a
 	  module, say M here and read Documentation/modules.txt. Most people
 	  will say N.
 
@@ -225,7 +225,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  i810-tco.o.
+	  i810-tco.
 
 config MIXCOMWD
 	tristate "Mixcom Watchdog"
@@ -238,7 +238,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called mixcomwd.o.  If you want to compile it as a
+	  The module is called mixcomwd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  Most
 	  people will say N.
 
@@ -249,7 +249,7 @@
 	  Enable the built-in watchdog timer support on the National 
 	  Semiconductor SCx200 processors.
 
-	  If compiled as a module, it will be called scx200_watchdog.o.
+	  If compiled as a module, it will be called scx200_watchdog.
 
 config 60XX_WDT
 	tristate "SBC-60XX Watchdog Timer"
@@ -263,7 +263,7 @@
 	  you can probably make this driver work with your card as well.
 
 	  You can compile this driver directly into the kernel, or use
-	  it as a module.  The module will be called sbc60xxwdt.o.
+	  it as a module.  The module will be called sbc60xxwdt.
 
 config W83877F_WDT
 	tristate "W83877F (EMACS) Watchdog Timer"
@@ -277,7 +277,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called mixcomwd.o.  If you want to compile it as a
+	  The module is called mixcomwd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  Most
 	  people will say N.
 
@@ -293,7 +293,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called machzwd.o.  If you want to compile it as a
+	  The module is called machzwd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config W83877F_WDT
@@ -303,17 +303,55 @@
 config SC520_WDT
 	tristate "AMD Elan SC520 processor Watchdog"
 	depends on WATCHDOG
+	help
+	  This is the driver for the hardware watchdog built in to the
+	  AMD "Elan" SC520 microcomputer commonly used in embedded systems.
+	  This watchdog simply watches your kernel to make sure it doesn't
+	  freeze, and if it does, it reboots your computer after a certain
+	  amount of time.
+	
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called sc520_wdt.
 
 config ALIM7101_WDT
 	tristate "ALi M7101 PMU Computer Watchdog"
 	depends on WATCHDOG
+	help
+	  This is the driver for the hardware watchdog on the ALi M7101 PMU
+	  as used in the x86 Cobalt servers.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module is called alim7101_wdt.  If you want to compile it as a
+	  module, say M here and read Documentation/modules.txt.  Most
+	  people will say N.
 
 config SC1200_WDT
 	tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
 	depends on WATCHDOG
+	help
+	  This is a driver for National Semiconductor PC87307/PC97307 hardware
+	  watchdog cards as found on the SC1200. This watchdog is mainly used
+	  for power management purposes and can be used to power down the device
+	  during inactivity periods (includes interrupt activity monitoring).
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module is called sc1200wdt.  If you want to compile it as a
+	  module, say M here and read Documentation/modules.txt.  Most
+	  people will say N.
 
 config WAFER_WDT
 	tristate "ICP Wafer 5823 Single Board Computer Watchdog"
 	depends on WATCHDOG
+	help
+	  This is a driver for the hardware watchdog on the ICP Wafer 5823
+	  Single Board Computer (and probably other similar models).
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt. The module will be called
+	  wafer5823wdt.o
 
 endmenu
diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile
--- a/drivers/eisa/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/eisa/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,8 +2,6 @@
 
 obj-$(CONFIG_EISA)	+= eisa-bus.o
 
-export-objs	:= eisa-bus.o
-
 clean-files:= devlist.h
 
 # Ugly hack to get DEVICE_NAME_SIZE value...
diff -Nru a/drivers/fc4/Kconfig b/drivers/fc4/Kconfig
--- a/drivers/fc4/Kconfig	Mon Feb 10 10:39:25 2003
+++ b/drivers/fc4/Kconfig	Mon Feb 10 10:39:25 2003
@@ -33,7 +33,7 @@
 	  that if you have older firmware in the card, you'll need the
 	  microcode from the Solaris driver to make it work.
 
-	  This support is also available as a module called soc.o ( = code
+	  This support is also available as a module called soc ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -48,7 +48,7 @@
 	  Interface Board). You'll probably need the microcode from the
 	  Solaris driver to make it work.
 
-	  This support is also available as a module called socal.o ( = code
+	  This support is also available as a module called socal ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -62,7 +62,7 @@
 	help
 	  If you never bought a disk array made by Sun, go with N.
 
-	  This support is also available as a module called pluto.o ( = code
+	  This support is also available as a module called pluto ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -76,7 +76,7 @@
 	  common is either A5000 array or internal disks in E[3-6]000
 	  machines.
 
-	  This support is also available as a module called fcal.o ( = code
+	  This support is also available as a module called fcal ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>. If unsure, say N.
diff -Nru a/drivers/fc4/Makefile b/drivers/fc4/Makefile
--- a/drivers/fc4/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/fc4/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux Fibre Channel device drivers.
 #
 
-export-objs := fc_syms.o
-
 fc4-objs := fc.o fc_syms.o
 
 obj-$(CONFIG_FC4) += fc4.o
diff -Nru a/drivers/fc4/fc.c b/drivers/fc4/fc.c
--- a/drivers/fc4/fc.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/fc4/fc.c	Mon Feb 10 10:39:28 2003
@@ -74,7 +74,7 @@
 #endif							       
 
 #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp))
-#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->host->hostdata[0]))
+#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0]))
 #define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp)))
 
 static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int);
@@ -449,7 +449,7 @@
 	}
 
 	if (status_byte(rsp_status) == QUEUE_FULL) {
-		printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->channel, SCpnt->target, rsp_status);
+		printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->device->channel, SCpnt->device->id, rsp_status);
 	}	
 	
 	SCpnt->result = (host_status << 16) | (rsp_status & 0xff);
@@ -771,10 +771,10 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(SCpnt->host->host_lock, flags);
+	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 	if (FCP_CMND(SCpnt)->done)
 		FCP_CMND(SCpnt)->done(SCpnt);
-	spin_unlock_irqrestore(SCpnt->host->host_lock, flags);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 }
 
 static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
@@ -799,8 +799,8 @@
 		fc->cmd_slots[fcmd->token] = fcmd;
 
 		if (SCpnt->device->tagged_supported) {
-			if (jiffies - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] > (5 * 60 * HZ)) {
-				fc->ages[SCpnt->channel * fc->targets + SCpnt->target] = jiffies;
+			if (jiffies - fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] > (5 * 60 * HZ)) {
+				fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] = jiffies;
 				fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
 			} else
 				fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
@@ -916,9 +916,9 @@
 		unsigned long flags;
 
 		SCpnt->result = DID_ABORT;
-		spin_lock_irqsave(SCpnt->host->host_lock, flags);
+		spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 		fcmd->done(SCpnt);
-		spin_unlock_irqrestore(SCpnt->host->host_lock, flags);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 		printk("FC: soft abort\n");
 		return SUCCESS;
 	} else {
@@ -932,7 +932,7 @@
 	fc_channel *fc = FC_SCMND(SCpnt);
 
 	fc->rst_pkt->eh_state = SCSI_STATE_FINISHED;
-	up(fc->rst_pkt->host->eh_action);
+	up(fc->rst_pkt->device->host->eh_action);
 }
 
 #define FCP_RESET_TIMEOUT (2*HZ)
@@ -955,9 +955,7 @@
 		cmd = fc->scsi_cmd_pool + 0;
 		FCD(("Preparing rst packet\n"))
 		fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd);
-		fc->rst_pkt->channel = SCpnt->channel;
-		fc->rst_pkt->target = SCpnt->target;
-		fc->rst_pkt->lun = 0;
+		fc->rst_pkt->device = SCpnt->device;
 		fc->rst_pkt->cmd_len = 0;
 		
 		fc->cmd_slots[0] = fcmd;
@@ -989,7 +987,7 @@
 	 * Set up the semaphore so we wait for the command to complete.
 	 */
 
-	fc->rst_pkt->host->eh_action = &sem;
+	fc->rst_pkt->device->host->eh_action = &sem;
 	fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
 
 	fc->rst_pkt->done = fcp_scsi_reset_done;
@@ -997,7 +995,7 @@
 	
 	down(&sem);
 
-	fc->rst_pkt->host->eh_action = NULL;
+	fc->rst_pkt->device->host->eh_action = NULL;
 	del_timer(&fc->rst_pkt->eh_timeout);
 
 	/*
diff -Nru a/drivers/hotplug/Kconfig b/drivers/hotplug/Kconfig
--- a/drivers/hotplug/Kconfig	Mon Feb 10 10:39:26 2003
+++ b/drivers/hotplug/Kconfig	Mon Feb 10 10:39:26 2003
@@ -16,7 +16,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pci_hotplug.o. If you want to compile it
+	  The module will be called pci_hotplug. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -30,7 +30,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpqphp.o. If you want to compile it
+	  The module will be called cpqphp. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -54,7 +54,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpqphp.o. If you want to compile it
+	  The module will be called cpqphp. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -68,7 +68,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called acpiphp.o. If you want to compile it
+	  The module will be called acpiphp. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -82,7 +82,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpci_hotplug.o. If you want to compile it
+	  The module will be called cpci_hotplug. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -96,7 +96,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpcihp_zt5550.o. If you want to compile it
+	  The module will be called cpcihp_zt5550. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
@@ -111,7 +111,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cpcihp_generic.o. If you want to compile it
+	  The module will be called cpcihp_generic. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  When in doubt, say N.
diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile
--- a/drivers/hotplug/Makefile	Mon Feb 10 10:39:30 2003
+++ b/drivers/hotplug/Makefile	Mon Feb 10 10:39:30 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux kernel pci hotplug controller drivers.
 #
 
-export-objs	:= pci_hotplug_core.o pci_hotplug_util.o cpci_hotplug_core.o
-
 obj-$(CONFIG_HOTPLUG_PCI)		+= pci_hotplug.o
 obj-$(CONFIG_HOTPLUG_PCI_COMPAQ)	+= cpqphp.o
 obj-$(CONFIG_HOTPLUG_PCI_IBM)		+= ibmphp.o
@@ -11,8 +9,7 @@
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550)	+= cpcihp_zt5550.o
 obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC)	+= cpcihp_generic.o
 
-pci_hotplug-objs	:=	pci_hotplug_core.o	\
-				pci_hotplug_util.o
+pci_hotplug-objs	:=	pci_hotplug_core.o
 
 ifdef CONFIG_HOTPLUG_PCI_CPCI
 pci_hotplug-objs	+=	cpci_hotplug_core.o	\
diff -Nru a/drivers/hotplug/acpiphp.h b/drivers/hotplug/acpiphp.h
--- a/drivers/hotplug/acpiphp.h	Mon Feb 10 10:39:33 2003
+++ b/drivers/hotplug/acpiphp.h	Mon Feb 10 10:39:33 2003
@@ -34,9 +34,8 @@
 #ifndef _ACPIPHP_H
 #define _ACPIPHP_H
 
-#include "include/acpi.h"
+#include <linux/acpi.h>
 #include "pci_hotplug.h"
-#include "acpi_bus.h"
 
 #define dbg(format, arg...)					\
 	do {							\
diff -Nru a/drivers/hotplug/acpiphp_glue.c b/drivers/hotplug/acpiphp_glue.c
--- a/drivers/hotplug/acpiphp_glue.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/hotplug/acpiphp_glue.c	Mon Feb 10 10:39:24 2003
@@ -578,6 +578,7 @@
 		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
 		if (!bridge->io_head) {
 			err("out of memory\n");
+			kfree(bridge);
 			return;
 		}
 		dbg("16bit I/O range: %04x-%04x\n",
@@ -592,6 +593,7 @@
 		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
 		if (!bridge->io_head) {
 			err("out of memory\n");
+			kfree(bridge);
 			return;
 		}
 		dbg("32bit I/O range: %08x-%08x\n",
@@ -613,6 +615,7 @@
 	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
 	if (!bridge->mem_head) {
 		err("out of memory\n");
+		kfree(bridge);
 		return;
 	}
 	dbg("32bit Memory range: %08x-%08x\n",
@@ -632,6 +635,7 @@
 		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
 		if (!bridge->p_mem_head) {
 			err("out of memory\n");
+			kfree(bridge);
 			return;
 		}
 		dbg("32bit Prefetchable memory range: %08x-%08x\n",
@@ -647,6 +651,7 @@
 		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
 		if (!bridge->p_mem_head) {
 			err("out of memory\n");
+			kfree(bridge);
 			return;
 		}
 		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
--- a/drivers/hotplug/cpci_hotplug_core.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/hotplug/cpci_hotplug_core.c	Mon Feb 10 10:39:26 2003
@@ -130,7 +130,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.latch_status = value;
-	return pci_hp_change_slot_info(hotplug_slot->name, &info);
+	return pci_hp_change_slot_info(hotplug_slot, &info);
 }
 
 static int
@@ -142,7 +142,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.adapter_status = value;
-	return pci_hp_change_slot_info(hotplug_slot->name, &info);
+	return pci_hp_change_slot_info(hotplug_slot, &info);
 }
 
 static int
diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c
--- a/drivers/hotplug/cpci_hotplug_pci.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/hotplug/cpci_hotplug_pci.c	Mon Feb 10 10:39:29 2003
@@ -341,7 +341,7 @@
 
 	/*
 	 * Need to explicitly set irq field to 0 so that it'll get assigned
-	 * by the pcibios platform dependant code called by pci_enable_device.
+	 * by the pcibios platform dependent code called by pci_enable_device.
 	 */
 	dev->irq = 0;
 
@@ -395,6 +395,8 @@
 	/* Scan behind bridge */
 	n = pci_scan_bridge(bus, dev, max, 2);
 	child = pci_find_bus(max + 1);
+	if (!child)
+		return -ENODEV;
 #ifdef CONFIG_PROC_FS
 	pci_proc_attach_bus(child);
 #endif
diff -Nru a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c
--- a/drivers/hotplug/cpqphp_core.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/hotplug/cpqphp_core.c	Mon Feb 10 10:39:22 2003
@@ -42,7 +42,7 @@
 
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependant we are... */
+#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
 
 
 /* Global variables */
@@ -488,6 +488,8 @@
 	bridgeSlot = 0xFF;
 
 	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
+	if (!PCIIRQRoutingInfoLength)
+		return -1;
 
 	len = (PCIIRQRoutingInfoLength->size -
 	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c
--- a/drivers/hotplug/cpqphp_ctrl.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/hotplug/cpqphp_ctrl.c	Mon Feb 10 10:39:24 2003
@@ -188,6 +188,8 @@
 			rc++;
 
 			p_slot = find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
+			if (!p_slot)
+				return 0;
 
 			// If the switch closed, must be a button
 			// If not in button mode, nevermind
@@ -1765,19 +1767,17 @@
 static int update_slot_info (struct controller *ctrl, struct slot *slot)
 {
 	struct hotplug_slot_info *info;
-	char buffer[SLOT_NAME_SIZE];
 	int result;
 
 	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
-	make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot);
 	info->power_status = get_slot_enabled(ctrl, slot);
 	info->attention_status = cpq_get_attention_status(ctrl, slot);
 	info->latch_status = cpq_get_latch_status(ctrl, slot);
 	info->adapter_status = get_presence_status(ctrl, slot);
-	result = pci_hp_change_slot_info(buffer, info);
+	result = pci_hp_change_slot_info(slot->hotplug_slot, info);
 	kfree (info);
 	return result;
 }
@@ -1799,8 +1799,12 @@
 				hp_slot = ctrl->event_queue[loop].hp_slot;
 
 				func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
+				if (!func)
+					return;
 
 				p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
+				if (!p_slot)
+					return;
 
 				dbg("hp_slot %d, func %p, p_slot %p\n",
 				    hp_slot, func, p_slot);
@@ -2511,8 +2515,14 @@
 		// Setup the IO, memory, and prefetchable windows
 
 		io_node = get_max_resource(&(resources->io_head), 0x1000);
+		if (!io_node)
+			return -ENOMEM;
 		mem_node = get_max_resource(&(resources->mem_head), 0x100000);
+		if (!mem_node)
+			return -ENOMEM;
 		p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
+		if (!p_mem_node)
+			return -ENOMEM;
 		dbg("Setup the IO, memory, and prefetchable windows\n");
 		dbg("io_node\n");
 		dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
diff -Nru a/drivers/hotplug/cpqphp_nvram.c b/drivers/hotplug/cpqphp_nvram.c
--- a/drivers/hotplug/cpqphp_nvram.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/hotplug/cpqphp_nvram.c	Mon Feb 10 10:39:31 2003
@@ -473,7 +473,7 @@
 		p_byte += 3;
 
 		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-			return(2);
+			return 2;
 
 		bus = p_ev_ctrl->bus;
 		device = p_ev_ctrl->device;
@@ -490,20 +490,20 @@
 			p_byte += 4;
 
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+				return 2;
 
 			// Skip forward to the next entry
 			p_byte += (nummem + numpmem + numio + numbus) * 8;
 
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+				return 2;
 
 			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;
 
 			p_byte += 3;
 
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+				return 2;
 
 			bus = p_ev_ctrl->bus;
 			device = p_ev_ctrl->device;
@@ -518,7 +518,7 @@
 		p_byte += 4;
 
 		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-			return(2);
+			return 2;
 
 		while (nummem--) {
 			mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
@@ -530,15 +530,19 @@
 			dbg("mem base = %8.8x\n",mem_node->base);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(mem_node);
+				return 2;
+			}
 
 			mem_node->length = *(u32*)p_byte;
 			dbg("mem length = %8.8x\n",mem_node->length);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(mem_node);
+				return 2;
+			}
 
 			mem_node->next = ctrl->mem_head;
 			ctrl->mem_head = mem_node;
@@ -554,15 +558,19 @@
 			dbg("pre-mem base = %8.8x\n",p_mem_node->base);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(p_mem_node);
+				return 2;
+			}
 
 			p_mem_node->length = *(u32*)p_byte;
 			dbg("pre-mem length = %8.8x\n",p_mem_node->length);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(p_mem_node);
+				return 2;
+			}
 
 			p_mem_node->next = ctrl->p_mem_head;
 			ctrl->p_mem_head = p_mem_node;
@@ -578,15 +586,19 @@
 			dbg("io base = %8.8x\n",io_node->base);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(io_node);
+				return 2;
+			}
 
 			io_node->length = *(u32*)p_byte;
 			dbg("io length = %8.8x\n",io_node->length);
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(io_node);
+				return 2;
+			}
 
 			io_node->next = ctrl->io_head;
 			ctrl->io_head = io_node;
@@ -601,15 +613,18 @@
 			bus_node->base = *(u32*)p_byte;
 			p_byte += 4;
 
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(bus_node);
+				return 2;
+			}
 
 			bus_node->length = *(u32*)p_byte;
 			p_byte += 4;
 
-
-			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
-				return(2);
+			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
+				kfree(bus_node);
+				return 2;
+			}
 
 			bus_node->next = ctrl->bus_head;
 			ctrl->bus_head = bus_node;
@@ -623,13 +638,11 @@
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
 
-		if (rc) {
+		if (rc)
 			return(rc);
-		}
 	} else {
-		if ((evbuffer[0] != 0) && (!ctrl->push_flag)) {
-			return(1);
-		}
+		if ((evbuffer[0] != 0) && (!ctrl->push_flag)) 
+			return 1;
 	}
 
 	return 0;
diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c
--- a/drivers/hotplug/cpqphp_pci.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/hotplug/cpqphp_pci.c	Mon Feb 10 10:39:32 2003
@@ -36,7 +36,7 @@
 #include <linux/pci.h>
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependant we are... */
+#include "../../arch/i386/pci/pci.h"	/* horrible hack showing how processor dependent we are... */
 
 
 u8 cpqhp_nic_irq;
@@ -435,6 +435,8 @@
 	u8 tbus, tdevice, tslot;
 
 	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
+	if (!PCIIRQRoutingInfoLength)
+		return -1;
 
 	len = (PCIIRQRoutingInfoLength->size -
 	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
@@ -1191,7 +1193,7 @@
 				if (temp != func->config_space[cloop >> 2]) {
 					dbg("Config space compare failure!!! offset = %x\n", cloop);
 					dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
-					dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop]);
+					dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]);
 					return 1;
 				}
 			}
diff -Nru a/drivers/hotplug/cpqphp_proc.c b/drivers/hotplug/cpqphp_proc.c
--- a/drivers/hotplug/cpqphp_proc.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/hotplug/cpqphp_proc.c	Mon Feb 10 10:39:32 2003
@@ -113,6 +113,8 @@
 
 	while (slot) {
 		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
+		if (!new_slot)
+			break;
 		out += sprintf(out, "assigned resources: memory\n");
 		index = 11;
 		res = new_slot->mem_head;
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
--- a/drivers/hotplug/ibmphp_core.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/hotplug/ibmphp_core.c	Mon Feb 10 10:39:33 2003
@@ -686,7 +686,6 @@
 int ibmphp_update_slot_info (struct slot *slot_cur)
 {
 	struct hotplug_slot_info *info;
-	char buffer[30];
 	int rc;
 	u8 bus_speed;
 	u8 mode;
@@ -697,7 +696,6 @@
 		return -ENOMEM;
 	}
         
-	strncpy (buffer, slot_cur->hotplug_slot->name, 30);
 	info->power_status = SLOT_PWRGD (slot_cur->status);
 	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
 	info->latch_status = SLOT_LATCH (slot_cur->status);
@@ -735,7 +733,7 @@
 	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
 	// To do: bus_names 
 	
-	rc = pci_hp_change_slot_info (buffer, info);
+	rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info);
 	kfree (info);
 	return rc;
 }
@@ -1057,6 +1055,8 @@
 
 	if (func->dev == NULL) {
 		dev0.bus = ibmphp_find_bus (func->busno);
+		if (!dev0.bus)
+			return 0;
 		dev0.devfn = ((func->device << 3) + (func->function & 0x7));
 		dev0.sysdata = dev0.bus->sysdata;
 
@@ -1097,6 +1097,8 @@
 			continue;
 		}
 		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		if (!tmp_slot)
+			return 0;
 		rc = slot_update (&tmp_slot);
 		if (rc)
 			return 0;
@@ -1219,6 +1221,8 @@
 
 	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
 		tmp_slot = ibmphp_get_slot_from_physical_num (i);
+		if (!tmp_slot)
+			return -ENODEV;
 		if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
 			count++;
 	}
diff -Nru a/drivers/hotplug/ibmphp_ebda.c b/drivers/hotplug/ibmphp_ebda.c
--- a/drivers/hotplug/ibmphp_ebda.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/hotplug/ibmphp_ebda.c	Mon Feb 10 10:39:23 2003
@@ -65,24 +65,11 @@
 static LIST_HEAD (opt_lo_head);
 static void *io_mem;
 
-char *chassis_str, *rxe_str, *str;
-
 /* Local functions */
 static int ebda_rsrc_controller (void);
 static int ebda_rsrc_rsrc (void);
 static int ebda_rio_table (void);
 
-static struct slot *alloc_ibm_slot (void)
-{
-	struct slot *slot;
-
-	slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
-	if (!slot)
-		return NULL;
-	memset (slot, 0, sizeof (*slot));
-	return slot;
-}
-
 static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
 {
 	struct ebda_hpc_list *list;
@@ -591,32 +578,6 @@
 	return 0;	
 }
 	
-static char *convert_2digits_to_char (int var)
-{
-	int bit;	
-	char *str1;
-
-	str = (char *) kmalloc (3, GFP_KERNEL);
-	memset (str, 0, 3);
-	str1 = (char *) kmalloc (2, GFP_KERNEL);
-	memset (str, 0, 3);
-	bit = (int)(var / 10);
-	switch (bit) {
-	case 0:
-		//one digit number
-		*str = (char)(var + 48);
-		return str;
-	default: 	
-		//2 digits number
-		*str1 = (char)(bit + 48);
-		strncpy (str, str1, 1);
-		memset (str1, 0, 3);
-		*str1 = (char)((var % 10) + 48);
-		strcat (str, str1);
-		return str;
-	}	
-	return NULL;	
-}
 
 /* Since we don't know the max slot number per each chassis, hence go
  * through the list of all chassis to find out the range
@@ -701,7 +662,7 @@
 {
 	struct opt_rio *opt_vg_ptr = NULL;
 	struct opt_rio_lo *opt_lo_ptr = NULL;
-	char *ptr_chassis_num, *ptr_rxe_num, *ptr_slot_num;
+	static char str[30];
 	int which = 0; /* rxe = 1, chassis = 0 */
 	u8 number = 1; /* either chassis or rxe # */
 	u8 first_slot = 1;
@@ -715,19 +676,7 @@
 	
 	slot_num = slot_cur->number;
 
-	chassis_str = (char *) kmalloc (30, GFP_KERNEL);
-	memset (chassis_str, 0, 30);
-	rxe_str = (char *) kmalloc (30, GFP_KERNEL);
-	memset (rxe_str, 0, 30);
-	ptr_chassis_num = (char *) kmalloc (3, GFP_KERNEL);
-	memset (ptr_chassis_num, 0, 3);
-	ptr_rxe_num = (char *) kmalloc (3, GFP_KERNEL);
-	memset (ptr_rxe_num, 0, 3);
-	ptr_slot_num = (char *) kmalloc (3, GFP_KERNEL);
-	memset (ptr_slot_num, 0, 3);
-	
-	strcpy (chassis_str, "chassis");
-	strcpy (rxe_str, "rxe");
+	memset (str, 0, sizeof(str));
 	
 	if (rio_table_ptr) {
 		if (rio_table_ptr->ver_num == 3) {
@@ -772,31 +721,10 @@
 		}
 	}
 
-	switch (which) {
-	case 0:
-		/* Chassis */
-		*ptr_chassis_num = (char)(number + 48);
-		strcat (chassis_str, ptr_chassis_num);
-		kfree (ptr_chassis_num);
-		strcat (chassis_str, "slot");
-		ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
-		strcat (chassis_str, ptr_slot_num);
-		kfree (ptr_slot_num);
-		return chassis_str;
-		break;
-	case 1:
-		/* RXE */
-		*ptr_rxe_num = (char)(number + 48);
-		strcat (rxe_str, ptr_rxe_num);
-		kfree (ptr_rxe_num);
-		strcat (rxe_str, "slot");
-		ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
-		strcat (rxe_str, ptr_slot_num);
-		kfree (ptr_slot_num);
-		return rxe_str;
-		break;
-	}	
-	return NULL;
+	sprintf(str, "%s%dslot%d",
+		which == 0 ? "chassis" : "rxe",
+		number, slot_num - first_slot + 1);
+	return str;
 }
 
 static struct pci_driver ibmphp_driver;
@@ -818,8 +746,7 @@
 	struct ebda_hpc_slot *slot_ptr;
 	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
 	int rc;
-	int retval;
-	struct slot *slot_cur;
+	struct slot *tmp_slot;
 	struct list_head *list;
 
 	addr = hpc_list_ptr->phys_addr;
@@ -844,8 +771,8 @@
 		/* init hpc structure */
 		hpc_ptr = alloc_ebda_hpc (slot_num, bus_num);
 		if (!hpc_ptr ) {
-			iounmap (io_mem);
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto error_no_hpc;
 		}
 		hpc_ptr->ctlr_id = ctlr_id;
 		hpc_ptr->ctlr_relative_id = ctlr;
@@ -871,8 +798,8 @@
 			if (!bus_info_ptr2) {
 				bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
 				if (!bus_info_ptr1) {
-					iounmap (io_mem);
-					return -ENOMEM;
+					rc = -ENOMEM;
+					goto error_no_hp_slot;
 				}
 				memset (bus_info_ptr1, 0, sizeof (struct bus_info));
 				bus_info_ptr1->slot_min = slot_ptr->slot_num;
@@ -932,16 +859,20 @@
 				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
 				hpc_ptr->irq = readb (io_mem + addr + 2);
 				addr += 3;
-				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
+				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", 
+					hpc_ptr->u.pci_ctlr.bus,
+					hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
 				break;
 
 			case 0:
 				hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
 				hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
-				retval = check_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1));
-				if (retval)
-					return -ENODEV;
-				request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp");
+				if (!request_region (hpc_ptr->u.isa_ctlr.io_start,
+						     (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1),
+						     "ibmphp")) {
+					rc = -ENODEV;
+					goto error_no_hp_slot;
+				}
 				hpc_ptr->irq = readb (io_mem + addr + 4);
 				addr += 5;
 				break;
@@ -954,8 +885,8 @@
 				addr += 6;
 				break;
 			default:
-				iounmap (io_mem);
-				return -ENODEV;
+				rc = -ENODEV;
+				goto error_no_hp_slot;
 		}
 
 		//reorganize chassis' linked list
@@ -971,79 +902,71 @@
 
 			hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
 			if (!hp_slot_ptr) {
-				iounmap (io_mem);
-				return -ENOMEM;
+				rc = -ENOMEM;
+				goto error_no_hp_slot;
 			}
 			memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot));
 
 			hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
 			if (!hp_slot_ptr->info) {
-				iounmap (io_mem);
-				kfree (hp_slot_ptr);
-				return -ENOMEM;
+				rc = -ENOMEM;
+				goto error_no_hp_info;
 			}
 			memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
 
 			hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
 			if (!hp_slot_ptr->name) {
-				iounmap (io_mem);
-				kfree (hp_slot_ptr->info);
-				kfree (hp_slot_ptr);
-				return -ENOMEM;
+				rc = -ENOMEM;
+				goto error_no_hp_name;
 			}
 
-			hp_slot_ptr->private = alloc_ibm_slot ();
-			if (!hp_slot_ptr->private) {
-				iounmap (io_mem);
-				kfree (hp_slot_ptr->name);
-				kfree (hp_slot_ptr->info);
-				kfree (hp_slot_ptr);
-				return -ENOMEM;
+			tmp_slot = kmalloc (sizeof (struct slot), GFP_KERNEL);
+			if (!tmp_slot) {
+				rc = -ENOMEM;
+				goto error_no_slot;
 			}
+			memset (tmp_slot, 0, sizeof (*tmp_slot));
 
-			((struct slot *)hp_slot_ptr->private)->flag = TRUE;
+			tmp_slot->flag = TRUE;
 
-			((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap;
+			tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
 			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
-				((struct slot *) hp_slot_ptr->private)->supported_speed =  3;
+				tmp_slot->supported_speed =  3;
 			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX)
-				((struct slot *) hp_slot_ptr->private)->supported_speed =  2;
+				tmp_slot->supported_speed =  2;
 			else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX)
-				((struct slot *) hp_slot_ptr->private)->supported_speed =  1;
+				tmp_slot->supported_speed =  1;
 				
 			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP)
-				((struct slot *) hp_slot_ptr->private)->supported_bus_mode = 1;
+				tmp_slot->supported_bus_mode = 1;
 			else
-				((struct slot *) hp_slot_ptr->private)->supported_bus_mode = 0;
+				tmp_slot->supported_bus_mode = 0;
 
 
-			((struct slot *) hp_slot_ptr->private)->bus = hpc_ptr->slots[index].slot_bus_num;
+			tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num;
 
 			bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);
 			if (!bus_info_ptr1) {
-				iounmap (io_mem);
-				return -ENODEV;
+				rc = -ENODEV;
+				goto error;
 			}
-			((struct slot *) hp_slot_ptr->private)->bus_on = bus_info_ptr1;
+			tmp_slot->bus_on = bus_info_ptr1;
 			bus_info_ptr1 = NULL;
-			((struct slot *) hp_slot_ptr->private)->ctrl = hpc_ptr;
+			tmp_slot->ctrl = hpc_ptr;
 
+			tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index;
+			tmp_slot->number = hpc_ptr->slots[index].slot_num;
+			tmp_slot->hotplug_slot = hp_slot_ptr;
+
+			hp_slot_ptr->private = tmp_slot;
 
-			((struct slot *) hp_slot_ptr->private)->ctlr_index = hpc_ptr->slots[index].ctl_index;
-			((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
-			
-			((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
 			rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
-			if (rc) {
-				iounmap (io_mem);
-				return rc;
-			}
+			if (rc)
+				goto error;
 
 			rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private);
-			if (rc) {
-				iounmap (io_mem);
-				return rc;
-			}
+			if (rc)
+				goto error;
 			hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
 
 			// end of registering ibm slot with hotplug core
@@ -1057,19 +980,29 @@
 	}			/* each hpc  */
 
 	list_for_each (list, &ibmphp_slot_head) {
-		slot_cur = list_entry (list, struct slot, ibm_slot_list);
+		tmp_slot = list_entry (list, struct slot, ibm_slot_list);
 
-		snprintf (slot_cur->hotplug_slot->name, 30, "%s", create_file_name (slot_cur));
-		if (chassis_str) 
-			kfree (chassis_str);
-		if (rxe_str)
-			kfree (rxe_str);
-		pci_hp_register (slot_cur->hotplug_slot);
+		snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
+		pci_hp_register (tmp_slot->hotplug_slot);
 	}
 
 	print_ebda_hpc ();
 	print_ibm_slot ();
 	return 0;
+
+error:
+	kfree (hp_slot_ptr->private);
+error_no_slot:
+	kfree (hp_slot_ptr->name);
+error_no_hp_name:
+	kfree (hp_slot_ptr->info);
+error_no_hp_info:
+	kfree (hp_slot_ptr);
+error_no_hp_slot:
+	free_ebda_hpc (hpc_ptr);
+error_no_hpc:
+	iounmap (io_mem);
+	return rc;
 }
 
 /* 
diff -Nru a/drivers/hotplug/ibmphp_pci.c b/drivers/hotplug/ibmphp_pci.c
--- a/drivers/hotplug/ibmphp_pci.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/hotplug/ibmphp_pci.c	Mon Feb 10 10:39:22 2003
@@ -951,6 +951,7 @@
 		if (rc) {
 			if (rc == -ENOMEM) {
 				ibmphp_remove_bus (bus, func->busno);
+				kfree (amount_needed);
 				return rc;
 			}
 			retval = rc;
@@ -1621,23 +1622,23 @@
 			}
 
 			for (i = 0; i < count; i++) {
-				if (cur_func->io[count]) {
-					debug ("io[%d] exists \n", count);
+				if (cur_func->io[i]) {
+					debug ("io[%d] exists \n", i);
 					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->io[count]);
-					cur_func->io[count] = NULL;
+						ibmphp_remove_resource (cur_func->io[i]);
+					cur_func->io[i] = NULL;
 				}
-				if (cur_func->mem[count]) {
-					debug ("mem[%d] exists \n", count);
+				if (cur_func->mem[i]) {
+					debug ("mem[%d] exists \n", i);
 					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->mem[count]);
-					cur_func->mem[count] = NULL;
+						ibmphp_remove_resource (cur_func->mem[i]);
+					cur_func->mem[i] = NULL;
 				}
-				if (cur_func->pfmem[count]) {
-					debug ("pfmem[%d] exists \n", count);
+				if (cur_func->pfmem[i]) {
+					debug ("pfmem[%d] exists \n", i);
 					if (the_end > 0)
-						ibmphp_remove_resource (cur_func->pfmem[count]);
-					cur_func->pfmem[count] = NULL;
+						ibmphp_remove_resource (cur_func->pfmem[i]);
+					cur_func->pfmem[i] = NULL;
 				}
 			}
 
diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
--- a/drivers/hotplug/pci_hotplug.h	Mon Feb 10 10:39:25 2003
+++ b/drivers/hotplug/pci_hotplug.h	Mon Feb 10 10:39:25 2003
@@ -46,8 +46,11 @@
 };
 
 struct hotplug_slot;
-struct hotplug_slot_core;
-
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
@@ -131,45 +134,13 @@
 
 	/* Variables below this are for use only by the hotplug pci core. */
 	struct list_head		slot_list;
-	struct hotplug_slot_core	*core_priv;
+	struct kobject			kobj;
 };
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
 extern int pci_hp_deregister		(struct hotplug_slot *slot);
-extern int pci_hp_change_slot_info	(const char *name,
+extern int pci_hp_change_slot_info	(struct hotplug_slot *slot,
 					 struct hotplug_slot_info *info);
-
-struct pci_dev_wrapped {
-	struct pci_dev	*dev;
-	void		*data;
-};
-
-struct pci_bus_wrapped {
-	struct pci_bus	*bus;
-	void		*data;
-};
-
-struct pci_visit {
-	int (* pre_visit_pci_bus)	(struct pci_bus_wrapped *,
-					 struct pci_dev_wrapped *);
-	int (* post_visit_pci_bus)	(struct pci_bus_wrapped *,
-					 struct pci_dev_wrapped *);
-
-	int (* pre_visit_pci_dev)	(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-	int (* visit_pci_dev)		(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-	int (* post_visit_pci_dev)	(struct pci_dev_wrapped *,
-					 struct pci_bus_wrapped *);
-};
-
-extern int pci_visit_dev	(struct pci_visit *fn,
-				 struct pci_dev_wrapped *wrapped_dev,
-				 struct pci_bus_wrapped *wrapped_parent);
-
-int pci_is_dev_in_use(struct pci_dev *dev);
-
-int pci_remove_device_safe(struct pci_dev *dev);
 
 #endif
 
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Mon Feb 10 10:39:31 2003
@@ -39,9 +39,9 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pci.h>
-#include <linux/dnotify.h>
-#include <linux/proc_fs.h>
 #include <asm/uaccess.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include "pci_hotplug.h"
 
 
@@ -67,29 +67,43 @@
 
 //////////////////////////////////////////////////////////////////
 
-/* Random magic number */
-#define PCIHPFS_MAGIC 0x52454541
+static spinlock_t list_lock;
+
+static LIST_HEAD(pci_hotplug_slot_list);
 
-struct hotplug_slot_core {
-	struct dentry	*dir_dentry;
-	struct dentry	*power_dentry;
-	struct dentry	*attention_dentry;
-	struct dentry	*latch_dentry;
-	struct dentry	*adapter_dentry;
-	struct dentry	*test_dentry;
-	struct dentry	*max_bus_speed_dentry;
-	struct dentry	*cur_bus_speed_dentry;
+static struct subsystem hotplug_slots_subsys;
+
+static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
+
+static struct sysfs_ops hotplug_slot_sysfs_ops = {
+	.show = hotplug_slot_attr_show,
+	.store = hotplug_slot_attr_store,
 };
 
-static struct super_operations pcihpfs_ops;
-static struct file_operations default_file_operations;
-static struct inode_operations pcihpfs_dir_inode_operations;
-static struct vfsmount *pcihpfs_mount;	/* one of the mounts of our fs for reference counting */
-static int pcihpfs_mount_count;		/* times we have mounted our fs */
-static spinlock_t mount_lock;		/* protects our mount_count */
-static spinlock_t list_lock;
+static struct kobj_type hotplug_slot_ktype = {
+	.sysfs_ops = &hotplug_slot_sysfs_ops
+};
+
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
 
-static LIST_HEAD(pci_hotplug_slot_list);
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -115,12 +129,6 @@
 	"133 MHz PCIX 533",	/* 0x13 */
 };
 
-#ifdef CONFIG_PROC_FS		
-extern struct proc_dir_entry *proc_bus_pci_dir;
-static struct proc_dir_entry *slotdir = NULL;
-static const char *slotdir_name = "slots";
-#endif
-
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
 extern int cpci_hotplug_init(int debug);
 extern void cpci_hotplug_exit(void);
@@ -129,438 +137,6 @@
 static inline void cpci_hotplug_exit(void) { }
 #endif
 
-static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (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_rdev = NODEV;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &default_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &pcihpfs_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		}
-	}
-	return inode; 
-}
-
-/* SMP-safe */
-static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
-	struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
-	int error = -ENOSPC;
-
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0);
-}
-
-static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode)
-{
- 	return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
-}
-
-static inline int pcihpfs_positive (struct dentry *dentry)
-{
-	return dentry->d_inode && !d_unhashed(dentry);
-}
-
-static int pcihpfs_empty (struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dcache_lock);
-
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
-		if (pcihpfs_positive(de)) {
-			spin_unlock(&dcache_lock);
-			return 0;
-		}
-	}
-
-	spin_unlock(&dcache_lock);
-	return 1;
-}
-
-static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry)
-{
-	int error = -ENOTEMPTY;
-
-	if (pcihpfs_empty(dentry)) {
-		struct inode *inode = dentry->d_inode;
-
-		lock_kernel();
-		inode->i_nlink--;
-		unlock_kernel();
-		dput(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-#define pcihpfs_rmdir pcihpfs_unlink
-
-/* default file operations */
-static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return 0;
-}
-
-static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return count;
-}
-
-static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	lock_kernel();
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		} 
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		} 
-		break;
-	default:
-		break;
-	}
-	unlock_kernel();
-	return retval;
-}
-
-static int default_open (struct inode *inode, struct file *filp)
-{
-	if (inode->u.generic_ip)
-		filp->private_data = inode->u.generic_ip;
-
-	return 0;
-}
-
-static struct file_operations default_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "power" files */
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations power_file_operations = {
-	.read =		power_read_file,
-	.write =	power_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "attention" files */
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations attention_file_operations = {
-	.read =		attention_read_file,
-	.write =	attention_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "latch" files */
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations latch_file_operations = {
-	.read =		latch_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "presence" files */
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations presence_file_operations = {
-	.read =		presence_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "max bus speed" files */
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations max_bus_speed_file_operations = {
-	.read		= max_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "current bus speed" files */
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations cur_bus_speed_file_operations = {
-	.read		= cur_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "test" files */
-static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations test_file_operations = {
-	.read =		default_read_file,
-	.write =	test_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-static struct inode_operations pcihpfs_dir_inode_operations = {
-	.create =	pcihpfs_create,
-	.lookup =	simple_lookup,
-	.unlink =	pcihpfs_unlink,
-	.mkdir =	pcihpfs_mkdir,
-	.rmdir =	pcihpfs_rmdir,
-	.mknod =	pcihpfs_mknod,
-};
-
-static struct super_operations pcihpfs_ops = {
-	.statfs =	simple_statfs,
-	.drop_inode =	generic_delete_inode,
-};
-
-static int pcihpfs_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 = PCIHPFS_MAGIC;
-	sb->s_op = &pcihpfs_ops;
-	inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		dbg("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, pcihpfs_fill_super);
-}
-
-static struct file_system_type pcihpfs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"pcihpfs",
-	.get_sb =	pcihpfs_get_sb,
-	.kill_sb =	kill_litter_super,
-};
-
-static int get_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	if (pcihpfs_mount) {
-		mntget(pcihpfs_mount);
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-
-	spin_unlock (&mount_lock);
-	mnt = kern_mount (&pcihpfs_type);
-	if (IS_ERR(mnt)) {
-		err ("could not mount the fs...erroring out!\n");
-		return -ENODEV;
-	}
-	spin_lock (&mount_lock);
-	if (!pcihpfs_mount) {
-		pcihpfs_mount = mnt;
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-	mntget(pcihpfs_mount);
-	++pcihpfs_mount_count;
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-
-go_ahead:
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-	return 0;
-}
-
-static void remove_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	mnt = pcihpfs_mount;
-	--pcihpfs_mount_count;
-	if (!pcihpfs_mount_count)
-		pcihpfs_mount = NULL;
-
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-}
-
-
-/**
- * pcihpfs_create_by_name - create a file, given a name
- * @name:	name of file
- * @mode:	type of file
- * @parent:	dentry of directory to create it in
- * @dentry:	resulting dentry of file
- *
- * There is a bit of overhead in creating a file - basically, we 
- * have to hash the name of the file, then look it up. This will
- * prevent files of the same name. 
- * We then call the proper vfs_ function to take care of all the 
- * file creation details. 
- * This function handles both regular files and directories.
- */
-static int pcihpfs_create_by_name (const char *name, mode_t mode,
-				   struct dentry *parent, struct dentry **dentry)
-{
-	struct dentry *d = NULL;
-	struct qstr qstr;
-	int error;
-
-	/* If the parent is not specified, we create it in the root.
-	 * We need the root dentry to do this, which is in the super 
-	 * block. A pointer to that is in the struct vfsmount that we
-	 * have around.
-	 */
-	if (!parent ) {
-		if (pcihpfs_mount && pcihpfs_mount->mnt_sb) {
-			parent = pcihpfs_mount->mnt_sb->s_root;
-		}
-	}
-
-	if (!parent) {
-		dbg("Ah! can not find a parent!\n");
-		return -EINVAL;
-	}
-
-	*dentry = NULL;
-	qstr.name = name;
-	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
-
-	parent = dget(parent);
-
-	down(&parent->d_inode->i_sem);
-
-	d = lookup_hash(&qstr,parent);
-
-	error = PTR_ERR(d);
-	if (!IS_ERR(d)) {
-		switch(mode & S_IFMT) {
-		case 0: 
-		case S_IFREG:
-			error = vfs_create(parent->d_inode,d,mode);
-			break;
-		case S_IFDIR:
-			error = vfs_mkdir(parent->d_inode,d,mode);
-			break;
-		default:
-			err("cannot create special files\n");
-		}
-		*dentry = d;
-	}
-	up(&parent->d_inode->i_sem);
-
-	dput(parent);
-	return error;
-}
-
-static struct dentry *fs_create_file (const char *name, mode_t mode,
-				      struct dentry *parent, void *data,
-				      struct file_operations *fops)
-{
-	struct dentry *dentry;
-	int error;
-
-	dbg("creating file '%s'\n",name);
-
-	error = pcihpfs_create_by_name(name,mode,parent,&dentry);
-	if (error) {
-		dentry = NULL;
-	} else {
-		if (dentry->d_inode) {
-			if (data)
-				dentry->d_inode->u.generic_ip = data;
-			if (fops)
-			dentry->d_inode->i_fop = fops;
-		}
-	}
-
-	return dentry;
-}
-
-static void fs_remove_file (struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	
-	if (!parent || !parent->d_inode)
-		return;
-
-	down(&parent->d_inode->i_sem);
-	if (pcihpfs_positive(dentry)) {
-		if (dentry->d_inode) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				vfs_rmdir(parent->d_inode,dentry);
-			else
-				vfs_unlink(parent->d_inode,dentry);
-		}
-
-		dput(dentry);
-	}
-	up(&parent->d_inode->i_sem);
-}
-
 /* Weee, fun with macros... */
 #define GET_STATUS(name,type)	\
 static int get_##name (struct hotplug_slot *slot, type *value)		\
@@ -584,80 +160,27 @@
 GET_STATUS(max_bus_speed, enum pci_bus_speed)
 GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg(" count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_power_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
-
+	retval = sprintf (buf, "%d\n", value);
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lpower;
 	u8 power;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
- 
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lpower = simple_strtoul (buff, NULL, 10);
+	lpower = simple_strtoul (buf, NULL, 10);
 	power = (u8)(lpower & 0xff);
 	dbg ("power = %d\n", power);
 
@@ -683,87 +206,39 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_power = {
+	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = power_read_file,
+	.store = power_write_file
+};
+
+static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_attention_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lattention;
 	u8 attention;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lattention = simple_strtoul (buff, NULL, 10);
+	lattention = simple_strtoul (buf, NULL, 10);
 	attention = (u8)(lattention & 0xff);
 	dbg (" - attention = %d\n", attention);
 
@@ -776,128 +251,63 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
+	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = attention_read_file,
+	.store = attention_write_file
+};
+
+static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_latch_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = latch_read_file,
+};
+
+static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_adapter_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = presence_read_file,
+};
+
 static char *unknown_speed = "Unknown bus speed";
 
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 	
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_max_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -907,47 +317,23 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = max_bus_speed_read_file,
+};
+
+static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_cur_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -957,51 +343,25 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = cur_bus_speed_read_file,
+};
+
+static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long ltest;
 	u32 test;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	ltest = simple_strtoul (buff, NULL, 10);
+	ltest = simple_strtoul (buf, NULL, 10);
 	test = (u32)(ltest & 0xffffffff);
 	dbg ("test = %d\n", test);
 
@@ -1014,104 +374,130 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_test = {
+	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.store = test_write_file
+};
+
+static int has_power_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		return 0;
+	return -ENOENT;
+}
+
+static int has_attention_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		return 0;
+	return -ENOENT;
+}
+
+static int has_latch_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_latch_status)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_adapter_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_adapter_status)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_max_bus_speed_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_max_bus_speed)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_cur_bus_speed_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->get_cur_bus_speed)
+		return 0;
+	return -ENOENT;
+}
+
+static int has_test_file (struct hotplug_slot *slot)
+{
+	if ((!slot) || (!slot->ops))
+		return -ENODEV;
+	if (slot->ops->hardware_test)
+		return 0;
+	return -ENOENT;
+}
+
 static int fs_add_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
-	int result;
+	if (has_power_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if (has_attention_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (has_latch_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
+
+	if (has_adapter_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (has_max_bus_speed_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (has_cur_bus_speed_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (has_test_file(slot) == 0)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 
-	result = get_mount();
-	if (result)
-		return result;
-
-	core->dir_dentry = fs_create_file (slot->name,
-					   S_IFDIR | S_IXUGO | S_IRUGO,
-					   NULL, NULL, NULL);
-	if (core->dir_dentry != NULL) {
-		if ((slot->ops->enable_slot) ||
-		    (slot->ops->disable_slot) ||
-		    (slot->ops->get_power_status))
-			core->power_dentry = 
-				fs_create_file ("power",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&power_file_operations);
-
-		if ((slot->ops->set_attention_status) ||
-		    (slot->ops->get_attention_status))
-			core->attention_dentry =
-				fs_create_file ("attention",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&attention_file_operations);
-
-		if (slot->ops->get_latch_status)
-			core->latch_dentry = 
-				fs_create_file ("latch",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&latch_file_operations);
-
-		if (slot->ops->get_adapter_status)
-			core->adapter_dentry = 
-				fs_create_file ("adapter",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&presence_file_operations);
-
-		if (slot->ops->get_max_bus_speed)
-			core->max_bus_speed_dentry = 
-				fs_create_file ("max_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&max_bus_speed_file_operations);
-
-		if (slot->ops->get_cur_bus_speed)
-			core->cur_bus_speed_dentry =
-				fs_create_file ("cur_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&cur_bus_speed_file_operations);
-
-		if (slot->ops->hardware_test)
-			core->test_dentry =
-				fs_create_file ("test",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&test_file_operations);
-	}
 	return 0;
 }
 
 static void fs_remove_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
+	if (has_power_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
 
-	if (core->dir_dentry) {
-		if (core->power_dentry)
-			fs_remove_file (core->power_dentry);
-		if (core->attention_dentry)
-			fs_remove_file (core->attention_dentry);
-		if (core->latch_dentry)
-			fs_remove_file (core->latch_dentry);
-		if (core->adapter_dentry)
-			fs_remove_file (core->adapter_dentry);
-		if (core->max_bus_speed_dentry)
-			fs_remove_file (core->max_bus_speed_dentry);
-		if (core->cur_bus_speed_dentry)
-			fs_remove_file (core->cur_bus_speed_dentry);
-		if (core->test_dentry)
-			fs_remove_file (core->test_dentry);
-		fs_remove_file (core->dir_dentry);
-	}
+	if (has_attention_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (has_latch_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	remove_mount();
+	if (has_adapter_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (has_max_bus_speed_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (has_cur_bus_speed_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (has_test_file(slot) == 0)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 }
 
 static struct hotplug_slot *get_slot_from_name (const char *name)
@@ -1138,7 +524,6 @@
  */
 int pci_hp_register (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core;
 	int result;
 
 	if (slot == NULL)
@@ -1146,21 +531,21 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
-	if (!core)
-		return -ENOMEM;
-
 	/* make sure we have not already registered this slot */
 	spin_lock (&list_lock);
 	if (get_slot_from_name (slot->name) != NULL) {
 		spin_unlock (&list_lock);
-		kfree (core);
 		return -EINVAL;
 	}
 
-	memset (core, 0, sizeof (struct hotplug_slot_core));
-	slot->core_priv = core;
+	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	if (kobject_register(&slot->kobj)) {
+		err("Unable to register kobject");
+		return -EINVAL;
+	}
+		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
 	spin_unlock (&list_lock);
 
@@ -1197,68 +582,56 @@
 	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
-	kfree(slot->core_priv);
 	dbg ("Removed slot %s from the list\n", slot->name);
+	kobject_unregister(&slot->kobj);
 	return 0;
 }
 
-static inline void update_dentry_inode_time (struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		inode->i_mtime = CURRENT_TIME;
-		dnotify_parent(dentry, DN_MODIFY);
-	}
-}
-
 /**
  * pci_hp_change_slot_info - changes the slot's information structure in the core
- * @name: the name of the slot whose info has changed
+ * @slot: pointer to the slot whose info has changed
  * @info: pointer to the info copy into the slot's info structure
  *
- * A slot with @name must have been registered with the pci 
+ * @slot must have been registered with the pci 
  * hotplug subsystem previously with a call to pci_hp_register().
  *
  * Returns 0 if successful, anything else for an error.
  */
-int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
+int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info)
 {
-	struct hotplug_slot *temp;
-	struct hotplug_slot_core *core;
-
-	if (info == NULL)
+	if ((slot == NULL) || (info == NULL))
 		return -ENODEV;
 
-	spin_lock (&list_lock);
-	temp = get_slot_from_name (name);
-	if (temp == NULL) {
-		spin_unlock (&list_lock);
-		return -ENODEV;
-	}
-
 	/*
-	 * check all fields in the info structure, and update timestamps
-	 * for the files referring to the fields that have now changed.
-	 */
-	core = temp->core_priv;
-	if ((core->power_dentry) &&
-	    (temp->info->power_status != info->power_status))
-		update_dentry_inode_time (core->power_dentry);
-	if ((core->attention_dentry) &&
-	    (temp->info->attention_status != info->attention_status))
-		update_dentry_inode_time (core->attention_dentry);
-	if ((core->latch_dentry) &&
-	    (temp->info->latch_status != info->latch_status))
-		update_dentry_inode_time (core->latch_dentry);
-	if ((core->adapter_dentry) &&
-	    (temp->info->adapter_status != info->adapter_status))
-		update_dentry_inode_time (core->adapter_dentry);
-	if ((core->cur_bus_speed_dentry) &&
-	    (temp->info->cur_bus_speed != info->cur_bus_speed))
-		update_dentry_inode_time (core->cur_bus_speed_dentry);
+	* check all fields in the info structure, and update timestamps
+	* for the files referring to the fields that have now changed.
+	*/
+	if ((has_power_file(slot) == 0) &&
+	    (slot->info->power_status != info->power_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((has_attention_file(slot) == 0) &&
+	    (slot->info->attention_status != info->attention_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if ((has_latch_file(slot) == 0) &&
+	    (slot->info->latch_status != info->latch_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
+
+	if ((has_adapter_file(slot) == 0) &&
+	    (slot->info->adapter_status != info->adapter_status))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if ((has_max_bus_speed_file(slot) == 0) &&
+	    (slot->info->max_bus_speed != info->max_bus_speed))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if ((has_cur_bus_speed_file(slot) == 0) &&
+	    (slot->info->cur_bus_speed != info->cur_bus_speed))
+		sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
 
-	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
-	spin_unlock (&list_lock);
 	return 0;
 }
 
@@ -1266,32 +639,25 @@
 {
 	int result;
 
-	spin_lock_init(&mount_lock);
 	spin_lock_init(&list_lock);
 
-	dbg("registering filesystem.\n");
-	result = register_filesystem(&pcihpfs_type);
+	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+	result = subsystem_register(&hotplug_slots_subsys);
 	if (result) {
-		err("register_filesystem failed with %d\n", result);
+		err("Register subsys with error %d\n", result);
 		goto exit;
 	}
-
 	result = cpci_hotplug_init(debug);
 	if (result) {
 		err ("cpci_hotplug_init with error %d\n", result);
-		goto error_fs;
+		goto err_subsys;
 	}
 
-#ifdef CONFIG_PROC_FS
-	/* create mount point for pcihpfs */
-	slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir);
-#endif
-
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	goto exit;
 	
-error_fs:
-	unregister_filesystem(&pcihpfs_type);
+err_subsys:
+	subsystem_unregister(&hotplug_slots_subsys);
 exit:
 	return result;
 }
@@ -1299,13 +665,7 @@
 static void __exit pci_hotplug_exit (void)
 {
 	cpci_hotplug_exit();
-
-	unregister_filesystem(&pcihpfs_type);
-
-#ifdef CONFIG_PROC_FS
-	if (slotdir)
-		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
-#endif
+	subsystem_unregister(&hotplug_slots_subsys);
 }
 
 module_init(pci_hotplug_init);
@@ -1320,4 +680,3 @@
 EXPORT_SYMBOL_GPL(pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
-
diff -Nru a/drivers/hotplug/pci_hotplug_util.c b/drivers/hotplug/pci_hotplug_util.c
--- a/drivers/hotplug/pci_hotplug_util.c	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,217 +0,0 @@
-/*
- * PCI HotPlug Utility functions
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * 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, 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.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include "pci_hotplug.h"
-
-
-#if !defined(CONFIG_HOTPLUG_PCI_MODULE)
-	#define MY_NAME	"pci_hotplug"
-#else
-	#define MY_NAME	THIS_MODULE->name
-#endif
-
-#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
-
-
-/* local variables */
-static int debug;
-
-
-/*
- * This is code that scans the pci buses.
- * Every bus and every function is presented to a custom
- * function that can act upon it.
- */
-
-static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
-{
-	struct list_head *ln;
-	struct pci_dev *dev;
-	struct pci_dev_wrapped wrapped_dev;
-	int result = 0;
-
-	dbg("scanning bus %02x\n", wrapped_bus->bus->number);
-
-	if (fn->pre_visit_pci_bus) {
-		result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
-		if (result)
-			return result;
-	}
-
-	ln = wrapped_bus->bus->devices.next; 
-	while (ln != &wrapped_bus->bus->devices) {
-		dev = pci_dev_b(ln);
-		ln = ln->next;
-
-		memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-		wrapped_dev.dev = dev;
-
-		result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
-		if (result)
-			return result;
-	}
-
-	if (fn->post_visit_pci_bus)
-		result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
-
-	return result;
-}
-
-
-static int pci_visit_bridge (struct pci_visit * fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
-{
-	struct pci_bus *bus;
-	struct pci_bus_wrapped wrapped_bus;
-	int result = 0;
-
-	dbg("scanning bridge %02x, %02x\n", PCI_SLOT(wrapped_dev->dev->devfn),
-	    PCI_FUNC(wrapped_dev->dev->devfn));
-
-	if (fn->visit_pci_dev) {
-		result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
-		if (result)
-			return result;
-	}
-
-	bus = wrapped_dev->dev->subordinate;
-	if(bus) {
-		memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-		wrapped_bus.bus = bus;
-
-		result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
-	}
-	return result;
-}
-
-
-int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
-{
-	struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
-	int result = 0;
-
-	if (!dev)
-		return 0;
-
-	if (fn->pre_visit_pci_dev) {
-		result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
-		if (result)
-			return result;
-	}
-
-	switch (dev->class >> 8) {
-		case PCI_CLASS_BRIDGE_PCI:
-			result = pci_visit_bridge(fn, wrapped_dev,
-						  wrapped_parent);
-			if (result)
-				return result;
-			break;
-		default:
-			dbg("scanning device %02x, %02x\n",
-			    PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-			if (fn->visit_pci_dev) {
-				result = fn->visit_pci_dev (wrapped_dev,
-							    wrapped_parent);
-				if (result)
-					return result;
-			}
-	}
-
-	if (fn->post_visit_pci_dev)
-		result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
-
-	return result;
-}
-
-/**
- * pci_is_dev_in_use - query devices' usage
- * @dev: PCI device to query
- *
- * Queries whether a given PCI device is in use by a driver or not.
- * Returns 1 if the device is in use, 0 if it is not.
- */
-int pci_is_dev_in_use(struct pci_dev *dev)
-{
-	/* 
-	 * dev->driver will be set if the device is in use by a new-style 
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them.
-	 */
-
-	int i;
-	int inuse = 0;
-
-	if (dev->driver) {
-		/* Assume driver feels responsible */
-		return 1;
-	}
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		} else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-		}
-	}
-	return inuse;
-}
-
-/**
- * pci_remove_device_safe - remove an unused hotplug device
- * @dev: the device to remove
- *
- * Delete the device structure from the device lists and 
- * notify userspace (/sbin/hotplug), but only if the device
- * in question is not being used by a driver.
- * Returns 0 on success.
- */
-int pci_remove_device_safe(struct pci_dev *dev)
-{
-	if (pci_is_dev_in_use(dev)) {
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-EXPORT_SYMBOL(pci_visit_dev);
-EXPORT_SYMBOL(pci_is_dev_in_use);
-EXPORT_SYMBOL(pci_remove_device_safe);
-
diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/i2c/Kconfig	Mon Feb 10 10:39:24 2003
@@ -27,7 +27,7 @@
 	  This I2C support is also available as a module.  If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-core.o.
+	  The module will be called i2c-core.
 
 config I2C_ALGOBIT
 	tristate "I2C bit-banging interfaces"
@@ -40,7 +40,7 @@
 	  This support is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-bit.o.
+	  The module will be called i2c-algo-bit.
 
 config I2C_PHILIPSPAR
 	tristate "Philips style parallel port adapter"
@@ -52,7 +52,7 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-philips-par.o.
+	  The module will be called i2c-philips-par.
 
 	  Note that if you want support for different parallel port devices,
 	  life will be much easier if you compile them all as modules.
@@ -67,7 +67,7 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elv.o.
+	  The module will be called i2c-elv.
 
 config I2C_VELLEMAN
 	tristate "Velleman K9000 adapter"
@@ -79,7 +79,7 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-velleman.o.
+	  The module will be called i2c-velleman.
 
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
@@ -89,7 +89,7 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_i2c.o.
+	  If compiled as a module, it will be called scx200_i2c.
 
 config SCx200_I2C_SCL
 	int "GPIO pin used for SCL"
@@ -115,7 +115,7 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_acb.o.
+	  If compiled as a module, it will be called scx200_acb.
 
 config I2C_ALGOPCF
 	tristate "I2C PCF 8584 interfaces"
@@ -128,7 +128,7 @@
 	  This support is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-pcf.o.
+	  The module will be called i2c-algo-pcf.
 
 config I2C_ELEKTOR
 	tristate "Elektor ISA card"
@@ -140,15 +140,31 @@
 	  This driver is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elektor.o.
+	  The module will be called i2c-elektor.
 
 config ITE_I2C_ALGO
 	tristate "ITE I2C Algorithm"
 	depends on MIPS_ITE8172 && I2C
+	help
+	  This supports the use of the ITE8172 I2C interface found on some MIPS
+	  systems. Say Y if you have one of these. You should also say Y for
+	  the ITE I2C peripheral driver support below.
+
+	  This support is also available as a module. If you want to compile
+	  it as a module, say M here and read Documentation/modules.txt.
+	  The module will be called i2c-algo-ite.
 
 config ITE_I2C_ADAP
 	tristate "ITE I2C Adapter"
 	depends on ITE_I2C_ALGO
+	help
+	  This supports the ITE8172 I2C peripheral found on some MIPS
+	  systems. Say Y if you have one of these. You should also say Y for
+	  the ITE I2C driver algorithm support above.
+
+	  This support is also available as a module. If you want to compile
+	  it as a module, say M here and read Documentation/modules.txt.
+	  The module will be called i2c-adap-ite.
 
 config I2C_ALGO8XX
 	tristate "MPC8xx CPM I2C interface"
@@ -178,7 +194,7 @@
 	  This code is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-dev.o.
+	  The module will be called i2c-dev.
 
 config I2C_PROC
 	tristate "I2C /proc interface (required for hardware sensors)"
@@ -189,7 +205,7 @@
 
 	  This code is also available as a module. If you want to compile
 	  it as a module, say M here and read <file:Documentation/modules.txt>.
-	  The module will be called i2c-proc.o.
+	  The module will be called i2c-proc.
 
 	source drivers/i2c/busses/Kconfig
 	source drivers/i2c/chips/Kconfig
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/i2c/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,9 +2,6 @@
 # Makefile for the kernel i2c bus driver.
 #
 
-export-objs	:= i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
-		   i2c-algo-ite.o i2c-proc.o i2c-algo-ibm_ocp.o
-
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Feb 10 10:39:31 2003
@@ -16,7 +16,7 @@
 	  while the kernel is running.  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
-	  The module will be called i2c-amd756.o.
+	  The module will be called i2c-amd756.
 
 	  You will also need the latest user-space utilties: you can find them
 	  in the lm_sensors package, which you can download at 
@@ -33,7 +33,7 @@
 	  while the kernel is running.  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
-	  The module will be called i2c-amd8111.o.
+	  The module will be called i2c-amd8111.
 
 	  You will also need the latest user-space utilties: you can find them
 	  in the lm_sensors package, which you can download at 
diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/drivers/i2c/chips/Kconfig	Mon Feb 10 10:39:27 2003
@@ -16,7 +16,7 @@
 	  be built as a module which can be inserted and removed while the 
 	  kernel is running.
 
-	  The module will be called adm1021.o.
+	  The module will be called adm1021.
 	  
 	  You will also need the latest user-space utilties: you can find them
 	  in the lm_sensors package, which you can download at 
@@ -31,7 +31,7 @@
 	  TCN75, and National Semi LM77. This can also be built as a module
 	  which can be inserted and removed while the kernel is running.
 
-	  The module will be called lm75.o.
+	  The module will be called lm75.
 
 	  You will also need the latest user-space utilties: you can find them
 	  in the lm_sensors package, which you can download at 
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/i2c/i2c-core.c	Mon Feb 10 10:39:23 2003
@@ -57,7 +57,7 @@
 
 /**** lock for writing to global variables: the adapter & driver list */
 DECLARE_MUTEX(adap_lock);
-DECLARE_MUTEX(driver_lock);
+static DECLARE_MUTEX(driver_lock);
 
 /**** adapter list */
 static struct i2c_adapter *adapters[I2C_ADAP_MAX];
diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
--- a/drivers/i2c/i2c-proc.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/i2c/i2c-proc.c	Mon Feb 10 10:39:27 2003
@@ -39,7 +39,7 @@
 			       struct i2c_adapter *adapter, int addr);
 static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
 			       long *results, int magnitude);
-static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
 			       long *results, int magnitude);
 static int i2c_proc_chips(ctl_table * ctl, int write,
 			      struct file *filp, void *buffer,
@@ -514,7 +514,7 @@
 	return 0;
 }
 
-int i2c_write_reals(int nrels, void *buffer, int *bufsize,
+int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
 			 long *results, int magnitude)
 {
 #define BUFLEN 20
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/drivers/ide/Kconfig	Mon Feb 10 10:39:27 2003
@@ -31,7 +31,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/ide.txt>. The module will be called ide-mod.o.
+	  <file:Documentation/ide.txt>. The module will be called ide-mod.
 	  Do not compile this driver as a module if your root file system (the
 	  one containing the directory /) is located on an IDE device.
 
@@ -77,7 +77,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ide-disk.o.  Do not compile this driver as a module
+	  will be called ide-disk.  Do not compile this driver as a module
 	  if your root file system (the one containing the directory /) is
 	  located on the IDE disk. If unsure, say Y.
 
@@ -136,7 +136,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ide-cd.o.
+	  will be called ide-cd.
 
 #dep_tristate '  Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
 config BLK_DEV_IDEFLOPPY
@@ -162,7 +162,7 @@
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ide-floppy.o.
+	  will be called ide-floppy.
 
 config BLK_DEV_IDESCSI
 	tristate "SCSI emulation support"
@@ -193,6 +193,13 @@
 config IDE_TASK_IOCTL
 	bool "IDE Taskfile Access"
 	depends on BLK_DEV_IDE
+	help
+	  This is a direct raw access to the media.  It is a complex but
+	  elegant solution to test and validate the domain of the hardware and
+	  perform below the driver data recover if needed.  This is the most
+	  basic form of media-forensics.
+
+	  If you are unsure, say N here.
 
 #bool '  IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO
 comment "IDE chipset support/bugfixes"
@@ -245,6 +252,10 @@
 	bool "PCI IDE chipset support" if PCI
 	depends on BLK_DEV_IDE
 	default BLK_DEV_IDEDMA_PMAC if ALL_PPC && BLK_DEV_IDEDMA_PMAC
+	help
+	  Say Y here for PCI systems which use IDE drive(s).
+	  This option helps the IDE driver to automatically detect and
+	  configure all PCI-based IDE interfaces in your system.
 
 config BLK_DEV_GENERIC
 	bool "Generic PCI IDE Chipset Support"
@@ -347,6 +358,10 @@
 config BLK_DEV_IDEDMA_FORCED
 	bool "Force enable legacy 2.0.X HOSTS to use DMA"
 	depends on BLK_DEV_IDEDMA_PCI
+	help
+	  This is an old piece of lost code from Linux 2.0 Kernels.
+
+	  Generally say N here.
 
 config IDEDMA_PCI_AUTO
 	bool "Use PCI DMA by default when available"
@@ -383,6 +398,12 @@
 config IDEDMA_PCI_WIP
 	bool "ATA Work(s) In Progress (EXPERIMENTAL)"
 	depends on BLK_DEV_IDEDMA_PCI && EXPERIMENTAL
+	help
+	  If you enable this you will be able to use and test highly
+	  developmental projects. If you say N, the configurator will
+	  simply skip those options.
+
+	  It is SAFEST to say N to this question.
 
 config IDEDMA_NEW_DRIVE_LISTINGS
 	bool "Good-Bad DMA Model-Firmware (WIP)"
@@ -656,6 +677,18 @@
 config BLK_DEV_SLC90E66
 	tristate "SLC90E66 chipset support"
 	depends on BLK_DEV_IDEDMA_PCI
+	help
+	  This driver ensures (U)DMA support for Victroy66 SouthBridges for
+	  SMsC with Intel NorthBridges.  This is an Ultra66 based chipset.
+	  The nice thing about it is that you can mix Ultra/DMA/PIO devices
+	  and it will handle timing cycles.  Since this is an improved
+	  look-a-like to the PIIX4 it should be a nice addition.
+
+	  If you say Y here, you need to say Y to "Use DMA by default when
+	  available" as well.
+
+	  Please read the comments at the top of
+	  drivers/ide/slc90e66.c.
 
 config BLK_DEV_TRM290
 	tristate "Tekram TRM290 chipset support"
@@ -880,6 +913,12 @@
 config BLK_DEV_4DRIVES
 	bool "Generic 4 drives/port support"
 	depends on IDE_CHIPSETS
+	help
+	  Certain older chipsets, including the Tekram 690CD, use a single set
+	  of I/O ports at 0x1f0 to control up to four drives, instead of the
+	  customary two drives per port. Support for this can be enabled at
+	  runtime using the "ide0=four" kernel boot parameter if you say Y
+	  here.
 
 config BLK_DEV_ALI14XX
 	tristate "ALI M14xx support"
diff -Nru a/drivers/ide/Makefile b/drivers/ide/Makefile
--- a/drivers/ide/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/ide/Makefile	Mon Feb 10 10:39:27 2003
@@ -7,8 +7,6 @@
 # Note : at this point, these files are compiled on all systems.
 # In the future, some of these should be built conditionally.
 #
-export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o
-
 # First come modules that register themselves with the core
 obj-$(CONFIG_BLK_DEV_IDEPCI)		+= pci/
 
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/ide/pci/amd74xx.c	Mon Feb 10 10:39:33 2003
@@ -82,7 +82,7 @@
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-static int amd_base;
+static long amd_base;
 static struct pci_dev *bmide_dev;
 extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
 
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/ide/pci/pdc202xx_new.c	Mon Feb 10 10:39:30 2003
@@ -339,7 +339,7 @@
 	 * fall back to U33 mode. The BIOS INT 13 hooks turn
 	 * the clock on then off for each read/write issued. I don't
 	 * do that here because it would require modifying the
-	 * kernel, seperating the fop routines from the kernel or
+	 * kernel, separating the fop routines from the kernel or
 	 * somehow hooking the fops calls. It may also be possible to
 	 * leave the 66Mhz clock on and readjust the timing
 	 * parameters.
diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
--- a/drivers/ide/pci/pdc202xx_old.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/ide/pci/pdc202xx_old.c	Mon Feb 10 10:39:33 2003
@@ -400,7 +400,7 @@
 	 * fall back to U33 mode. The BIOS INT 13 hooks turn
 	 * the clock on then off for each read/write issued. I don't
 	 * do that here because it would require modifying the
-	 * kernel, seperating the fop routines from the kernel or
+	 * kernel, separating the fop routines from the kernel or
 	 * somehow hooking the fops calls. It may also be possible to
 	 * leave the 66Mhz clock on and readjust the timing
 	 * parameters.
diff -Nru a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
--- a/drivers/ide/pci/sis5513.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/ide/pci/sis5513.c	Mon Feb 10 10:39:27 2003
@@ -22,7 +22,7 @@
 
 /*
  * TODO:
- *	- Get ridden of SisHostChipInfo[] completness dependancy.
+ *	- Get ridden of SisHostChipInfo[] completness dependency.
  *	- Study drivers/ide/ide-timing.h.
  *	- Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
  *	  or remove ATA_00 define
@@ -64,7 +64,7 @@
 /* Miscellaneaous flags */
 #define SIS5513_LATENCY		0x01
 
-/* registers layout and init values are chipset family dependant */
+/* registers layout and init values are chipset family dependent */
 /* 1/ define families */
 #define ATA_00		0x00
 #define ATA_16		0x01
diff -Nru a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
--- a/drivers/ieee1394/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/ieee1394/Kconfig	Mon Feb 10 10:39:23 2003
@@ -18,7 +18,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ieee1394.o.
+	  will be called ieee1394.
 
 comment "Subsystem Options"
 	depends on IEEE1394
@@ -67,7 +67,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called pcilynx.o.
+	  will be called pcilynx.
 
 # Non-maintained pcilynx options
 # if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then
@@ -87,7 +87,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ohci1394.o.
+	  will be called ohci1394.
 
 comment "Protocol Drivers"
 	depends on IEEE1394
@@ -131,7 +131,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called dv1394.o.
+	  will be called dv1394.
 
 config IEEE1394_RAWIO
 	tristate "Raw IEEE1394 I/O support"
@@ -145,7 +145,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called raw1394.o.
+	  will be called raw1394.
 
 config IEEE1394_CMP
 	tristate "IEC61883-1 Plug support"
@@ -157,7 +157,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called amdtp.o.
+	  will be called amdtp.
 
 config IEEE1394_AMDTP
 	tristate "IEC61883-6 (Audio transmission) support"
@@ -172,6 +172,6 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called amdtp.o.
+	  will be called amdtp.
 
 endmenu
diff -Nru a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
--- a/drivers/ieee1394/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/ieee1394/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux IEEE 1394 implementation
 #
 
-export-objs := ieee1394_core.o ohci1394.o cmp.o
-
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
 		 highlevel.o csr.o nodemgr.o oui.o dma.o iso.o
 
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/ieee1394/sbp2.c	Mon Feb 10 10:39:23 2003
@@ -829,7 +829,7 @@
 {
 	struct sbp2scsi_host_info *hi;
 	
-	hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->host->hostdata[0];
+	hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->device->host->hostdata[0];
 
 	if (hi == NULL) {
 		printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__);
@@ -2659,7 +2659,7 @@
 	/*
 	 * Pull our host info and scsi id instance data from the scsi command
 	 */
-	hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
+	hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
 
 	if (!hi) {
 		SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
@@ -2668,7 +2668,7 @@
 		return(0);
 	}
 
-	scsi_id = hi->scsi_id[SCpnt->target];
+	scsi_id = hi->scsi_id[SCpnt->device->id];
 
 	/*
 	 * If scsi_id is null, it means there is no device in this slot,
@@ -2684,7 +2684,7 @@
 	 * Until we handle multiple luns, just return selection time-out
 	 * to any IO directed at non-zero LUNs
 	 */
-	if (SCpnt->lun) {
+	if (SCpnt->device->lun) {
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done (SCpnt);
 		return(0);
@@ -2882,8 +2882,8 @@
  */
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) 
 {
-	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
-	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->target];
+	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
+	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
 	struct sbp2_command_info *command;
 	unsigned long flags;
 
@@ -2932,8 +2932,8 @@
  */
 static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) 
 {
-	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
-	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->target];
+	struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0];
+	struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id];
 
 	SBP2_ERR("reset requested");
 
diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig
--- a/drivers/input/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/input/Kconfig	Mon Feb 10 10:39:23 2003
@@ -21,7 +21,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called input.o. If you want to compile it as a
+	  The module will be called input. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 comment "Userland interfaces"
@@ -41,7 +41,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mousedev.o. If you want to compile it as
+	  The module will be called mousedev. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_MOUSEDEV_PSAUX
@@ -82,7 +82,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called joydev.o. If you want to compile it as a
+	  The module will be called joydev. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_TSDEV
@@ -97,7 +97,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tsdev.o. If you want to compile it as a
+	  The module will be called tsdev. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_TSDEV_SCREEN_X
@@ -119,7 +119,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called evdev.o. If you want to compile it as a
+	  The module will be called evdev. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_EVBUG
@@ -136,7 +136,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called joydev.o. If you want to compile it as a
+	  The module will be called joydev. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 comment "Input I/O drivers"
diff -Nru a/drivers/input/Makefile b/drivers/input/Makefile
--- a/drivers/input/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/input/Makefile	Mon Feb 10 10:39:32 2003
@@ -2,10 +2,6 @@
 # Makefile for the input core drivers.
 #
 
-# Objects that export symbols.
-
-export-objs	:= input.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_INPUT)		+= input.o
diff -Nru a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
--- a/drivers/input/gameport/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/input/gameport/Kconfig	Mon Feb 10 10:39:23 2003
@@ -18,7 +18,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gameport.o. If you want to compile it as
+	  The module will be called gameport. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SOUND_GAMEPORT
@@ -36,7 +36,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ns558.o. If you want to compile it as a
+	  The module will be called ns558. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config GAMEPORT_L4
@@ -47,7 +47,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called lightning.o. If you want to compile it as
+	  The module will be called lightning. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config GAMEPORT_EMU10K1
@@ -59,7 +59,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called emu10k1-gp.o. If you want to compile it as
+	  The module will be called emu10k1-gp. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config GAMEPORT_VORTEX
@@ -71,7 +71,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called vortex.o. If you want to compile it as a
+	  The module will be called vortex. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config GAMEPORT_FM801
diff -Nru a/drivers/input/gameport/Makefile b/drivers/input/gameport/Makefile
--- a/drivers/input/gameport/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/input/gameport/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,10 +2,6 @@
 # Makefile for the gameport drivers.
 #
 
-# Objects that export symbols.
-
-export-objs	:= gameport.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_GAMEPORT)		+= gameport.o
diff -Nru a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
--- a/drivers/input/joystick/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/input/joystick/Kconfig	Mon Feb 10 10:39:23 2003
@@ -29,7 +29,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called analog.o. If you want to compile it as a
+	  The module will be called analog. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_A3D
@@ -41,7 +41,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called a3d.o. If you want to compile it as a
+	  The module will be called a3d. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_ADI
@@ -53,7 +53,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called adi.o. If you want to compile it as a
+	  The module will be called adi. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_COBRA
@@ -64,7 +64,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cobra.o. If you want to compile it as a
+	  The module will be called cobra. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_GF2K
@@ -76,7 +76,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gf2k.o. If you want to compile it as a
+	  The module will be called gf2k. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_GRIP
@@ -88,7 +88,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called grip.o. If you want to compile it as a
+	  The module will be called grip. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_GRIP_MP
@@ -100,7 +100,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called grip_mp.o. If you want to compile it as a
+	  The module will be called grip_mp. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_GUILLEMOT
@@ -112,7 +112,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called guillemot.o. If you want to compile it as a
+	  The module will be called guillemot. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_INTERACT
@@ -124,7 +124,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called interact.o. If you want to compile it as
+	  The module will be called interact. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_SIDEWINDER
@@ -136,7 +136,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sidewinder.o. If you want to compile it
+	  The module will be called sidewinder. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_TMDC
@@ -148,7 +148,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tmdc.o. If you want to compile it as a
+	  The module will be called tmdc. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/input/joystick/iforce/Kconfig"
@@ -162,7 +162,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called warrior.o. If you want to compile it as a
+	  The module will be called warrior. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_MAGELLAN
@@ -174,7 +174,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called magellan.o. If you want to compile it as
+	  The module will be called magellan. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_SPACEORB
@@ -186,7 +186,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called spaceorb.o. If you want to compile it as
+	  The module will be called spaceorb. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_SPACEBALL
@@ -199,7 +199,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called spaceball.o. If you want to compile it as
+	  The module will be called spaceball. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_STINGER
@@ -211,7 +211,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called stinger.o. If you want to compile it as a
+	  The module will be called stinger. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_TWIDDLER
@@ -223,7 +223,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called twidjoy.o. If you want to compile it as a
+	  The module will be called twidjoy. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_DB9
@@ -238,7 +238,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called db9.o. If you want to compile it as a
+	  The module will be called db9. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_GAMECON
@@ -254,7 +254,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gamecon.o. If you want to compile it as a
+	  The module will be called gamecon. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_TURBOGRAFX
@@ -268,7 +268,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called turbografx.o. If you want to compile it
+	  The module will be called turbografx. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_AMIGA
@@ -280,7 +280,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called amijoy.o. If you want to compile it as
+	  The module will be called amijoy. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_JOYDUMP
@@ -293,6 +293,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called joydump.o. If you want to compile it as
+	  The module will be called joydump. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig
--- a/drivers/input/joystick/iforce/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/input/joystick/iforce/Kconfig	Mon Feb 10 10:39:24 2003
@@ -11,7 +11,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called iforce.o. If you want to compile it as a
+	  The module will be called iforce. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config JOYSTICK_IFORCE_USB
diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
--- a/drivers/input/keyboard/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/input/keyboard/Kconfig	Mon Feb 10 10:39:33 2003
@@ -25,7 +25,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called atkbd.o. If you want to compile it as a
+	  The module will be called atkbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config KEYBOARD_SUNKBD
@@ -38,7 +38,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sunkbd.o. If you want to compile it as a
+	  The module will be called sunkbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config KEYBOARD_XTKBD
@@ -52,7 +52,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called xtkbd.o. If you want to compile it as a
+	  The module will be called xtkbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config KEYBOARD_NEWTON
@@ -63,7 +63,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called maple_keyb.o. If you want to compile it as a
+	  The module will be called maple_keyb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config KEYBOARD_MAPLE
@@ -75,7 +75,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called maple_keyb.o. If you want to compile it as a
+	  The module will be called maple_keyb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config KEYBOARD_AMIGA
@@ -87,6 +87,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called amikbd.o. If you want to compile it as a
+	  The module will be called amikbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	Mon Feb 10 10:39:26 2003
+++ b/drivers/input/misc/Kconfig	Mon Feb 10 10:39:26 2003
@@ -23,7 +23,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pcspkr.o. If you want to compile it as a
+	  The module will be called pcspkr. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_SPARCSPKR
@@ -37,7 +37,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pcspkr.o. If you want to compile it as a
+	  The module will be called pcspkr. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config INPUT_M68K_BEEP
@@ -53,7 +53,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called uinput.o.  If you want to compile it as a
+	  The module will be called uinput.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.	    
 
 config INPUT_GSC
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/input/mouse/Kconfig	Mon Feb 10 10:39:31 2003
@@ -25,7 +25,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called psmouse.o. If you want to compile it as a
+	  The module will be called psmouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config MOUSE_SERIAL
@@ -40,7 +40,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sermouse.o. If you want to compile it as a
+	  The module will be called sermouse. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config MOUSE_INPORT
@@ -52,7 +52,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called inport.o. If you want to compile it as a
+	  The module will be called inport. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
 config MOUSE_ATIXL
@@ -70,7 +70,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called logibm.o. If you want to compile it as a
+	  The module will be called logibm. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
 config MOUSE_PC110PAD
@@ -82,7 +82,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pc110pad.o. If you want to compile it as a
+	  The module will be called pc110pad. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
 config MOUSE_MAPLE
@@ -94,7 +94,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called maplemouse.o. If you want to compile it as a
+	  The module will be called maplemouse. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
 config MOUSE_AMIGA
@@ -106,7 +106,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called amimouse.o. If you want to compile it as a
+	  The module will be called amimouse. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
 config MOUSE_RISCPC
@@ -118,6 +118,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rpcmouse.o. If you want to compile it as a
+	  The module will be called rpcmouse. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
diff -Nru a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
--- a/drivers/input/mouse/rpcmouse.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/input/mouse/rpcmouse.c	Mon Feb 10 10:39:26 2003
@@ -88,7 +88,7 @@
 
 	input_register_device(&rpcmouse_dev);
 
-	printk(KERN_INFO "input: Acorn RiscPC mouse irq %d", IRQ_VSYNCPULSE);
+	printk(KERN_INFO "input: Acorn RiscPC mouse\n");
 
 	return 0;
 }
diff -Nru a/drivers/input/power.c b/drivers/input/power.c
--- a/drivers/input/power.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/input/power.c	Mon Feb 10 10:39:30 2003
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
- * Should you need to contact me, the author, you can do so either by
+ * Should you need to contact me, the author, you can do so by
  * e-mail - mail your message to <jsimmons@transvirtual.com>.
  */
 
diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/drivers/input/serio/Kconfig	Mon Feb 10 10:39:27 2003
@@ -15,7 +15,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called serio.o. If you want to compile it
+	  The module will be called serio. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_I8042
@@ -31,7 +31,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called i8042.o. If you want to compile it
+	  The module will be called i8042. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_SERPORT
@@ -48,7 +48,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called serport.o. If you want to compile it as a
+	  The module will be called serport. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_CT82C710
@@ -63,7 +63,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ct82c710.o. If you want to compile it as a
+	  The module will be called ct82c710. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_Q40KBD
@@ -83,7 +83,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called parkbd.o. If you want to compile it as a
+	  The module will be called parkbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_RPCKBD
@@ -96,7 +96,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rpckbd.o. If you want to compile it as a
+	  The module will be called rpckbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SERIO_AMBAKMI
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/input/serio/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,10 +2,6 @@
 # Makefile for the input core drivers.
 #
 
-# Objects that export symbols.
-
-export-objs	:= serio.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_SERIO)		+= serio.o
diff -Nru a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
--- a/drivers/input/touchscreen/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/drivers/input/touchscreen/Kconfig	Mon Feb 10 10:39:27 2003
@@ -20,7 +20,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gunze.o. If you want to compile it as a
+	  The module will be called gunze. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config TOUCHSCREEN_GUNZE
@@ -34,6 +34,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called gunze.o. If you want to compile it as a
+	  The module will be called gunze. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile
--- a/drivers/isdn/capi/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/isdn/capi/Makefile	Mon Feb 10 10:39:27 2003
@@ -1,9 +1,5 @@
 # Makefile for the CAPI subsystem.
 
-# Objects that export symbols.
-
-export-objs	:= kcapi.o capiutil.o capilib.o capifs.o
-
 # Ordering constraints: kernelcapi.o first
 
 # Each configuration option enables a list of files.
diff -Nru a/drivers/isdn/eicon/Makefile b/drivers/isdn/eicon/Makefile
--- a/drivers/isdn/eicon/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/isdn/eicon/Makefile	Mon Feb 10 10:39:24 2003
@@ -1,9 +1,5 @@
 # Makefile for the eicon ISDN device driver
 
-# Objects that export symbols.
-
-export-objs	:= Divas_mod.o eicon_mod.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_ISDN_DRV_EICON_OLD)    	+= eicon.o
diff -Nru a/drivers/isdn/eicon/eicon.h b/drivers/isdn/eicon/eicon.h
--- a/drivers/isdn/eicon/eicon.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/isdn/eicon/eicon.h	Mon Feb 10 10:39:24 2003
@@ -305,7 +305,7 @@
  * Per card driver data
  */
 typedef struct eicon_card {
-	eicon_hwif hwif;                 /* Hardware dependant interface     */
+	eicon_hwif hwif;                 /* Hardware dependent interface     */
 	DESCRIPTOR *d;			 /* IDI Descriptor		     */
         u_char ptype;                    /* Protocol type (1TR6 or Euro)     */
         u_char bus;                      /* Bustype (ISA, MCA, PCI)          */
diff -Nru a/drivers/isdn/hardware/avm/Makefile b/drivers/isdn/hardware/avm/Makefile
--- a/drivers/isdn/hardware/avm/Makefile	Mon Feb 10 10:39:26 2003
+++ b/drivers/isdn/hardware/avm/Makefile	Mon Feb 10 10:39:26 2003
@@ -1,9 +1,5 @@
 # Makefile for the AVM ISDN device drivers
 
-# Objects that export symbols.
-
-export-objs	:= b1dma.o b1pcmcia.o b1.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA)	+= b1isa.o b1.o
diff -Nru a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile
--- a/drivers/isdn/hardware/eicon/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/isdn/hardware/eicon/Makefile	Mon Feb 10 10:39:31 2003
@@ -1,9 +1,5 @@
 # Makefile for the Eicon DIVA ISDN drivers.
 
-# Objects that export symbols.
-
-export-objs     := diva_didd.o
-
 # Multipart objects. 
 
 divas-objs      := divasmain.o divasfunc.o di.o io.o istream.o diva.o dlist.o divasproc.o diva_dma.o
diff -Nru a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
--- a/drivers/isdn/hardware/eicon/diva_didd.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/isdn/hardware/eicon/diva_didd.c	Mon Feb 10 10:39:29 2003
@@ -120,7 +120,7 @@
 	return (0);
 }
 
-static void DIVA_EXIT_FUNCTION remove_proc(void)
+static void remove_proc(void)
 {
 	remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
 	remove_proc_entry(main_proc_dir, proc_net_isdn);
diff -Nru a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h
--- a/drivers/isdn/hardware/eicon/io.h	Mon Feb 10 10:39:33 2003
+++ b/drivers/isdn/hardware/eicon/io.h	Mon Feb 10 10:39:33 2003
@@ -174,7 +174,7 @@
  word                assign;         /* list of pending ASSIGNs  */
  word                head;           /* head of request queue    */
  word                tail;           /* tail of request queue    */
- ADAPTER             a ;             /* not a seperate structure */
+ ADAPTER             a ;             /* not a separate structure */
  void        (* out)(ADAPTER * a) ;
  byte        (* dpc)(ADAPTER * a) ;
  byte        (* tst_irq)(ADAPTER * a) ;
diff -Nru a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
--- a/drivers/isdn/hisax/Makefile	Mon Feb 10 10:39:25 2003
+++ b/drivers/isdn/hisax/Makefile	Mon Feb 10 10:39:25 2003
@@ -4,10 +4,6 @@
 
 EXTRA_CFLAGS      += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS)
 
-# Objects that export symbols.
-
-export-objs	  := config.o hisax_isac.o hisax_hscx.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_ISDN_DRV_HISAX)		+= hisax.o
diff -Nru a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
--- a/drivers/isdn/hisax/isdnl2.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/isdn/hisax/isdnl2.c	Mon Feb 10 10:39:24 2003
@@ -1445,7 +1445,7 @@
 }
 
 static void
-l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 	
@@ -1456,7 +1456,7 @@
 }
 
 static void
-l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
@@ -1469,7 +1469,7 @@
 }
 
 static void
-l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
@@ -1480,7 +1480,7 @@
 }
 
 static void
-l2_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
@@ -1615,14 +1615,14 @@
 	{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
 	{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
 	{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
-	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da},
+	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
 	{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
 	{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
-	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},
-	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},
-	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da},
-	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},
-	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
+	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
+	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
+	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
+	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
+	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
 };
 
 #define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
diff -Nru a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
--- a/drivers/isdn/hisax/l3dss1.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/isdn/hisax/l3dss1.c	Mon Feb 10 10:39:26 2003
@@ -2169,7 +2169,7 @@
 
 /***********************************************/
 /* handle special commands for this protocol.  */
-/* Examples are call independant services like */
+/* Examples are call independent services like */
 /* remote operations with dummy  callref.      */
 /***********************************************/
 static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic)
diff -Nru a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
--- a/drivers/isdn/hisax/l3ni1.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/isdn/hisax/l3ni1.c	Mon Feb 10 10:39:24 2003
@@ -2024,7 +2024,7 @@
 
 /***********************************************/
 /* handle special commands for this protocol.  */
-/* Examples are call independant services like */
+/* Examples are call independent services like */
 /* remote operations with dummy  callref.      */
 /***********************************************/
 static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic)
diff -Nru a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig
--- a/drivers/isdn/hysdn/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/isdn/hysdn/Kconfig	Mon Feb 10 10:39:31 2003
@@ -6,7 +6,7 @@
 	depends on m && PROC_FS
 	help
 	  Say Y here if you have one of Hypercope's active PCI ISDN cards
-	  Champ, Ergo and Metro. You will then get a module called hysdn.o.
+	  Champ, Ergo and Metro. You will then get a module called hysdn.
 	  Please read the file <file:Documentation/isdn/README.hysdn> for more
 	  information.
 
diff -Nru a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
--- a/drivers/isdn/hysdn/hysdn_boot.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/isdn/hysdn/hysdn_boot.c	Mon Feb 10 10:39:26 2003
@@ -78,7 +78,7 @@
 }				/* DecryptBuf */
 
 /********************************************************************************/
-/* pof_handle_data executes the required actions dependant on the active record */
+/* pof_handle_data executes the required actions dependent on the active record */
 /* id. If successful 0 is returned, a negative value shows an error.           */
 /********************************************************************************/
 static int
diff -Nru a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile
--- a/drivers/isdn/i4l/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/isdn/i4l/Makefile	Mon Feb 10 10:39:24 2003
@@ -1,9 +1,5 @@
 # Makefile for the kernel ISDN subsystem and device drivers.
 
-# Objects that export symbols.
-
-export-objs	:= isdn_common.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_ISDN)			+= isdn.o
diff -Nru a/drivers/isdn/sc/Kconfig b/drivers/isdn/sc/Kconfig
--- a/drivers/isdn/sc/Kconfig	Mon Feb 10 10:39:25 2003
+++ b/drivers/isdn/sc/Kconfig	Mon Feb 10 10:39:25 2003
@@ -9,6 +9,6 @@
 	  driver currently builds only in a modularized version ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want, details in <file:Documentation/modules.txt>); the module will
-	  be called sc.o.  See <file:Documentation/isdn/README.sc> and
+	  be called sc.  See <file:Documentation/isdn/README.sc> and
 	  <http://www.spellcast.com/> for more information.
 
diff -Nru a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
--- a/drivers/macintosh/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/macintosh/Makefile	Mon Feb 10 10:39:31 2003
@@ -2,17 +2,6 @@
 # Makefile for the Macintosh-specific device drivers.
 #
 
-# Objects that export symbols.
-
-export-objs	:= adb.o mac_hid.o via-pmu.o
-
-# Object file lists.
-
-obj-y	:=
-obj-m	:=
-obj-n	:=
-obj-	:=
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_PMAC_PBOOK)	+= mediabay.o
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/macintosh/adb.c	Mon Feb 10 10:39:33 2003
@@ -246,10 +246,10 @@
 {
 	strcpy(current->comm, "kadbprobe");
 	
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	flush_signals(current);
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	printk(KERN_INFO "adb: starting probe task...\n");
 	do_adb_reset_bus();
diff -Nru a/drivers/mca/Makefile b/drivers/mca/Makefile
--- a/drivers/mca/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/mca/Makefile	Mon Feb 10 10:39:27 2003
@@ -5,4 +5,3 @@
 obj-$(CONFIG_MCA_PROC_FS)	+= mca-proc.o
 obj-$(CONFIG_MCA_LEGACY)	+= mca-legacy.o
 
-export-objs	:= mca-bus.o mca-legacy.o mca-proc.o mca-driver.o
diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig
--- a/drivers/md/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/md/Kconfig	Mon Feb 10 10:39:23 2003
@@ -41,7 +41,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called linear.o.
+	  will be called linear.
 
 	  If unsure, say Y.
 
@@ -63,7 +63,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called raid0.o.
+	  will be called raid0.
 
 	  If unsure, say Y.
 
@@ -85,7 +85,7 @@
 	  learn where to get the supporting user space utilities raidtools.
 
 	  If you want to use such a RAID-1 set, say Y. This code is also
-	  available as a module called raid1.o ( = code which can be inserted
+	  available as a module called raid1 ( = code which can be inserted
 	  in and removed from the running kernel whenever you want).  If you
 	  want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
@@ -110,7 +110,7 @@
 	  learn where to get the supporting user space utilities raidtools.
 
 	  If you want to use such a RAID-4/RAID-5 set, say Y. This code is
-	  also available as a module called raid5.o ( = code which can be
+	  also available as a module called raid5 ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
@@ -141,7 +141,7 @@
 	  Higher level volume managers such as LVM2 use this driver.
 
 	  If you want to compile this as a module, say M here and read 
-	  <file:Documentation/modules.txt>.  The module will be called dm-mod.o.
+	  <file:Documentation/modules.txt>.  The module will be called dm-mod.
 
 	  If unsure, say N.
 
diff -Nru a/drivers/md/Makefile b/drivers/md/Makefile
--- a/drivers/md/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/md/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,7 +2,6 @@
 # Makefile for the kernel software RAID and LVM drivers.
 #
 
-export-objs	:= md.o xor.o dm-table.o dm-target.o
 dm-mod-objs	:= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
 		   dm-ioctl.o
 
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/md/md.c	Mon Feb 10 10:39:24 2003
@@ -2444,9 +2444,9 @@
 
 static inline void flush_curr_signals(void)
 {
-	spin_lock(&current->sig->siglock);
+	spin_lock(&current->sighand->siglock);
 	flush_signals(current);
-	spin_unlock(&current->sig->siglock);
+	spin_unlock(&current->sighand->siglock);
 }
 
 int md_thread(void * arg)
diff -Nru a/drivers/media/Kconfig b/drivers/media/Kconfig
--- a/drivers/media/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/media/Kconfig	Mon Feb 10 10:39:24 2003
@@ -21,7 +21,7 @@
 	  Documentation/video4linux/API.html.  Documentation for V4L2 is
 	  available on the web at http://bytesex.org/v4l/
 
-	  This driver is also available as a module called videodev.o ( = code
+	  This driver is also available as a module called videodev ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
--- a/drivers/media/dvb/dvb-core/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/media/dvb/dvb-core/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for the kernel DVB device drivers.
 #
 
-export-objs     := dvb_ksyms.o
-
 dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
 		dvb_frontend.o dvb_i2c.o dvb_net.o dvb_ksyms.o
 
diff -Nru a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
--- a/drivers/media/dvb/frontends/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/media/dvb/frontends/Kconfig	Mon Feb 10 10:39:23 2003
@@ -31,7 +31,7 @@
 
 	  This tuner module needs some microcode located in a file called 
 	  "Sc_main.mc" in the windows driver. Please pass the module parameter
-	  mcfile="/PATH/FILENAME" when loading alps_tdlb7.o.
+	  mcfile="/PATH/FILENAME" when loading alps_tdlb7.
 
 	  If you don't know what tuner module is soldered on your 
 	  DVB adapter simply enable all supported frontends, the 
diff -Nru a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
--- a/drivers/media/radio/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/drivers/media/radio/Kconfig	Mon Feb 10 10:39:29 2003
@@ -23,7 +23,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-cadet.o.
+	  will be called radio-cadet.
 
 config RADIO_RTRACK
 	tristate "AIMSlab RadioTrack (aka RadioReveal) support"
@@ -51,7 +51,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-aimslab.o.
+	  will be called radio-aimslab.
 
 config RADIO_RTRACK_PORT
 	hex "RadioTrack i/o port (0x20f or 0x30f)"
@@ -76,7 +76,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-rtrack2.o.
+	  will be called radio-rtrack2.
 
 config RADIO_RTRACK2_PORT
 	hex "RadioTrack II i/o port (0x20c or 0x30c)"
@@ -101,7 +101,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-aztech.o.
+	  will be called radio-aztech.
 
 config RADIO_AZTECH_PORT
 	hex "Aztech/Packard Bell I/O port (0x350 or 0x358)"
@@ -127,7 +127,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-gemtek.o.
+	  will be called radio-gemtek.
 
 config RADIO_GEMTEK_PORT
 	hex "GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)"
@@ -153,7 +153,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-gemtek-pci.o.
+	  will be called radio-gemtek-pci.
 
 config RADIO_MAXIRADIO
 	tristate "Guillemot MAXI Radio FM 2000 radio"
@@ -170,7 +170,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-maxiradio.o.
+	  will be called radio-maxiradio.
 
 config RADIO_MAESTRO
 	tristate "Maestro on board radio"
@@ -187,7 +187,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-maestro.o.
+	  will be called radio-maestro.
 
 config RADIO_MIROPCM20
 	tristate "miroSOUND PCM20 radio"
@@ -205,7 +205,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called miropcm20.o.
+	  will be called miropcm20.
 
 config RADIO_MIROPCM20_RDS
 	tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)"
@@ -221,7 +221,7 @@
 	  availability of RDS is reported over V4L by the basic driver
 	  already.  Here RDS can be read from files in /dev/v4l/rds.
 
-	  As module the driver will be called miropcm20-rds.o.
+	  As module the driver will be called miropcm20-rds.
 
 config RADIO_SF16FMI
 	tristate "SF16FMI Radio"
@@ -240,7 +240,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-sf16fmi.o.
+	  will be called radio-sf16fmi.
 
 config RADIO_TERRATEC
 	tristate "TerraTec ActiveRadio ISA Standalone"
@@ -263,7 +263,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-terratec.o.
+	  will be called radio-terratec.
 
 config RADIO_TERRATEC_PORT
 	hex "Terratec i/o port (normally 0x590)"
@@ -280,7 +280,7 @@
 	  This is a driver for the Trust FM radio cards. Say Y if you have
 	  such a card and want to use it under Linux.
 
-	  This driver is also available as a module called radio-trust.o ( =
+	  This driver is also available as a module called radio-trust ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -308,7 +308,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-typhoon.o.
+	  will be called radio-typhoon.
 
 config RADIO_TYPHOON_PROC_FS
 	bool "Support for /proc/radio-typhoon"
@@ -354,7 +354,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called radio-zoltrix.o.
+	  will be called radio-zoltrix.
 
 config RADIO_ZOLTRIX_PORT
 	hex "ZOLTRIX I/O port (0x20c or 0x30c)"
diff -Nru a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
--- a/drivers/media/radio/Makefile	Mon Feb 10 10:39:28 2003
+++ b/drivers/media/radio/Makefile	Mon Feb 10 10:39:28 2003
@@ -2,11 +2,6 @@
 # Makefile for the kernel character device drivers.
 #
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs     := miropcm20-rds-core.o
-
 miropcm20-objs	:= miropcm20-rds-core.o miropcm20-radio.o
 
 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
diff -Nru a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
--- a/drivers/media/radio/radio-zoltrix.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/media/radio/radio-zoltrix.c	Mon Feb 10 10:39:33 2003
@@ -2,7 +2,7 @@
  * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
  *
  * BUGS  
- *  Due to the inconsistancy in reading from the signal flags
+ *  Due to the inconsistency in reading from the signal flags
  *  it is difficult to get an accurate tuned signal.
  *
  *  It seems that the card is not linear to 0 volume. It cuts off
diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
--- a/drivers/media/video/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/drivers/media/video/Kconfig	Mon Feb 10 10:39:32 2003
@@ -19,7 +19,7 @@
 
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
-	depends on VIDEO_DEV && PCI && I2C_ALGOBIT
+	depends on VIDEO_DEV && PCI && I2C_ALGOBIT && SOUND
 	---help---
 	  Support for BT848 based frame grabber/overlay boards. This includes
 	  the Miro, Hauppauge and STB boards. Please read the material in
@@ -28,7 +28,7 @@
 	  If you say Y or M here, you need to say Y or M to "I2C support" and
 	  "I2C bit-banging interfaces" in the character device section.
 
-	  This driver is available as a module called bttv.o ( = code
+	  This driver is available as a module called bttv ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -38,7 +38,7 @@
 	depends on VIDEO_DEV
 	help
 	  Say Y if you have such a thing.  This driver is also available as a
-	  module called pms.o ( = code which can be inserted in and removed
+	  module called pms ( = code which can be inserted in and removed
 	  from the running kernel whenever you want).  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
@@ -52,7 +52,7 @@
 	  Otherwise, or if you don't understand a word, say N.
 	  See <http://www.cpu.lu/~mlan/planb.html> for more info.
 
-	  Saying M will compile this driver as a module (planb.o).
+	  Saying M will compile this driver as a module (planb).
 
 config VIDEO_BWQCAM
 	tristate "Quickcam BW Video For Linux"
@@ -61,7 +61,7 @@
 	  Say Y have if you the black and white version of the QuickCam
 	  camera. See the next option for the color version.
 
-	  This driver is also available as a module called bw-qcam.o ( = code
+	  This driver is also available as a module called bw-qcam ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -74,7 +74,7 @@
 	  Connectix QuickCam.  If you have one of these cameras, say Y here,
 	  otherwise say N.  This driver does not work with the original
 	  monochrome QuickCam, QuickCam VC or QuickClip.  It is also available
-	  as a module (c-qcam.o).
+	  as a module (c-qcam).
 	  Read <file:Documentation/video4linux/CQcam.txt> for more information.
 
 config VIDEO_W9966
@@ -85,7 +85,7 @@
 	  Currently tested with the LifeView FlyCam Supra.
 	  If you have one of these cameras, say Y here
 	  otherwise say N.
-	  This driver is also available as a module (w9966.o).
+	  This driver is also available as a module (w9966).
 
 	  Check out <file:Documentation/video4linux/w9966.txt> for more
 	  information.
@@ -103,7 +103,7 @@
 	  Please read <file:Documentation/video4linux/README.cpia> for more
 	  information.
 
-	  This driver is also available as a module (cpia.o).
+	  This driver is also available as a module (cpia).
 
 config VIDEO_CPIA_PP
 	tristate "CPiA Parallel Port Lowlevel Support"
@@ -113,7 +113,7 @@
 	  Vision's CPiA (Colour Processor Interface ASIC), such as the
 	  Creative Webcam II. If you have the parallel port version of one
 	  of these cameras, say Y here, otherwise say N. It is also available
-	  as a module (cpia_pp.o).
+	  as a module (cpia_pp).
 
 config VIDEO_CPIA_USB
 	tristate "CPiA USB Lowlevel Support"
@@ -123,7 +123,7 @@
 	  (Colour Processor Interface ASIC), such as the Creative Webcam II.
 	  If you have the USB version of one of these cameras, say Y here,
 	  otherwise say N. This will not work with the Creative Webcam III.
-	  It is also available as a module (cpia_usb.o).
+	  It is also available as a module (cpia_usb).
 
 config VIDEO_SAA5249
 	tristate "SAA5249 Teletext processor"
@@ -132,7 +132,7 @@
 	  Support for I2C bus based teletext using the SAA5249 chip. At the
 	  moment this is only useful on some European WinTV cards.
 
-	  This driver is also available as a module called saa5249.o ( = code
+	  This driver is also available as a module called saa5249 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -177,10 +177,16 @@
 config VIDEO_ZORAN_DC10
 	tristate "Miro DC10(+) support"
 	depends on VIDEO_ZORAN
+	help
+	  Say Y to support the Pinnacle Systems Studio DC10 plus TV/Video
+	  card.  Vendor page at <http://www.pinnaclesys.com/>.
 
 config VIDEO_ZORAN_LML33
 	tristate "Linux Media Labs LML33 support"
 	depends on VIDEO_ZORAN
+	help
+	  Say Y here to support the Linux Media Labs LML33 TV/Video card.
+	  Resources page is at <http://www.linuxmedialabs.com/lml33doc.html>.
 
 config VIDEO_ZR36120
 	tristate "Zoran ZR36120/36125 Video For Linux"
@@ -191,7 +197,7 @@
 	  and Buster boards. Please read the material in
 	  <file:Documentation/video4linux/zr36120.txt> for more information.
 
-	  This driver is also available as a module called zr36120.o ( = code
+	  This driver is also available as a module called zr36120 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -207,7 +213,7 @@
 	  If you say Y or M here, you need to say Y or M to "Sony Programmable
 	  I/O Control Device" in the character device section.
 
-	  This driver is available as a module called meye.o ( = code
+	  This driver is available as a module called meye ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -219,7 +225,7 @@
 	  This is a video4linux driver for Philips SAA7130/7134 based
 	  TV cards.
 
-	  This driver is available as a module called saa7134.o ( = code
+	  This driver is available as a module called saa7134 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile	Mon Feb 10 10:39:25 2003
+++ b/drivers/media/video/Makefile	Mon Feb 10 10:39:25 2003
@@ -2,12 +2,6 @@
 # Makefile for the video capture/playback device drivers.
 #
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs     :=	videodev.o v4l2-common.o v4l1-compat.o \
-			bttv-if.o cpia.o video-buf.o
-
 bttv-objs	:=	bttv-driver.o bttv-cards.o bttv-if.o \
 			bttv-risc.o bttv-vbi.o
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
--- a/drivers/media/video/bt819.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/media/video/bt819.c	Mon Feb 10 10:39:23 2003
@@ -48,18 +48,8 @@
 
 static unsigned short normal_i2c[] = {34>>1, I2C_CLIENT_END };
 static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
-static unsigned short probe[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
-static unsigned force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };	
-
-static struct i2c_client_address_data addr_data = {
-	normal_i2c , normal_i2c_range,
-	probe , probe_range,
-	ignore , ignore_range,
-	force
-};
+
+I2C_CLIENT_INSMOD;
 
 static struct i2c_client client_template;
 
@@ -100,10 +90,6 @@
 
 /* ----------------------------------------------------------------------- */
 
-static int bt819_probe(struct i2c_adapter *adap)
-{
-	return i2c_probe(adap, &addr_data, bt819_attach);
-}
 
 static int bt819_setbit(struct bt819 *dev, int subaddr, int bit, int data)
 {
@@ -211,6 +197,10 @@
 	MOD_INC_USE_COUNT;
 	return 0;
 }
+static int bt819_probe(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, bt819_attach);
+}
 
 static int bt819_detach(struct i2c_client *client)
 {
@@ -448,21 +438,19 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_bt819 = {
-	"bt819",		/* name */
-	I2C_DRIVERID_BT819,	/* ID */
-	I2C_DF_NOTIFY,
-	bt819_probe,
-	bt819_detach,
-	bt819_command
+        .name = "bt819",		/* name */
+	.id = I2C_DRIVERID_BT819,	/* ID */
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = bt819_probe,
+	.detach_client = bt819_detach,
+	.command = bt819_command
+
 };
 
 static struct i2c_client client_template = {
-	"bt819_client",
-	-1,
-	0,
-	0,
-	NULL,
-	&i2c_driver_bt819
+	.name = "bt819_client",
+	.id = -1,
+	.driver = &i2c_driver_bt819
 };
 
 static int bt819_setup(void)
diff -Nru a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
--- a/drivers/media/video/bt856.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/media/video/bt856.c	Mon Feb 10 10:39:23 2003
@@ -82,6 +82,7 @@
 	int contrast;
 	int hue;
 	int sat;
+	struct semaphore lock;
 };
 
 #define   I2C_BT856        0x88
@@ -90,11 +91,6 @@
 
 /* ----------------------------------------------------------------------- */
 
-static int bt856_probe(struct i2c_adapter *adap)
-{
-	return i2c_probe(adap, &addr_data , bt856_attach);
-}
-
 static int bt856_setbit(struct bt856 *dev, int subaddr, int bit, int data)
 {
 	return i2c_smbus_write_byte_data(dev->client, subaddr,(dev->reg[subaddr] & ~(1 << bit)) | (data ? (1 << bit) : 0));
@@ -134,7 +130,7 @@
 	encoder->norm = VIDEO_MODE_NTSC;
 	encoder->enable = 1;
 
-	DEBUG(printk(KERN_INFO "%s-bt856: attach\n", encoder->bus->name));
+	DEBUG(printk(KERN_INFO "%s-bt856: attach\n", encoder->client->name));
 
 	i2c_smbus_write_byte_data(client, 0xdc, 0x18);
 	encoder->reg[0xdc] = 0x18;
@@ -167,6 +163,10 @@
 	return 0;
 }
 
+static int bt856_probe(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data , bt856_attach);
+}
 
 static int bt856_detach(struct i2c_client *client)
 {
@@ -299,21 +299,19 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_bt856 = {
-	"bt856",		/* name */
-	I2C_DRIVERID_BT856,	/* ID */
-	I2C_DF_NOTIFY,
-	bt856_probe,
-	bt856_detach,
-	bt856_command
+	.owner = THIS_MODULE,
+	.name = "bt856",		/* name */
+	.id = I2C_DRIVERID_BT856,	/* ID */
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = bt856_probe,
+	.detach_client = bt856_detach,
+	.command = bt856_command
 };
 
 static struct i2c_client client_template = {
-	"bt856_client",
-	-1,
-	0,
-	0,
-	NULL,
-	&i2c_driver_bt856
+	.name = "bt856_client",
+	.id = -1,
+	.driver = &i2c_driver_bt856
 };
 
 static int bt856_init(void)
diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
--- a/drivers/media/video/bttv-driver.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/media/video/bttv-driver.c	Mon Feb 10 10:39:30 2003
@@ -247,7 +247,7 @@
 	},{
 		.v4l2_id        = V4L2_STD_PAL_N,
 		.name           = "PAL-N",
-		.Fsc             35468950,
+		.Fsc            = 35468950,
 		.swidth         = 768,
 		.sheight        = 576,
 		.totalwidth     = 1135,
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/media/video/saa5249.c	Mon Feb 10 10:39:30 2003
@@ -280,17 +280,17 @@
 {
 	sigset_t oldblocked = current->blocked;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(delay);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = oldblocked;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 }
 
 
diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
--- a/drivers/media/video/saa7185.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/media/video/saa7185.c	Mon Feb 10 10:39:23 2003
@@ -186,7 +186,7 @@
 {
 	int i;
 	struct saa7185 *encoder;
-	struct i2c_client client;
+	struct i2c_client *client;
 
 	client = kmalloc(sizeof(*client), GFP_KERNEL);
 	if (client == NULL)
@@ -194,14 +194,14 @@
 	client_template.adapter = adap;
 	client_template.addr = addr;
 	memcpy(client, &client_template, sizeof(*client));
-	encoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
+	encoder = kmalloc(sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL) {
 		kfree(client);
 		return -ENOMEM;
 	}
 
 
-	memset(encoder, 0, sizeof(*decoder));
+	memset(encoder, 0, sizeof(*encoder));
 	strcpy(client->name, "saa7185");
 	encoder->client = client;
 	client->data = encoder;
@@ -221,7 +221,7 @@
 		printk(KERN_INFO "%s_attach: chip version %d\n",
 		       client->name, i2c_smbus_read_byte(client) >> 5);
 	}
-	init_MUTEX(&decoder->lock);
+	init_MUTEX(&encoder->lock);
 	i2c_attach_client(client);
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -355,6 +355,7 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa7185 = {
+	.owner 		= THIS_MODULE,
 	.name	 	= "saa7185",		 /* name */
 	.id 		= I2C_DRIVERID_SAA7185B, /* ID */
 	.flags 		= I2C_DF_NOTIFY,
diff -Nru a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
--- a/drivers/media/video/stradis.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/media/video/stradis.c	Mon Feb 10 10:39:32 2003
@@ -241,12 +241,6 @@
 	}
 }
 
-static void detach_inform(struct saa7146 *saa, int id)
-{
-	int i;
-	i = saa->nr;
-}
-
 static void I2CBusScan(struct saa7146 *saa)
 {
 	int i;
@@ -1323,9 +1317,12 @@
 		clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y));
 }
 
-static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+static int saa_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long argl)
 {
-	struct saa7146 *saa = (struct saa7146 *) dev;
+	struct saa7146 *saa = file->private_data;
+	void *arg = (void *)argl;
+
 	switch (cmd) {
 	case VIDIOCGCAP:
 		{
@@ -1809,24 +1806,23 @@
 	return 0;
 }
 
-static int saa_mmap(struct video_device *dev, const char *adr,
-		    unsigned long size)
+static int saa_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct saa7146 *saa = (struct saa7146 *) dev;
+	struct saa7146 *saa = file->private_data;
 	printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
 	return -EINVAL;
 }
 
-static long saa_read(struct video_device *dev, char *buf,
-		     unsigned long count, int nonblock)
+static ssize_t saa_read(struct file *file, char *buf,
+			size_t count, loff_t *ppos)
 {
 	return -EINVAL;
 }
 
-static long saa_write(struct video_device *dev, const char *buf,
-		      unsigned long count, int nonblock)
+static ssize_t saa_write(struct file *file, const char *buf,
+			 size_t count, loff_t *ppos)
 {
-	struct saa7146 *saa = (struct saa7146 *) dev;
+	struct saa7146 *saa = file->private_data;
 	unsigned long todo = count;
 	int blocksize, split;
 	unsigned long flags;
@@ -1945,11 +1941,23 @@
 	return count;
 }
 
-static int saa_open(struct video_device *dev, int flags)
+static int saa_open(struct inode *inode, struct file *file)
 {
-	struct saa7146 *saa = (struct saa7146 *) dev;
+	struct saa7146 *saa = NULL;
+	unsigned int minor = minor(inode->i_rdev);
+	int i;
+
+	for (i = 0; i < SAA7146_MAX; i++) {
+		if (saa7146s[i].video_dev.minor == minor) {
+			saa = &saa7146s[i];
+		}
+	}
+	if (saa == NULL) {
+		return -ENODEV;
+	}
+	file->private_data = saa;
 
-	saa->video_dev.busy = 0;
+	//saa->video_dev.busy = 0; /* old hack to support multiple open */
 	saa->user++;
 	if (saa->user > 1)
 		return 0;	/* device open already, don't reset */
@@ -1957,29 +1965,37 @@
 	return 0;
 }
 
-static void saa_close(struct video_device *dev)
+static int saa_release(struct inode *inode, struct file *file)
 {
-	struct saa7146 *saa = (struct saa7146 *) dev;
+	struct saa7146 *saa = file->private_data;
 	saa->user--;
-	saa->video_dev.busy = 0;
+	//saa->video_dev.busy = 0; /* old hack to support multiple open */
 	if (saa->user > 0)	/* still someone using device */
-		return;
+		return 0;
 	saawrite(0x007f0000, SAA7146_MC1);	/* stop all overlay dma */
+	return 0;
 }
 
-/* template for video_device-structure */
-static struct video_device saa_template =
+static struct file_operations saa_fops =
 {
 	.owner		= THIS_MODULE,
-	.name		= "SAA7146A",
-	.type		= VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
-	.hardware	= VID_HARDWARE_SAA7146,
 	.open		= saa_open,
-	.close		= saa_close,
+	.release	= saa_release,
+	.ioctl		= saa_ioctl,
 	.read		= saa_read,
+	.llseek		= no_llseek,
 	.write		= saa_write,
-	.ioctl		= saa_ioctl,
 	.mmap		= saa_mmap,
+};
+
+/* template for video_device-structure */
+static struct video_device saa_template =
+{
+	.name		= "SAA7146A",
+	.type		= VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
+	.hardware	= VID_HARDWARE_SAA7146,
+	.fops		= &saa_fops,
+	.minor		= -1,
 };
 
 static int configure_saa7146(struct pci_dev *dev, int num)
diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
--- a/drivers/media/video/zr36120.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/media/video/zr36120.c	Mon Feb 10 10:39:27 2003
@@ -86,7 +86,7 @@
  * 0x28 and 0x2C. How you do that is left as an exercise
  * to the impatient reader :)
  */
-#define T 1	/* to seperate the bools from the ints */
+#define T 1	/* to separate the bools from the ints */
 #define F 0
 static struct tvcard tvcards[] = {
 	/* reported working by <middelin@polyware.nl> */
diff -Nru a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
--- a/drivers/message/fusion/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/message/fusion/Kconfig	Mon Feb 10 10:39:33 2003
@@ -21,10 +21,10 @@
 
 	  If you have Fusion MPT hardware and want to use it, you can say
 	  Y or M here to add MPT (base + ScsiHost) drivers.
-	  <Y> = build lib (fusion.o), and link [static] into the kernel [2]
+	  <Y> = build lib (fusion), and link [static] into the kernel [2]
 	  proper
-	  <M> = compiled as [dynamic] modules [3] named: (mptbase.o,
-	  mptscsih.o)
+	  <M> = compiled as [dynamic] modules [3] named: (mptbase,
+	  mptscsih)
 
 	  [2] In order enable capability to boot the linux kernel
 	  natively from a Fusion MPT target device, you MUST
@@ -39,9 +39,9 @@
 
 	  If you say Y or M here you will get a choice of these
 	  additional protocol and support module options:         Module Name:
-	  <M>   Enhanced SCSI error reporting                     (isense.o)
-	  <M>   Fusion MPT misc device (ioctl) driver             (mptctl.o)
-	  <M>   Fusion MPT LAN driver                             (mptlan.o)
+	  <M>   Enhanced SCSI error reporting                     (isense)
+	  <M>   Fusion MPT misc device (ioctl) driver             (mptctl)
+	  <M>   Fusion MPT LAN driver                             (mptlan)
 
 	  ---
 	  Fusion MPT is trademark of LSI Logic Corporation, and its
@@ -95,7 +95,7 @@
 	  ASC/ASCQ=29h/00h "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED"
 
 	  Say M for "Enhanced SCSI error reporting" to compile this optional module,
-	  creating a driver named: isense.o.
+	  creating a driver named: isense.
 
 	  NOTE: Support for building this feature into the kernel is not
 	  available, due to kernel size considerations.
@@ -114,7 +114,7 @@
 	  of the MPT adapter firmware.  Refer to readme file(s) distributed
 	  with the Fusion MPT linux driver for additional details.
 
-	  If enabled by saying M to this, a driver named: mptctl.o
+	  If enabled by saying M to this, a driver named: mptctl
 	  will be compiled.
 
 	  If unsure whether you really want or need this, say N.
@@ -131,7 +131,7 @@
 	  Installing this driver requires the knowledge to configure and
 	  activate a new network interface, "fc0", using standard Linux tools.
 
-	  If enabled by saying M to this, a driver named: mptlan.o
+	  If enabled by saying M to this, a driver named: mptlan
 	  will be compiled.
 
 	  If unsure whether you really want or need this, say N.
diff -Nru a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
--- a/drivers/message/fusion/Makefile	Mon Feb 10 10:39:29 2003
+++ b/drivers/message/fusion/Makefile	Mon Feb 10 10:39:29 2003
@@ -46,8 +46,6 @@
 
 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
 
-export-objs	:= mptbase.o mptscsih.o mptlan.o mptctl.o isense.o
-
 obj-$(CONFIG_FUSION)		+= mptbase.o mptscsih.o
 obj-$(CONFIG_FUSION_ISENSE)	+= isense.o
 obj-$(CONFIG_FUSION_CTL)	+= mptctl.o
diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/message/fusion/mptscsih.c	Mon Feb 10 10:39:25 2003
@@ -775,7 +775,7 @@
 			if (dlen >= SCSI_STD_INQUIRY_BYTES) {
 				mptscsih_initTarget(hd,
 						hd->port,
-						sc->target,
+						sc->device->id,
 						pScsiReq->LUN[1],
 						sc->buffer,
 						dlen);
@@ -845,7 +845,7 @@
 
 			/* GEM Workaround. */
 			if (hd->is_spi)
-				mptscsih_no_negotiate(hd, sc->target);
+				mptscsih_no_negotiate(hd, sc->device->id);
 			break;
 
 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
@@ -857,7 +857,7 @@
 
 			/* GEM Workaround. */
 			if (hd->is_spi)
-				mptscsih_no_negotiate(hd, sc->target);
+				mptscsih_no_negotiate(hd, sc->device->id);
 			break;
 
 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
@@ -916,7 +916,7 @@
 			   ) {
 				mptscsih_initTarget(hd,
 						hd->port,
-						sc->target,
+						sc->device->id,
 						pScsiReq->LUN[1],
 						sc->buffer,
 						xfer_cnt);
@@ -1000,7 +1000,7 @@
 			   ) {
 				mptscsih_initTarget(hd,
 						hd->port,
-						sc->target,
+						sc->device->id,
 						pScsiReq->LUN[1],
 						sc->buffer,
 						xfer_cnt);
@@ -1594,10 +1594,10 @@
 	if (time - last_queue_full > 10 * HZ) {
 		char *ioc_str = "ioc?";
 
-		if (sc->host != NULL && sc->host->hostdata != NULL)
-			ioc_str = ((MPT_SCSI_HOST *)sc->host->hostdata)->ioc->name;
+		if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
+			ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
 		printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
-				ioc_str, 0, sc->target, sc->lun);
+				ioc_str, 0, sc->device->id, sc->device->lun);
 		last_queue_full = time;
 	}
 }
@@ -2576,9 +2576,9 @@
 	int	 issueCmd;
 
 	did_errcode = 0;
-	hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
-	target = SCpnt->target;
-	lun = SCpnt->lun;
+	hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
+	target = SCpnt->device->id;
+	lun = SCpnt->device->lun;
 	SCpnt->scsi_done = done;
 
 	pTarget = hd->Targets[target];
@@ -3159,7 +3159,7 @@
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) {
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
 		SCpnt->result = DID_RESET << 16;
 		SCpnt->scsi_done(SCpnt);
 		nehprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
@@ -3227,7 +3227,7 @@
 
 	hd->abortSCpnt = SCpnt;
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-	                       SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP)
+	                       SCpnt->device->id, SCpnt->device->lun, ctx2abort, NO_SLEEP)
 		< 0) {
 
 		/* The TM request failed and the subsequent FW-reload failed!
@@ -3263,7 +3263,7 @@
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
 		nehprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
 			   "Can't locate host! (sc=%p)\n",
 			   SCpnt));
@@ -3292,7 +3292,7 @@
 	}
 
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-	                       SCpnt->target, 0, 0, NO_SLEEP)
+	                       SCpnt->device->id, 0, 0, NO_SLEEP)
 		< 0){
 		/* The TM request failed and the subsequent FW-reload failed!
 		 * Fatal error case.
@@ -3323,7 +3323,7 @@
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
 		nehprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
 			   "Can't locate host! (sc=%p)\n",
 			   SCpnt ) );
@@ -3385,7 +3385,7 @@
 	int              status = SUCCESS;
 
 	/*  If we can't locate the host to reset, then we failed. */
-	if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){
+	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
 		nehprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
 			     "Can't locate host! (sc=%p)\n",
 			     SCpnt ) );
@@ -4237,7 +4237,7 @@
 					pReq->LUN[1],
 					target->dev_vol_name);
 		else
-			sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->target, sc->lun);
+			sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun);
 		thisIo.DevIDStr = devFoo;
 /* fubar */
 		thisIo.dataPtr = NULL;
@@ -4261,7 +4261,7 @@
 	MPT_SCSI_HOST *hd;
 	int i;
 
-	hd = (MPT_SCSI_HOST *) sc->host->hostdata;
+	hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
 
 	for (i = 0; i < hd->ioc->req_depth; i++) {
 		if (hd->ScsiLookup[i] == sc) {
diff -Nru a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
--- a/drivers/message/i2o/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/message/i2o/Kconfig	Mon Feb 10 10:39:23 2003
@@ -22,7 +22,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  You will get modules called
-	  i2o_core.o and i2o_config.o.
+	  i2o_core and i2o_config.
 
 	  If unsure, say N.
 
@@ -33,7 +33,7 @@
 	  Say Y for support of PCI bus I2O interface adapters. Currently this
 	  is the only variety supported, so you should say Y.
 
-	  This support is also available as a module called i2o_pci.o ( = code
+	  This support is also available as a module called i2o_pci ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -45,7 +45,7 @@
 	  Include support for the I2O Block OSM. The Block OSM presents disk
 	  and other structured block devices to the operating system.
 
-	  This support is also available as a module called i2o_block.o ( =
+	  This support is also available as a module called i2o_block ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -58,7 +58,7 @@
 	  support for token ring or FDDI if you wish to use token ring or FDDI
 	  I2O cards with this driver.
 
-	  This support is also available as a module called i2o_lan.o ( = code
+	  This support is also available as a module called i2o_lan ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -71,7 +71,7 @@
 	  I2O controller. You can use both the SCSI and Block OSM together if
 	  you wish.
 
-	  This support is also available as a module called i2o_scsi.o ( =
+	  This support is also available as a module called i2o_scsi ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -84,7 +84,7 @@
 	  able to read I2O related information from the virtual directory
 	  /proc/i2o.
 
-	  This support is also available as a module called i2o_proc.o ( =
+	  This support is also available as a module called i2o_proc ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
--- a/drivers/message/i2o/Makefile	Mon Feb 10 10:39:29 2003
+++ b/drivers/message/i2o/Makefile	Mon Feb 10 10:39:29 2003
@@ -5,8 +5,6 @@
 # In the future, some of these should be built conditionally.
 #
 
-export-objs	:= i2o_core.o
-
 obj-$(CONFIG_I2O_PCI)	+= i2o_pci.o
 obj-$(CONFIG_I2O)	+= i2o_core.o i2o_config.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
diff -Nru a/drivers/mtd/Makefile b/drivers/mtd/Makefile
--- a/drivers/mtd/Makefile	Mon Feb 10 10:39:26 2003
+++ b/drivers/mtd/Makefile	Mon Feb 10 10:39:26 2003
@@ -4,8 +4,6 @@
 # Based on:
 # $Id: Makefile,v 1.66 2002/04/23 13:52:14 mag Exp $
 
-export-objs	:= mtdcore.o mtdpart.o redboot.o cmdline.o afs.o mtdconcat.o
-
 obj-y           += chips/ maps/ devices/ nand/
 
 #                       *** BIG UGLY NOTE ***
diff -Nru a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile
--- a/drivers/mtd/chips/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/mtd/chips/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,8 +3,6 @@
 #
 # $Id: Makefile,v 1.7 2001/10/05 06:53:51 dwmw2 Exp $
 
-export-objs	:= chipreg.o gen_probe.o
-
 #                       *** BIG UGLY NOTE ***
 #
 # The removal of get_module_symbol() and replacement with
diff -Nru a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
--- a/drivers/mtd/chips/jedec.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/mtd/chips/jedec.c	Mon Feb 10 10:39:29 2003
@@ -608,7 +608,7 @@
 
    /* Poll the flash for erasure completion, specs say this can take as long
       as 480 seconds to do all the sectors (for a 2 meg flash). 
-      Erasure time is dependant on chip age, temp and wear.. */
+      Erasure time is dependent on chip age, temp and wear.. */
    
    /* This being a generic routine assumes a 32 bit bus. It does read32s
       and bundles interleved chips into the same grouping. This will work 
diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
--- a/drivers/mtd/devices/blkmtd.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/mtd/devices/blkmtd.c	Mon Feb 10 10:39:23 2003
@@ -305,10 +305,10 @@
   DEBUG(1, "blkmtd: writetask: starting (pid = %d)\n", tsk->pid);
   daemonize();
   strcpy(tsk->comm, "blkmtdd");
-  spin_lock_irq(&tsk->sig->siglock);
+  spin_lock_irq(&tsk->sighand->siglock);
   sigfillset(&tsk->blocked);
   recalc_sigpending();
-  spin_unlock_irq(&tsk->sig->siglock);
+  spin_unlock_irq(&tsk->sighand->siglock);
 
   if(alloc_kiovec(1, &iobuf)) {
     printk("blkmtd: write_queue_task cant allocate kiobuf\n");
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/mtd/ftl.c	Mon Feb 10 10:39:31 2003
@@ -841,7 +841,7 @@
 		return -EROFS;
 	}
     
-	DEBUG(0, "ftl_cs: ftl_open(%s)\n", inode->i_bdev->b_disk->disk_name);
+	DEBUG(0, "ftl_cs: ftl_open(%s)\n", inode->i_bdev->bd_disk->disk_name);
 
 	atomic_inc(&partition->open);
 
@@ -855,7 +855,7 @@
 	partition_t *part = inode->i_bdev->bd_disk->private_data;
 	int i;
     
-	DEBUG(0, "ftl_cs: ftl_close(%s)\n", inode->i_bdev->b_disk->disk_name);
+	DEBUG(0, "ftl_cs: ftl_close(%s)\n", inode->i_bdev->bd_disk->disk_name);
 
 	/* Wait for any pending erase operations to complete */
 	if (part->mtd->sync)
diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/mtd/maps/Kconfig	Mon Feb 10 10:39:33 2003
@@ -137,7 +137,7 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_docflash.o.
+	  If compiled as a module, it will be called scx200_docflash.
 
 config MTD_L440GX
 	tristate "BIOS flash chip on Intel L440GX boards"
diff -Nru a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
--- a/drivers/mtd/maps/elan-104nc.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/mtd/maps/elan-104nc.c	Mon Feb 10 10:39:27 2003
@@ -27,7 +27,7 @@
    
    16 bit I/O port (0x22) for some sort of paging.
 
-The single flash device is divided into 3 partition which appear as seperate
+The single flash device is divided into 3 partition which appear as separate
 MTD devices.
 
 Linux thinks that the I/O port is used by the PIC and hence check_region() will
diff -Nru a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
--- a/drivers/mtd/maps/sa1100-flash.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/mtd/maps/sa1100-flash.c	Mon Feb 10 10:39:24 2003
@@ -512,6 +512,37 @@
 #define h3xxx_set_vpp NULL
 #endif
 
+#ifdef CONFIG_SA1100_HACKKIT
+static struct mtd_partition hackkit_partitions[] = {
+	{
+		.name		= "BLOB",
+		.size		= 0x00040000,
+		.offset		= 0x00000000,
+		.mask_flags	= MTD_WRITEABLE,  /* force read-only */
+	}, {
+		.name		= "config",
+		.size		= 0x00040000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "kernel",
+		.size		= 0x00100000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "initrd",
+		.size		= 0x00180000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "rootfs",
+		.size		= 0x700000,
+		.offset		= MTDPART_OFS_APPEND,
+	}, {
+		.name		= "data",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= MTDPART_OFS_APPEND,
+	}
+};
+#endif
+
 #ifdef CONFIG_SA1100_HUW_WEBPANEL
 static struct mtd_partition huw_webpanel_partitions[] = {
 	{
@@ -847,6 +878,12 @@
 	if (machine_is_h3xxx()) {
 		*parts       = h3xxx_partitions;
 		nb_parts     = ARRAY_SIZE(h3xxx_partitions);
+	}
+#endif
+#ifdef CONFIG_SA1100_HACKKIT
+	if (machine_is_hackkit()) {
+		*parts = hackkit_partitions;
+		nb_parts = ARRAY_SIZE(hackkit_partitions);
 	}
 #endif
 #ifdef CONFIG_SA1100_HUW_WEBPANEL
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/mtd/mtdblock.c	Mon Feb 10 10:39:25 2003
@@ -453,10 +453,10 @@
 	/* we might get involved when memory gets low, so use PF_MEMALLOC */
 	tsk->flags |= PF_MEMALLOC;
 	strcpy(tsk->comm, "mtdblockd");
-	spin_lock_irq(&tsk->sig->siglock);
+	spin_lock_irq(&tsk->sighand->siglock);
 	sigfillset(&tsk->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&tsk->sig->siglock);
+	spin_unlock_irq(&tsk->sighand->siglock);
 	daemonize();
 
 	while (!leaving) {
diff -Nru a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
--- a/drivers/mtd/nand/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/mtd/nand/Makefile	Mon Feb 10 10:39:23 2003
@@ -3,8 +3,6 @@
 #
 # $Id: Makefile,v 1.5 2001/09/19 22:39:59 dwmw2 Exp $
 
-export-objs	:= nand.o nand_ecc.o
-
 nandobjs-y			:= nand.o
 nandobjs-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o
 
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/3c509.c	Mon Feb 10 10:39:23 2003
@@ -103,6 +103,10 @@
 static int el3_debug = 2;
 #endif
 
+/* Used to do a global count of all the cards in the system.  Must be
+ * a global variable so that the mca/eisa probe routines can increment
+ * it */
+static int el3_cards = 0;
 
 /* To minimize the size of the driver source I only define operating
    constants if they are used several times.  You'll need the manual
@@ -167,16 +171,15 @@
 	/* skb send-queue */
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
-	char mca_slot;
 #ifdef CONFIG_PM
 	struct pm_dev *pmdev;
 #endif
-#ifdef __ISAPNP__
-	struct pnp_dev *pnpdev;
-#endif
-#ifdef CONFIG_EISA
-	struct eisa_device *edev;
-#endif
+	enum {
+		EL3_MCA,
+		EL3_PNP,
+		EL3_EISA,
+	} type;						/* type of device */
+	struct device *dev;
 };
 static int id_port __initdata = 0x110;	/* Start with 0x110 to avoid new sound cards.*/
 static struct net_device *el3_root_dev;
@@ -200,6 +203,8 @@
 static int el3_resume(struct pm_dev *pdev);
 static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
 #endif
+/* generic device remove for all device types */
+static int el3_device_remove (struct device *device);
 
 #ifdef CONFIG_EISA
 struct eisa_device_id el3_eisa_ids[] = {
@@ -209,31 +214,46 @@
 };
 
 static int el3_eisa_probe (struct device *device);
-static int el3_eisa_remove (struct device *device);
 
 struct eisa_driver el3_eisa_driver = {
 		.id_table = el3_eisa_ids,
 		.driver   = {
 				.name    = "3c509",
 				.probe   = el3_eisa_probe,
-				.remove  = __devexit_p (el3_eisa_remove)
+				.remove  = __devexit_p (el3_device_remove)
 		}
 };
 #endif
 
 #ifdef CONFIG_MCA
-struct el3_mca_adapters_struct {
-	char* name;
-	int id;
+static int el3_mca_probe(struct device *dev);
+
+static short el3_mca_adapter_ids[] __initdata = {
+		0x627c,
+		0x627d,
+		0x62db,
+		0x62f6,
+		0x62f7,
+		0x0000
+};
+
+static char *el3_mca_adapter_names[] __initdata = {
+		"3Com 3c529 EtherLink III (10base2)",
+		"3Com 3c529 EtherLink III (10baseT)",
+		"3Com 3c529 EtherLink III (test mode)",
+		"3Com 3c529 EtherLink III (TP or coax)",
+		"3Com 3c529 EtherLink III (TP)",
+		NULL
 };
 
-static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = {
-	{ "3Com 3c529 EtherLink III (10base2)", 0x627c },
-	{ "3Com 3c529 EtherLink III (10baseT)", 0x627d },
-	{ "3Com 3c529 EtherLink III (test mode)", 0x62db },
-	{ "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
-	{ "3Com 3c529 EtherLink III (TP)", 0x62f7 },
-	{ NULL, 0 },
+static struct mca_driver el3_mca_driver = {
+		.id_table = el3_mca_adapter_ids,
+		.driver = {
+				.name = "3c529",
+				.bus = &mca_bus_type,
+				.probe = el3_mca_probe,
+				.remove = __devexit_p(el3_device_remove),
+		},
 };
 #endif /* CONFIG_MCA */
 
@@ -264,12 +284,12 @@
 };
 
 static u16 el3_isapnp_phys_addr[8][3];
-#endif /* __ISAPNP__ */
 static int nopnp;
+#endif /* __ISAPNP__ */
 
 /* With the driver model introduction for EISA devices, both init
  * and cleanup have been split :
- * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove
+ * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove
  * - MCA/ISA still use el3_probe
  *
  * Both call el3_common_init/el3_common_remove. */
@@ -278,10 +298,9 @@
 {
 	struct el3_private *lp = dev->priv;
 	short i;
-  
-#ifdef CONFIG_EISA
-	if (!lp->edev)				/* EISA devices are not chained */
-#endif
+
+	el3_cards++;
+	if (!lp->dev)				/* probed devices are not chained */
 	{
 			lp->next_dev = el3_root_dev;
 			el3_root_dev = dev;
@@ -337,17 +356,13 @@
 		struct el3_private *lp = dev->priv;
 
 		(void) lp;				/* Keep gcc quiet... */
-#ifdef CONFIG_MCA		
-		if(lp->mca_slot!=-1)
-			mca_mark_as_unused(lp->mca_slot);
-#endif
 #ifdef CONFIG_PM
 		if (lp->pmdev)
 			pm_unregister(lp->pmdev);
 #endif
 #ifdef __ISAPNP__
-		if (lp->pnpdev)
-			pnp_device_detach(lp->pnpdev);
+		if (lp->type == EL3_PNP)
+			pnp_device_detach(to_pnp_dev(lp->dev));
 #endif
 
 		unregister_netdev (dev);
@@ -363,76 +378,11 @@
 	int ioaddr, irq, if_port;
 	u16 phys_addr[3];
 	static int current_tag;
-	int mca_slot = -1;
 #ifdef __ISAPNP__
 	static int pnp_cards;
 	struct pnp_dev *idev = NULL;
 #endif /* __ISAPNP__ */
 
-#ifdef CONFIG_MCA
-	/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
-	 * modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
-	 * to support standard MCA probing.
-	 *
-	 * redone for multi-card detection by ZP Gu (zpg@castle.net)
-	 * now works as a module
-	 */
-
-	if( MCA_bus ) {
-		int slot, j;
-		u_char pos4, pos5;
-
-		for( j = 0; el3_mca_adapters[j].name != NULL; j ++ ) {
-			slot = 0;
-			while( slot != MCA_NOTFOUND ) {
-				slot = mca_find_unused_adapter(
-					el3_mca_adapters[j].id, slot );
-				if( slot == MCA_NOTFOUND ) break;
-
-				/* if we get this far, an adapter has been
-				 * detected and is enabled
-				 */
-
-				pos4 = mca_read_stored_pos( slot, 4 );
-				pos5 = mca_read_stored_pos( slot, 5 );
-
-				ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
-				irq = pos5 & 0x0f;
-
-				/* probing for a card at a particular IO/IRQ */
-				if(dev && ((dev->irq >= 1 && dev->irq != irq) ||
-			   	(dev->base_addr >= 1 && dev->base_addr != ioaddr))) {
-					slot++;         /* probing next slot */
-					continue;
-				}
-
-				printk("3c509: found %s at slot %d\n",
-					el3_mca_adapters[j].name, slot + 1 );
-
-				/* claim the slot */
-				mca_set_adapter_name(slot, el3_mca_adapters[j].name);
-				mca_set_adapter_procfn(slot, NULL, NULL);
-				mca_mark_as_used(slot);
-
-				if_port = pos4 & 0x03;
-				if (el3_debug > 2) {
-					printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
-				}
-				EL3WINDOW(0);
-				for (i = 0; i < 3; i++) {
-					phys_addr[i] = htons(read_eeprom(ioaddr, i));
-				}
-				
-				mca_slot = slot;
-
-				goto found;
-			}
-		}
-		/* if we get here, we didn't find an MCA adapter */
-		return -ENODEV;
-	}
-#endif /* CONFIG_MCA */
-
 #ifdef __ISAPNP__
 	if (nopnp == 1)
 		goto no_pnp;
@@ -580,7 +530,7 @@
 
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
- found:
+
 	dev = init_etherdev(NULL, sizeof(struct el3_private));
 	if (dev == NULL) {
 	    release_region(ioaddr, EL3_IO_EXTENT);
@@ -594,13 +544,80 @@
 	dev->if_port = if_port;
 	lp = dev->priv;
 #ifdef __ISAPNP__
-	lp->pnpdev = idev;
+	lp->dev = &idev->dev;
 #endif
-	lp->mca_slot = mca_slot;
 
 	return el3_common_init (dev);
 }
 
+#ifdef CONFIG_MCA
+static int __init el3_mca_probe(struct device *device) {
+		/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
+		 * heavily modified by Chris Beauregard
+		 * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
+		 * probing.
+		 *
+		 * redone for multi-card detection by ZP Gu (zpg@castle.net)
+		 * now works as a module */
+
+		struct el3_private *lp;
+		short i;
+		int ioaddr, irq, if_port;
+		u16 phys_addr[3];
+		struct net_device *dev = NULL;
+		u_char pos4, pos5;
+		struct mca_device *mdev = to_mca_device(device);
+		int slot = mdev->slot;
+
+		pos4 = mca_device_read_stored_pos(mdev, 4);
+		pos5 = mca_device_read_stored_pos(mdev, 5);
+
+		ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
+		irq = pos5 & 0x0f;
+
+
+		printk("3c529: found %s at slot %d\n",
+			   el3_mca_adapter_names[mdev->index], slot + 1);
+
+		/* claim the slot */
+		strncpy(device->name, el3_mca_adapter_names[mdev->index],
+				sizeof(device->name));
+		mca_device_set_claim(mdev, 1);
+
+		if_port = pos4 & 0x03;
+
+		irq = mca_device_transform_irq(mdev, irq);
+		ioaddr = mca_device_transform_ioport(mdev, ioaddr); 
+		if (el3_debug > 2) {
+				printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
+		}
+		EL3WINDOW(0);
+		for (i = 0; i < 3; i++) {
+				phys_addr[i] = htons(read_eeprom(ioaddr, i));
+		}
+
+		dev = init_etherdev(NULL, sizeof(struct el3_private));
+		if (dev == NULL) {
+				release_region(ioaddr, EL3_IO_EXTENT);
+				return -ENOMEM;
+		}
+
+		SET_MODULE_OWNER(dev);
+
+		memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
+		dev->base_addr = ioaddr;
+		dev->irq = irq;
+		dev->if_port = if_port;
+		lp = dev->priv;
+		lp->dev = device;
+		lp->type = EL3_MCA;
+		device->driver_data = dev;
+
+		return el3_common_init (dev);
+}
+		
+#endif /* CONFIG_MCA */
+
 #ifdef CONFIG_EISA
 static int __init el3_eisa_probe (struct device *device)
 {
@@ -642,25 +659,26 @@
 	dev->irq = irq;
 	dev->if_port = if_port;
 	lp = dev->priv;
-	lp->mca_slot = -1;
-	lp->edev = edev;
+	lp->dev = device;
+	lp->type = EL3_EISA;
 	eisa_set_drvdata (edev, dev);
 
 	return el3_common_init (dev);
 }
+#endif
 
-static int __devexit el3_eisa_remove (struct device *device)
+/* This remove works for all device types.
+ *
+ * The net dev must be stored in the driver_data field */
+static int __devexit el3_device_remove (struct device *device)
 {
-		struct eisa_device *edev;
 		struct net_device *dev;
 
-		edev = to_eisa_device (device);
-		dev  = eisa_get_drvdata (edev);
+		dev  = device->driver_data;
 
 		el3_common_remove (dev);
 		return 0;
 }
-#endif
 
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
@@ -1080,7 +1098,7 @@
 	free_irq(dev->irq, dev);
 	/* Switching back to window 0 disables the IRQ. */
 	EL3WINDOW(0);
-	if (!lp->edev) {
+	if (lp->type != EL3_EISA) {
 	    /* But we explicitly zero the IRQ line select anyway. Don't do
 	     * it on EISA cards, it prevents the module from getting an
 	     * IRQ after unload+reload... */
@@ -1530,7 +1548,7 @@
 
 static int __init el3_init_module(void)
 {
-	int el3_cards = 0;
+	el3_cards = 0;
 
 	if (debug >= 0)
 		el3_debug = debug;
@@ -1548,8 +1566,9 @@
 	if (eisa_driver_register (&el3_eisa_driver) < 0) {
 			eisa_driver_unregister (&el3_eisa_driver);
 	}
-	else
-			el3_cards++;				/* Found an eisa card */
+#endif
+#ifdef CONFIG_MCA
+	mca_register_driver(&el3_mca_driver);
 #endif
 	return el3_cards ? 0 : -ENODEV;
 }
@@ -1568,6 +1587,9 @@
 
 #ifdef CONFIG_EISA
 	eisa_driver_unregister (&el3_eisa_driver);
+#endif
+#ifdef CONFIG_MCA
+	mca_unregister_driver(&el3_mca_driver);
 #endif
 }
 
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/net/8139too.c	Mon Feb 10 10:39:22 2003
@@ -1589,10 +1589,10 @@
 	unsigned long timeout;
 
 	daemonize();
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigemptyset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	strncpy (current->comm, dev->name, sizeof(current->comm) - 1);
 	current->comm[sizeof(current->comm) - 1] = '\0';
@@ -1604,9 +1604,9 @@
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 		}
 
 		if (tp->time_to_die)
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/net/Kconfig	Mon Feb 10 10:39:31 2003
@@ -55,7 +55,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called dummy.o.  If you want to use more than one dummy
+	  will be called dummy.  If you want to use more than one dummy
 	  device at a time, you need to compile this driver as a module.
 	  Instead of 'dummy', the devices will then be called 'dummy0',
 	  'dummy1' etc.
@@ -80,7 +80,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called bonding.o.
+	  will be called bonding.
 
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
@@ -101,7 +101,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eql.o.  If you want to compile it as a
+	  The module will be called eql.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -125,7 +125,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tun.o.  If you want to compile it as a
+	  The module will be called tun.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you don't know what to use this for, you don't need it.
@@ -150,7 +150,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ethertap.o. If you want to compile it as a
+	  The module will be called ethertap. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you don't know what to use this for, you don't need it.
@@ -167,7 +167,7 @@
 	  provided by your regular phone modem.
 
 	  At present this driver only compiles as a module, so say M here if
-	  you have this card. The module will be called sb1000.o. Then read
+	  you have this card. The module will be called sb1000. Then read
 	  <file:Documentation/networking/README.sb1000> for information on how
 	  to use this module, as it needs special ppp scripts for establishing
 	  a connection. Further documentation and the necessary scripts can be
@@ -212,6 +212,14 @@
 	  kernel: saying N will just cause the configurator to skip all
 	  the questions about Ethernet network cards. If unsure, say N.
 
+config MII
+	tristate "generic Media Independent Interface device support"
+	depends on NET_ETHERNET
+	help
+	  Most ethernet controllers have MII transceiver either as an external
+	  or internal device.  It is safe to say Y or M here even if your
+	  ethernet card lack MII.
+
 config ARM_AM79C961A
 	bool "ARM EBSA110 AM79C961A support"
 	depends on NET_ETHERNET && ARM && ARCH_EBSA110
@@ -229,7 +237,7 @@
 	  motherboard will usually use a MACE (Medium Access Control for
 	  Ethernet) interface. Say Y to include support for the MACE chip.
 
-	  This driver is also available as a module called mace.o ( = code
+	  This driver is also available as a module called mace ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -252,7 +260,7 @@
 	  Say Y for support of BMAC Ethernet interfaces. These are used on G3
 	  computers.
 
-	  This driver is also available as a module called bmac.o ( = code
+	  This driver is also available as a module called bmac ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -263,7 +271,7 @@
 	help
 	  Say Y if your machine has this type of Ethernet network card.
 
-	  This driver is also available as a module called oaknet.o ( = code
+	  This driver is also available as a module called oaknet ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -277,7 +285,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module is called ariadne.o. If you want to compile it as
+	  want). The module is called ariadne. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config ARIADNE2
@@ -290,7 +298,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ariadne2.o. If you want to compile it as
+	  The module will be called ariadne2. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config NE2K_ZORRO
@@ -306,7 +314,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module is called a2065.o. If you want to compile it as a
+	  want). The module is called a2065. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config HYDRA
@@ -317,7 +325,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module is called hydra.o. If you want to compile it as a
+	  want). The module is called hydra. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config APNE
@@ -329,7 +337,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module is called apne.o. If you want to compile it as a
+	  want). The module is called apne. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config APOLLO_ELPLUS
@@ -363,7 +371,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  This module will
-	  be called mac89x0.o.
+	  be called mac89x0.
 
 config MACSONIC
 	tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
@@ -379,7 +387,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  This module will
-	  be called macsonic.o.
+	  be called macsonic.
 
 config MACMACE
 	bool "Macintosh (AV) onboard MACE ethernet (EXPERIMENTAL)"
@@ -529,7 +537,7 @@
 	  cards are based on the AMD Lance chipset, which is better known
 	  via the NE2100 cards.
 
-	  This support is also available as a module called sunlance.o ( =
+	  This support is also available as a module called sunlance ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -543,7 +551,7 @@
 	  both PCI and Sbus devices. This driver also supports the "qfe" quad
 	  100baseT device available in both PCI and Sbus configurations.
 
-	  This support is also available as a module called sunhme.o ( = code
+	  This support is also available as a module called sunhme ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -555,7 +563,7 @@
 	  This driver supports the "be" interface available as an Sbus option.
 	  This is Sun's older 100baseT Ethernet device.
 
-	  This support is also available as a module called sunbmac.o ( = code
+	  This support is also available as a module called sunbmac ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -568,7 +576,7 @@
 	  an Sbus option. Note that this is not the same as Quad FastEthernet
 	  "qfe" which is supported by the Happy Meal driver instead.
 
-	  This support is also available as a module called sunqe.o ( = code
+	  This support is also available as a module called sunqe ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -606,7 +614,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c501.o.  If you want to compile it as a
+	  The module will be called 3c501.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -620,7 +628,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c503.o.  If you want to compile it as a
+	  The module will be called 3c503.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -637,7 +645,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called 3c505.o.
+	  called 3c505.
 
 config EL16
 	tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
@@ -649,7 +657,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c507.o.  If you want to compile it as a
+	  The module will be called 3c507.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -669,7 +677,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called 3c509.o.
+	  called 3c509.
 
 config 3C515
 	tristate "3c515 ISA \"Fast EtherLink\""
@@ -683,7 +691,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called 3c515.o.
+	  called 3c515.
 
 config ELMC
 	tristate "3c523 \"EtherLink/MC\" support"
@@ -695,7 +703,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c523.o.  If you want to compile it as a
+	  The module will be called 3c523.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -709,7 +717,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c527.o.  If you want to compile it as a
+	  The module will be called 3c527.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -749,7 +757,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called lance.o.
+	  recommended.  The module will be called lance.
 
 config NET_VENDOR_SMC
 	bool "Western Digital/SMC cards"
@@ -774,7 +782,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wd.o.  If you want to compile it as a
+	  The module will be called wd.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -788,7 +796,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smc-mca.o.  If you want to compile it as a
+	  The module will be called smc-mca.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -809,7 +817,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smc-ultra.o.  If you want to compile it as
+	  The module will be called smc-ultra.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -823,7 +831,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smc-ultra32.o.  If you want to compile it
+	  The module will be called smc-ultra32.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -840,7 +848,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smc9194.o.  If you want to compile it as a
+	  The module will be called smc9194.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -868,7 +876,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ni5010.o.  If you want to compile it as a
+	  The module will be called ni5010.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -882,7 +890,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ni52.o.  If you want to compile it as a
+	  The module will be called ni52.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -896,7 +904,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ni65.o.  If you want to compile it as a
+	  The module will be called ni65.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -915,7 +923,7 @@
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called at1700.o.
+	  called at1700.
 
 config DEPCA
 	tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
@@ -931,7 +939,7 @@
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
 	  called
-	  depca.o.
+	  depca.
 
 config HP100
 	tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
@@ -945,7 +953,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called hp100.o.
+	  called hp100.
 
 config NET_ISA
 	bool "Other ISA cards"
@@ -974,7 +982,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called e2100.o.  If you want to compile it as a
+	  The module will be called e2100.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -992,7 +1000,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called ewrk3.o.
+	  called ewrk3.
 
 config EEXPRESS
 	tristate "EtherExpress 16 support"
@@ -1009,7 +1017,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called eexpress.o.
+	  called eexpress.
 
 config EEXPRESS_PRO
 	tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
@@ -1023,7 +1031,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eepro.o.  If you want to compile it as a
+	  The module will be called eepro.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1040,7 +1048,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called fmv18x.o.  If you want to compile it as a
+	  The module will be called fmv18x.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1054,7 +1062,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called hp-plus.o.  If you want to compile it as a
+	  The module will be called hp-plus.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1068,7 +1076,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called hp.o.  If you want to compile it as a
+	  The module will be called hp.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1090,7 +1098,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eth16i.o.  If you want to compile it as a
+	  The module will be called eth16i.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1111,7 +1119,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ne.o.  If you want to compile it as a
+	  The module will be called ne.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1137,7 +1145,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called ewrk3.o.
+	  called ewrk3.
 
 config SK_G16
 	tristate "SK_G16 support (OBSOLETE)"
@@ -1160,7 +1168,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called sk_mca.o.  If you want to compile it as a
+	  The module is called sk_mca.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1174,7 +1182,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ne2.o.  If you want to compile it as a
+	  The module will be called ne2.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1218,7 +1226,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pcnet32.o.  If you want to compile it as a
+	  The module will be called pcnet32.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1232,7 +1240,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called amd8111e.o.  If you want to compile it as a
+	  The module will be called amd8111e.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1248,7 +1256,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called starfire.o.
+	  recommended.  The module will be called starfire.
 
 config AC3200
 	tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
@@ -1260,7 +1268,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ac3200.o.  If you want to compile it as a
+	  The module will be called ac3200.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1276,7 +1284,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called apricot.o.
+	  called apricot.
 
 config B44
 	tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)"
@@ -1290,7 +1298,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called b44.o.
+	  called b44.
 
 config CS89x0
 	tristate "CS89x0 support"
@@ -1306,7 +1314,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called cs89x.o.
+	  called cs89x.
 
 config DGRS
 	tristate "Digi Intl. RightSwitch SE-X support"
@@ -1321,7 +1329,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dgrs.o.  If you want to compile it as a
+	  The module will be called dgrs.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1335,7 +1343,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eepro100.o.  If you want to compile it as
+	  The module will be called eepro100.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -1412,7 +1420,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called e100.o.  If you want to compile it as a
+	  The module will be called e100.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1426,7 +1434,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called lne390.o.  If you want to compile it as a
+	  The module will be called lne390.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1465,7 +1473,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ne2k-pci.o.  If you want to compile it as
+	  The module will be called ne2k-pci.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -1480,7 +1488,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ne3210.o.  If you want to compile it as a
+	  The module will be called ne3210.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1494,7 +1502,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called es3210.o.  If you want to compile it as a
+	  The module will be called es3210.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1510,7 +1518,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read Documentation/modules.txt. This is recommended.
-	  The module will be called 8139cp.o.
+	  The module will be called 8139cp.
 
 config 8139TOO
 	tristate "RealTek RTL-8139 PCI Fast Ethernet Adapter support"
@@ -1525,7 +1533,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called 8139too.o.
+	  recommended.  The module will be called 8139too.
 
 config 8139TOO_PIO
 	bool "Use PIO instead of MMIO"
@@ -1584,7 +1592,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called sis900.o.
+	  recommended.  The module will be called sis900.
 
 config EPIC100
 	tristate "SMC EtherPower II"
@@ -1628,7 +1636,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tlan.o.  If you want to compile it as a
+	  The module will be called tlan.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1643,7 +1651,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called via-rhine.o.  If you want to compile it as
+	  The module will be called via-rhine.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -1706,7 +1714,7 @@
 	  If you want to compile this driver as a module however ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called atp.o.
+	  <file:Documentation/modules.txt>.  The module will be called atp.
 
 config DE600
 	tristate "D-Link DE600 pocket adapter support"
@@ -1724,7 +1732,7 @@
 	  which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called de600.o.
+	  The module will be called de600.
 
 config DE620
 	tristate "D-Link DE620 pocket adapter support"
@@ -1742,7 +1750,7 @@
 	  which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called de620.o.
+	  The module will be called de620.
 
 config SGISEEQ
 	bool "SGI Seeq ethernet controller support"
@@ -1804,7 +1812,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called acenic.o.
+	  recommended.  The module will be called acenic.
 
 config ACENIC_OMIT_TIGON_I
 	bool "Omit support for old Tigon I based AceNICs"
@@ -1831,7 +1839,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called dl2k.o.
+	  recommended.  The module will be called dl2k.
 
 config E1000
 	tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
@@ -1873,7 +1881,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called e1000.o.  If you want to compile it as a
+	  The module will be called e1000.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -1890,7 +1898,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called myri_sbus.o.
+	  recommended.  The module will be called myri_sbus.
 
 config NS83820
 	tristate "National Semiconduct DP83820 support"
@@ -1914,7 +1922,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called hamachi.o.
+	  called hamachi.
 
 config YELLOWFIN
 	tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
@@ -1929,7 +1937,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called yellowfin.o.
+	  recommended.  The module will be called yellowfin.
 
 config R8169
 	tristate "Realtek 8169 gigabit ethernet support"
@@ -1940,7 +1948,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called r8169.o.
+	  recommended.  The module will be called r8169.
 
 config SK98LIN
 	tristate "SysKonnect SK-98xx support"
@@ -1968,7 +1976,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called sk98lin.o.
+	  recommended.  The module will be called sk98lin.
 
 config TIGON3
 	tristate "Broadcom Tigon3 support"
@@ -1979,7 +1987,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called tg3.o.
+	  recommended.  The module will be called tg3.
 
 endmenu
 
@@ -2036,7 +2044,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called skfp.o.
+	  recommended.  The module will be called skfp.
 
 config HIPPI
 	bool "HIPPI driver support (EXPERIMENTAL)"
@@ -2059,7 +2067,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rrunner.o. If you want to compile it as a
+	  The module will be called rrunner. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -2108,7 +2116,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.  The module will be
-	  called plip.o.  If unsure, say Y or M, in case you buy a laptop
+	  called plip.  If unsure, say Y or M, in case you buy a laptop
 	  later.
 
 config PPP
@@ -2140,7 +2148,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you said Y to "Version information on all symbols" above, then
 	  you cannot compile the PPP driver into the kernel; you can then only
-	  compile it as a module.  The module will be called ppp_generic.o.
+	  compile it as a module.  The module will be called ppp_generic.
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.
@@ -2231,7 +2239,7 @@
 	  and is patent-free.
 
 	  Note that the BSD compression code will always be compiled as a
-	  module; it is called bsd_comp.o and will show up in the directory
+	  module; it is called bsd_comp and will show up in the directory
 	  modules once you have said "make modules". If unsure, say N.
 
 config PPPOE
@@ -2287,7 +2295,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>. The module will be
-	  called slip.o.
+	  called slip.
 
 config SLIP_COMPRESSED
 	bool "CSLIP compressed headers"
@@ -2374,7 +2382,7 @@
 	  You can also compile this as a module ( = code which can be inserted
 	  in and removed from the running kernel whenever you want), say M
 	  here and read <file:Documentation/modules.txt>.  The module will be
-	  called strip.o.
+	  called strip.
 
 config ARLAN
 	tristate "Aironet Arlan 655 & IC2200 DS support"
@@ -2404,7 +2412,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aironet4500_core.o. If you want to
+	  The module will be called aironet4500_core. If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.
@@ -2434,7 +2442,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aironet4500_card.o.  If you want to
+	  The module will be called aironet4500_card.  If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -2481,7 +2489,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aironet4500_proc.o. If you want to
+	  The module will be called aironet4500_proc. If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -2517,7 +2525,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called iph5526.o. For general information about
+	  The module will be called iph5526. For general information about
 	  modules read <file:Documentation/modules.txt>.
 
 config RCPCI
@@ -2527,7 +2535,7 @@
 	  This is a driver for hardware which provides a Virtual Private
 	  Network (VPN). Say Y if you have it.
 
-	  This code is also available as a module called rcpci.o ( = code
+	  This code is also available as a module called rcpci ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -2552,7 +2560,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called shaper.o.  If you want to compile it as a
+	  The module will be called shaper.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,12 +2,6 @@
 # Makefile for the Linux network (ethercard) device drivers.
 #
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs     :=	8390.o arlan.o aironet4500_core.o aironet4500_card.o \
-			ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
-			net_init.o mii.o
 rcpci-objs	:=	rcpci45.o rclanmtl.o
 
 ifeq ($(CONFIG_ISDN_PPP),y)
@@ -63,6 +57,7 @@
 # end link order section
 #
 
+obj-$(CONFIG_MII) += mii.o
 obj-$(CONFIG_AIRONET4500) 	+= aironet4500_core.o
 obj-$(CONFIG_AIRONET4500_CS) 	+= aironet4500_core.o
 obj-$(CONFIG_AIRONET4500_NONCS)  += aironet4500_card.o
@@ -199,3 +194,6 @@
 obj-$(CONFIG_NET_TULIP) += tulip/
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
+
+
+include $(TOPDIR)/drivers/usb/net/Makefile.mii
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/Space.c	Mon Feb 10 10:39:23 2003
@@ -224,6 +224,9 @@
 #ifdef CONFIG_EL2 		/* 3c503 */
 	{el2_probe, 0},
 #endif
+#ifdef CONFIG_EL3
+	{el3_probe, 0},
+#endif
 #ifdef CONFIG_HPLAN
 	{hp_probe, 0},
 #endif
diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c
--- a/drivers/net/acenic.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/acenic.c	Mon Feb 10 10:39:27 2003
@@ -482,7 +482,7 @@
  *
  * One advantagous side effect of this allocation approach is that the
  * entire rx processing can be done without holding any spin lock
- * since the rx rings and registers are totally independant of the tx
+ * since the rx rings and registers are totally independent of the tx
  * ring and its registers.  This of course includes the kmalloc's of
  * new skb's. Thus start_xmit can run in parallel with rx processing
  * and the memory allocation on SMP systems.
diff -Nru a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
--- a/drivers/net/appletalk/Kconfig	Mon Feb 10 10:39:26 2003
+++ b/drivers/net/appletalk/Kconfig	Mon Feb 10 10:39:26 2003
@@ -68,7 +68,7 @@
 	  If you say M here, the AppleTalk-IP support will be compiled as a
 	  module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want, read
-	  <file:Documentation/modules.txt>).  The module is called ipddp.o.
+	  <file:Documentation/modules.txt>).  The module is called ipddp.
 	  In this case, you will be able to use both encapsulation and
 	  decapsulation simultaneously, by loading two copies of the module
 	  and specifying different values for the module option ipddp_mode.
diff -Nru a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile
--- a/drivers/net/appletalk/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/appletalk/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for drivers/net/appletalk
 #
 
-export-objs :=
-
 obj-$(CONFIG_IPDDP) += ipddp.o
 obj-$(CONFIG_COPS) += cops.o
 obj-$(CONFIG_LTPC) += ltpc.o
diff -Nru a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
--- a/drivers/net/arcnet/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/arcnet/Kconfig	Mon Feb 10 10:39:32 2003
@@ -23,7 +23,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called arcnet.o.  If you want to compile it as a
+	  The module will be called arcnet.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -71,7 +71,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called com90xx.o.  If you want to compile it as a
+	  The module will be called com90xx.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -86,7 +86,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called com90io.o.  If you want to compile it as a
+	  The module will be called com90io.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -101,7 +101,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module will be called arc-rimi.o.  If you want to compile
+	  want). The module will be called arc-rimi.  If you want to compile
 	  it as a module, say M here and read <file:Documentation/modules.txt>
 	  as  well as <file:Documentation/networking/net-modules.txt>.
 
@@ -115,7 +115,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called com20020.o.  If you want to compile it as
+	  The module will be called com20020.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
 
diff -Nru a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile
--- a/drivers/net/arcnet/Makefile	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/arcnet/Makefile	Mon Feb 10 10:39:29 2003
@@ -1,8 +1,6 @@
 # Makefile for linux/drivers/net/arcnet
 #
 
-export-objs := arcnet.o com20020.o
-
 obj-$(CONFIG_ARCNET) += arcnet.o
 obj-$(CONFIG_ARCNET_1201) += rfc1201.o
 obj-$(CONFIG_ARCNET_1051) += rfc1051.o
diff -Nru a/drivers/net/arlan.c b/drivers/net/arlan.c
--- a/drivers/net/arlan.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/arlan.c	Mon Feb 10 10:39:29 2003
@@ -1188,34 +1188,31 @@
 {
 
 	struct net_device *dev;
+	struct arlan_private *ap;
 
 	ARLAN_DEBUG_ENTRY("arlan_allocate_device");
 
-	if (!devs)
-		dev = init_etherdev(0, sizeof(struct arlan_private));
-	else
-	{
+	if (!devs) {
+		dev = init_etherdev(0, sizeof(struct arlan_private) + sizeof(struct arlan_shmem));
+		if (!dev) {
+			printk(KERN_ERR "ARLAN: init_etherdev failed\n");
+			return 0;
+		}
+		ap = dev->priv;
+		ap->config = dev->priv + sizeof(struct arlan_private);
+		ap->init_etherdev_alloc = 1;
+	} else {
 		dev = devs;
-		dev->priv = kmalloc(sizeof(struct arlan_private), GFP_KERNEL);
-	};
-
-	if (dev == NULL || dev->priv == NULL)
-	{
-		printk(KERN_CRIT "init_etherdev failed ");
-		return 0;
+		dev->priv = kmalloc(sizeof(struct arlan_private) + sizeof(struct arlan_shmem), GFP_KERNEL);
+		if (!dev->priv) {
+			printk(KERN_ERR "ARLAN: kmalloc of dev->priv failed\n");
+			return 0;
+		}
+		ap = dev->priv;
+		ap->config = dev->priv + sizeof(struct arlan_private);
+		memset(ap, 0, sizeof(*ap));
 	}
 
-	memset(dev->priv,0,sizeof(struct arlan_private));
-
-	((struct arlan_private *) dev->priv)->conf =
-	    kmalloc(sizeof(struct arlan_shmem), GFP_KERNEL);
-
-	if (dev == NULL || dev->priv == NULL ||
-	    ((struct arlan_private *) dev->priv)->conf == NULL)
-	{
-		return 0;
-		printk(KERN_CRIT " No memory at arlan_allocate_device \n");
-	}
 	/* Fill in the 'dev' fields. */
 	dev->base_addr = 0;
 	dev->mem_start = 0;
@@ -2017,32 +2014,24 @@
 	ARLAN_DEBUG_ENTRY("init_module");
 
 	if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)
-	{
-		printk(KERN_WARNING "arlan: wrong module params for multiple devices\n ");
-		return -1;
-	}
+		return -EINVAL;
+
 	numDevices = arlan_find_devices();
 	if (numDevices == 0)
-	{
-		printk(KERN_ERR "arlan: no devices found \n");
-		return -1;
-	}
+		return -ENODEV;
 
 	siteName = kmalloc(100, GFP_KERNEL);
 	if(siteName==NULL)
-	{
-		printk(KERN_ERR "arlan: No memory for site name.\n");
-		return -1;
-	}
+		return -ENOMEM;
+
 	for (i = 0; i < numDevices && i < MAX_ARLANS; i++)
 	{
 		if (!arlan_allocate_device(i, NULL))
-			return -1;
+			return -ENOMEM;
+
 		if (arlan_device[i] == NULL)
-		{
-			printk(KERN_CRIT "arlan: Not Enough memory \n");
-			return -1;
-		}
+			return -ENOMEM;
+
 		if (probe)
 			arlan_probe_everywhere(arlan_device[i]);
 //		arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );
@@ -2056,6 +2045,7 @@
 void cleanup_module(void)
 {
 	int i = 0;
+	struct arlan_private ap;
 
 	ARLAN_DEBUG_ENTRY("cleanup_module");
 
@@ -2069,13 +2059,14 @@
 
 //			release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 );
 			unregister_netdev(arlan_device[i]);
-			if (arlan_device[i]->priv)
-			{
-				if (((struct arlan_private *) arlan_device[i]->priv)->conf)
-					kfree(((struct arlan_private *) arlan_device[i]->priv)->conf);
+			ap = arlan_device[i]->priv;
+			if (ap->init_etherdev_alloc) {
 				kfree(arlan_device[i]);
+				arlan_device[i] = NULL;
+			} else {
+				kfree(ap);
+				ap = NULL;
 			}
-			arlan_device[i] = NULL;
 		}
 	}
 	ARLAN_DEBUG_EXIT("cleanup_module");
diff -Nru a/drivers/net/arlan.h b/drivers/net/arlan.h
--- a/drivers/net/arlan.h	Mon Feb 10 10:39:28 2003
+++ b/drivers/net/arlan.h	Mon Feb 10 10:39:28 2003
@@ -410,6 +410,7 @@
       int	out_time10;
       int	in_bytes10;
       int	out_bytes10;
+      int	init_etherdev_alloc;
 };
 
 
diff -Nru a/drivers/net/declance.c b/drivers/net/declance.c
--- a/drivers/net/declance.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/declance.c	Mon Feb 10 10:39:29 2003
@@ -279,7 +279,7 @@
 			lp->tx_old - lp->tx_new-1)
 
 /* The lance control ports are at an absolute address, machine and tc-slot
- * dependant.
+ * dependent.
  * DECstations do only 32-bit access and the LANCE uses 16 bit addresses,
  * so we have to give the structure an extra member making rap pointing
  * at the right address
diff -Nru a/drivers/net/e100/Makefile b/drivers/net/e100/Makefile
--- a/drivers/net/e100/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/e100/Makefile	Mon Feb 10 10:39:32 2003
@@ -4,5 +4,5 @@
 
 obj-$(CONFIG_E100) += e100.o
 
-e100-objs := e100_main.o e100_config.o e100_proc.o e100_phy.o \
+e100-objs := e100_main.o e100_config.o e100_phy.o \
 	     e100_eeprom.o e100_test.o
diff -Nru a/drivers/net/e100/e100.h b/drivers/net/e100/e100.h
--- a/drivers/net/e100/e100.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/e100/e100.h	Mon Feb 10 10:39:24 2003
@@ -56,7 +56,6 @@
 
 #include <linux/if.h>
 #include <asm/uaccess.h>
-#include <linux/proc_fs.h>
 #include <linux/ip.h>
 
 #define E100_REGS_LEN 1
@@ -926,20 +925,7 @@
 
 	struct cfg_params params;	/* adapter's command line parameters */
 
-	struct proc_dir_entry *proc_parent;
-
 	char *id_string;
-	char *cable_status;
-	char *mdix_status;
-
-	/* Variables for HWI */
-	int saved_open_circut;
-	int saved_short_circut;
-	int saved_distance;
-	int saved_i;
-	int saved_same;
-	unsigned char hwi_started;
-	struct timer_list hwi_timer;	/* hwi timer id */
 
 	u32 speed_duplex_caps;	/* adapter's speed/duplex capabilities */
 
diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c
--- a/drivers/net/e100/e100_main.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/e100/e100_main.c	Mon Feb 10 10:39:27 2003
@@ -83,13 +83,15 @@
 #include "e100_phy.h"
 #include "e100_vendor.h"
 
-#ifdef CONFIG_PROC_FS
-extern int e100_create_proc_subdir(struct e100_private *, char *);
-extern void e100_remove_proc_subdir(struct e100_private *, char *);
-#else
-#define e100_create_proc_subdir(X, Y) 0
-#define e100_remove_proc_subdir(X, Y) do {} while(0)
-#endif
+static char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
+	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+	"tx_heartbeat_errors", "tx_window_errors",
+};
+#define E100_STATS_LEN	sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
 
 static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
 static void e100_get_speed_duplex_caps(struct e100_private *);
@@ -135,7 +137,7 @@
 
 /* Global Data structures and variables */
 char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
-char e100_driver_version[]="2.1.29-k1";
+char e100_driver_version[]="2.1.29-k4";
 const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
 char e100_short_driver_name[] = "e100";
 static int e100nics = 0;
@@ -150,15 +152,6 @@
         .priority       = 0
 };
 #endif
-static int e100_notify_netdev(struct notifier_block *, unsigned long event, void *ptr);
- 
-struct notifier_block e100_notifier_netdev = {
-	.notifier_call  = e100_notify_netdev,
-	.next           = NULL,
-	.priority       = 0
-};
-
-static void e100_get_mdix_status(struct e100_private *bdp);
 
 /*********************************************************************/
 /*! This is a GCC extension to ANSI C.
@@ -196,6 +189,7 @@
 char *e100_get_brand_msg(struct e100_private *);
 static u8 e100_pci_setup(struct pci_dev *, struct e100_private *);
 static u8 e100_sw_init(struct e100_private *);
+static void e100_tco_workaround(struct e100_private *);
 static unsigned char e100_alloc_space(struct e100_private *);
 static void e100_dealloc_space(struct e100_private *);
 static int e100_alloc_tcb_pool(struct e100_private *);
@@ -213,7 +207,7 @@
 
 static unsigned char e100_clr_cntrs(struct e100_private *);
 static unsigned char e100_load_microcode(struct e100_private *);
-static unsigned char e100_hw_init(struct e100_private *, u32);
+static unsigned char e100_hw_init(struct e100_private *);
 static unsigned char e100_setup_iaaddr(struct e100_private *, u8 *);
 static unsigned char e100_update_stats(struct e100_private *bdp);
 
@@ -349,8 +343,6 @@
 u32 e100_rx_srv(struct e100_private *);
 
 void e100_watchdog(struct net_device *);
-static void e100_do_hwi(struct net_device *);
-static void e100_hwi_restore(struct e100_private *);
 void e100_refresh_txthld(struct e100_private *);
 void e100_manage_adaptive_ifs(struct e100_private *);
 void e100_clear_pools(struct e100_private *);
@@ -610,10 +602,6 @@
 	bdp->watchdog_timer.data = (unsigned long) dev;
 	bdp->watchdog_timer.function = (void *) &e100_watchdog;
 
-	init_timer(&bdp->hwi_timer);
-	bdp->hwi_timer.data = (unsigned long) dev;
-	bdp->hwi_timer.function = (void *) &e100_do_hwi;
-
 	if ((rc = e100_pci_setup(pcid, bdp)) != 0) {
 		goto err_dealloc;
 	}
@@ -686,21 +674,6 @@
 	       bdp->device->name, e100_get_brand_msg(bdp));
 	e100_print_brd_conf(bdp);
 	bdp->id_string = e100_get_brand_msg(bdp);
-	e100_get_mdix_status(bdp);
-
-	if (netif_carrier_ok(bdp->device)) 
-		bdp->cable_status = "Cable OK";
-	else {
-		if (bdp->rev_id < D102_REV_ID) 
-			bdp->cable_status = "Not supported";
-		else
-			bdp->cable_status = "Not available";
-	}
-
-	if (e100_create_proc_subdir(bdp, bdp->ifname) < 0) {
-		printk(KERN_ERR "e100: Failed to create proc dir for %s\n",
-		       bdp->device->name);
-	}
 
 	bdp->wolsupported = 0;
 	bdp->wolopts = 0;
@@ -766,8 +739,6 @@
 
 	unregister_netdev(dev);
 
-	e100_remove_proc_subdir(bdp, bdp->ifname);
-
 	e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
 
 	if (bdp->non_tx_command_state != E100_NON_TX_IDLE) {
@@ -804,7 +775,6 @@
 #ifdef CONFIG_PM
 		register_reboot_notifier(&e100_notifier_reboot);
 #endif 
-		register_netdevice_notifier(&e100_notifier_netdev);
 	}
 
 	return ret;
@@ -816,7 +786,6 @@
 #ifdef CONFIG_PM	
 	unregister_reboot_notifier(&e100_notifier_reboot);
 #endif 
-	unregister_netdevice_notifier(&e100_notifier_netdev);
 
 	pci_unregister_driver(&e100_driver);
 }
@@ -1265,7 +1234,7 @@
 	/* read NIC's part number */
 	e100_rd_pwa_no(bdp);
 
-	if (!e100_hw_init(bdp, PORT_SOFTWARE_RESET)) {
+	if (!e100_hw_init(bdp)) {
 		printk(KERN_ERR "e100: hw init failed\n");
 		return false;
 	}
@@ -1314,10 +1283,46 @@
 	return 1;
 }
 
+static void __devinit
+e100_tco_workaround(struct e100_private *bdp)
+{
+	int i;
+
+	/* Do software reset */
+	e100_sw_reset(bdp, PORT_SOFTWARE_RESET);
+
+	/* Do a dummy LOAD CU BASE command. */
+	/* This gets us out of pre-driver to post-driver. */
+	e100_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE);
+
+	/* Wait 20 msec for reset to take effect */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ / 50 + 1);
+
+	/* disable interrupts since they are enabled */
+	/* after device reset                        */
+	e100_disable_clear_intr(bdp);
+
+	/* Wait for command to be cleared up to 1 sec */
+	for (i=0; i<100; i++) {
+		if (!readb(&bdp->scb->scb_cmd_low))
+			break;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 100 + 1);
+	}
+
+	/* Wait for TCO request bit in PMDR register to be clear */
+	for (i=0; i<50; i++) {
+		if (!(readb(&bdp->scb->scb_ext.d101m_scb.scb_pmdr) & BIT_1))
+			break;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 100 + 1);
+	}
+}
+
 /**
  * e100_hw_init - initialized tthe hardware
  * @bdp: atapter's private data struct
- * @reset_cmd: s/w reset or selective reset
  *
  * This routine performs a reset on the adapter, and configures the adapter.
  * This includes configuring the 82557 LAN controller, validating and setting
@@ -1329,13 +1334,16 @@
  *      false - If the adapter failed initialization
  */
 unsigned char __devinit
-e100_hw_init(struct e100_private *bdp, u32 reset_cmd)
+e100_hw_init(struct e100_private *bdp)
 {
 	if (!e100_phy_init(bdp))
 		return false;
 
-	/* Issue a software reset to the e100 */
-	e100_sw_reset(bdp, reset_cmd);
+	e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
+
+	/* Only 82559 or above needs TCO workaround */
+	if (bdp->rev_id >= D101MA_REV_ID)
+		e100_tco_workaround(bdp);
 
 	/* Load the CU BASE (set to 0, because we use linear mode) */
 	if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0))
@@ -1391,6 +1399,7 @@
 	u32 next_phys;		/* the next phys addr */
 	u16 txcommand = CB_S_BIT | CB_TX_SF_BIT;
 
+	bdp->tx_count = 0;
 	if (bdp->flags & USE_IPCB) {
 		txcommand |= CB_IPCB_TRANSMIT | CB_CID_DEFAULT;
 	} else if (bdp->flags & IS_BACHELOR) {
@@ -1634,7 +1643,6 @@
 	if (!netif_running(dev)) {
 		return;
 	}
-	e100_get_mdix_status(bdp);
 
 	/* check if link state has changed */
 	if (e100_phy_check(bdp)) {
@@ -1647,37 +1655,10 @@
 
 			e100_config_fc(bdp);
 			e100_config(bdp);  
-			bdp->cable_status = "Cable OK";
 
 		} else {
 			printk(KERN_ERR "e100: %s NIC Link is Down\n",
 			       bdp->device->name);
-                	if (bdp->rev_id < D102_REV_ID)
-				bdp->cable_status = "Not supported";
-		        else {				
-				/* Initiate hwi, ie, cable diagnostic */
-				bdp->saved_open_circut = 0xffff;
-				bdp->saved_short_circut = 0xffff;
-				bdp->saved_distance = 0xffff;
-				bdp->saved_i = 0;
-				bdp->saved_same = 0;
-				bdp->hwi_started = 1;
-				
-				/* Disable MDI/MDI-X auto switching */
-                		e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
-		                	MDI_MDIX_RESET_ALL_MASK);
-
-				/* Set to 100 Full as required by hwi test */
-				e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
-				       BMCR_SPEED100 | BMCR_FULLDPLX);
-
-				/* Enable and execute HWI test */
-				e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
-					(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
-
-				/* Launch hwi timer in 1 msec */
-				mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
-			}
 		}
 	}
 
@@ -1836,10 +1817,8 @@
 		bdp->drv_stats.rx_intr_pkts += e100_rx_srv(bdp);
 
 	/* clean up after tx'ed packets */
-	if (intr_status & (SCB_STATUS_ACK_CNA | SCB_STATUS_ACK_CX)) {
-		bdp->tx_count = 0;	/* restart tx interrupt batch count */
+	if (intr_status & (SCB_STATUS_ACK_CNA | SCB_STATUS_ACK_CX))
 		e100_tx_srv(bdp);
-	}
 
 	e100_set_intr_mask(bdp);
 }
@@ -2147,11 +2126,12 @@
 	tcb->tcb_thrshld = bdp->tx_thld;
 	tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_S_BIT);
 
-	/* set the I bit on the modulo tcbs, so we will get an interrupt * to
-	 * clean things up */
-	if (!(++bdp->tx_count % TX_FRAME_CNT)) {
+	/* Set I (Interrupt) bit on every (TX_FRAME_CNT)th packet */
+	if (!(++bdp->tx_count % TX_FRAME_CNT))
 		tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_I_BIT);
-	}
+	else
+		/* Clear I bit on other packets */
+		tcb->tcb_hdr.cb_cmd &= ~__constant_cpu_to_le16(CB_I_BIT);
 
 	tcb->tcb_skb = skb;
 
@@ -3054,12 +3034,6 @@
 	if (bdp->device->flags & IFF_UP) {
 		e100_disable_clear_intr(bdp);
 		del_timer_sync(&bdp->watchdog_timer);
-		del_timer_sync(&bdp->hwi_timer);
-		/* If in middle of cable diag, */
-		if (bdp->hwi_started) {
-			bdp->hwi_started = 0;
-			e100_hwi_restore(bdp);
-		}
 		netif_carrier_off(bdp->device);
 		netif_stop_queue(bdp->device); 
 		bdp->last_tcb = NULL;
@@ -3205,6 +3179,22 @@
 	case ETHTOOL_SEEPROM:
 		rc = e100_ethtool_eeprom(dev, ifr);
 		break;
+	case ETHTOOL_GSTATS: {
+		struct {
+			struct ethtool_stats cmd;
+			uint64_t data[E100_STATS_LEN];
+		} stats = { {ETHTOOL_GSTATS, E100_STATS_LEN} };
+		struct e100_private *bdp = dev->priv;
+		void *addr = ifr->ifr_data;
+		int i;
+
+		for(i = 0; i < E100_STATS_LEN; i++)
+			stats.data[i] =
+				((unsigned long *)&bdp->drv_stats.net_stats)[i];
+		if(copy_to_user(addr, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
 	case ETHTOOL_GWOL:
 	case ETHTOOL_SWOL:
 		rc = e100_ethtool_wol(dev, ifr);
@@ -3456,6 +3446,7 @@
 		sizeof (info.fw_version) - 1);
 	strncpy(info.bus_info, bdp->pdev->slot_name,
 		sizeof (info.bus_info) - 1);
+	info.n_stats = E100_STATS_LEN;
 	info.regdump_len  = E100_REGS_LEN * sizeof(u32);
 	info.eedump_len = (bdp->eeprom_size << 1);	
 	info.testinfo_len = E100_MAX_TEST_RES;
@@ -3816,6 +3807,19 @@
 				test_strings[i]);
 		}
 		break;
+	case ETH_SS_STATS: {
+		char *strings = NULL;
+		void *addr = ifr->ifr_data;
+		info.len = E100_STATS_LEN;
+		strings = *e100_gstrings_stats;
+		if(copy_to_user(ifr->ifr_data, &info, sizeof(info)))
+			return -EFAULT;
+		addr += offsetof(struct ethtool_gstrings, data);
+		if(copy_to_user(addr, strings,
+		   info.len * ETH_GSTRING_LEN))
+			return -EFAULT;
+		return 0;
+	}
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -4054,29 +4058,6 @@
 	spin_unlock_bh(&(bdp->bd_non_tx_lock));
 }
 
-int e100_notify_netdev(struct notifier_block *nb, unsigned long event, void *p)
-{
-	struct e100_private *bdp;
-	struct net_device *netdev = p;
-	
-	if(netdev == NULL)
-		return NOTIFY_DONE;
-	
-	switch(event) {
-	case NETDEV_CHANGENAME:
-		if(netdev->open == e100_open) {
-			bdp = netdev->priv;
-			/* rename the proc nodes the easy way */
-			e100_remove_proc_subdir(bdp, bdp->ifname);
-			memcpy(bdp->ifname, netdev->name, IFNAMSIZ);
-			bdp->ifname[IFNAMSIZ-1] = 0;
-			e100_create_proc_subdir(bdp, bdp->ifname);
-		}
-		break;
-	}
-	return NOTIFY_DONE;
-}
-
 #ifdef CONFIG_PM
 static int
 e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
@@ -4139,128 +4120,6 @@
 	return 0;
 }
 #endif /* CONFIG_PM */
-
-static void
-e100_get_mdix_status(struct e100_private *bdp)
-{	
-	if (bdp->rev_id < D102_REV_ID) {
-		if (netif_carrier_ok(bdp->device))
-			bdp->mdix_status = "MDI";				
-		else			
-			bdp->mdix_status = "None";
-	} else {	
-		u16 ctrl_reg;
-		/* Read the MDIX control register */
-		e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &ctrl_reg);
-		if (ctrl_reg & MDI_MDIX_CONFIG_IS_OK) {
-			if (ctrl_reg & MDI_MDIX_STATUS)
-				bdp->mdix_status = "MDI-X";
-			else
-				bdp->mdix_status = "MDI";
-		} else
-			bdp->mdix_status = "None";
-	}
-}
-
-static void
-e100_do_hwi(struct net_device *dev)
-{
-	struct e100_private *bdp = dev->priv;
-	u16 ctrl_reg;
-	int distance, open_circut, short_circut;
-
-	e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
-
-	distance = ctrl_reg & HWI_TEST_DISTANCE;
-	open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
-	short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
-
-	if ((distance == bdp->saved_distance) &&
-	    (open_circut == bdp->saved_open_circut) &&
-	    (short_circut == bdp->saved_short_circut)) 
-		bdp->saved_same++;
-	else {
-		bdp->saved_same = 0;
-		bdp->saved_distance = distance;
-		bdp->saved_open_circut = open_circut;
-		bdp->saved_short_circut = short_circut;
-	}
-		
-	if (bdp->saved_same == MAX_SAME_RESULTS) {
-		if ((open_circut && !(short_circut)) ||
-		    (!(open_circut) && short_circut)) {
-
-			u8 near_end = ((distance * HWI_REGISTER_GRANULARITY) <
-				       HWI_NEAR_END_BOUNDARY);
-			if (open_circut) {
-				if (near_end) 
-					bdp->cable_status = "Open Circut Near End";
-				else 
-					bdp->cable_status = "Open Circut Far End";
-			} else {
-				if (near_end) 
-					bdp->cable_status = "Short Circut Near End";
-				else 
-					bdp->cable_status = "Short Circut Far End";
-			}
-			goto done;
-		}
-	}
-	else if (bdp->saved_i == HWI_MAX_LOOP) {
-		bdp->cable_status = "Test failed";
-		goto done;
-	}
-		
-	/* Do another hwi test */
-	e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
-		       (HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
-	bdp->saved_i++;
-	/* relaunch hwi timer in 1 msec */
-	mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
-	return;
-
-done:
-	e100_hwi_restore(bdp);
-	bdp->hwi_started = 0;
-	return;
-}
-
-static void e100_hwi_restore(struct e100_private *bdp)
-{
-	u16 control = 0;
-
-	/* Restore speed, duplex and autoneg before */
-	/* hwi test, i.e., cable diagnostic         */
-	
-	/* Reset hwi test */
-        e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,					       HWI_RESET_ALL_MASK);
-				
-	if ((bdp->params.e100_speed_duplex == E100_AUTONEG) &&
-        	(bdp->rev_id >= D102_REV_ID)) 
-		/* Enable MDI/MDI-X auto switching */
-                e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
-			MDI_MDIX_AUTO_SWITCH_ENABLE);
-
-	switch (bdp->params.e100_speed_duplex) {
-	case E100_SPEED_10_HALF:
-		break;
-	case E100_SPEED_10_FULL:
-		control = BMCR_FULLDPLX;
-		break;
-	case E100_SPEED_100_HALF:
-		control = BMCR_SPEED100;
-		break;
-	case E100_SPEED_100_FULL:
-		control = BMCR_SPEED100 | BMCR_FULLDPLX;
-		break;
-	case E100_AUTONEG:
-		control = BMCR_ANENABLE | BMCR_ANRESTART;
-		break;
-	}
-	/* Restore original speed/duplex */
-	e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
-	return;
-}
 
 #ifdef E100_CU_DEBUG
 unsigned char
diff -Nru a/drivers/net/e100/e100_proc.c b/drivers/net/e100/e100_proc.c
--- a/drivers/net/e100/e100_proc.c	Mon Feb 10 10:39:25 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,474 +0,0 @@
-/*******************************************************************************
-
-  
-  Copyright(c) 1999 - 2002 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.
-  
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-*******************************************************************************/
-
-/**********************************************************************
-*                                                                       *
-* INTEL CORPORATION                                                     *
-*                                                                       *
-* This software is supplied under the terms of the license included     *
-* above.  All use of this driver must be in accordance with the terms   *
-* of that license.                                                      *
-*                                                                       *
-* Module Name:  e100_proc.c                                             *
-*                                                                       *
-* Abstract:     Functions to handle the proc file system.               *
-*               Create the proc directories and files and run read and  *
-*               write requests from the user                            *
-*                                                                       *
-* Environment:  This file is intended to be specific to the Linux       *
-*               operating system.                                       *
-*                                                                       *
-**********************************************************************/
-
-#include <linux/config.h>
-
-#ifdef CONFIG_PROC_FS
-#include "e100.h"
-/* MDI sleep time is at least 50 ms, in jiffies */
-#define MDI_SLEEP_TIME ((HZ / 20) + 1)
-/***************************************************************************/
-/*       /proc File System Interaface Support Functions                    */
-/***************************************************************************/
-
-static struct proc_dir_entry *adapters_proc_dir = 0;
-
-/* externs from e100_main.c */
-extern char e100_short_driver_name[];
-extern char e100_driver_version[];
-extern struct net_device_stats *e100_get_stats(struct net_device *dev);
-extern char *e100_get_brand_msg(struct e100_private *bdp);
-extern int e100_mdi_write(struct e100_private *, u32, u32, u16);
-
-static void e100_proc_cleanup(void);
-static unsigned char e100_init_proc_dir(void);
-
-#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
-#define WRITE_BUF_MAX_LEN 20	
-#define READ_BUF_MAX_LEN  256
-#define E100_PE_LEN       25
-
-#define bdp_drv_off(off) (unsigned long)(offsetof(struct e100_private, drv_stats.off))
-#define bdp_prm_off(off) (unsigned long)(offsetof(struct e100_private, params.off))
-
-typedef struct _e100_proc_entry {
-	char *name;
-	read_proc_t *read_proc;
-	write_proc_t *write_proc;
-	unsigned long offset;	/* offset into bdp. ~0 means no value, pass NULL. */
-} e100_proc_entry;
-
-static int
-generic_read(char *page, char **start, off_t off, int count, int *eof, int len)
-{
-	if (len <= off + count)
-		*eof = 1;
-
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-
-static int
-read_ulong(char *page, char **start, off_t off,
-	   int count, int *eof, unsigned long l)
-{
-	int len;
-
-	len = sprintf(page, "%lu\n", l);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_gen_ulong(char *page, char **start, off_t off,
-	       int count, int *eof, void *data)
-{
-	unsigned long val = 0;
-
-	if (data)
-		val = *((unsigned long *) data);
-
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_hwaddr(char *page, char **start, off_t off,
-	    int count, int *eof, unsigned char *hwaddr)
-{
-	int len;
-
-	len = sprintf(page, "%02X:%02X:%02X:%02X:%02X:%02X\n",
-		      hwaddr[0], hwaddr[1], hwaddr[2],
-		      hwaddr[3], hwaddr[4], hwaddr[5]);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_descr(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	int len;
-
-	len = sprintf(page, "%s\n", bdp->id_string);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_permanent_hwaddr(char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned char *hwaddr = bdp->perm_node_address;
-
-	return read_hwaddr(page, start, off, count, eof, hwaddr);
-}
-
-static int
-read_part_number(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	int len;
-
-	len = sprintf(page, "%06lx-%03x\n",
-		      (unsigned long) (bdp->pwa_no >> 8),
-		      (unsigned int) (bdp->pwa_no & 0xFF));
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static void
-set_led(struct e100_private *bdp, u16 led_mdi_op)
-{
-	e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
-		       bdp->phy_addr, led_mdi_op);
-
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(MDI_SLEEP_TIME);
-
-	/* turn led ownership to the chip */
-	e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
-		       bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL);
-}
-
-static int
-write_blink_led_timer(struct file *file, const char *buffer,
-		      unsigned long count, void *data)
-{
-	struct e100_private *bdp = data;
-	char s_blink_op[WRITE_BUF_MAX_LEN + 1];
-	char *res;
-	unsigned long i_blink_op;
-
-	if (!buffer)
-		return -EINVAL;
-
-	if (count > WRITE_BUF_MAX_LEN) {
-		count = WRITE_BUF_MAX_LEN;
-	}
-	if (copy_from_user(s_blink_op, buffer, count))
-		return -EFAULT;
-	s_blink_op[count] = '\0';
-	i_blink_op = simple_strtoul(s_blink_op, &res, 0);
-	if (res == s_blink_op) {
-		return -EINVAL;
-	}
-
-	switch (i_blink_op) {
-
-	case LED_OFF:
-		set_led(bdp, PHY_82555_LED_OFF);
-		break;
-	case LED_ON:
-		if (bdp->rev_id >= D101MA_REV_ID)
-			set_led(bdp, PHY_82555_LED_ON_559);
-		else
-			set_led(bdp, PHY_82555_LED_ON_PRE_559);
-
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return count;
-}
-
-static e100_proc_entry e100_proc_list[] = {
-	{"Description",           read_descr,            0, 0},
-	{"Permanent_HWaddr",      read_permanent_hwaddr, 0, 0},
-	{"Part_Number",           read_part_number,      0, 0},
-	{"\n",},
-	{"Rx_TCP_Checksum_Good",  read_gen_ulong, 0, ~0},
-	{"Rx_TCP_Checksum_Bad",   read_gen_ulong, 0, ~0},
-	{"Tx_TCP_Checksum_Good",  read_gen_ulong, 0, ~0},
-	{"Tx_TCP_Checksum_Bad",   read_gen_ulong, 0, ~0},
-	{"\n",},
-	{"Tx_Abort_Late_Coll",    read_gen_ulong, 0, bdp_drv_off(tx_late_col)},
-	{"Tx_Deferred_Ok",        read_gen_ulong, 0, bdp_drv_off(tx_ok_defrd)},
-	{"Tx_Single_Coll_Ok",     read_gen_ulong, 0, bdp_drv_off(tx_one_retry)},
-	{"Tx_Multi_Coll_Ok",      read_gen_ulong, 0, bdp_drv_off(tx_mt_one_retry)},
-	{"Rx_Long_Length_Errors", read_gen_ulong, 0, ~0},
-	{"\n",},
-	{"Tx_Flow_Control_Pause", read_gen_ulong, 0, bdp_drv_off(xmt_fc_pkts)},
-	{"Rx_Flow_Control_Pause", read_gen_ulong, 0, bdp_drv_off(rcv_fc_pkts)},
-	{"Rx_Flow_Control_Unsup", read_gen_ulong, 0, bdp_drv_off(rcv_fc_unsupported)},
-	{"\n",},
-	{"Tx_TCO_Packets",        read_gen_ulong, 0, bdp_drv_off(xmt_tco_pkts)},
-	{"Rx_TCO_Packets",        read_gen_ulong, 0, bdp_drv_off(rcv_tco_pkts)},
-	{"\n",},
-	{"Rx_Interrupt_Packets",  read_gen_ulong, 0, bdp_drv_off(rx_intr_pkts)},
-	{"Identify_Adapter", 0, write_blink_led_timer, 0},
-	{"", 0, 0, 0}
-};
-
-static int
-read_info(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	e100_proc_entry *pe;
-	int tmp;
-	void *val;
-	int len = 0;
-
-	for (pe = e100_proc_list; pe->name[0]; pe++) {
-		if (pe->name[0] == '\n') {
-			len += sprintf(page + len, "\n");
-			continue;
-		}
-
-		if (pe->read_proc) {
-			if ((len + READ_BUF_MAX_LEN + E100_PE_LEN + 1) >=
-			    PAGE_SIZE)
-				break;
-
-			if (pe->offset != ~0)
-				val = ((char *) bdp) + pe->offset;
-			else
-				val = NULL;
-
-			len += sprintf(page + len, "%-"
-				       __MODULE_STRING(E100_PE_LEN)
-				       "s ", pe->name);
-			len += pe->read_proc(page + len, start, 0,
-					     READ_BUF_MAX_LEN + 1, &tmp, val);
-		}
-	}
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static struct proc_dir_entry *
-create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
-	       read_proc_t * read_proc, write_proc_t * write_proc)
-{
-	struct proc_dir_entry *pdep;
-	mode_t mode = S_IFREG;
-
-	if (write_proc) {
-		mode |= S_IWUSR;
-		if (read_proc) {
-			mode |= S_IRUSR;
-		}
-
-	} else if (read_proc) {
-		mode |= S_IRUGO;
-	}
-
-	if (!(pdep = create_proc_entry(name, mode, parent)))
-		return NULL;
-
-	pdep->read_proc = read_proc;
-	pdep->write_proc = write_proc;
-	pdep->data = data;
-	return pdep;
-}
-
-void
-e100_remove_proc_subdir(struct e100_private *bdp, char *name)
-{
-	e100_proc_entry *pe;
-	char info[256];
-	int len;
-
-	/* If our root /proc dir was not created, there is nothing to remove */
-	if (adapters_proc_dir == NULL) {
-		return;
-	}
-
-	len = strlen(bdp->ifname);
-	strncpy(info, bdp->ifname, sizeof (info));
-	strncat(info + len, ".info", sizeof (info) - len);
-
-	if (bdp->proc_parent) {
-		for (pe = e100_proc_list; pe->name[0]; pe++) {
-			if (pe->name[0] == '\n')
-				continue;
-
-			remove_proc_entry(pe->name, bdp->proc_parent);
-		}
-
-		remove_proc_entry(bdp->ifname, adapters_proc_dir);
-		bdp->proc_parent = NULL;
-	}
-
-	remove_proc_entry(info, adapters_proc_dir);
-
-	/* try to remove the main /proc dir, if it's empty */
-	e100_proc_cleanup();
-}
-
-int
-e100_create_proc_subdir(struct e100_private *bdp)
-{
-	struct proc_dir_entry *dev_dir;
-	e100_proc_entry *pe;
-	char info[256];
-	int len;
-	void *data;
-
-	/* create the main /proc dir if needed */
-	if (!adapters_proc_dir) {
-		if (!e100_init_proc_dir())
-			return -ENOMEM;
-	}
-
-	strncpy(info, bdp->ifname, sizeof (info));
-	len = strlen(info);
-	strncat(info + len, ".info", sizeof (info) - len);
-
-	/* info */
-	if (!(create_proc_rw(info, bdp, adapters_proc_dir, read_info, 0))) {
-		e100_proc_cleanup();
-		return -ENOMEM;
-	}
-
-	dev_dir = create_proc_entry(bdp->ifname, S_IFDIR,
-				    adapters_proc_dir);
-	bdp->proc_parent = dev_dir;
-
-	if (!dev_dir) {
-		e100_remove_proc_subdir(bdp, bdp->ifname);
-		return -ENOMEM;
-	}
-
-	for (pe = e100_proc_list; pe->name[0]; pe++) {
-		if (pe->name[0] == '\n')
-			continue;
-
-		if (pe->offset != ~0)
-			data = ((char *) bdp) + pe->offset;
-		else
-			data = NULL;
-
-		if (!(create_proc_rw(pe->name, data, dev_dir,
-				     pe->read_proc, pe->write_proc))) {
-			e100_remove_proc_subdir(bdp, bdp->ifname);
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
-/****************************************************************************
- * Name:          e100_init_proc_dir
- *
- * Description:   This routine creates the top-level /proc directory for the
- *                driver in /proc/net
- *
- * Arguments:     none
- *
- * Returns:       true on success, false on fail
- *
- ***************************************************************************/
-static unsigned char
-e100_init_proc_dir(void)
-{
-	int len;
-
-	/* first check if adapters_proc_dir already exists */
-	len = strlen(ADAPTERS_PROC_DIR);
-	for (adapters_proc_dir = proc_net->subdir;
-	     adapters_proc_dir; adapters_proc_dir = adapters_proc_dir->next) {
-
-		if ((adapters_proc_dir->namelen == len) &&
-		    (!memcmp(adapters_proc_dir->name, ADAPTERS_PROC_DIR, len)))
-			break;
-	}
-
-	if (!adapters_proc_dir)
-		adapters_proc_dir =
-			create_proc_entry(ADAPTERS_PROC_DIR, S_IFDIR, proc_net);
-
-	if (!adapters_proc_dir)
-		return false;
-
-	return true;
-}
-
-/****************************************************************************
- * Name:          e100_proc_cleanup
- *
- * Description:   This routine clears the top-level /proc directory, if empty.
- *
- * Arguments:     none
- *
- * Returns:       none
- *
- ***************************************************************************/
-static void
-e100_proc_cleanup(void)
-{
-	struct proc_dir_entry *de;
-
-	if (adapters_proc_dir == NULL) {
-		return;
-	}
-
-	/* check if subdir list is empty before removing adapters_proc_dir */
-	for (de = adapters_proc_dir->subdir; de; de = de->next) {
-		/* ignore . and .. */
-		if (*(de->name) != '.')
-			break;
-	}
-
-	if (de)
-		return;
-
-	remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);
-	adapters_proc_dir = NULL;
-}
-
-#endif /* CONFIG_PROC_FS */
diff -Nru a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
--- a/drivers/net/e1000/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/e1000/Makefile	Mon Feb 10 10:39:23 2003
@@ -32,5 +32,4 @@
 
 obj-$(CONFIG_E1000) += e1000.o
 
-e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o \
-	      e1000_proc.o
+e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/e1000/e1000.h	Mon Feb 10 10:39:23 2003
@@ -157,9 +157,6 @@
 struct e1000_adapter {
 	struct timer_list watchdog_timer;
 	struct timer_list phy_info_timer;
-#ifdef CONFIG_PROC_FS
-	struct list_head proc_list_head;
-#endif
 	struct vlan_group *vlgrp;
 	char *id_string;
 	uint32_t bd_number;
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/e1000/e1000_ethtool.c	Mon Feb 10 10:39:27 2003
@@ -39,6 +39,16 @@
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
 
+static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+	"rx_length_errors", "rx_over_errors", "rx_crc_errors",
+	"rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+	"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+	"tx_heartbeat_errors", "tx_window_errors",
+};
+#define E1000_STATS_LEN	sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN
+
 static void
 e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd)
 {
@@ -173,6 +183,7 @@
 	strncpy(drvinfo->version, e1000_driver_version, 32);
 	strncpy(drvinfo->fw_version, "N/A", 32);
 	strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32);
+	drvinfo->n_stats = E1000_STATS_LEN;
 #define E1000_REGS_LEN 32
 	drvinfo->regdump_len  = E1000_REGS_LEN * sizeof(uint32_t);
 	drvinfo->eedump_len  = e1000_eeprom_size(&adapter->hw);
@@ -209,18 +220,24 @@
                       struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	int i, max_len, first_word, last_word;
-
-	if(eeprom->len == 0)
-		return -EINVAL;
+	int max_len, first_word, last_word;
+	int ret_val = 0;
+	int i;
+
+	if(eeprom->len == 0) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
 	max_len = e1000_eeprom_size(hw);
 
-	if(eeprom->offset > eeprom->offset + eeprom->len)
-		return -EINVAL;
-	
+	if(eeprom->offset > eeprom->offset + eeprom->len) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
+
 	if((eeprom->offset + eeprom->len) > max_len)
 		eeprom->len = (max_len - eeprom->offset);
 
@@ -230,7 +247,8 @@
 	for(i = 0; i <= (last_word - first_word); i++)
 		e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
 
-	return 0;
+geeprom_error:
+	return ret_val;
 }
 
 static int
@@ -238,9 +256,10 @@
                       struct ethtool_eeprom *eeprom, void *user_data)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	uint16_t eeprom_buff[256];
-	int i, max_len, first_word, last_word;
+	uint16_t *eeprom_buff;
+	int max_len, first_word, last_word;
 	void *ptr;
+	int i;
 
 	if(eeprom->len == 0)
 		return -EOPNOTSUPP;
@@ -255,6 +274,10 @@
 
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+	if(eeprom_buff == NULL)
+		return -ENOMEM;
+
 	ptr = (void *)eeprom_buff;
 
 	if(eeprom->offset & 1) {
@@ -269,8 +292,10 @@
 		e1000_read_eeprom(hw, last_word,
 		                  &eeprom_buff[last_word - first_word]);
 	}
-	if(copy_from_user(ptr, user_data, eeprom->len))
+	if(copy_from_user(ptr, user_data, eeprom->len)) {
+		kfree(eeprom_buff);
 		return -EFAULT;
+	}
 
 	for(i = 0; i <= (last_word - first_word); i++)
 		e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
@@ -279,6 +304,8 @@
 	if(first_word <= EEPROM_CHECKSUM_REG)
 		e1000_update_eeprom_checksum(hw);
 
+	kfree(eeprom_buff);
+
 	return 0;
 }
 
@@ -438,6 +465,28 @@
 			return -EFAULT;
 		return 0;
 	}
+	case ETHTOOL_GSTRINGS: {
+		struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
+		char *strings = NULL;
+
+		if(copy_from_user(&gstrings, addr, sizeof(gstrings)))
+			return -EFAULT;
+		switch(gstrings.string_set) {
+		case ETH_SS_STATS:
+			gstrings.len = E1000_STATS_LEN;
+			strings = *e1000_gstrings_stats;
+			break;
+		default:
+			return -EOPNOTSUPP;
+		}
+		if(copy_to_user(addr, &gstrings, sizeof(gstrings)))
+			return -EFAULT;
+		addr += offsetof(struct ethtool_gstrings, data);
+		if(copy_to_user(addr, strings,
+		   gstrings.len * ETH_GSTRING_LEN))
+			return -EFAULT;
+		return 0;
+	}
 	case ETHTOOL_GREGS: {
 		struct ethtool_regs regs = {ETHTOOL_GREGS};
 		uint32_t regs_buff[E1000_REGS_LEN];
@@ -493,26 +542,40 @@
 	}
 	case ETHTOOL_GEEPROM: {
 		struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
-		uint16_t eeprom_buff[256];
+		uint16_t *eeprom_buff;
 		void *ptr;
-		int err;
+		int max_len, err = 0;
 
-		if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
-			return -EFAULT;
+		max_len = e1000_eeprom_size(&adapter->hw);
 
-		if((err = e1000_ethtool_geeprom(adapter, 
-			&eeprom, eeprom_buff)))
-			return err;
+		eeprom_buff = kmalloc(max_len, GFP_KERNEL);
 
-		if(copy_to_user(addr, &eeprom, sizeof(eeprom)))
-			return -EFAULT;
+		if(eeprom_buff == NULL)
+			return -ENOMEM;
+
+		if(copy_from_user(&eeprom, addr, sizeof(eeprom))) {
+			err = -EFAULT;
+			goto err_geeprom_ioctl;
+		}
+
+		if((err = e1000_ethtool_geeprom(adapter, &eeprom,
+						eeprom_buff)))
+			goto err_geeprom_ioctl;
+
+		if(copy_to_user(addr, &eeprom, sizeof(eeprom))) {
+			err = -EFAULT;
+			goto err_geeprom_ioctl;
+		}
 
 		addr += offsetof(struct ethtool_eeprom, data);
 		ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
 
 		if(copy_to_user(addr, ptr, eeprom.len))
-			return -EFAULT;
-		return 0;
+			err = -EFAULT;
+
+err_geeprom_ioctl:
+		kfree(eeprom_buff);
+		return err;
 	}
 	case ETHTOOL_SEEPROM: {
 		struct ethtool_eeprom eeprom;
@@ -525,6 +588,20 @@
 
 		addr += offsetof(struct ethtool_eeprom, data);
 		return e1000_ethtool_seeprom(adapter, &eeprom, addr);
+	}
+	case ETHTOOL_GSTATS: {
+		struct {
+			struct ethtool_stats cmd;
+			uint64_t data[E1000_STATS_LEN];
+		} stats = { {ETHTOOL_GSTATS, E1000_STATS_LEN} };
+		int i;
+
+		for(i = 0; i < E1000_STATS_LEN; i++)
+			stats.data[i] =
+				((unsigned long *)&adapter->net_stats)[i];
+		if(copy_to_user(addr, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
 	}
 	default:
 		return -EOPNOTSUPP;
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/net/e1000/e1000_main.c	Mon Feb 10 10:39:25 2003
@@ -59,7 +59,7 @@
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "4.4.19-k1";
+char e1000_driver_version[] = "4.4.19-k3";
 char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -171,7 +171,6 @@
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
 static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
-static int e1000_notify_netdev(struct notifier_block *, unsigned long event, void *ptr);
 static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
 #ifdef CONFIG_PM
 static int e1000_resume(struct pci_dev *pdev);
@@ -183,17 +182,9 @@
 	.priority	= 0
 };
 
-struct notifier_block e1000_notifier_netdev = {
-	.notifier_call	= e1000_notify_netdev,
-	.next		= NULL,
-	.priority	= 0
-};
-
 /* Exported from other modules */
 
 extern void e1000_check_options(struct e1000_adapter *adapter);
-extern void e1000_proc_dev_setup(struct e1000_adapter *adapter);
-extern void e1000_proc_dev_free(struct e1000_adapter *adapter);
 extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
 
 static struct pci_driver e1000_driver = {
@@ -229,10 +220,8 @@
 	printk(KERN_INFO "%s\n", e1000_copyright);
 
 	ret = pci_module_init(&e1000_driver);
-	if(ret >= 0) {
+	if(ret >= 0)
 		register_reboot_notifier(&e1000_notifier_reboot);
-		register_netdevice_notifier(&e1000_notifier_netdev);
-	}
 	return ret;
 }
 
@@ -249,7 +238,6 @@
 e1000_exit_module(void)
 {
 	unregister_reboot_notifier(&e1000_notifier_reboot);
-	unregister_netdevice_notifier(&e1000_notifier_netdev);
 	pci_unregister_driver(&e1000_driver);
 }
 
@@ -433,10 +421,8 @@
 		netdev->features = NETIF_F_SG;
 	}
 
-#ifdef NETIF_F_TSO
 	if(adapter->hw.mac_type >= e1000_82544)
 		netdev->features |= NETIF_F_TSO;
-#endif
  
 	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
@@ -490,7 +476,6 @@
 
 	printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string);
 	e1000_check_options(adapter);
-	e1000_proc_dev_setup(adapter);
 
 	/* Initial Wake on LAN setting
 	 * If APM wake is enabled in the EEPROM,
@@ -548,8 +533,6 @@
 
 	e1000_phy_hw_reset(&adapter->hw);
 
-	e1000_proc_dev_free(adapter);
-
 	iounmap(adapter->hw.hw_addr);
 	pci_release_regions(pdev);
 
@@ -1314,7 +1297,6 @@
 static inline boolean_t
 e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags)
 {
-#ifdef NETIF_F_TSO
 	struct e1000_context_desc *context_desc;
 	int i;
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
@@ -1358,7 +1340,6 @@
 
 		return TRUE;
 	}
-#endif
 	
 	return FALSE;
 }
@@ -1398,6 +1379,8 @@
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	int len, offset, size, count, i;
+	int tso = skb_shinfo(skb)->tso_size;
+	int nr_frags = skb_shinfo(skb)->nr_frags;
 
 	int f;
 	len = skb->len - skb->data_len;
@@ -1409,6 +1392,10 @@
 	while(len) {
 		i = (i + 1) % tx_ring->count;
 		size = min(len, adapter->max_data_per_txd);
+		/* Workaround for premature desc write-backs
+		 * in TSO mode.  Append 4-byte sentinel desc */
+		if(tso && !nr_frags && size == len && size > 4)
+			size -= 4;
 		tx_ring->buffer_info[i].length = size;
 		tx_ring->buffer_info[i].dma =
 			pci_map_single(adapter->pdev,
@@ -1422,7 +1409,7 @@
 		count++;
 	}
 
-	for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+	for(f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
 		frag = &skb_shinfo(skb)->frags[f];
@@ -1432,6 +1419,10 @@
 		while(len) {
 			i = (i + 1) % tx_ring->count;
 			size = min(len, adapter->max_data_per_txd);
+			/* Workaround for premature desc write-backs
+			 * in TSO mode.  Append 4-byte sentinel desc */
+			if(tso && f == (nr_frags-1) && size == len && size > 4)
+				size -= 4;
 			tx_ring->buffer_info[i].length = size;
 			tx_ring->buffer_info[i].dma =
 				pci_map_page(adapter->pdev,
@@ -1439,6 +1430,7 @@
 					frag->page_offset + offset,
 					size,
 					PCI_DMA_TODEVICE);
+			tx_ring->buffer_info[i].time_stamp = jiffies;
 
 			len -= size;
 			offset += size;
@@ -1520,13 +1512,8 @@
 	for(f = 0; f < skb_shinfo(skb)->nr_frags; f++)
 		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
 		                       adapter->max_data_per_txd);
-#ifdef NETIF_F_TSO
 	if((skb_shinfo(skb)->tso_size) || (skb->ip_summed == CHECKSUM_HW))
 		count++;
-#else
-	if(skb->ip_summed == CHECKSUM_HW)
-		count++;
-#endif
 
 	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
 		netif_stop_queue(netdev);
@@ -1823,7 +1810,10 @@
 	
 #ifdef CONFIG_E1000_NAPI
 	if (netif_rx_schedule_prep(netdev)) {
-		e1000_irq_disable(adapter);
+		/* Disable interrupts and enable polling */
+		atomic_inc(&adapter->irq_sem);
+		E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+		E1000_WRITE_FLUSH(&adapter->hw);
 		__netif_rx_schedule(netdev);
 	}
 #else
@@ -2425,29 +2415,6 @@
 			if(pci_dev_driver(pdev) == &e1000_driver)
 				e1000_suspend(pdev, 3);
 		}
-	}
-	return NOTIFY_DONE;
-}
-
-static int
-e1000_notify_netdev(struct notifier_block *nb, unsigned long event, void *p)
-{
-	struct e1000_adapter *adapter;
-	struct net_device *netdev = p;
-	if(netdev == NULL)
-		return NOTIFY_DONE;
-
-	switch(event) {
-	case NETDEV_CHANGENAME:
-		if(netdev->open == e1000_open) {
-			adapter = netdev->priv;
-			/* rename the proc nodes the easy way */
-			e1000_proc_dev_free(adapter);
-			memcpy(adapter->ifname, netdev->name, IFNAMSIZ);
-			adapter->ifname[IFNAMSIZ-1] = 0;
-			e1000_proc_dev_setup(adapter);
-		}
-		break;
 	}
 	return NOTIFY_DONE;
 }
diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
--- a/drivers/net/e1000/e1000_osdep.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/e1000/e1000_osdep.h	Mon Feb 10 10:39:24 2003
@@ -27,7 +27,7 @@
 *******************************************************************************/
 
 
-/* glue for the OS independant part of e1000
+/* glue for the OS independent part of e1000
  * includes register access macros
  */
 
diff -Nru a/drivers/net/e1000/e1000_proc.c b/drivers/net/e1000/e1000_proc.c
--- a/drivers/net/e1000/e1000_proc.c	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,702 +0,0 @@
-/*******************************************************************************
-
-  
-  Copyright(c) 1999 - 2002 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.
-  
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/*
- * Proc fs support.
- *
- * Read-only files created by driver (if CONFIG_PROC_FS):
- *
- * /proc/net/PRO_LAN_Adapters/<ethx>.info
- * /proc/net/PRO_LAN_Adapters/<ethx>/<attribute>
- *
- * where <ethx>      is the system device name, i.e eth0.
- *       <attribute> is the driver attribute name.
- *
- * There is one file for each driver attribute, where the contents
- * of the file is the attribute value.  The ethx.info file contains
- * a list of all driver attributes in one file.
- *
- */
-
-#include "e1000.h"
-
-#ifdef CONFIG_PROC_FS
-
-#include <linux/proc_fs.h>
-
-#define ADAPTERS_PROC_DIR           "PRO_LAN_Adapters"
-#define TAG_MAX_LENGTH              32
-#define LINE_MAX_LENGTH             80
-#define FIELD_MAX_LENGTH            LINE_MAX_LENGTH - TAG_MAX_LENGTH - 3
-
-extern char e1000_driver_name[];
-extern char e1000_driver_version[];
-
-/*
- * The list of driver proc attributes is stored in a proc_list link
- * list.  The list is build with proc_list_setup and is used to
- * build the proc fs nodes.  The private data for each node is the
- * corresponding link in the link list.
- */
-
-struct proc_list {
-	struct list_head list;                  /* link list */
-	char tag[TAG_MAX_LENGTH + 1];           /* attribute name */
-	void *data;                             /* attribute data */
-	size_t len;				/* sizeof data */
-	char *(*func)(void *, size_t, char *);  /* format data func */
-};
-
-static int
-e1000_proc_read(char *page, char **start, off_t off, int count, int *eof)
-{
-	int len = strlen(page);
-
-	page[len++] = '\n';
-
-	if(len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if(len > count)
-		len = count;
-	if(len < 0)
-		len = 0;
-
-	return len;
-}
-
-static int
-e1000_proc_info_read(char *page, char **start, off_t off,
-                     int count, int *eof, void *data)
-{
-	struct list_head *proc_list_head = data, *curr;
-	struct proc_list *elem;
-	char *p = page;
-	char buf[FIELD_MAX_LENGTH + 1];
-
-	list_for_each(curr, proc_list_head) {
-		elem = list_entry(curr, struct proc_list, list);
-
-		if (p - page + LINE_MAX_LENGTH >= PAGE_SIZE)
-			break;
-
-		if(!strlen(elem->tag))
-			p += sprintf(p, "\n");
-		else
-			p += sprintf(p, "%-*.*s %.*s\n",
-				TAG_MAX_LENGTH, TAG_MAX_LENGTH,
-				elem->tag, FIELD_MAX_LENGTH,
-				elem->func(elem->data, elem->len, buf));
-	}
-
-	*p = '\0';
-
-	return e1000_proc_read(page, start, off, count, eof);
-}
-
-static int
-e1000_proc_single_read(char *page, char **start, off_t off,
-                       int count, int *eof, void *data)
-{
-	struct proc_list *elem = data;
-
-	sprintf(page, "%.*s", FIELD_MAX_LENGTH, elem->func(elem->data,
-	        elem->len, page));
-
-	return e1000_proc_read(page, start, off, count, eof);
-}
-
-static void
-e1000_proc_dirs_free(char *name, struct list_head *proc_list_head)
-{
-	struct proc_dir_entry *intel_proc_dir, *proc_dir;
-	char info_name[strlen(name) + strlen(".info")];
-
-	for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
-		intel_proc_dir = intel_proc_dir->next) {
-		if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
-		   !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)))
-			break;
-	}
-
-	if(!intel_proc_dir)
-		return;
-
-	for(proc_dir = intel_proc_dir->subdir; proc_dir;
-		proc_dir = proc_dir->next) {
-		if ((proc_dir->namelen == strlen(name)) &&
-		    !memcmp(proc_dir->name, name, strlen(name)))
-			break;
-	}
-
-	if(proc_dir) {
-		struct list_head *curr;
-		struct proc_list *elem;
-
-		list_for_each(curr, proc_list_head) {
-			elem = list_entry(curr, struct proc_list, list);
-			remove_proc_entry(elem->tag, proc_dir);
-		}
-
-		strcpy(info_name, name);
-		strcat(info_name, ".info");
-
-		remove_proc_entry(info_name, intel_proc_dir);
-		remove_proc_entry(name, intel_proc_dir);
-	}
-
-	/* If the intel dir is empty, remove it */
-
-	for(proc_dir = intel_proc_dir->subdir; proc_dir;
-		proc_dir = proc_dir->next) {
-
-		/* ignore . and .. */
-
-		if(*(proc_dir->name) == '.')
-			continue;
-		break;
-	}
-
-	if(!proc_dir)
-		remove_proc_entry(ADAPTERS_PROC_DIR, proc_net);
-}
-
-
-static int
-e1000_proc_singles_create(struct proc_dir_entry *parent,
-                          struct list_head *proc_list_head)
-{
-	struct list_head *curr;
-	struct proc_list *elem;
-
-	list_for_each(curr, proc_list_head) {
-		struct proc_dir_entry *proc_entry;
-
-		elem = list_entry(curr, struct proc_list, list);
-
-		if(!strlen(elem->tag))
-			continue;
-
-		if(!(proc_entry =
-			create_proc_entry(elem->tag, S_IFREG, parent)))
-			return 0;
-
-		proc_entry->read_proc = e1000_proc_single_read;
-		proc_entry->data = elem;
-		SET_MODULE_OWNER(proc_entry);
-	}
-
-	return 1;
-}
-
-static void
-e1000_proc_dirs_create(void *data, char *name,
-                       struct list_head *proc_list_head)
-{
-	struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry;
-	char info_name[strlen(name) + strlen(".info")];
-
-	for(intel_proc_dir = proc_net->subdir; intel_proc_dir;
-		intel_proc_dir = intel_proc_dir->next) {
-		if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) &&
-		   !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR)))
-			break;
-	}
-
-	if(!intel_proc_dir)
-		if(!(intel_proc_dir =
-			create_proc_entry(ADAPTERS_PROC_DIR,
-				S_IFDIR, proc_net)))
-			return;
-
-	if(!(proc_dir =
-		create_proc_entry(name, S_IFDIR, intel_proc_dir)))
-		return;
-	SET_MODULE_OWNER(proc_dir);
-
-	if(!e1000_proc_singles_create(proc_dir, proc_list_head))
-		return;
-
-	strcpy(info_name, name);
-	strcat(info_name, ".info");
-
-	if(!(info_entry =
-		create_proc_entry(info_name, S_IFREG, intel_proc_dir)))
-		return;
-	SET_MODULE_OWNER(info_entry);
-
-	info_entry->read_proc = e1000_proc_info_read;
-	info_entry->data = proc_list_head;
-}
-
-static void
-e1000_proc_list_add(struct list_head *proc_list_head, char *tag,
-                    void *data, size_t len,
-		    char *(*func)(void *, size_t, char *))
-{
-	struct proc_list *new = (struct proc_list *)
-		kmalloc(sizeof(struct proc_list), GFP_KERNEL);
-
-	if(!new)
-		return;
-
-	strncpy(new->tag, tag, TAG_MAX_LENGTH);
-	new->data = data;
-	new->len  = len;
-	new->func = func;
-
-	list_add_tail(&new->list, proc_list_head);
-}
-
-static void
-e1000_proc_list_free(struct list_head *proc_list_head)
-{
-	struct proc_list *elem;
-
-	while(!list_empty(proc_list_head)) {
-		elem = list_entry(proc_list_head->next, struct proc_list, list);
-		list_del(&elem->list);
-		kfree(elem);
-	}
-}
-
-/*
- * General purpose formating functions
- */
-
-static char *
-e1000_proc_str(void *data, size_t len, char *buf)
-{
-	sprintf(buf, "%s", (char *)data);
-	return buf;
-}
-
-static char *
-e1000_proc_hex(void *data, size_t len, char *buf)
-{
-	switch(len) {
-	case sizeof(uint8_t):
-		sprintf(buf, "0x%02x", *(uint8_t *)data);
-		break;
-	case sizeof(uint16_t):
-		sprintf(buf, "0x%04x", *(uint16_t *)data);
-		break;
-	case sizeof(uint32_t):
-		sprintf(buf, "0x%08x", *(uint32_t *)data);
-		break;
-	case sizeof(uint64_t):
-		sprintf(buf, "0x%08Lx", (unsigned long long)*(uint64_t *)data);
-		break;
-	}
-	return buf;
-}
-
-static char *
-e1000_proc_unsigned(void *data, size_t len, char *buf)
-{
-	switch(len) {
-	case sizeof(uint8_t):
-		sprintf(buf, "%u", *(uint8_t *)data);
-		break;
-	case sizeof(uint16_t):
-		sprintf(buf, "%u", *(uint16_t *)data);
-		break;
-	case sizeof(uint32_t):
-		sprintf(buf, "%u", *(uint32_t *)data);
-		break;
-	case sizeof(uint64_t):
-		sprintf(buf, "%Lu", (unsigned long long)*(uint64_t *)data);
-		break;
-	}
-	return buf;
-}
-
-/*
- * Specific formating functions
- */
-
-static char *
-e1000_proc_part_number(void *data, size_t len, char *buf)
-{
-	sprintf(buf, "%06x-%03x", *(uint32_t *)data >> 8,
-	        *(uint32_t *)data & 0x000000FF);
-	return buf;
-}
-
-static char *
-e1000_proc_slot(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	sprintf(buf, "%u", PCI_SLOT(adapter->pdev->devfn));
-	return buf;
-}
-
-static char *
-e1000_proc_bus_type(void *data, size_t len, char *buf)
-{
-	e1000_bus_type bus_type = *(e1000_bus_type *)data;
-	sprintf(buf,
-		bus_type == e1000_bus_type_pci  ? "PCI"   :
-		bus_type == e1000_bus_type_pcix ? "PCI-X" :
-		"UNKNOWN");
-	return buf;
-}
-
-static char *
-e1000_proc_bus_speed(void *data, size_t len, char *buf)
-{
-	e1000_bus_speed bus_speed = *(e1000_bus_speed *)data;
-	sprintf(buf,
-		bus_speed == e1000_bus_speed_33  ? "33MHz"  :
-		bus_speed == e1000_bus_speed_66  ? "66MHz"  :
-		bus_speed == e1000_bus_speed_100 ? "100MHz" :
-		bus_speed == e1000_bus_speed_133 ? "133MHz" :
-		"UNKNOWN");
-	return buf;
-}
-
-static char *
-e1000_proc_bus_width(void *data, size_t len, char *buf)
-{
-	e1000_bus_width bus_width = *(e1000_bus_width *)data;
-	sprintf(buf,
-		bus_width == e1000_bus_width_32 ? "32-bit"   :
-		bus_width == e1000_bus_width_64 ? "64-bit" :
-		"UNKNOWN");
-	return buf;
-}
-
-static char *
-e1000_proc_hwaddr(void *data, size_t len, char *buf)
-{
-	unsigned char *hwaddr = data;
-	sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
-		hwaddr[0], hwaddr[1], hwaddr[2],
-		hwaddr[3], hwaddr[4], hwaddr[5]);
-	return buf;
-}
-
-static char *
-e1000_proc_link(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	sprintf(buf, netif_running(adapter->netdev) ?
-		netif_carrier_ok(adapter->netdev) ?
-		"up" : "down" : "N/A");
-	return buf;
-}
-
-static char *
-e1000_proc_link_speed(void *data, size_t len, char *buf)
-{
-	uint16_t link_speed = *(uint16_t *)data;
-	sprintf(buf, link_speed ? "%u" : "N/A", link_speed);
-	return buf;
-}
-
-static char *
-e1000_proc_link_duplex(void *data, size_t len, char *buf)
-{
-	uint16_t link_duplex = *(uint16_t *)data;
-	sprintf(buf,
-		link_duplex == FULL_DUPLEX ? "Full" :
-		link_duplex == HALF_DUPLEX ? "Half" :
-		"N/A");
-	return buf;
-}
-
-static char *
-e1000_proc_state(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	sprintf(buf, adapter->netdev->flags & IFF_UP ? "up" : "down");
-	return buf;
-}
-
-static char *
-e1000_proc_media_type(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	sprintf(buf,
-		adapter->hw.media_type == e1000_media_type_copper ?
-		"Copper" : "Fiber");
-	return buf;
-}
-
-static char *
-e1000_proc_cable_length(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	e1000_cable_length cable_length = adapter->phy_info.cable_length;
-	sprintf(buf, "%s%s",
-		cable_length == e1000_cable_length_50      ? "0-50"    :
-		cable_length == e1000_cable_length_50_80   ? "50-80"   :
-		cable_length == e1000_cable_length_80_110  ? "80-110"  :
-		cable_length == e1000_cable_length_110_140 ? "110-140" :
-		cable_length == e1000_cable_length_140     ? "> 140"   :
-		"Unknown",
-		cable_length != e1000_cable_length_undefined ?
-		" Meters (+/- 20 Meters)" : "");
-	return buf;
-}
-
-static char *
-e1000_proc_extended(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	e1000_10bt_ext_dist_enable dist_enable =
-		adapter->phy_info.extended_10bt_distance;
-	sprintf(buf,
-		dist_enable == e1000_10bt_ext_dist_enable_normal ? "Disabled" :
-		dist_enable == e1000_10bt_ext_dist_enable_lower  ? "Enabled"  :
-		"Unknown");
-	return buf;
-}
-
-static char *
-e1000_proc_cable_polarity(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	e1000_rev_polarity polarity = adapter->phy_info.cable_polarity;
-	sprintf(buf,
-		polarity == e1000_rev_polarity_normal   ? "Normal"   :
-		polarity == e1000_rev_polarity_reversed ? "Reversed" :
-		"Unknown");
-	return buf;
-}
-
-static char *
-e1000_proc_polarity_correction(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	e1000_polarity_reversal correction =
-		adapter->phy_info.polarity_correction;
-	sprintf(buf,
-		correction == e1000_polarity_reversal_enabled  ? "Disabled" :
-		correction == e1000_polarity_reversal_disabled ? "Enabled"  :
-		"Unknown");
-	return buf;
-}
-
-static char *
-e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf)
-{
-	struct e1000_adapter *adapter = data;
-	e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode;
-	sprintf(buf,
-		mdix_mode == e1000_auto_x_mode_manual_mdi  ? "MDI"   :
-		mdix_mode == e1000_auto_x_mode_manual_mdix ? "MDI-X" :
-		"Unknown");
-	return buf;
-}
-
-static char *
-e1000_proc_rx_status(void *data, size_t len, char *buf)
-{
-	e1000_1000t_rx_status rx_status = *(e1000_1000t_rx_status *)data;
-	sprintf(buf,
-		rx_status == e1000_1000t_rx_status_not_ok ? "NOT_OK" :
-		rx_status == e1000_1000t_rx_status_ok     ? "OK"     :
-		"Unknown");
-	return buf;
-}
-
-/*
- * e1000_proc_list_setup - build link list of proc praramters
- * @adapter: board private structure
- *
- * Order matters - ethx.info entries are ordered in the order links
- * are added to list.
- */
-
-#define LIST_ADD_F(T,D,F) \
-	e1000_proc_list_add(proc_list_head, (T), (D), sizeof(*(D)), (F))
-#define LIST_ADD_BLANK() LIST_ADD_F("", NULL, NULL)
-#define LIST_ADD_S(T,D) LIST_ADD_F((T), (D), e1000_proc_str)
-#define LIST_ADD_H(T,D) LIST_ADD_F((T), (D), e1000_proc_hex)
-#define LIST_ADD_U(T,D) LIST_ADD_F((T), (D), e1000_proc_unsigned)
-
-static void
-e1000_proc_list_setup(struct e1000_adapter *adapter)
-{
-	struct e1000_hw *hw = &adapter->hw;
-	struct list_head *proc_list_head = &adapter->proc_list_head;
-
-	INIT_LIST_HEAD(proc_list_head);
-
-	LIST_ADD_S("Description", adapter->id_string);
-	LIST_ADD_F("Part_Number", &adapter->part_num, e1000_proc_part_number);
-	LIST_ADD_S("Driver_Name", e1000_driver_name);
-	LIST_ADD_S("Driver_Version", e1000_driver_version);
-	LIST_ADD_H("PCI_Vendor", &hw->vendor_id);
-	LIST_ADD_H("PCI_Device_ID", &hw->device_id);
-	LIST_ADD_H("PCI_Subsystem_Vendor", &hw->subsystem_vendor_id);
-	LIST_ADD_H("PCI_Subsystem_ID", &hw->subsystem_id);
-	LIST_ADD_H("PCI_Revision_ID", &hw->revision_id);
-	LIST_ADD_U("PCI_Bus", &adapter->pdev->bus->number);
-	LIST_ADD_F("PCI_Slot", adapter, e1000_proc_slot);
-
-	if(adapter->hw.mac_type >= e1000_82543) {
-		LIST_ADD_F("PCI_Bus_Type",
-		           &hw->bus_type, e1000_proc_bus_type);
-		LIST_ADD_F("PCI_Bus_Speed",
-		           &hw->bus_speed, e1000_proc_bus_speed);
-		LIST_ADD_F("PCI_Bus_Width",
-		           &hw->bus_width, e1000_proc_bus_width);
-	}
-
-	LIST_ADD_U("IRQ", &adapter->pdev->irq);
-	LIST_ADD_S("System_Device_Name", adapter->ifname);
-	LIST_ADD_F("Current_HWaddr",
-	            adapter->netdev->dev_addr, e1000_proc_hwaddr);
-	LIST_ADD_F("Permanent_HWaddr",
-	            adapter->hw.perm_mac_addr, e1000_proc_hwaddr);
-
-	LIST_ADD_BLANK();
-
-	LIST_ADD_F("Link", adapter, e1000_proc_link);
-	LIST_ADD_F("Speed", &adapter->link_speed, e1000_proc_link_speed);
-	LIST_ADD_F("Duplex", &adapter->link_duplex, e1000_proc_link_duplex);
-	LIST_ADD_F("State", adapter, e1000_proc_state);
-
-	LIST_ADD_BLANK();
-
-	/* Standard net device stats */
-	LIST_ADD_U("Rx_Packets", &adapter->net_stats.rx_packets);
-	LIST_ADD_U("Tx_Packets", &adapter->net_stats.tx_packets);
-	LIST_ADD_U("Rx_Bytes", &adapter->net_stats.rx_bytes);
-	LIST_ADD_U("Tx_Bytes", &adapter->net_stats.tx_bytes);
-	LIST_ADD_U("Rx_Errors", &adapter->net_stats.rx_errors);
-	LIST_ADD_U("Tx_Errors", &adapter->net_stats.tx_errors);
-	LIST_ADD_U("Rx_Dropped", &adapter->net_stats.rx_dropped);
-	LIST_ADD_U("Tx_Dropped", &adapter->net_stats.tx_dropped);
-
-	LIST_ADD_U("Multicast", &adapter->net_stats.multicast);
-	LIST_ADD_U("Collisions", &adapter->net_stats.collisions);
-
-	LIST_ADD_U("Rx_Length_Errors", &adapter->net_stats.rx_length_errors);
-	LIST_ADD_U("Rx_Over_Errors", &adapter->net_stats.rx_over_errors);
-	LIST_ADD_U("Rx_CRC_Errors", &adapter->net_stats.rx_crc_errors);
-	LIST_ADD_U("Rx_Frame_Errors", &adapter->net_stats.rx_frame_errors);
-	LIST_ADD_U("Rx_FIFO_Errors", &adapter->net_stats.rx_fifo_errors);
-	LIST_ADD_U("Rx_Missed_Errors", &adapter->net_stats.rx_missed_errors);
-
-	LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors);
-	LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors);
-	LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors);
-	LIST_ADD_U("Tx_Heartbeat_Errors",
-	           &adapter->net_stats.tx_heartbeat_errors);
-	LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors);
-
-	/* 8254x-specific stats */
-	LIST_ADD_U("Tx_Abort_Late_Coll", &adapter->stats.latecol);
-	LIST_ADD_U("Tx_Deferred_Ok", &adapter->stats.dc);
-	LIST_ADD_U("Tx_Single_Coll_Ok", &adapter->stats.scc);
-	LIST_ADD_U("Tx_Multi_Coll_Ok", &adapter->stats.mcc);
-	LIST_ADD_U("Rx_Long_Length_Errors", &adapter->stats.roc);
-	LIST_ADD_U("Rx_Short_Length_Errors", &adapter->stats.ruc);
-	
-	/* The 82542 does not have some of these stats */
-	if(adapter->hw.mac_type >= e1000_82543) {
-		LIST_ADD_U("Rx_Align_Errors", &adapter->stats.algnerrc);
-		LIST_ADD_U("Tx_TCP_Seg_Good", &adapter->stats.tsctc);
-		LIST_ADD_U("Tx_TCP_Seg_Failed", &adapter->stats.tsctfc);
-	}
-	
-	LIST_ADD_U("Rx_Flow_Control_XON", &adapter->stats.xonrxc);
-	LIST_ADD_U("Rx_Flow_Control_XOFF", &adapter->stats.xoffrxc);
-	LIST_ADD_U("Tx_Flow_Control_XON", &adapter->stats.xontxc);
-	LIST_ADD_U("Tx_Flow_Control_XOFF", &adapter->stats.xofftxc);
-	LIST_ADD_U("Rx_CSum_Offload_Good", &adapter->hw_csum_good);
-	LIST_ADD_U("Rx_CSum_Offload_Errors", &adapter->hw_csum_err);
-
-	LIST_ADD_BLANK();
-
-	/* Cable diags */
-	LIST_ADD_F("PHY_Media_Type", adapter, e1000_proc_media_type);
-	if(adapter->hw.media_type == e1000_media_type_copper) {
-		LIST_ADD_F("PHY_Cable_Length",
-		           adapter, e1000_proc_cable_length);
-		LIST_ADD_F("PHY_Extended_10Base_T_Distance",
-		           adapter, e1000_proc_extended);
-		LIST_ADD_F("PHY_Cable_Polarity",
-		           adapter, e1000_proc_cable_polarity);
-		LIST_ADD_F("PHY_Disable_Polarity_Correction",
-		           adapter, e1000_proc_polarity_correction);
-		LIST_ADD_U("PHY_Idle_Errors",
-		           &adapter->phy_stats.idle_errors);
-		LIST_ADD_U("PHY_Receive_Errors",
-		           &adapter->phy_stats.receive_errors);
-		LIST_ADD_F("PHY_MDI_X_Enabled",
-		           adapter, e1000_proc_mdi_x_enabled);
-		LIST_ADD_F("PHY_Local_Receiver_Status",
-		           &adapter->phy_info.local_rx,
-			   e1000_proc_rx_status);
-		LIST_ADD_F("PHY_Remote_Receiver_Status",
-		           &adapter->phy_info.remote_rx,
-			   e1000_proc_rx_status);
-	}
-
-}
-
-/*
- * e1000_proc_dev_setup - create proc fs nodes and link list
- * @adapter: board private structure
- */
-
-void
-e1000_proc_dev_setup(struct e1000_adapter *adapter)
-{
-	e1000_proc_list_setup(adapter);
-
-	e1000_proc_dirs_create(adapter,
-	                       adapter->ifname,
-	                       &adapter->proc_list_head);
-}
-
-/*
- * e1000_proc_dev_free - free proc fs nodes and link list
- * @adapter: board private structure
- */
-
-void
-e1000_proc_dev_free(struct e1000_adapter *adapter)
-{
-	e1000_proc_dirs_free(adapter->ifname, &adapter->proc_list_head);
-
-	e1000_proc_list_free(&adapter->proc_list_head);
-}
-
-#else /* CONFIG_PROC_FS */
-
-void e1000_proc_dev_setup(struct e1000_adapter *adapter) {}
-void e1000_proc_dev_free(struct e1000_adapter *adapter) {}
-
-#endif /* CONFIG_PROC_FS */
-
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/fealnx.c	Mon Feb 10 10:39:30 2003
@@ -1563,7 +1563,7 @@
 }
 
 
-/* This routine is logically part of the interrupt handler, but seperated
+/* This routine is logically part of the interrupt handler, but separated
    for clarity and better register allocation. */
 static int netdev_rx(struct net_device *dev)
 {
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/net/hamachi.c	Mon Feb 10 10:39:33 2003
@@ -1468,7 +1468,7 @@
 	spin_unlock(&hmp->lock);
 }
 
-/* This routine is logically part of the interrupt handler, but seperated
+/* This routine is logically part of the interrupt handler, but separated
    for clarity and better register allocation. */
 static int hamachi_rx(struct net_device *dev)
 {
diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
--- a/drivers/net/hamradio/6pack.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/hamradio/6pack.c	Mon Feb 10 10:39:24 2003
@@ -113,7 +113,7 @@
 
 	/* 6pack stuff */
 	unsigned char		tx_delay;
-	unsigned char		persistance;
+	unsigned char		persistence;
 	unsigned char		slottime;
 	unsigned char		duplex;
 	unsigned char		led_state;
@@ -302,7 +302,7 @@
 
 	switch (p[0]) {
 		case 1:	sp->tx_delay = p[1];		return;
-		case 2:	sp->persistance = p[1];		return;
+		case 2:	sp->persistence = p[1];		return;
 		case 3: sp->slottime = p[1];		return;
 		case 4: /* ignored */			return;
 		case 5: sp->duplex = p[1];		return;
@@ -392,7 +392,7 @@
 
 	random = random * 17 + 41;
 
-	if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistance)) {
+	if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) {
 		sp->led_state = 0x70;
 		sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1);
 		sp->tx_enable = 1;
@@ -469,7 +469,7 @@
 
 	sp->duplex = 0;
 	sp->tx_delay    = SIXP_TXDELAY;
-	sp->persistance = SIXP_PERSIST;
+	sp->persistence = SIXP_PERSIST;
 	sp->slottime    = SIXP_SLOTTIME;
 	sp->led_state   = 0x60;
 	sp->status      = 1;
diff -Nru a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
--- a/drivers/net/hamradio/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/hamradio/Kconfig	Mon Feb 10 10:39:23 2003
@@ -15,7 +15,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called mkiss.o.
+	  will be called mkiss.
 
 config 6PACK
 	tristate "Serial port 6PACK driver"
@@ -35,7 +35,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called 6pack.o.
+	  will be called 6pack.
 
 config BPQETHER
 	tristate "BPQ Ethernet driver"
@@ -64,7 +64,7 @@
 
 	  This driver can operate multiple boards simultaneously. If you
 	  compile it as a module (by saying M instead of Y), it will be called
-	  dmascc.o. If you don't pass any parameter to the driver, all
+	  dmascc. If you don't pass any parameter to the driver, all
 	  possible I/O addresses are probed. This could irritate other devices
 	  that are currently not in use. You may specify the list of addresses
 	  to be probed by "dmascc=addr1,addr2,..." (when compiled into the
@@ -94,7 +94,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called scc.o.
+	  will be called scc.
 
 config SCC_DELAY
 	bool "additional delay for PA0HZP OptoSCC compatible boards"
@@ -132,7 +132,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called baycom_ser_fdx.o.
+	  recommended.  The module will be called baycom_ser_fdx.
 
 config BAYCOM_SER_HDX
 	tristate "BAYCOM ser12 halfduplex driver for AX.25"
@@ -151,7 +151,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called baycom_ser_hdx.o.
+	  recommended.  The module will be called baycom_ser_hdx.
 
 config BAYCOM_PAR
 	tristate "BAYCOM picpar and par96 driver for AX.25"
@@ -167,7 +167,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called baycom_par.o.
+	  recommended.  The module will be called baycom_par.
 
 config BAYCOM_EPP
 	tristate "BAYCOM epp driver for AX.25"
@@ -183,7 +183,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  This is
-	  recommended.  The module will be called baycom_par.o.
+	  recommended.  The module will be called baycom_par.
 
 config YAM
 	tristate "YAM driver for AX.25"
diff -Nru a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile
--- a/drivers/net/hamradio/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/hamradio/Makefile	Mon Feb 10 10:39:23 2003
@@ -10,8 +10,6 @@
 #		Christoph Hellwig <hch@infradead.org>
 #
 
-export-objs	= hdlcdrv.o
-
 obj-$(CONFIG_DMASCC)		+= dmascc.o
 obj-$(CONFIG_SCC)		+= scc.o
 obj-$(CONFIG_MKISS)		+= mkiss.o
diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/net/hamradio/scc.c	Mon Feb 10 10:39:31 2003
@@ -1703,7 +1703,7 @@
 
 	/*
 	 * Start transmission if the trx state is idle or
-	 * t_idle hasn't expired yet. Use dwait/persistance/slottime
+	 * t_idle hasn't expired yet. Use dwait/persistence/slottime
 	 * algorithm for normal halfduplex operation.
 	 */
 
diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
--- a/drivers/net/hamradio/yam.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/hamradio/yam.c	Mon Feb 10 10:39:30 2003
@@ -34,7 +34,7 @@
  *   0.5 F6FBB 01.08.98  Shared IRQs, /proc/net and network statistics
  *   0.6 F6FBB 25.08.98  Added 1200Bds format
  *   0.7 F6FBB 12.09.98  Added to the kernel configuration
- *   0.8 F6FBB 14.10.98  Fixed slottime/persistance timing bug
+ *   0.8 F6FBB 14.10.98  Fixed slottime/persistence timing bug
  *       OK1ZIA 2.09.01  Fixed "kfree_skb on hard IRQ" 
  *                       using dev_kfree_skb_any(). (important in 2.4 kernel)
  *   
diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
--- a/drivers/net/irda/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/irda/Kconfig	Mon Feb 10 10:39:30 2003
@@ -9,7 +9,7 @@
 	depends on IRDA
 	help
 	  Say Y here if you want to build support for the IrTTY line
-	  discipline.  If you want to compile it as a module (irtty-sir.o), say M
+	  discipline.  If you want to compile it as a module (irtty-sir), say M
 	  here and read <file:Documentation/modules.txt>.  IrTTY makes it
 	  possible to use Linux's own serial driver for all IrDA ports that
 	  are 16550 compatible.  Most IrDA chips are 16550 compatible so you
@@ -72,7 +72,7 @@
 	depends on IRDA
 	help
 	  Say Y here if you want to build support for the IrTTY line
-	  discipline.  If you want to compile it as a module (irtty.o), say M
+	  discipline.  If you want to compile it as a module (irtty), say M
 	  here and read <file:Documentation/modules.txt>.  IrTTY makes it
 	  possible to use Linux's own serial driver for all IrDA ports that
 	  are 16550 compatible.  Most IrDA chips are 16550 compatible so you
@@ -86,7 +86,7 @@
 	depends on IRDA
 	---help---
 	  Say Y here if you want to build support for the IrPORT IrDA device
-	  driver. If you want to compile it as a module (irport.o), say M here
+	  driver. If you want to compile it as a module (irport), say M here
 	  and read <file:Documentation/modules.txt>.  IrPORT can be used
 	  instead of IrTTY and sometimes this can be better.  One example is
 	  if your IrDA port does not have echo-canceling, which will work OK
@@ -188,7 +188,7 @@
 	  Say Y here if you want to build support for the Adaptec Airport 1000
 	  and 2000 dongles.  If you want to compile it as a module, say M here
 	  and read <file:Documentation/modules.txt>.  The module will be
-	  called old_belkin.o.  Some information is contained in the comments
+	  called old_belkin.  Some information is contained in the comments
 	  at the top of <file:drivers/net/irda/old_belkin.c>.
 
 config EP7211_IR
@@ -230,7 +230,7 @@
 	depends on IRDA && USB && EXPERIMENTAL
 	---help---
 	  Say Y here if you want to build support for the USB IrDA FIR Dongle
-	  device driver.  If you want to compile it as a module (irda-usb.o),
+	  device driver.  If you want to compile it as a module (irda-usb),
 	  say M here and read <file:Documentation/modules.txt>.  IrDA-USB
 	  support the various IrDA USB dongles available and most of their
 	  pecularities.  Those dongles plug in the USB port of your computer,
@@ -251,7 +251,7 @@
 
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  nsc-ircc.o.
+	  nsc-ircc.
 
 config WINBOND_FIR
 	tristate "Winbond W83977AF (IR)"
@@ -264,7 +264,7 @@
 
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  w83977af_ir.o.
+	  w83977af_ir.
 
 config TOSHIBA_OLD
 	tristate "Toshiba Type-O IR Port (old driver)"
@@ -276,7 +276,7 @@
 	  maintained and will be removed in favor of the new driver.
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called toshoboe.o.
+	  The module will be called toshoboe.
 
 config TOSHIBA_FIR
 	tristate "Toshiba Type-O IR Port"
@@ -287,7 +287,7 @@
 	  Libretto 100/110CT, Tecra 8100, Portege 7020 and many more laptops.
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called donauboe.o.
+	  The module will be called donauboe.
 
 config SMC_IRCC_FIR
 	tristate "SMC IrCC (EXPERIMENTAL)"
@@ -297,7 +297,7 @@
 	  Communications Controller.  It is used in the Fujitsu Lifebook 635t
 	  and Sony PCG-505TX.  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.  The module will be
-	  called smc-ircc.o.
+	  called smc-ircc.
 
 config ALI_FIR
 	tristate "ALi M5123 FIR (EXPERIMENTAL)"
@@ -310,7 +310,7 @@
 
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  ali-ircc.o.
+	  ali-ircc.
 
 config VLSI_FIR
 	tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)"
@@ -322,7 +322,8 @@
 	  FIR (4Mbps) speeds.
 
 	  If you want to compile it as a module, say M here and read
-	  <file:Documentation/modules.txt>. The module will be called vlsi_ir.o.
+	  <file:Documentation/modules.txt>. The module will be called
+	  vlsi_ir.
 
 config SA1100_FIR
 	tristate "SA1100 Internal IR"
diff -Nru a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
--- a/drivers/net/irda/Makefile	Mon Feb 10 10:39:26 2003
+++ b/drivers/net/irda/Makefile	Mon Feb 10 10:39:26 2003
@@ -5,8 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs	= irport.o sir_core.o
-
 # Old SIR drivers (irtty is broken)
 obj-$(CONFIG_IRTTY_OLD)		+= irtty.o
 obj-$(CONFIG_IRPORT_SIR)	+= 		irport.o
diff -Nru a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
--- a/drivers/net/irda/irport.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/irda/irport.c	Mon Feb 10 10:39:29 2003
@@ -102,9 +102,6 @@
  	int i;
 
  	for (i=0; (io[i] < 2000) && (i < 4); i++) {
- 		int ioaddr = io[i];
- 		if (check_region(ioaddr, IO_EXTENT))
- 			continue;
  		if (irport_open(i, io[i], irq[i]) != NULL)
  			return 0;
  	}
@@ -142,6 +139,14 @@
 
 	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
 
+	/* Lock the port that we need */
+	ret = request_region(iobase, IO_EXTENT, driver_name);
+	if (!ret) {
+		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
+			   __FUNCTION__, iobase);
+		return NULL;
+	}
+
 	/*
 	 *  Allocate new instance of the driver
 	 */
@@ -149,6 +154,7 @@
 	if (!self) {
 		ERROR("%s(), can't allocate memory for "
 		      "control block!\n", __FUNCTION__);
+		release_region(iobase, IO_EXTENT);
 		return NULL;
 	}
 	memset(self, 0, sizeof(struct irport_cb));
@@ -164,14 +170,6 @@
         self->io.sir_ext   = IO_EXTENT;
         self->io.irq       = irq;
         self->io.fifo_size = 16;
-
-	/* Lock the port that we need */
-	ret = request_region(self->io.sir_base, self->io.sir_ext, driver_name);
-	if (!ret) { 
-		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
-			   __FUNCTION__, self->io.sir_base);
-		return NULL;
-	}
 
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&self->qos);
diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/irda/sir_kthread.c	Mon Feb 10 10:39:30 2003
@@ -116,10 +116,10 @@
 	daemonize();
 	strcpy(current->comm, "kIrDAd");
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	set_fs(KERNEL_DS);
 
diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
--- a/drivers/net/lasi_82596.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/lasi_82596.c	Mon Feb 10 10:39:23 2003
@@ -91,6 +91,7 @@
 #include <asm/irq.h>
 #include <asm/pdc.h>
 #include <asm/cache.h>
+#include <asm/parisc-device.h>
 
 static char version[] __devinitdata =
 	"82596.c $Revision: 1.29 $\n";
@@ -121,13 +122,13 @@
 
 
 #define  CHECK_WBACK(addr,len) \
-	do { if (!dma_consistent) dma_cache_wback((unsigned long)addr,len); } while (0)
+	do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0)
 
 #define  CHECK_INV(addr,len) \
-	do { if (!dma_consistent) dma_cache_inv((unsigned long)addr,len); } while(0)
+	do { dma_cache_sync((void *)addr,len, DMA_FROM_DEVICE); } while(0)
 
 #define  CHECK_WBACK_INV(addr,len) \
-	do { if (!dma_consistent) dma_cache_wback_inv((unsigned long)addr,len); } while (0)
+	do { dma_cache_sync((void *)addr,len, DMA_BIDIRECTIONAL); } while (0)
 
 
 #define PA_I82596_RESET		0	/* Offsets relative to LASI-LAN-Addr.*/
@@ -383,6 +384,7 @@
 	int options;
 	spinlock_t lock;
 	dma_addr_t dma_addr;
+	struct device *dev;
 };
 
 static char init_setup[] =
@@ -402,10 +404,6 @@
 	0x00,
 	0x7f /*  *multi IA */ };
 
-static struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for 
-					pci_* functions under ccio. */
-static int dma_consistent = 1;	/* Zero if pci_alloc_consistent() fails */
-
 static int i596_open(struct net_device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -558,8 +556,8 @@
 		if (skb == NULL)
 			panic("82596: alloc_skb() failed");
 		skb_reserve(skb, 2);
-		dma_addr = pci_map_single(fake_pci_dev, skb->tail,PKT_BUF_SZ,
-					PCI_DMA_FROMDEVICE);
+		dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
+					  DMA_FROM_DEVICE);
 		skb->dev = dev;
 		rbd->v_next = rbd+1;
 		rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
@@ -605,9 +603,9 @@
 	for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
 		if (rbd->skb == NULL)
 			break;
-		pci_unmap_single(fake_pci_dev,
+		dma_unmap_single(lp->dev,
 				 (dma_addr_t)WSWAPchar(rbd->b_data), 
-				 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				 PKT_BUF_SZ, DMA_FROM_DEVICE);
 		dev_kfree_skb(rbd->skb);
 	}
 }
@@ -774,7 +772,7 @@
 				struct sk_buff *newskb;
 				dma_addr_t dma_addr;
 
-				pci_unmap_single(fake_pci_dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
 				/* Get fresh skbuff to replace filled one. */
 				newskb = dev_alloc_skb(PKT_BUF_SZ + 4);
 				if (newskb == NULL) {
@@ -788,7 +786,7 @@
 				rx_in_place = 1;
 				rbd->skb = newskb;
 				newskb->dev = dev;
-				dma_addr = pci_map_single(fake_pci_dev, newskb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
 				rbd->v_data = newskb->tail;
 				rbd->b_data = WSWAPchar(dma_addr);
 				CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
@@ -805,7 +803,7 @@
 				skb->dev = dev;
 				if (!rx_in_place) {
 					/* 16 byte align the data fields */
-					pci_dma_sync_single(fake_pci_dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+					dma_sync_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
 					skb_reserve(skb, 2);
 					memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len);
 				}
@@ -886,7 +884,7 @@
 			{
 				struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
 				struct sk_buff *skb = tx_cmd->skb;
-				pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE);
+				dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
 
 				dev_kfree_skb(skb);
 
@@ -1118,8 +1116,8 @@
 		tbd->pad = 0;
 		tbd->size = EOF | length;
 
-		tx_cmd->dma_addr = pci_map_single(fake_pci_dev, skb->data, skb->len, 
-				PCI_DMA_TODEVICE);
+		tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len,
+				DMA_TO_DEVICE);
 		tbd->data = WSWAPchar(tx_cmd->dma_addr);
 
 		DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
@@ -1156,6 +1154,8 @@
 {
 	int i;
 	struct i596_private *lp;
+	/* we're going to overwrite dev->priv, so pull the device out */
+	struct device *gen_dev = dev->priv;
 	char eth_addr[6];
 	dma_addr_t dma_addr;
 
@@ -1198,17 +1198,11 @@
 		printk("82596.c: MAC of HP700 LAN read from EEPROM\n");
 	}
 
-	dev->mem_start = (unsigned long) pci_alloc_consistent(fake_pci_dev, 
-		sizeof(struct i596_private), &dma_addr);
+	dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev, 
+		sizeof(struct i596_private), &dma_addr, GFP_KERNEL);
 	if (!dev->mem_start) {
-		printk("%s: Couldn't get consistent shared memory\n", dev->name);
-		dma_consistent = 0;
-		dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
-		if (!dev->mem_start) {
-			printk("%s: Couldn't get shared memory\n", dev->name);
-			return -ENOMEM;
-		}
-		dma_addr = virt_to_bus(dev->mem_start);
+		printk("%s: Couldn't get shared memory\n", dev->name);
+		return -ENOMEM;
 	}
 
 	ether_setup(dev);
@@ -1243,6 +1237,7 @@
 	lp->scb.rfd = I596_NULL;
 	lp->lock = SPIN_LOCK_UNLOCKED;
 	lp->dma_addr = dma_addr;
+	lp->dev = gen_dev;
 
 	CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private));
 
@@ -1320,7 +1315,7 @@
 					if ((ptr->status) & 0x1000)
 						lp->stats.tx_aborted_errors++;
 				}
-				pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE);
+				dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
 				dev_kfree_skb_irq(skb);
 
 				tx_cmd->cmd.command = 0; /* Mark free */
@@ -1530,8 +1525,6 @@
 		return -ENODEV;
 	}
 	
-	fake_pci_dev = ccio_get_fake(dev);
-
 	if (!dev->irq) {
 		printk(KERN_ERR __FILE__ ": IRQ not found for i82596 at 0x%lx\n", dev->hpa);
 		return -ENODEV;
@@ -1546,6 +1539,7 @@
 	netdevice->base_addr = dev->hpa;
 	netdevice->irq = dev->irq;
 	netdevice->init = i82596_probe;
+	netdevice->priv = &dev->dev;
 
 	retval = register_netdev(netdevice);
 	if (retval) {
@@ -1601,13 +1595,8 @@
 		unregister_netdev(netdevice);
 
 		lp = (struct i596_private *) netdevice->priv;
-		if (dma_consistent)
-			pci_free_consistent(fake_pci_dev, 
-					    sizeof(struct i596_private), 
-				(void *)netdevice->mem_start, lp->dma_addr);
-		else
-			free_page(netdevice->mem_start);
-
+		dma_free_noncoherent(lp->dev, sizeof(struct i596_private), 
+				       (void *)netdevice->mem_start, lp->dma_addr);
 		netdevice->priv = NULL;
 	}
 
diff -Nru a/drivers/net/mac8390.c b/drivers/net/mac8390.c
--- a/drivers/net/mac8390.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/mac8390.c	Mon Feb 10 10:39:27 2003
@@ -121,7 +121,7 @@
 	1, /* dayna-lc */
 };
 
-static const char __initdata * version =
+static char version[] __initdata =
 	"mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
 		
 extern int mac8390_probe(struct net_device * dev);
diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
--- a/drivers/net/pcmcia/3c574_cs.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/pcmcia/3c574_cs.c	Mon Feb 10 10:39:24 2003
@@ -305,6 +305,7 @@
 	link = &lp->link; dev = &lp->dev;
 	link->priv = dev->priv = link->irq.Instance = lp;
 	
+	init_timer(&link->release);
 	link->release.function = &tc574_release;
 	link->release.data = (u_long)link;
 	link->io.NumPorts1 = 32;
diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
--- a/drivers/net/pcmcia/3c589_cs.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/pcmcia/3c589_cs.c	Mon Feb 10 10:39:32 2003
@@ -229,6 +229,7 @@
     link = &lp->link; dev = &lp->dev;
     link->priv = dev->priv = link->irq.Instance = lp;
     
+    init_timer(&link->release);
     link->release.function = &tc589_release;
     link->release.data = (unsigned long)link;
     link->io.NumPorts1 = 16;
diff -Nru a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
--- a/drivers/net/pcmcia/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/pcmcia/Kconfig	Mon Feb 10 10:39:30 2003
@@ -30,7 +30,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c589_cs.o.  If you want to compile it as
+	  The module will be called 3c589_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>. If
 	  unsure, say N.
 
@@ -43,7 +43,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 3c574_cs.o.  If you want to compile it as
+	  The module will be called 3c574_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -56,7 +56,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called fmvj18x_cs.o.  If you want to compile it
+	  The module will be called fmvj18x_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
@@ -69,7 +69,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pcnet_cs.o.  If you want to compile it as
+	  The module will be called pcnet_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>. If
 	  unsure, say N.
 
@@ -82,7 +82,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called nmclan_cs.o.  If you want to compile it as
+	  The module will be called nmclan_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -95,7 +95,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smc91c92_cs.o.  If you want to compile it
+	  The module will be called smc91c92_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
@@ -108,7 +108,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called xirc2ps_cs.o.  If you want to compile it
+	  The module will be called xirc2ps_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
@@ -123,7 +123,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called axnet_cs.o.  If you want to compile it as
+	  The module will be called axnet_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -136,7 +136,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called com20020_cs.o.  If you want to compile it
+	  The module will be called com20020_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
@@ -150,7 +150,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ibmtr_cs.o.  If you want to compile it as
+	  The module will be called ibmtr_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config NET_PCMCIA_RADIO
@@ -177,7 +177,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ray_cs.o.  If you want to compile it as a
+	  The module will be called ray_cs.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -191,7 +191,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aironet4500_cs.o. If you want to
+	  The module will be called aironet4500_cs. If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile
--- a/drivers/net/pcmcia/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/pcmcia/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,9 +2,6 @@
 # Makefile for the Linux PCMCIA network device drivers.
 #
 
-# Things that need to export symbols
-export-objs	:= ray_cs.o
-
 # 16-bit client drivers
 obj-$(CONFIG_PCMCIA_3C589)	+= 3c589_cs.o
 obj-$(CONFIG_PCMCIA_3C574)	+= 3c574_cs.o
diff -Nru a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c
--- a/drivers/net/pcmcia/aironet4500_cs.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/pcmcia/aironet4500_cs.c	Mon Feb 10 10:39:23 2003
@@ -246,6 +246,7 @@
 
 	memset(link->dev, 0, sizeof(struct dev_node_t));
 
+	init_timer(&link->release);
 	link->release.function = &awc_release;
 	link->release.data = (u_long)link;
 //	link->io.NumPorts1 = 32;
diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/net/pcmcia/axnet_cs.c	Mon Feb 10 10:39:28 2003
@@ -203,6 +203,7 @@
     link = &info->link; dev = &info->dev;
     link->priv = info;
     
+    init_timer(&link->release);
     link->release.function = &axnet_release;
     link->release.data = (u_long)link;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
diff -Nru a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
--- a/drivers/net/pcmcia/com20020_cs.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/pcmcia/com20020_cs.c	Mon Feb 10 10:39:27 2003
@@ -221,6 +221,7 @@
     memset(link, 0, sizeof(struct dev_link_t));
     dev->priv = lp;
 
+    init_timer(&link->release);
     link->release.function = &com20020_release;
     link->release.data = (u_long)link;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/pcmcia/ibmtr_cs.c	Mon Feb 10 10:39:27 2003
@@ -221,6 +221,7 @@
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
+    init_timer(&link->release);
     link->release.function = &ibmtr_release;
     link->release.data = (u_long)link;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
--- a/drivers/net/pcmcia/nmclan_cs.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/pcmcia/nmclan_cs.c	Mon Feb 10 10:39:23 2003
@@ -493,6 +493,7 @@
     link = &lp->link; dev = &lp->dev;
     link->priv = dev->priv = link->irq.Instance = lp;
 
+    init_timer(&link->release);
     link->release.function = &nmclan_release;
     link->release.data = (u_long)link;
     link->io.NumPorts1 = 32;
diff -Nru a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c
--- a/drivers/net/pcmcia/ray_cs.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/net/pcmcia/ray_cs.c	Mon Feb 10 10:39:25 2003
@@ -378,6 +378,7 @@
     memset(dev, 0, sizeof(struct net_device));
     memset(local, 0, sizeof(ray_dev_t));
 
+    init_timer(&link->release);
     link->release.function = &ray_release;
     link->release.data = (u_long)link;
 
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	Mon Feb 10 10:39:25 2003
@@ -632,6 +632,7 @@
     link = &local->link; dev = &local->dev;
     link->priv = dev->priv = local;
 
+    init_timer(&link->release);
     link->release.function = &xirc2ps_release;
     link->release.data = (u_long) link;
 
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/ppp_generic.c	Mon Feb 10 10:39:32 2003
@@ -962,11 +962,10 @@
 		if (ppp->pass_filter.filter
 		    && sk_run_filter(skb, ppp->pass_filter.filter,
 				     ppp->pass_filter.len) == 0) {
-			if (ppp->debug & 1) {
+			if (ppp->debug & 1)
 				printk(KERN_DEBUG "PPP: outbound frame not passed\n");
-				kfree_skb(skb);
-				return;
-			}
+			kfree_skb(skb);
+			return;
 		}
 		/* if this packet passes the active filter, record the time */
 		if (!(ppp->active_filter.filter
diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c
--- a/drivers/net/rrunner.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/rrunner.c	Mon Feb 10 10:39:24 2003
@@ -386,7 +386,7 @@
 		writel(0, &regs->CmdRing[i]);
 
 /*
- * Why 32 ? is this not cache line size dependant?
+ * Why 32 ? is this not cache line size dependent?
  */
 	writel(RBURST_64|WBURST_64, &regs->PciState);
 	wmb();
diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
--- a/drivers/net/sgiseeq.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/sgiseeq.c	Mon Feb 10 10:39:32 2003
@@ -524,7 +524,7 @@
 	 * 2) Do no allow the HPC to look at a new descriptor until
 	 *    we have completely set up it's state.  This means, do
 	 *    not clear HPCDMA_EOX in the current last descritptor
-	 *    until the one we are adding looks consistant and could
+	 *    until the one we are adding looks consistent and could
 	 *    be processes right now.
 	 * 3) The tx interrupt code must notice when we've added a new
 	 *    entry and the HPC got to the end of the chain before we
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/net/sis900.c	Mon Feb 10 10:39:26 2003
@@ -750,7 +750,7 @@
 
 /* Read and write the MII management registers using software-generated
    serial MDIO protocol. Note that the command bits and data bits are
-   send out seperately */
+   send out separately */
 #define mdio_delay()    inl(mdio_addr)
 
 static void mdio_idle(long mdio_addr)
diff -Nru a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
--- a/drivers/net/sk98lin/skgeinit.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/sk98lin/skgeinit.c	Mon Feb 10 10:39:27 2003
@@ -1134,7 +1134,7 @@
  *	After calling this function the descriptor rings and rx and tx
  *	queues of this port may be reconfigured.
  *
- *	It is possible to stop the receive and transmit path seperate or
+ *	It is possible to stop the receive and transmit path separate or
  *	both together.
  *
  *	Dir =	SK_STOP_TX 	Stops the transmit path only and resets
diff -Nru a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
--- a/drivers/net/sk98lin/skvpd.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/sk98lin/skvpd.c	Mon Feb 10 10:39:29 2003
@@ -88,7 +88,7 @@
  *	Revision 1.9  1998/09/16 07:33:52  malthoff
  *	remove memcmp() by SK_MEMCMP and
  *	memcpy() by SK_MEMCPY() to be
- *	independant from the 'C' Standard Library.
+ *	independent from the 'C' Standard Library.
  *	
  *	Revision 1.8  1998/08/19 12:52:35  malthoff
  *	compiler fix: use SK_VPD_KEY instead of S_VPD.
diff -Nru a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
--- a/drivers/net/sk98lin/skxmac2.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/net/sk98lin/skxmac2.c	Mon Feb 10 10:39:33 2003
@@ -194,7 +194,7 @@
  *
  *	Revision 1.12  1998/10/14 14:45:04  malthoff
  *	Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by
- *	SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independant
+ *	SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent
  *	from the Sirq module.
  *
  *	Revision 1.11  1998/10/14 13:59:01  gklug
@@ -826,7 +826,7 @@
 	for (i = 0; i < 3; i++) {
 		/*
 		 * The following 2 statements are together endianess
-		 * independant. Remember this when changing.
+		 * independent. Remember this when changing.
 		 */
 		SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord);
 		XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord);
diff -Nru a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c
--- a/drivers/net/skfp/cfm.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/net/skfp/cfm.c	Mon Feb 10 10:39:27 2003
@@ -21,15 +21,15 @@
 */
 
 /*
- *	Hardware independant state machine implemantation
+ *	Hardware independent state machine implemantation
  *	The following external SMT functions are referenced :
  *
  *		queue_event()
  *
- *	The following external HW dependant functions are referenced :
+ *	The following external HW dependent functions are referenced :
  *		config_mux()
  *
- *	The following HW dependant events are required :
+ *	The following HW dependent events are required :
  *		NONE 
  */
 
diff -Nru a/drivers/net/skfp/ecm.c b/drivers/net/skfp/ecm.c
--- a/drivers/net/skfp/ecm.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/skfp/ecm.c	Mon Feb 10 10:39:24 2003
@@ -17,23 +17,23 @@
 /*
 	SMT ECM
 	Entity Coordination Management
-	Hardware independant state machine
+	Hardware independent state machine
 */
 
 /*
- * Hardware independant state machine implemantation
+ * Hardware independent state machine implemantation
  * The following external SMT functions are referenced :
  *
  * 		queue_event()
  * 		smt_timer_start()
  * 		smt_timer_stop()
  *
- * 	The following external HW dependant functions are referenced :
+ * 	The following external HW dependent functions are referenced :
  * 		sm_pm_bypass_req()
  * 		sm_pm_ls_latch()
  * 		sm_pm_get_ls()
  * 
- * 	The following HW dependant events are required :
+ * 	The following HW dependent events are required :
  *		NONE
  *
  */
diff -Nru a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h
--- a/drivers/net/skfp/h/osdef1st.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/skfp/h/osdef1st.h	Mon Feb 10 10:39:30 2003
@@ -13,7 +13,7 @@
  ******************************************************************************/
 
 /* 
- * Operating system-dependant definitions that have to be defined
+ * Operating system-dependent definitions that have to be defined
  * before any other header files are included.
  */
 
diff -Nru a/drivers/net/skfp/h/supern_2.h b/drivers/net/skfp/h/supern_2.h
--- a/drivers/net/skfp/h/supern_2.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/skfp/h/supern_2.h	Mon Feb 10 10:39:30 2003
@@ -926,7 +926,7 @@
 #define	PL_PC1		(1<<7)		/* BREAK   - entry point in start PCM*/
 #define	PL_PC2		(2<<7)		/* TRACE   - to localize stuck Beacon*/
 #define	PL_PC3		(3<<7)		/* CONNECT - synchronize ends of conn*/
-#define	PL_PC4		(4<<7)		/* NEXT	   - to seperate the signalng*/
+#define	PL_PC4		(4<<7)		/* NEXT	   - to separate the signalng*/
 #define	PL_PC5		(5<<7)		/* SIGNAL  - PCM trans/rec. bit infos*/
 #define	PL_PC6		(6<<7)		/* JOIN	   - 1. state to activ conn. */
 #define	PL_PC7		(7<<7)		/* VERIFY  - 2. - " - (3. ACTIVE) */
diff -Nru a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
--- a/drivers/net/skfp/pcmplc.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/skfp/pcmplc.c	Mon Feb 10 10:39:23 2003
@@ -20,19 +20,19 @@
 */
 
 /*
- * Hardware independant state machine implemantation
+ * Hardware independent state machine implemantation
  * The following external SMT functions are referenced :
  *
  * 		queue_event()
  * 		smt_timer_start()
  * 		smt_timer_stop()
  *
- * 	The following external HW dependant functions are referenced :
+ * 	The following external HW dependent functions are referenced :
  * 		sm_pm_control()
  *		sm_ph_linestate()
  *		sm_pm_ls_latch()
  *
- * 	The following HW dependant events are required :
+ * 	The following HW dependent events are required :
  *		PC_QLS
  *		PC_ILS
  *		PC_HLS
@@ -714,7 +714,7 @@
 	mib = phy->mib ;
 
 	/*
-	 * general transitions independant of state
+	 * general transitions independent of state
 	 */
 	switch (cmd) {
 	case PC_STOP :
diff -Nru a/drivers/net/skfp/rmt.c b/drivers/net/skfp/rmt.c
--- a/drivers/net/skfp/rmt.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/net/skfp/rmt.c	Mon Feb 10 10:39:33 2003
@@ -20,18 +20,18 @@
 */
 
 /*
- * Hardware independant state machine implemantation
+ * Hardware independent state machine implemantation
  * The following external SMT functions are referenced :
  *
  * 		queue_event()
  * 		smt_timer_start()
  * 		smt_timer_stop()
  *
- * 	The following external HW dependant functions are referenced :
+ * 	The following external HW dependent functions are referenced :
  *		sm_ma_control()
  *		sm_mac_check_beacon_claim()
  *
- * 	The following HW dependant events are required :
+ * 	The following HW dependent events are required :
  *		RM_RING_OP
  *		RM_RING_NON_OP
  *		RM_MY_BEACON
diff -Nru a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
--- a/drivers/net/skfp/skfddi.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/skfp/skfddi.c	Mon Feb 10 10:39:23 2003
@@ -33,7 +33,7 @@
  *   The driver architecture is based on the DEC FDDI driver by
  *   Lawrence V. Stefani and several ethernet drivers.
  *   I also used an existing Windows NT miniport driver.
- *   All hardware dependant fuctions are handled by the SysKonnect
+ *   All hardware dependent fuctions are handled by the SysKonnect
  *   Hardware Module.
  *   The only headerfiles that are directly related to this source
  *   are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h.
@@ -1729,7 +1729,7 @@
  *	dma_complete
  *
  *	The hardware module calls this routine when it has completed a DMA
- *	transfer. If the operating system dependant module has set up the DMA
+ *	transfer. If the operating system dependent module has set up the DMA
  *	channel via dma_master() (e.g. Windows NT or AIX) it should clean up
  *	the DMA channel.
  * Args
diff -Nru a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
--- a/drivers/net/skfp/smt.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/skfp/smt.c	Mon Feb 10 10:39:30 2003
@@ -417,7 +417,7 @@
 		/*
 		 * Make sure the fddiMACUNDA_Flag = FALSE is
 		 * included in the SRF so we don't generate
-		 * a seperate SRF for the deassertion of this
+		 * a separate SRF for the deassertion of this
 		 * condition
 		 */
 		update_dac(smc,0) ;
diff -Nru a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c
--- a/drivers/net/skfp/smtdef.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/skfp/smtdef.c	Mon Feb 10 10:39:23 2003
@@ -217,7 +217,7 @@
 	mib->fddiSMTStatRptPolicy = TRUE ;
 	mib->fddiSMTTrace_MaxExpiration = SEC2MIB(7) ;
 	mib->fddiSMTMACIndexes = INDEX_MAC ;
-	mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ;	/* seperated */
+	mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ;	/* separated */
 
 	mib->m[MAC0].fddiMACIndex = INDEX_MAC ;
 	mib->m[MAC0].fddiMACFrameStatusFunctions = FSC_TYPE0 ;
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/net/tg3.c	Mon Feb 10 10:39:28 2003
@@ -1,4 +1,4 @@
-/* $Id: tg3.c,v 1.43.2.80 2002/03/14 00:10:04 davem Exp $
+/*
  * tg3.c: Broadcom Tigon3 ethernet driver.
  *
  * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
@@ -54,8 +54,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.2a"
-#define DRV_MODULE_RELDATE	"Dec 9, 2002"
+#define DRV_MODULE_VERSION	"1.4"
+#define DRV_MODULE_RELDATE	"Feb 1, 2003"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -141,6 +141,12 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_SYSKONNECT, 0x4400,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000,
@@ -163,6 +169,8 @@
 		spin_unlock_irqrestore(&tp->indirect_lock, flags);
 	} else {
 		writel(val, tp->regs + off);
+		if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
+			readl(tp->regs + off);
 	}
 }
 
@@ -213,28 +221,11 @@
 	tw32(TG3PCI_MISC_HOST_CTRL,
 	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
-
-	if (tp->hw_status->status & SD_STATUS_UPDATED) {
-		tw32(GRC_LOCAL_CTRL,
-		     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
-	}
 	tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
-}
-
-static inline void tg3_mask_ints(struct tg3 *tp)
-{
-	tw32(TG3PCI_MISC_HOST_CTRL,
-	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
-}
 
-static inline void tg3_unmask_ints(struct tg3 *tp)
-{
-	tw32(TG3PCI_MISC_HOST_CTRL,
-	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
-	if (tp->hw_status->status & SD_STATUS_UPDATED) {
+	if (tp->hw_status->status & SD_STATUS_UPDATED)
 		tw32(GRC_LOCAL_CTRL,
 		     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
-	}
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
@@ -900,6 +891,20 @@
 
 	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
 
+	/* Some third-party PHYs need to be reset on link going
+	 * down.
+	 *
+	 * XXX 5705 note: This workaround also applies to 5705_a0
+	 */
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) &&
+	    netif_carrier_ok(tp->dev)) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if (!(bmsr & BMSR_LSTATUS))
+			tg3_phy_reset(tp, 1);
+	}
+
 	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
 		tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1867,7 +1872,7 @@
  * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO
  * which is within the range of the new packet's length is chosen.
  *
- * The "seperate ring for rx status" scheme may sound queer, but it makes
+ * The "separate ring for rx status" scheme may sound queer, but it makes
  * sense from a cache coherency perspective.  If only the host writes
  * to the buffer post rings, and only the chip writes to the rx status
  * rings, then cache lines never move beyond shared-modified state.
@@ -1958,13 +1963,12 @@
 		}
 
 		if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) &&
-		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM)) {
-			skb->csum = htons((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
-					  >> RXD_TCPCSUM_SHIFT);
-			skb->ip_summed = CHECKSUM_HW;
-		} else {
+		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
+		    (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
+		      >> RXD_TCPCSUM_SHIFT) == 0xffff))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
 			skb->ip_summed = CHECKSUM_NONE;
-		}
 
 		skb->protocol = eth_type_trans(skb, tp->dev);
 #if TG3_VLAN_TAG_USED
@@ -2017,10 +2021,12 @@
 {
 	struct tg3 *tp = netdev->priv;
 	struct tg3_hw_status *sblk = tp->hw_status;
+	unsigned long flags;
 	int done;
 
-	spin_lock_irq(&tp->lock);
+	spin_lock_irqsave(&tp->lock, flags);
 
+	/* handle link change and other phy events */
 	if (!(tp->tg3_flags &
 	      (TG3_FLAG_USE_LINKCHG_REG |
 	       TG3_FLAG_POLL_SERDES))) {
@@ -2031,12 +2037,14 @@
 		}
 	}
 
+	/* run TX completion thread */
 	if (sblk->idx[0].tx_consumer != tp->tx_cons) {
 		spin_lock(&tp->tx_lock);
 		tg3_tx(tp);
 		spin_unlock(&tp->tx_lock);
 	}
 
+	/* run RX thread, within the bounds set by NAPI */
 	done = 1;
 	if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
 		int orig_budget = *budget;
@@ -2054,44 +2062,35 @@
 			done = 0;
 	}
 
+	/* if no more work, tell net stack and NIC we're done */
 	if (done) {
 		netif_rx_complete(netdev);
-		tg3_unmask_ints(tp);
+		tg3_enable_ints(tp);
 	}
 
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
 	return (done ? 0 : 1);
 }
 
-static __inline__ void tg3_interrupt_main_work(struct net_device *dev, struct tg3 *tp)
+static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp)
 {
 	struct tg3_hw_status *sblk = tp->hw_status;
-	int work_exists = 0;
+	unsigned int work_exists = 0;
 
+	/* check for phy events */
 	if (!(tp->tg3_flags &
 	      (TG3_FLAG_USE_LINKCHG_REG |
 	       TG3_FLAG_POLL_SERDES))) {
 		if (sblk->status & SD_STATUS_LINK_CHG)
 			work_exists = 1;
 	}
+	/* check for RX/TX work to do */
 	if (sblk->idx[0].tx_consumer != tp->tx_cons ||
 	    sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
 		work_exists = 1;
 
-	if (!work_exists)
-		return;
-
-	if (netif_rx_schedule_prep(dev)) {
-		/* NOTE: These writes are posted by the readback of
-		 *       the mailbox register done by our caller.
-		 */
-		tg3_mask_ints(tp);
-		__netif_rx_schedule(dev);
-	} else {
-		printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
-		       dev->name);
-	}
+	return work_exists;
 }
 
 static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -2104,15 +2103,32 @@
 	spin_lock_irqsave(&tp->lock, flags);
 
 	if (sblk->status & SD_STATUS_UPDATED) {
+		/*
+		 * writing any value to intr-mbox-0 clears PCI INTA# and
+		 * chip-internal interrupt pending events.
+		 * writing non-zero to intr-mbox-0 additional tells the
+		 * NIC to stop sending us irqs, engaging "in-intr-handler"
+		 * event coalescing.
+		 */
 		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
 			     0x00000001);
+		/*
+		 * Flush PCI write.  This also guarantees that our
+		 * status block has been flushed to host memory.
+		 */
+		tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 		sblk->status &= ~SD_STATUS_UPDATED;
 
-		tg3_interrupt_main_work(dev, tp);
-
-		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			     0x00000000);
-		tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+		if (likely(tg3_has_work(dev, tp)))
+			netif_rx_schedule(dev);		/* schedule NAPI poll */
+		else {
+			/* no work, shared interrupt perhaps?  re-enable
+			 * interrupts, and flush that PCI write
+			 */
+			tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			     	0x00000000);
+			tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+		}
 	}
 
 	spin_unlock_irqrestore(&tp->lock, flags);
@@ -2213,11 +2229,6 @@
 		return -1;
 	}
 
-	/* NOTE: Broadcom's driver botches this case up really bad.
-	 *       This is especially true if any of the frag pages
-	 *       are in highmem.  It will instantly oops in that case.
-	 */
-
 	/* New SKB is guarenteed to be linear. */
 	entry = *start;
 	new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
@@ -2649,6 +2660,17 @@
 	return 0;
 }
 
+static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
+			       int new_mtu)
+{
+	dev->mtu = new_mtu;
+
+	if (new_mtu > ETH_DATA_LEN)
+		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
+	else
+		tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE;
+}
+
 static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct tg3 *tp = dev->priv;
@@ -2660,7 +2682,7 @@
 		/* We'll just catch it later when the
 		 * device is up'd.
 		 */
-		dev->mtu = new_mtu;
+		tg3_set_mtu(dev, tp, new_mtu);
 		return 0;
 	}
 
@@ -2669,12 +2691,7 @@
 
 	tg3_halt(tp);
 
-	dev->mtu = new_mtu;
-
-	if (new_mtu > ETH_DATA_LEN)
-		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
-	else
-		tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE;
+	tg3_set_mtu(dev, tp, new_mtu);
 
 	tg3_init_rings(tp);
 	tg3_init_hw(tp);
@@ -4285,6 +4302,12 @@
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
 		tw32(MAC_SERDES_CFG, 0x616000);
 
+	/* Prevent chip from dropping frames when flow control
+	 * is enabled.
+	 */
+	tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2);
+	tr32(MAC_LOW_WMARK_MAX_RX_FRAME);
+
 	err = tg3_setup_phy(tp);
 	if (err)
 		return err;
@@ -4353,8 +4376,9 @@
 static void tg3_timer(unsigned long __opaque)
 {
 	struct tg3 *tp = (struct tg3 *) __opaque;
+	unsigned long flags;
 
-	spin_lock_irq(&tp->lock);
+	spin_lock_irqsave(&tp->lock, flags);
 	spin_lock(&tp->tx_lock);
 
 	/* All of this garbage is because when using non-tagged
@@ -4436,7 +4460,7 @@
 	}
 
 	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
 	tp->timer.expires = jiffies + tp->timer_offset;
 	add_timer(&tp->timer);
@@ -5793,7 +5817,8 @@
 		tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) &&
+	    (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)) {
 		tg3_writephy(tp, 0x1c, 0x8d68);
 		tg3_writephy(tp, 0x1c, 0x8d68);
 	}
@@ -5999,6 +6024,14 @@
 			pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
 		}
 	}
+
+	/* Back to back register writes can cause problems on this chip,
+	 * the workaround is to read back all reg writes except those to
+	 * mailbox regs.  See tg3_write_indirect_reg32().
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
+		tp->tg3_flags |= TG3_FLAG_5701_REG_WRITE_BUG;
+
 	if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
 		tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
 	if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
@@ -6013,8 +6046,11 @@
 
 	/* Force the chip into D0. */
 	err = tg3_set_power_state(tp, 0);
-	if (err)
+	if (err) {
+		printk(KERN_ERR PFX "(%s) transition to D0 failed\n",
+		       tp->pdev->slot_name);
 		return err;
+	}
 
 	/* 5700 B0 chips do not support checksumming correctly due
 	 * to hardware bugs.
@@ -6022,18 +6058,14 @@
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
 		tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
 
-	/* Regardless of whether checksums work or not, we configure
-	 * the StrongARM chips to not compute the pseudo header checksums
-	 * in either direction.  Because of the way Linux checksum support
-	 * works we do not need the chips to do this, and taking the load
-	 * off of the TX/RX onboard StrongARM cpus means that they will not be
-	 * the bottleneck.  Whoever wrote Broadcom's driver did not
-	 * understand the situation at all.  He could have bothered
-	 * to read Jes's Acenic driver because the logic (and this part of
-	 * the Tigon2 hardware/firmware) is pretty much identical.
+	/* Pseudo-header checksum is done by hardware logic and not
+	 * the offload processers, so make the chip do the pseudo-
+	 * header checksums on receive.  For transmit it is more
+	 * convenient to do the pseudo-header checksum in software
+	 * as Linux does that on transmit for us in all cases.
 	 */
 	tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM;
-	tp->tg3_flags |= TG3_FLAG_NO_RX_PSEUDO_CSUM;
+	tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM;
 
 	/* Derive initial jumbo mode from MTU assigned in
 	 * ether_setup() via the alloc_etherdev() call
@@ -6111,19 +6143,8 @@
 	if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
 		tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
 
-	/* Quick sanity check.  Make sure we see an expected
-	 * value here.
-	 */
 	grc_misc_cfg = tr32(GRC_MISC_CFG);
 	grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
-	if (grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5700 &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5701 &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704 &&
-	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1)
-		return -ENODEV;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
 	    grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
@@ -6131,14 +6152,16 @@
 		tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
 	}
 
-	/* ROFL, you should see Broadcom's driver code implementing
-	 * this, stuff like "if (a || b)" where a and b are always
-	 * mutually exclusive.  DaveM finds like 6 bugs today, hello!
-	 */
+	/* this one is limited to 10/100 only */
 	if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE)
 		tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
 	err = tg3_phy_probe(tp);
+	if (err) {
+		printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
+		       tp->pdev->slot_name, err);
+		/* ... but do not return immediately ... */
+	}
 
 	tg3_read_partno(tp);
 
@@ -6192,17 +6215,10 @@
 	/* 5700 chips can get confused if TX buffers straddle the
 	 * 4GB address boundary in some cases.
 	 */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-		/* ROFL!  Latest Broadcom driver disables NETIF_F_HIGHDMA
-		 * in this case instead of fixing their workaround code.
-		 *
-		 * Like, hey, there is this skb_copy() thing guys,
-		 * use it.  Oh I can't stop laughing...
-		 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
 		tp->dev->hard_start_xmit = tg3_start_xmit_4gbug;
-	} else {
+	else
 		tp->dev->hard_start_xmit = tg3_start_xmit;
-	}
 
 	tp->rx_offset = 2;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
@@ -6368,6 +6384,7 @@
 			(0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
 			(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
 			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+		/* XXX 5705 note: set MIN_DMA to zero here */
 	} else {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
 			tp->dma_rwctrl =
@@ -6385,12 +6402,19 @@
 				(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
 
 		/* Wheee, some more chip bugs... */
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 ||
-		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A2 ||
-		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A3 ||
-		    tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
-			tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+			u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f);
+
+			if (ccval == 0x6 || ccval == 0x7)
+				tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
+		}
 	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+		tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA
+				    << DMA_RWCTRL_MIN_DMA_SHIFT);
 
 	/* We don't do this on x86 because it seems to hurt performace.
 	 * It does help things on other platforms though.
diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/tg3.h	Mon Feb 10 10:39:24 2003
@@ -113,6 +113,8 @@
 #define  CHIPREV_ID_5703_A2		 0x1002
 #define  CHIPREV_ID_5703_A3		 0x1003
 #define  CHIPREV_ID_5704_A0		 0x2000
+#define  CHIPREV_ID_5704_A1		 0x2001
+#define  CHIPREV_ID_5704_A2		 0x2002
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -454,6 +456,7 @@
 #define  RCV_RULE_DISABLE_MASK		 0x7fffffff
 #define MAC_RCV_RULE_CFG		0x00000500
 #define  RCV_RULE_CFG_DEFAULT_CLASS	0x00000008
+#define MAC_LOW_WMARK_MAX_RX_FRAME	0x00000504
 /* 0x504 --> 0x590 unused */
 #define MAC_SERDES_CFG			0x00000590
 #define MAC_SERDES_STAT			0x00000594
@@ -1136,6 +1139,7 @@
 #define  GRC_MISC_CFG_BOARD_ID_5703S	0x00002000
 #define  GRC_MISC_CFG_BOARD_ID_5704	0x00000000
 #define  GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
+#define  GRC_MISC_CFG_BOARD_ID_5704_A2	0x00008000
 #define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
 #define GRC_LOCAL_CTRL			0x00006808
 #define  GRC_LCLCTRL_INT_ACTIVE		0x00000001
@@ -1791,6 +1795,7 @@
 #define TG3_FLAG_USE_LINKCHG_REG	0x00000008
 #define TG3_FLAG_USE_MI_INTERRUPT	0x00000010
 #define TG3_FLAG_ENABLE_ASF		0x00000020
+#define TG3_FLAG_5701_REG_WRITE_BUG	0x00000040
 #define TG3_FLAG_POLL_SERDES		0x00000080
 #define TG3_FLAG_MBOX_WRITE_REORDER	0x00000100
 #define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/tokenring/Kconfig	Mon Feb 10 10:39:24 2003
@@ -32,7 +32,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ibmtr.o. If you want to compile it as a
+	  The module will be called ibmtr. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config IBMOL
@@ -48,7 +48,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called olympic.o. If you want to compile it
+	  The module will be called olympic. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  Also read <file:Documentation/networking/olympic.txt> or check the
@@ -66,7 +66,7 @@
 
 	  This driver is also available as a modules ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The modules will be called lanstreamer.o. If you want to compile it
+	  The modules will be called lanstreamer. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config 3C359
@@ -82,7 +82,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will will be called 3c359.o. If you want to compile it
+	  The module will will be called 3c359. If you want to compile it
 	  as a module, say M here and read Documentation/modules.txt.
 
 	  Also read the file <file:Documentation/networking/3c359.txt> or check the 
@@ -111,7 +111,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tms380tr.o. If you want to compile it
+	  The module will be called tms380tr. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config TMSPCI
@@ -128,7 +128,7 @@
 
 	  This driver is available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tmspci.o. If you want to compile it
+	  The module will be called tmspci. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config TMSISA
@@ -142,7 +142,7 @@
 
 	  This driver is available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tmsisa.o. If you want to compile it
+	  The module will be called tmsisa. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config ABYSS
@@ -154,7 +154,7 @@
 
 	  This driver is available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called abyss.o. If you want to compile it
+	  The module will be called abyss. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config MADGEMC
@@ -166,7 +166,7 @@
 
 	  This driver is available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called madgemc.o. If you want to compile it
+	  The module will be called madgemc. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config SMCTR
@@ -184,7 +184,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called smctr.o. If you want to compile it
+	  The module will be called smctr. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 endmenu
diff -Nru a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile
--- a/drivers/net/tokenring/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/tokenring/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for drivers/net/tokenring
 #
 
-export-objs := tms380tr.o
-
 obj-$(CONFIG_IBMTR) 	+= ibmtr.o
 obj-$(CONFIG_IBMOL) 	+= olympic.o
 obj-$(CONFIG_IBMLS) 	+= lanstreamer.o
diff -Nru a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
--- a/drivers/net/tokenring/madgemc.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/tokenring/madgemc.c	Mon Feb 10 10:39:32 2003
@@ -514,7 +514,7 @@
  *
  * Register selection is normally done via three contiguous
  * bits.  However, some boards (such as the MC16/32) use only
- * two bits, plus a seperate bit in the glue chip.  This
+ * two bits, plus a separate bit in the glue chip.  This
  * sets the SRSX bit (the top bit).  See page 4-17 in the
  * Yellow Book for which registers are affected.
  *
@@ -629,7 +629,7 @@
 /*
  * Read the card type (MC16 or MC32) from the card.
  *
- * The configuration registers are stored in two seperate
+ * The configuration registers are stored in two separate
  * pages.  Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE)
  * for page zero, or setting bit 3 for page one.
  *
diff -Nru a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h
--- a/drivers/net/tokenring/smctr_firmware.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/tokenring/smctr_firmware.h	Mon Feb 10 10:39:30 2003
@@ -1,6 +1,6 @@
 /*
  * The firmware this driver downloads into the tokenring card is a
- * seperate program and is not GPL'd source code, even though the Linux
+ * separate program and is not GPL'd source code, even though the Linux
  * side driver and the routine that loads this data into the card are.
  *
  * This firmware is licensed to you strictly for use in conjunction
diff -Nru a/drivers/net/tokenring/tmsisa.c b/drivers/net/tokenring/tmsisa.c
--- a/drivers/net/tokenring/tmsisa.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/tokenring/tmsisa.c	Mon Feb 10 10:39:23 2003
@@ -302,7 +302,7 @@
  * Calling this on a board that does not support it can be a very
  * dangerous thing.  The Madge board, for instance, will lock your
  * machine hard when this is called.  Luckily, its supported in a
- * seperate driver.  --ASF
+ * separate driver.  --ASF
  */
 static void tms_isa_read_eeprom(struct net_device *dev)
 {
diff -Nru a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
--- a/drivers/net/tokenring/tmspci.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/net/tokenring/tmspci.c	Mon Feb 10 10:39:31 2003
@@ -190,7 +190,7 @@
  * Calling this on a board that does not support it can be a very
  * dangerous thing.  The Madge board, for instance, will lock your
  * machine hard when this is called.  Luckily, its supported in a
- * seperate driver.  --ASF
+ * separate driver.  --ASF
  */
 static void tms_pci_read_eeprom(struct net_device *dev)
 {
diff -Nru a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
--- a/drivers/net/tulip/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/net/tulip/Kconfig	Mon Feb 10 10:39:30 2003
@@ -27,7 +27,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tulip.o.  If you want to compile it as a
+	  The module will be called tulip.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -48,7 +48,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tulip.o.  If you want to compile it as a
+	  The module will be called tulip.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -86,7 +86,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called de4x5.o.  If you want to compile it as a
+	  The module will be called de4x5.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -110,7 +110,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dmfe.o.  If you want to compile it as a
+	  The module will be called dmfe.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -125,7 +125,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called xircom_cb.o.  If you want to compile
+	  The module will be called xircom_cb.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>. If unsure, say N.
 
@@ -140,7 +140,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called xircom_tulip_cb.o.  If you want to compile
+	  The module will be called xircom_tulip_cb.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>. If unsure, say N.
 
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/tulip/de4x5.c	Mon Feb 10 10:39:23 2003
@@ -440,7 +440,7 @@
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
diff -Nru a/drivers/net/tulip/de4x5.h b/drivers/net/tulip/de4x5.h
--- a/drivers/net/tulip/de4x5.h	Mon Feb 10 10:39:29 2003
+++ b/drivers/net/tulip/de4x5.h	Mon Feb 10 10:39:29 2003
@@ -1026,6 +1026,4 @@
 #define DE4X5_SET_OMR           0x0d /* Set the OMR Register contents */
 #define DE4X5_GET_REG           0x0e /* Get the DE4X5 Registers */
 
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-
 #define MOTO_SROM_BUG    ((lp->active == 8) && (((le32_to_cpu(get_unaligned(((s32 *)dev->dev_addr))))&0x00ffffff)==0x3e0008))
diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wan/Kconfig	Mon Feb 10 10:39:24 2003
@@ -54,7 +54,7 @@
 
 	  The driver will be compiled as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cosa.o. For general information about
+	  The module will be called cosa. For general information about
 	  modules read <file:Documentation/modules.txt>.
 
 #
@@ -76,7 +76,7 @@
 	  use this driver.
 
 	  If you want to compile this as a module, say M and read
-	  <file:Documentation/modules.txt>.  The module will be called comx.o.
+	  <file:Documentation/modules.txt>.  The module will be called comx.
 
 config COMX_HW_COMX
 	tristate "Support for COMX/CMX/HiCOMX boards"
@@ -90,7 +90,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  comx-hw-comx.o.
+	  comx-hw-comx.
 
 config COMX_HW_LOCOMX
 	tristate "Support for LoCOMX board"
@@ -101,7 +101,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  comx-hw-locomx.o.
+	  comx-hw-locomx.
 
 config COMX_HW_MIXCOM
 	tristate "Support for MixCOM board"
@@ -119,7 +119,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>. The module will be called
-	  comx-hw-mixcom.o.
+	  comx-hw-mixcom.
 
 config COMX_HW_MUNICH
 	tristate "Support for MUNICH based boards: SliceCOM, PCICOM (WelCOM)"
@@ -130,7 +130,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called comx-hw-munich.o. If you want to compile it
+	  The module will be called comx-hw-munich. If you want to compile it
 	  as a module, say M here and read Documentation/modules.txt.
 
 	  Read linux/Documentation/networking/slicecom.txt for help on
@@ -147,7 +147,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  comx-proto-ppp.o.
+	  comx-proto-ppp.
 
 config COMX_PROTO_LAPB
 	tristate "Support for LAPB protocol on MultiGate boards"
@@ -158,7 +158,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  comx-proto-lapb.o.
+	  comx-proto-lapb.
 
 config COMX_PROTO_FR
 	tristate "Support for Frame Relay on MultiGate boards"
@@ -169,7 +169,7 @@
 
 	  If you want to compile this as a module, say M and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  comx-proto-fr.o.
+	  comx-proto-fr.
 
 #
 # The Etinc driver has not been tested as non-modular yet.
@@ -185,7 +185,7 @@
 
 	  The driver will be compiled as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dscc4.o. For general information about
+	  The module will be called dscc4. For general information about
 	  modules read <file:Documentation/modules.txt>.
 
 #
@@ -214,7 +214,7 @@
 	  To change setting such as syncPPP vs cisco HDLC or clock source you
 	  will need lmcctl.  It is available at <ftp://ftp.lanmedia.com/>.
 
-	  This code is also available as a module called lmc.o ( = code
+	  This code is also available as a module called lmc ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -229,7 +229,7 @@
 	  This driver can only be compiled as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to do that, say M here. The module will be called
-	  sealevel.o.
+	  sealevel.
 
 config SYNCLINK_SYNCPPP
 	tristate "SyncLink HDLC/SYNCPPP support"
@@ -317,7 +317,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read Documentation/modules.txt. The module will be
-	  called pc300.o.
+	  called pc300.
 
 	  If you haven't heard about it, it's safe to say N.
 
@@ -369,7 +369,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want)
 	  say M here and read <file:Documentation/modules.txt>.
-	  The module will be called farsync.o and if you want the module to be
+	  The module will be called farsync and if you want the module to be
 	  automatically loaded when the interface is referenced then you
 	  should add "alias hdlcX farsync" to /etc/modules.conf for each
 	  interface, where X is 0, 1, 2, ...
@@ -408,7 +408,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dlci.o. If you want to compile it as a
+	  The module will be called dlci. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config DLCI_COUNT
@@ -441,7 +441,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sdla.o. If you want to compile it as a
+	  The module will be called sdla. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 # Wan router core.
@@ -491,7 +491,7 @@
 
 	  The driver will be compiled as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wanpipe.o.  For general information about
+	  The module will be called wanpipe.  For general information about
 	  modules read <file:Documentation/modules.txt>.
 
 config WANPIPE_CHDLC
@@ -583,7 +583,7 @@
 
 	  The driver will be compiled as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cyclomx.o. For general information about
+	  The module will be called cyclomx. For general information about
 	  modules read <file:Documentation/modules.txt>.
 
 config CYCLOMX_X25
@@ -610,7 +610,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called lapbether.o.  If unsure, say N.
+	  will be called lapbether.  If unsure, say N.
 
 config X25_ASY
 	tristate "X.25 async driver (EXPERIMENTAL)"
@@ -625,7 +625,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called x25_asy.o.  If unsure, say N.
+	  will be called x25_asy.  If unsure, say N.
 
 config SBNI
 	tristate "Granch SBNI12 Leased Line adapter support"
@@ -634,7 +634,7 @@
 	  This is a driver for ISA SBNI12-xx cards which are low cost
 	  alternatives to leased line modems. Say Y if you want to insert
 	  the driver into the kernel or say M to compile it as a module (the
-	  module will be called sbni.o).
+	  module will be called sbni).
 
 	  You can find more information and last versions of drivers and
 	  utilities at <http://www.granch.ru/>. If you have any question you
diff -Nru a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
--- a/drivers/net/wan/Makefile	Mon Feb 10 10:39:28 2003
+++ b/drivers/net/wan/Makefile	Mon Feb 10 10:39:28 2003
@@ -5,9 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs :=	z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o \
-		dlci.o
-
 wanpipe-y			:= sdlamain.o sdla_ft1.o
 wanpipe-$(CONFIG_WANPIPE_X25)	+= sdla_x25.o
 wanpipe-$(CONFIG_WANPIPE_FR)	+= sdla_fr.o
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wan/dscc4.c	Mon Feb 10 10:39:24 2003
@@ -1787,7 +1787,7 @@
 	return -ENOMEM;
 }
 
-static void __exit dscc4_remove_one(struct pci_dev *pdev)
+static void __devexit dscc4_remove_one(struct pci_dev *pdev)
 {
 	struct dscc4_pci_priv *ppriv;
 	struct dscc4_dev_priv *root;
@@ -1867,7 +1867,7 @@
 	.name		= DRV_NAME,
 	.id_table	= dscc4_pci_tbl,
 	.probe		= dscc4_init_one,
-	.remove		= dscc4_remove_one,
+	.remove		= __devexit_p(dscc4_remove_one),
 };
 
 static int __init dscc4_init_module(void)
diff -Nru a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h
--- a/drivers/net/wan/lmc/lmc_ioctl.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/wan/lmc/lmc_ioctl.h	Mon Feb 10 10:39:23 2003
@@ -173,7 +173,7 @@
 
 /*
  * Some of the MII16 bits are mirrored in the MII17 register as well,
- * but let's keep thing seperate for now, and get only the cable from
+ * but let's keep thing separate for now, and get only the cable from
  * the MII17.
  */
 #define LMC_MII17_SSI_CABLE_MASK	0x0038	/* mask to extract the cable type */
diff -Nru a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
--- a/drivers/net/wan/lmc/lmc_main.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wan/lmc/lmc_main.c	Mon Feb 10 10:39:24 2003
@@ -1074,7 +1074,7 @@
          * This prevents taking someone else's device.
          *
          * Check either the subvendor or the subdevice, some systems reverse
-         * the setting in the bois, seems to be version and arch dependant?
+         * the setting in the bois, seems to be version and arch dependent?
          * Fix the two variables
          *
          */
diff -Nru a/drivers/net/wan/lmc/lmc_ver.h b/drivers/net/wan/lmc/lmc_ver.h
--- a/drivers/net/wan/lmc/lmc_ver.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/wan/lmc/lmc_ver.h	Mon Feb 10 10:39:23 2003
@@ -25,7 +25,7 @@
   * made the souce code not only hard to read but version problems hard
   * to track down.  If I'm overiding a function/etc with something in
   * this file it will be prefixed by "LMC_" which will mean look
-  * here for the version dependant change that's been done.
+  * here for the version dependent change that's been done.
   *
   */
 
diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wireless/Kconfig	Mon Feb 10 10:39:24 2003
@@ -31,7 +31,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wavelan.o.  If you want to compile it as a
+	  The module will be called wavelan.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> as well
 	  as <file:Documentation/networking/net-modules.txt>.
 
@@ -50,7 +50,7 @@
 	  and Cisco proprietary API, so both the Linux Wireless Tools and the
 	  Cisco Linux utilities can be used to configure the card.
 
-	  The driver can be compiled as a module and will be named "airo.o".
+	  The driver can be compiled as a module and will be named "airo".
 
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
@@ -121,7 +121,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called netwave_cs.o.  If you want to compile it
+	  The module will be called netwave_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
@@ -135,7 +135,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wavelan_cs.o.  If you want to compile it
+	  The module will be called wavelan_cs.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
diff -Nru a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
--- a/drivers/net/wireless/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/net/wireless/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,9 +2,6 @@
 # Makefile for the Linux Wireless network device drivers.
 #
 
-# Things that need to export symbols
-export-objs	:= airo.o orinoco.o hermes.o
-
 # Obsolete cards
 obj-$(CONFIG_WAVELAN)		+= wavelan.o
 obj-$(CONFIG_PCMCIA_NETWAVE)	+= netwave_cs.o
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/net/wireless/airo.c	Mon Feb 10 10:39:23 2003
@@ -5144,7 +5144,7 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Translate scan data returned from the card to a card independant
+ * Translate scan data returned from the card to a card independent
  * format that the Wireless Tools will understand - Jean II
  */
 static inline char *airo_translate_scan(struct net_device *dev,
diff -Nru a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
--- a/drivers/net/wireless/airo_cs.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wireless/airo_cs.c	Mon Feb 10 10:39:24 2003
@@ -216,6 +216,7 @@
 		return NULL;
 	}
 	memset(link, 0, sizeof(struct dev_link_t));
+	init_timer(&link->release);
 	link->release.function = &airo_release;
 	link->release.data = (u_long)link;
 	
diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/net/wireless/netwave_cs.c	Mon Feb 10 10:39:33 2003
@@ -462,6 +462,7 @@
     memset(priv, 0, sizeof(*priv));
     link = &priv->link; dev = &priv->dev;
     link->priv = dev->priv = priv;
+    init_timer(&link->release);
     link->release.function = &netwave_release;
     link->release.data = (u_long)link;
 	
diff -Nru a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
--- a/drivers/net/wireless/orinoco.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/net/wireless/orinoco.h	Mon Feb 10 10:39:24 2003
@@ -36,7 +36,7 @@
 
 
 struct orinoco_private {
-	void *card;	/* Pointer to card dependant structure */
+	void *card;	/* Pointer to card dependent structure */
 	int (*hard_reset)(struct orinoco_private *);
 
 	/* Synchronisation stuff */
diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/net/wireless/orinoco_cs.c	Mon Feb 10 10:39:32 2003
@@ -203,6 +203,7 @@
 	link->priv = dev;
 
 	/* Initialize the dev_link_t structure */
+	init_timer(&link->release);
 	link->release.function = &orinoco_cs_release;
 	link->release.data = (u_long) link;
 
diff -Nru a/drivers/nubus/Makefile b/drivers/nubus/Makefile
--- a/drivers/nubus/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/nubus/Makefile	Mon Feb 10 10:39:32 2003
@@ -2,8 +2,6 @@
 # Makefile for the nubus specific drivers.
 #
 
-export-objs := nubus_syms.o
-
 obj-y   := nubus.o
 
 obj-$(CONFIG_MODULES) += nubus_syms.o 
diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile
--- a/drivers/parisc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/parisc/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for most of the non-PCI devices in PA-RISC machines
 #
 
-export-objs			:= gsc.o superio.o
-
 obj-y :=
 obj-m :=
 obj-n :=
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/parisc/ccio-dma.c	Mon Feb 10 10:39:24 2003
@@ -852,7 +852,7 @@
 ** in the DMA stream. Allocates PDIR entries but does not fill them.
 ** Returns the number of DMA chunks.
 **
-** Doing the fill seperate from the coalescing/allocation keeps the
+** Doing the fill separate from the coalescing/allocation keeps the
 ** code simpler. Future enhancement could make one pass through
 ** the sglist do both.
 */
@@ -1553,38 +1553,6 @@
 
 	ioc_count++;
 	return 0;
-}
-
-struct pci_dev * ccio_get_fake(const struct parisc_device *dev)
-{
-	struct ioc *ioc;
-
-	dev = find_pa_parent_type(dev, HPHW_IOA);
-	if(!dev)
-		return NULL;
-
-	ioc = ccio_find_ioc(dev->hw_path);
-	if(!ioc)
-		return NULL;
-
-	if(ioc->fake_pci_dev)
-		return ioc->fake_pci_dev;
-
-	ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
-	if(ioc->fake_pci_dev == NULL) {
-		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
-		return NULL;
-	}
-	memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
-
-	ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
-	if(ioc->fake_pci_dev->dev.platform_data == NULL) {
-		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
-		return NULL;
-	}
-
-	HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc;
-	return ioc->fake_pci_dev;
 }
 
 /* We *can't* support JAVA (T600). Venture there at your own risk. */
diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
--- a/drivers/parisc/ccio-rm-dma.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/parisc/ccio-rm-dma.c	Mon Feb 10 10:39:24 2003
@@ -116,7 +116,7 @@
 {
 	int tmp = nents;
 
-        /* KISS: map each buffer seperately. */
+        /* KISS: map each buffer separately. */
 	while (nents) {
 		sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
 		sg_dma_len(sglist) = sglist->length;
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- a/drivers/parisc/sba_iommu.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/parisc/sba_iommu.c	Mon Feb 10 10:39:30 2003
@@ -974,8 +974,8 @@
  *
  * See Documentation/DMA-mapping.txt
  */
-static void *
-sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle)
+static void *sba_alloc_consistent(struct device *hwdev, size_t size,
+					dma_addr_t *dma_handle, int gfp)
 {
 	void *ret;
 
@@ -985,7 +985,7 @@
 		return 0;
 	}
 
-        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+        ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret) {
 		memset(ret, 0, size);
@@ -1132,7 +1132,7 @@
  * in the DMA stream. Allocates PDIR entries but does not fill them.
  * Returns the number of DMA chunks.
  *
- * Doing the fill seperate from the coalescing/allocation keeps the
+ * Doing the fill separate from the coalescing/allocation keeps the
  * code simpler. Future enhancement could make one pass through
  * the sglist do both.
  */
diff -Nru a/drivers/parport/Kconfig b/drivers/parport/Kconfig
--- a/drivers/parport/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/parport/Kconfig	Mon Feb 10 10:39:33 2003
@@ -28,7 +28,7 @@
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  parport.o.  If you have more than one parallel port and want to
+	  parport.  If you have more than one parallel port and want to
 	  specify which port and IRQ to be used by this driver at module load
 	  time, take a look at <file:Documentation/parport.txt>.
 
@@ -47,7 +47,7 @@
 	  as a module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  parport_pc.o.
+	  parport_pc.
 
 	  If unsure, say Y.
 
@@ -63,7 +63,7 @@
 	help
 	  This adds support for multi-IO PCI cards that have parallel and
 	  serial ports.  You should say Y or M here.  If you say M, the module
-	  will be called parport_serial.o.
+	  will be called parport_serial.
 
 config PARPORT_PC_FIFO
 	bool "Use FIFO/DMA if available (EXPERIMENTAL)"
@@ -103,7 +103,7 @@
 	help
 	  Say Y here if you need support for the parallel port hardware on
 	  Amiga machines. This code is also available as a module (say M),
-	  called parport_amiga.o. If in doubt, saying N is the safe plan.
+	  called parport_amiga. If in doubt, saying N is the safe plan.
 
 config PARPORT_MFC3
 	tristate "Multiface III parallel port"
@@ -111,7 +111,7 @@
 	help
 	  Say Y here if you need parallel port support for the MFC3 card.
 	  This code is also available as a module (say M), called
-	  parport_mfc3.o. If in doubt, saying N is the safe plan.
+	  parport_mfc3. If in doubt, saying N is the safe plan.
 
 config PARPORT_ATARI
 	tristate "Atari hardware"
@@ -119,7 +119,7 @@
 	help
 	  Say Y here if you need support for the parallel port hardware on
 	  Atari machines. This code is also available as a module (say M),
-	  called parport_atari.o. If in doubt, saying N is the safe plan.
+	  called parport_atari. If in doubt, saying N is the safe plan.
 
 config PARPORT_GSC
 	tristate
diff -Nru a/drivers/parport/Makefile b/drivers/parport/Makefile
--- a/drivers/parport/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/parport/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the kernel Parallel port device drivers.
 #
 
-export-objs	:= init.o parport_pc.o
-
 parport-objs	:= share.o ieee1284.o ieee1284_ops.o init.o procfs.o
 
 ifeq ($(CONFIG_PARPORT_1284),y)
diff -Nru a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
--- a/drivers/parport/parport_cs.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/parport/parport_cs.c	Mon Feb 10 10:39:33 2003
@@ -134,6 +134,7 @@
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
+    init_timer(&link->release);
     link->release.function = &parport_cs_release;
     link->release.data = (u_long)link;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
--- a/drivers/parport/parport_gsc.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/parport/parport_gsc.c	Mon Feb 10 10:39:31 2003
@@ -40,6 +40,7 @@
 
 #include <linux/parport.h>
 #include <asm/pdc.h>
+#include <asm/parisc-device.h>
 #include <asm/hardware.h>
 #include <asm/parport_gsc.h>
 
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/parport/parport_pc.c	Mon Feb 10 10:39:33 2003
@@ -2987,7 +2987,7 @@
 	.id_table	= pnp_dev_table,
 };
 #else
-static const struct pnp_driver parport_pc_pnp_driver;
+static struct pnp_driver parport_pc_pnp_driver;
 #endif
 
 /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	Mon Feb 10 10:39:32 2003
+++ b/drivers/pci/Makefile	Mon Feb 10 10:39:32 2003
@@ -2,11 +2,9 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-export-objs	:= access.o hotplug.o pci-driver.o pci.o pool.o \
-			probe.o proc.o search.o setup-bus.o
-
 obj-y		+= access.o probe.o pci.o pool.o quirks.o \
-			names.o pci-driver.o search.o hotplug.o
+			names.o pci-driver.o search.o hotplug.o \
+			pci-sysfs.o
 obj-$(CONFIG_PM)  += power.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
--- a/drivers/pci/hotplug.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/pci/hotplug.c	Mon Feb 10 10:39:32 2003
@@ -2,6 +2,14 @@
 #include <linux/module.h>
 #include "pci.h"
 
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
 
 #ifdef CONFIG_HOTPLUG
 int pci_hotplug (struct device *dev, char **envp, int num_envp,
@@ -57,13 +65,179 @@
 
 	return 0;
 }
-#else
+
+static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
+{
+	struct list_head *ln;
+	struct pci_dev *dev;
+	struct pci_dev_wrapped wrapped_dev;
+	int result = 0;
+
+	DBG("scanning bus %02x\n", wrapped_bus->bus->number);
+
+	if (fn->pre_visit_pci_bus) {
+		result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
+		if (result)
+			return result;
+	}
+
+	ln = wrapped_bus->bus->devices.next; 
+	while (ln != &wrapped_bus->bus->devices) {
+		dev = pci_dev_b(ln);
+		ln = ln->next;
+
+		memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
+		wrapped_dev.dev = dev;
+
+		result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
+		if (result)
+			return result;
+	}
+
+	if (fn->post_visit_pci_bus)
+		result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
+
+	return result;
+}
+
+static int pci_visit_bridge (struct pci_visit * fn,
+			     struct pci_dev_wrapped *wrapped_dev,
+			     struct pci_bus_wrapped *wrapped_parent)
+{
+	struct pci_bus *bus;
+	struct pci_bus_wrapped wrapped_bus;
+	int result = 0;
+
+	DBG("scanning bridge %02x, %02x\n", PCI_SLOT(wrapped_dev->dev->devfn),
+	    PCI_FUNC(wrapped_dev->dev->devfn));
+
+	if (fn->visit_pci_dev) {
+		result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
+		if (result)
+			return result;
+	}
+
+	bus = wrapped_dev->dev->subordinate;
+	if(bus) {
+		memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
+		wrapped_bus.bus = bus;
+
+		result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
+	}
+	return result;
+}
+
+/**
+ * pci_visit_dev - scans the pci buses.
+ * Every bus and every function is presented to a custom
+ * function that can act upon it.
+ */
+int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
+		   struct pci_bus_wrapped *wrapped_parent)
+{
+	struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
+	int result = 0;
+
+	if (!dev)
+		return 0;
+
+	if (fn->pre_visit_pci_dev) {
+		result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
+		if (result)
+			return result;
+	}
+
+	switch (dev->class >> 8) {
+		case PCI_CLASS_BRIDGE_PCI:
+			result = pci_visit_bridge(fn, wrapped_dev,
+						  wrapped_parent);
+			if (result)
+				return result;
+			break;
+		default:
+			DBG("scanning device %02x, %02x\n",
+			    PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+			if (fn->visit_pci_dev) {
+				result = fn->visit_pci_dev (wrapped_dev,
+							    wrapped_parent);
+				if (result)
+					return result;
+			}
+	}
+
+	if (fn->post_visit_pci_dev)
+		result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
+
+	return result;
+}
+EXPORT_SYMBOL(pci_visit_dev);
+
+/**
+ * pci_is_dev_in_use - query devices' usage
+ * @dev: PCI device to query
+ *
+ * Queries whether a given PCI device is in use by a driver or not.
+ * Returns 1 if the device is in use, 0 if it is not.
+ */
+int pci_is_dev_in_use(struct pci_dev *dev)
+{
+	/* 
+	 * dev->driver will be set if the device is in use by a new-style 
+	 * driver -- otherwise, check the device's regions to see if any
+	 * driver has claimed them.
+	 */
+
+	int i;
+	int inuse = 0;
+
+	if (dev->driver) {
+		/* Assume driver feels responsible */
+		return 1;
+	}
+
+	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
+		if (!pci_resource_start(dev, i))
+			continue;
+		if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+			inuse = check_region(pci_resource_start(dev, i),
+					     pci_resource_len(dev, i));
+		} else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
+			inuse = check_mem_region(pci_resource_start(dev, i),
+						 pci_resource_len(dev, i));
+		}
+	}
+	return inuse;
+}
+EXPORT_SYMBOL(pci_is_dev_in_use);
+
+/**
+ * pci_remove_device_safe - remove an unused hotplug device
+ * @dev: the device to remove
+ *
+ * Delete the device structure from the device lists and 
+ * notify userspace (/sbin/hotplug), but only if the device
+ * in question is not being used by a driver.
+ * Returns 0 on success.
+ */
+int pci_remove_device_safe(struct pci_dev *dev)
+{
+	if (pci_is_dev_in_use(dev)) {
+		return -EBUSY;
+	}
+	pci_remove_device(dev);
+	return 0;
+}
+EXPORT_SYMBOL(pci_remove_device_safe);
+
+#else /* CONFIG_HOTPLUG */
+
 int pci_hotplug (struct device *dev, char **envp, int num_envp,
 		 char *buffer, int buffer_size)
 {
 	return -ENODEV;
 }
-#endif
+
+#endif /* CONFIG_HOTPLUG */
 
 /**
  * pci_insert_device - insert a pci device
@@ -81,6 +255,8 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_attach_device(dev);
 #endif
+	/* add sysfs device files */
+	pci_create_sysfs_dev_files(dev);
 }
 
 static void
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pci/pci-sysfs.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,77 @@
+/*
+ * drivers/pci/pci-sysfs.c
+ *
+ * (C) Copyright 2002 Greg Kroah-Hartman
+ * (C) Copyright 2002 IBM Corp.
+ *
+ * File attributes for PCI devices
+ *
+ * Modeled after usb's driverfs.c 
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stat.h>
+
+#include "pci.h"
+
+#if BITS_PER_LONG == 32
+#define LONG_FORMAT "\t%08lx"
+#else
+#define LONG_FORMAT "\t%16lx"
+#endif
+
+/* show configuration fields */
+#define pci_config_attr(field, format_string)				\
+static ssize_t								\
+show_##field (struct device *dev, char *buf)				\
+{									\
+	struct pci_dev *pdev;						\
+									\
+	pdev = to_pci_dev (dev);					\
+	return sprintf (buf, format_string, pdev->field);		\
+}									\
+static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+pci_config_attr(vendor, "%04x\n");
+pci_config_attr(device, "%04x\n");
+pci_config_attr(subsystem_vendor, "%04x\n");
+pci_config_attr(subsystem_device, "%04x\n");
+pci_config_attr(class, "%06x\n");
+pci_config_attr(irq, "%u\n");
+
+/* show resources */
+static ssize_t
+pci_show_resources(struct device * dev, char * buf)
+{
+	struct pci_dev * pci_dev = to_pci_dev(dev);
+	char * str = buf;
+	int i;
+
+	for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) {
+		str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n",
+			       pci_resource_start(pci_dev,i),
+			       pci_resource_end(pci_dev,i),
+			       pci_resource_flags(pci_dev,i));
+	}
+	return (str - buf);
+}
+
+static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
+
+void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	/* current configuration's attributes */
+	device_create_file (dev, &dev_attr_vendor);
+	device_create_file (dev, &dev_attr_device);
+	device_create_file (dev, &dev_attr_subsystem_vendor);
+	device_create_file (dev, &dev_attr_subsystem_device);
+	device_create_file (dev, &dev_attr_class);
+	device_create_file (dev, &dev_attr_irq);
+	device_create_file (dev, &dev_attr_resource);
+}
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/pci/pci.h	Mon Feb 10 10:39:24 2003
@@ -2,4 +2,4 @@
 
 extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
 			 char *buffer, int buffer_size);
-
+extern void pci_create_sysfs_dev_files(struct pci_dev *pdev);
diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c
--- a/drivers/pci/proc.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/pci/proc.c	Mon Feb 10 10:39:28 2003
@@ -373,32 +373,6 @@
 
 struct proc_dir_entry *proc_bus_pci_dir;
 
-/* driverfs files */
-static ssize_t pci_show_irq(struct device * dev, char * buf)
-{
-	struct pci_dev * pci_dev = to_pci_dev(dev);
-	return sprintf(buf,"%u\n",pci_dev->irq);
-}
-
-static DEVICE_ATTR(irq,S_IRUGO,pci_show_irq,NULL);
-
-static ssize_t pci_show_resources(struct device * dev, char * buf)
-{
-	struct pci_dev * pci_dev = to_pci_dev(dev);
-	char * str = buf;
-	int i;
-
-	for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) {
-		str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n",
-			       pci_resource_start(pci_dev,i),
-			       pci_resource_end(pci_dev,i),
-			       pci_resource_flags(pci_dev,i));
-	}
-	return (str - buf);
-}
-
-static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
-
 int pci_proc_attach_device(struct pci_dev *dev)
 {
 	struct pci_bus *bus = dev->bus;
@@ -422,8 +396,6 @@
 	e->data = dev;
 	e->size = PCI_CFG_SPACE_SIZE;
 
-	device_create_file(&dev->dev,&dev_attr_irq);
-	device_create_file(&dev->dev,&dev_attr_resource);
 	return 0;
 }
 
diff -Nru a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
--- a/drivers/pcmcia/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/pcmcia/Kconfig	Mon Feb 10 10:39:30 2003
@@ -25,8 +25,8 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  When compiled this way, there will be modules called pcmcia_core.o
-	  and ds.o.  If you want to compile it as a module, say M here and
+	  When compiled this way, there will be modules called pcmcia_core
+	  and ds.  If you want to compile it as a module, say M here and
 	  read <file:Documentation/modules.txt>.
 
 config CARDBUS
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	Mon Feb 10 10:39:30 2003
+++ b/drivers/pcmcia/Makefile	Mon Feb 10 10:39:30 2003
@@ -2,8 +2,6 @@
 # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
 #
 
-export-objs := ds.o cs.o yenta.o sa1100_generic.o
-
 obj-$(CONFIG_PCMCIA)			+= pcmcia_core.o ds.o
 ifeq ($(CONFIG_CARDBUS),y)
   obj-$(CONFIG_PCMCIA) 			+= yenta_socket.o
diff -Nru a/drivers/pcmcia/sa1100_trizeps.c b/drivers/pcmcia/sa1100_trizeps.c
--- a/drivers/pcmcia/sa1100_trizeps.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/pcmcia/sa1100_trizeps.c	Mon Feb 10 10:39:29 2003
@@ -13,7 +13,8 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 
-#include <asm/hardware.h>   // included trizeps.h
+#include <asm/hardware.h>
+#include <asm/arch/trizeps.h>
 #include <asm/mach-types.h>
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -54,7 +55,7 @@
 	return NUMBER_OF_TRIZEPS_PCMCIA_SLOTS;
 
  irq_err:
-	printk( KERN_ERR __FUNCTION__ ": PCMCIA Request for IRQ %u failed\n", TRIZEPS_IRQ_PCMCIA_CD0 );
+	printk( KERN_ERR "%s(): PCMCIA Request for IRQ %u failed\n", __FUNCTION__, TRIZEPS_IRQ_PCMCIA_CD0 );
 	return -1;
 }
 
diff -Nru a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
--- a/drivers/pnp/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/drivers/pnp/Kconfig	Mon Feb 10 10:39:27 2003
@@ -56,7 +56,7 @@
 	  Say Y here if you would like support for ISA Plug and Play devices.
 	  Some information is in <file:Documentation/isapnp.txt>.
 
-	  This support is also available as a module called isapnp.o ( =
+	  This support is also available as a module called isapnp ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/pnp/Makefile b/drivers/pnp/Makefile
--- a/drivers/pnp/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/pnp/Makefile	Mon Feb 10 10:39:23 2003
@@ -9,4 +9,3 @@
 obj-$(CONFIG_PNPBIOS)		+= pnpbios/
 obj-$(CONFIG_ISAPNP)		+= isapnp/
 
-export-objs	:= core.o driver.o resource.o $(pnp-card-y)
diff -Nru a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
--- a/drivers/pnp/isapnp/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/pnp/isapnp/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the kernel ISAPNP driver.
 #
 
-export-objs := core.o compat.o
-
 isapnp-proc-$(CONFIG_PROC_FS) = proc.o
 
 obj-y := core.o compat.o $(isapnp-proc-y)
diff -Nru a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
--- a/drivers/pnp/pnpbios/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/pnp/pnpbios/Makefile	Mon Feb 10 10:39:31 2003
@@ -2,8 +2,6 @@
 # Makefile for the kernel PNPBIOS driver.
 #
 
-export-objs := core.o
-
 pnpbios-proc-$(CONFIG_PROC_FS) = proc.o
 
 obj-y := core.o $(pnpbios-proc-y)
diff -Nru a/drivers/s390/Kconfig b/drivers/s390/Kconfig
--- a/drivers/s390/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/drivers/s390/Kconfig	Mon Feb 10 10:39:31 2003
@@ -48,7 +48,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called loop.o.
+	  will be called loop.
 
 	  Most users will answer N here.
 
@@ -77,7 +77,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called nbd.o.
+	  will be called nbd.
 
 	  If unsure, say N.
 
@@ -97,7 +97,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M and read <file:Documentation/modules.txt>. The module will be
-	  called rd.o.
+	  called rd.
 
 	  Most normal users won't need the RAM disk functionality, and can
 	  thus say N here.
@@ -127,7 +127,7 @@
 	  or zSeries as a disk.  This is useful as a _fast_ swap device if you
 	  want to access more than 2G of memory when running in 31 bit mode.
 	  This option is also available as a module which will be called
-	  xpram.o.  If unsure, say "N".
+	  xpram.  If unsure, say "N".
 
 comment "S/390 block device drivers"
 
@@ -286,7 +286,7 @@
 	  least one of the tape interface options and one of the tape
 	  hardware options in order to access a tape device.
 	  This option is also available as a module. The module will be
-	  called tape390.o and include all selected interfaces and
+	  called tape390 and include all selected interfaces and
 	  hardware drivers.
 
 comment "S/390 tape interface support"
@@ -368,7 +368,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called dummy.o.  If you want to use more than one dummy
+	  will be called dummy.  If you want to use more than one dummy
 	  device at a time, you need to compile this driver as a module.
 	  Instead of 'dummy', the devices will then be called 'dummy0',
 	  'dummy1' etc.
@@ -393,7 +393,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called bonding.o.
+	  will be called bonding.
 
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
@@ -414,7 +414,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eql.o.  If you want to compile it as a
+	  The module will be called eql.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -438,7 +438,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tun.o.  If you want to compile it as a
+	  The module will be called tun.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you don't know what to use this for, you don't need it.
@@ -524,7 +524,7 @@
   	   or zSeries. This device driver supports Token Ring (IEEE 802.5),
   	   FDDI (IEEE 802.7) and Ethernet. 
 	   This option is also available as a module which will be
-	   called lcs.o . If you do not know what it is, it's safe to say "Y".
+	   called lcs . If you do not know what it is, it's safe to say "Y".
 
 config CTC
 	tristate "CTC device support"
@@ -535,7 +535,7 @@
 	  coupling using ESCON. It also supports virtual CTCs when running
 	  under VM. It will use the channel device configuration if this is
 	  available.  This option is also available as a module which will be
-	  called ctc.o.  If you do not know what it is, it's safe to say "Y".
+	  called ctc.  If you do not know what it is, it's safe to say "Y".
 
 config IUCV
 	tristate "IUCV device support (VM only)"
@@ -543,7 +543,7 @@
 	help
 	  Select this option if you want to use inter-user communication
 	  vehicle networking under VM or VIF.  This option is also available
-	  as a module which will be called iucv.o. If unsure, say "Y".
+	  as a module which will be called iucv. If unsure, say "Y".
 
 config CCWGROUP
  	tristate
diff -Nru a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile
--- a/drivers/s390/block/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/s390/block/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # S/390 block devices
 #
 
-export-objs := dasd.o dasd_devmap.o dasd_ioctl.o dasd_erp.o
-
 dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o
 dasd_fba_mod-objs  := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
 dasd_diag_mod-objs := dasd_diag.o
diff -Nru a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
--- a/drivers/s390/char/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/s390/char/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,8 +2,6 @@
 # S/390 character devices
 #
 
-export-objs := sclp.o tape_core.o tape_devmap.o tape_std.o
-
 tub3270-objs := tuball.o tubfs.o tubtty.o \
                      tubttyaid.o tubttybld.o tubttyscl.o \
                      tubttyrcl.o tubttysiz.o
diff -Nru a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
--- a/drivers/s390/char/sclp_tty.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/s390/char/sclp_tty.c	Mon Feb 10 10:39:23 2003
@@ -198,7 +198,7 @@
 		break;
 	case TIOCSCLPSDELIM:
 		/*
-		 * set special character used for seperating upper and
+		 * set special character used for separating upper and
 		 * lower case, 0x00 disables this feature
 		 */
 		if (get_user(sclp_ioctls.delim, (unsigned char *) arg))
@@ -206,7 +206,7 @@
 		break;
 	case TIOCSCLPGDELIM:
 		/*
-		 * get special character used for seperating upper and
+		 * get special character used for separating upper and
 		 * lower case, 0x00 disables this feature
 		 */
 		if (put_user(sclp_ioctls.delim, (unsigned char *) arg))
@@ -507,7 +507,7 @@
 
 /*
  * get a EBCDIC string in upper/lower case,
- * find out characters in lower/upper case seperated by a special character,
+ * find out characters in lower/upper case separated by a special character,
  * modifiy original string,
  * returns length of resulting string
  */
diff -Nru a/drivers/s390/char/sclp_tty.h b/drivers/s390/char/sclp_tty.h
--- a/drivers/s390/char/sclp_tty.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/s390/char/sclp_tty.h	Mon Feb 10 10:39:27 2003
@@ -42,7 +42,7 @@
 #define TIOCSCLPSINIT	_IO(SCLP_IOCTL_LETTER, 6)
 /* enable/disable conversion from upper to lower case of input */
 #define TIOCSCLPSCASE	_IOW(SCLP_IOCTL_LETTER, 7, unsigned char)
-/* set special character used for seperating upper and lower case, */
+/* set special character used for separating upper and lower case, */
 /* 0x00 disables this feature */
 #define TIOCSCLPSDELIM	_IOW(SCLP_IOCTL_LETTER, 9, unsigned char)
 
@@ -58,7 +58,7 @@
 #define TIOCSCLPGOBUF	_IOR(SCLP_IOCTL_LETTER, 15, unsigned short)
 /* Is conversion from upper to lower case of input enabled ? */
 #define TIOCSCLPGCASE	_IOR(SCLP_IOCTL_LETTER, 17, unsigned char)
-/* get special character used for seperating upper and lower case, */
+/* get special character used for separating upper and lower case, */
 /* 0x00 disables this feature */
 #define TIOCSCLPGDELIM	_IOR(SCLP_IOCTL_LETTER, 19, unsigned char)
 /* get the number of buffers/pages got from kernel at startup */
diff -Nru a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
--- a/drivers/s390/char/tape_char.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/s390/char/tape_char.c	Mon Feb 10 10:39:30 2003
@@ -64,7 +64,7 @@
  * Terminate write command (we write two TMs and skip backward over last)
  * This ensures that the tape is always correctly terminated.
  * When the user writes afterwards a new file, he will overwrite the
- * second TM and therefore one TM will remain to seperate the
+ * second TM and therefore one TM will remain to separate the
  * two files on the tape...
  */
 static inline void
diff -Nru a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
--- a/drivers/s390/cio/Makefile	Mon Feb 10 10:39:22 2003
+++ b/drivers/s390/cio/Makefile	Mon Feb 10 10:39:22 2003
@@ -3,15 +3,8 @@
 #
 
 obj-y += airq.o blacklist.o chsc.o cio.o css.o requestirq.o 
-export-objs += airq.o css.o cio.o requestirq.o
-
 ccw_device-objs += device.o device_fsm.o device_ops.o
 ccw_device-objs += device_id.o device_pgid.o device_status.o
 obj-y += ccw_device.o
-export-objs += device.o device_ops.o 
-
 obj-$(CONFIG_CCWGROUP) += ccwgroup.o
-export-objs += ccwgroup.o
-
 obj-$(CONFIG_QDIO) += qdio.o
-export-objs += qdio.o
diff -Nru a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
--- a/drivers/s390/net/Makefile	Mon Feb 10 10:39:25 2003
+++ b/drivers/s390/net/Makefile	Mon Feb 10 10:39:25 2003
@@ -2,8 +2,6 @@
 # S/390 network devices
 #
 
-export-objs := iucv.o fsm.o cu3088.o
-
 ctc-objs := ctcmain.o ctctty.o
 
 obj-$(CONFIG_IUCV) += iucv.o fsm.o
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/s390/net/lcs.c	Mon Feb 10 10:39:23 2003
@@ -61,7 +61,7 @@
  */
 #define VERSION_LCS_C  "$Revision: 1.42 $"
 
-static const char *version="LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
+static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 
 /**
  * Some prototypes.
diff -Nru a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
--- a/drivers/sbus/char/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/sbus/char/Makefile	Mon Feb 10 10:39:31 2003
@@ -7,8 +7,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs := bbc_i2c.o
-
 vfc-objs := vfc_dev.o vfc_i2c.o
 bbc-objs := bbc_i2c.o bbc_envctrl.o
 
diff -Nru a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
--- a/drivers/sbus/char/aurora.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/sbus/char/aurora.c	Mon Feb 10 10:39:23 2003
@@ -1046,7 +1046,7 @@
 			    &bp->r[chip]->r[CD180_MSVR]);
 	}
 	
-	/* Now we must calculate some speed dependant things. */
+	/* Now we must calculate some speed dependent things. */
 	
 	/* Set baud rate for port. */
 	tmp = (((bp->oscfreq + baud/2) / baud +
diff -Nru a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
--- a/drivers/sbus/char/bbc_envctrl.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/sbus/char/bbc_envctrl.c	Mon Feb 10 10:39:26 2003
@@ -30,7 +30,7 @@
  *
  * The max1617 is capable of being programmed with power-off
  * temperature values, one low limit and one high limit.  These
- * can be controlled independantly for the cpu or ambient temperature.
+ * can be controlled independently for the cpu or ambient temperature.
  * If a limit is violated, the power is simply shut off.  The frequency
  * with which the max1617 does temperature sampling can be controlled
  * as well.
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/3w-xxxx.c	Mon Feb 10 10:39:32 2003
@@ -2187,7 +2187,7 @@
 		return (FAILED);
 	}
 
-	tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 	if (tw_dev == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
 		return (FAILED);
@@ -2200,14 +2200,14 @@
 	for (i=0;i<TW_Q_LENGTH;i++) {
 		if (tw_dev->srb[i] == SCpnt) {
 			if (tw_dev->state[i] == TW_S_STARTED) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt);
 				tw_dev->state[i] = TW_S_COMPLETED;
 				tw_state_request_finish(tw_dev, i);
 				spin_unlock(&tw_dev->tw_lock);
 				return (SUCCESS);
 			}
 			if (tw_dev->state[i] == TW_S_PENDING) {
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt);
 				if (tw_dev->pending_head == TW_Q_LENGTH-1) {
 					tw_dev->pending_head = TW_Q_START;
 				} else {
@@ -2221,7 +2221,7 @@
 			}
 			if (tw_dev->state[i] == TW_S_POSTED) {
 				/* If the command has already been posted, we have to reset the card */
-				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
+				printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt);
 				/* We have to let AEN requests through before the reset */
 				spin_unlock(&tw_dev->tw_lock);
 				spin_unlock_irq(tw_dev->host->host_lock);
@@ -2254,7 +2254,7 @@
 		return (FAILED);
 	}
 
-	tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 	if (tw_dev == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
 		return (FAILED);
@@ -2356,7 +2356,7 @@
 	int request_id = 0;
 	int error = 0;
 	unsigned long flags = 0;
-	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 
 	if (tw_dev == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
@@ -2369,7 +2369,7 @@
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
 
 	/* Skip scsi command if it isn't for us */
-	if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) {
+	if ((tw_dev->is_unit_present[SCpnt->device->id] == FALSE) || (SCpnt->device->lun != 0)) {
 		SCpnt->result = (DID_BAD_TARGET << 16);
 		done(SCpnt);
 		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
@@ -2618,7 +2618,7 @@
 
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	memset(param, 0, sizeof(TW_Sector));
-	param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->target;
+	param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
 	param->parameter_id = 7; /* unit flags */
 	param->parameter_size_bytes = 1;
 	param_value = tw_dev->alignment_physical_address[request_id];
@@ -2697,7 +2697,7 @@
 	command_packet->byte0.sgl_offset = 2;
 	command_packet->size = 4;
 	command_packet->request_id = request_id;
-	command_packet->byte3.unit = tw_dev->srb[request_id]->target;
+	command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
 	command_packet->byte3.host_id = 0;
 	command_packet->status = 0;
 	command_packet->flags = 0;
@@ -2711,7 +2711,7 @@
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	memset(param, 0, sizeof(TW_Sector));
 	param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + 
-	tw_dev->srb[request_id]->target;
+	tw_dev->srb[request_id]->device->id;
 	param->parameter_id = 4;	/* unitcapacity parameter */
 	param->parameter_size_bytes = 4;
 	param_value = tw_dev->alignment_physical_address[request_id];
@@ -2817,7 +2817,7 @@
 	command_packet->byte0.sgl_offset = 3;
 	command_packet->size = 3;
 	command_packet->request_id = request_id;
-	command_packet->byte3.unit = srb->target;
+	command_packet->byte3.unit = srb->device->id;
 	command_packet->byte3.host_id = 0;
 	command_packet->status = 0;
 	command_packet->flags = 0;
@@ -2924,7 +2924,7 @@
 	command_packet->byte0.sgl_offset = 0;
 	command_packet->size = 2;
 	command_packet->request_id = request_id;
-	command_packet->byte3.unit = tw_dev->srb[request_id]->target;
+	command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
 	command_packet->byte3.host_id = 0;
 	command_packet->status = 0;
 	command_packet->flags = 0;
diff -Nru a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c
--- a/drivers/scsi/53c7,8xx.c	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6432 +0,0 @@
-/*
- * PERM_OPTIONS are driver options which will be enabled for all NCR boards
- * in the system at driver initialization time.
- *
- * Don't THINK about touching these in PERM_OPTIONS : 
- *   OPTION_IO_MAPPED 
- * 	Memory mapped IO does not work under i86 Linux. 
- *
- *   OPTION_DEBUG_TEST1
- *	Test 1 does bus mastering and interrupt tests, which will help weed 
- *	out brain damaged main boards.
- *
- * These are development kernel changes.  Code for them included in this
- * driver release may or may not work.  If you turn them on, you should be 
- * running the latest copy of the development sources from
- *
- *	ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/53c7,8xx
- *
- * and be subscribed to the ncr53c810@colorado.edu mailing list.  To
- * subscribe, send mail to majordomo@colorado.edu with 
- *
- * 	subscribe ncr53c810
- * 
- * in the text.
- *
- *
- *   OPTION_NO_ASYNC
- *	Don't negotiate for asynchronous transfers on the first command 
- *	when OPTION_ALWAYS_SYNCHRONOUS is set.  Useful for dain bramaged
- *	devices which do something bad rather than sending a MESSAGE 
- *	REJECT back to us like they should if they can't cope.
- *
- *   OPTION_SYNCHRONOUS
- *	Enable support for synchronous transfers.  Target negotiated 
- *	synchronous transfers will be responded to.  To initiate 
- *	a synchronous transfer request,  call 
- *
- *	    request_synchronous (hostno, target) 
- *
- *	from within KGDB.
- *
- *   OPTION_ALWAYS_SYNCHRONOUS
- *	Negotiate for synchronous transfers with every target after
- *	driver initialization or a SCSI bus reset.  This is a bit dangerous, 
- *	since there are some dain bramaged SCSI devices which will accept
- *	SDTR messages but keep talking asynchronously.
- *
- *   OPTION_DISCONNECT
- *	Enable support for disconnect/reconnect.  To change the 
- *	default setting on a given host adapter, call
- *
- *	    request_disconnect (hostno, allow)
- *
- *	where allow is non-zero to allow, 0 to disallow.
- * 
- *  If you really want to run 10MHz FAST SCSI-II transfers, you should 
- *  know that the NCR driver currently ignores parity information.  Most
- *  systems do 5MHz SCSI fine.  I've seen a lot that have problems faster
- *  than 8MHz.  To play it safe, we only request 5MHz transfers.
- *
- *  If you'd rather get 10MHz transfers, edit sdtr_message and change 
- *  the fourth byte from 50 to 25.
- */
-
-#error Please convert me to Documentation/DMA-mapping.txt
-
-#include <linux/config.h>
-
-#ifdef CONFIG_SCSI_NCR53C7xx_sync
-#ifdef CONFIG_SCSI_NCR53C7xx_DISCONNECT
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\
-	OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS)
-#else
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|\
-	OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS)
-#endif
-#else
-#ifdef CONFIG_SCSI_NCR53C7xx_DISCONNECT
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\
-	OPTION_SYNCHRONOUS)
-#else
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_SYNCHRONOUS)
-#endif
-#endif
-
-/*
- * Sponsored by 
- *	iX Multiuser Multitasking Magazine
- *	Hannover, Germany
- *	hm@ix.de
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt
- *      Visionary Computing 
- *      (Unix and Linux consulting and custom programming)
- *      drew@PoohSticks.ORG
- *	+1 (303) 786-7975
- *
- * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
- * 
- * For more information, please consult 
- *
- * NCR53C810 
- * SCSI I/O Processor
- * Programmer's Guide
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810/53C820
- * PCI-SCSI I/O Processor Design In Guide
- *
- * For literature on Symbios Logic Inc. formerly NCR, SCSI, 
- * and Communication products please call (800) 334-5454 or
- * (719) 536-3300. 
- * 
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000 
- * +1 (800) 433-5177
- */
-
-/*
- * Design issues : 
- * The cumulative latency needed to propagate a read/write request 
- * through the file system, buffer cache, driver stacks, SCSI host, and 
- * SCSI device is ultimately the limiting factor in throughput once we 
- * have a sufficiently fast host adapter.
- *  
- * So, to maximize performance we want to keep the ratio of latency to data 
- * transfer time to a minimum by
- * 1.  Minimizing the total number of commands sent (typical command latency
- *	including drive and bus mastering host overhead is as high as 4.5ms)
- *	to transfer a given amount of data.  
- *
- *      This is accomplished by placing no arbitrary limit on the number
- *	of scatter/gather buffers supported, since we can transfer 1K
- *	per scatter/gather buffer without Eric's cluster patches, 
- *	4K with.  
- *
- * 2.  Minimizing the number of fatal interrupts serviced, since
- * 	fatal interrupts halt the SCSI I/O processor.  Basically,
- *	this means offloading the practical maximum amount of processing 
- *	to the SCSI chip.
- * 
- *	On the NCR53c810/820/720,  this is accomplished by using 
- *		interrupt-on-the-fly signals when commands complete, 
- *		and only handling fatal errors and SDTR / WDTR 	messages 
- *		in the host code.
- *
- *	On the NCR53c710, interrupts are generated as on the NCR53c8x0,
- *		only the lack of an interrupt-on-the-fly facility complicates
- *		things.   Also, SCSI ID registers and commands are 
- *		bit fielded rather than binary encoded.
- *		
- * 	On the NCR53c700 and NCR53c700-66, operations that are done via 
- *		indirect, table mode on the more advanced chips must be
- *	        replaced by calls through a jump table which 
- *		acts as a surrogate for the DSA.  Unfortunately, this 
- * 		will mean that we must service an interrupt for each 
- *		disconnect/reconnect.
- * 
- * 3.  Eliminating latency by pipelining operations at the different levels.
- * 	
- *	This driver allows a configurable number of commands to be enqueued
- *	for each target/lun combination (experimentally, I have discovered
- *	that two seems to work best) and will ultimately allow for 
- *	SCSI-II tagged queuing.
- * 	
- *
- * Architecture : 
- * This driver is built around a Linux queue of commands waiting to 
- * be executed, and a shared Linux/NCR array of commands to start.  Commands
- * are transferred to the array  by the run_process_issue_queue() function 
- * which is called whenever a command completes.
- *
- * As commands are completed, the interrupt routine is triggered,
- * looks for commands in the linked list of completed commands with
- * valid status, removes these commands from a list of running commands, 
- * calls the done routine, and flags their target/luns as not busy.
- *
- * Due to limitations in the intelligence of the NCR chips, certain
- * concessions are made.  In many cases, it is easier to dynamically 
- * generate/fix-up code rather than calculate on the NCR at run time.  
- * So, code is generated or fixed up for
- *
- * - Handling data transfers, using a variable number of MOVE instructions
- *	interspersed with CALL MSG_IN, WHEN MSGIN instructions.
- *
- * 	The DATAIN and DATAOUT routines	are separate, so that an incorrect
- *	direction can be trapped, and space isn't wasted. 
- *
- *	It may turn out that we're better off using some sort 
- *	of table indirect instruction in a loop with a variable
- *	sized table on the NCR53c710 and newer chips.
- *
- * - Checking for reselection (NCR53c710 and better)
- *
- * - Handling the details of SCSI context switches (NCR53c710 and better),
- *	such as reprogramming appropriate synchronous parameters, 
- *	removing the dsa structure from the NCR's queue of outstanding
- *	commands, etc.
- *
- */
-
-/* 
- * Accommodate differences between stock 1.2.x and 1.3.x asm-i386/types.h
- * so lusers can drop in 53c7,8xx.* and get something which compiles 
- * without warnings.
- */
-
-#include <linux/version.h>
-
-#include <linux/module.h>
-
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/time.h>
-#include <linux/blk.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#include "scsi.h"
-#include "hosts.h"
-#include "53c7,8xx.h"
-#include <linux/stat.h>
-#include <linux/stddef.h>
-
-static int check_address (unsigned long addr, int size);
-static void dump_events (struct Scsi_Host *host, int count);
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, 
-    int free, int issue);
-static void hard_reset (struct Scsi_Host *host);
-static void ncr_scsi_reset (struct Scsi_Host *host);
-static void print_lots (struct Scsi_Host *host);
-static void set_synchronous (struct Scsi_Host *host, int target, int sxfer, 
-    int scntl3, int now_connected);
-static int datapath_residual (struct Scsi_Host *host);
-static const char * sbcl_to_phase (int sbcl);
-static void print_progress (Scsi_Cmnd *cmd);
-static void print_queues (struct Scsi_Host *host);
-static void process_issue_queue (unsigned long flags);
-static int shutdown (struct Scsi_Host *host);
-static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
-static int disable (struct Scsi_Host *host);
-static int NCR53c8xx_run_tests (struct Scsi_Host *host);
-static int NCR53c8xx_script_len;
-static int NCR53c8xx_dsa_len;
-static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
-static void do_NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
-static int ncr_halt (struct Scsi_Host *host);
-static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
-    *cmd);
-static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-static void print_dsa (struct Scsi_Host *host, u32 *dsa,
-    const char *prefix);
-static int print_insn (struct Scsi_Host *host, const u32 *insn,
-    const char *prefix, int kernel);
-
-static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
-static void NCR53c8x0_init_fixup (struct Scsi_Host *host);
-static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd);
-static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
-
-/* INSMOD variables */
-static long long perm_options = PERM_OPTIONS;
-/* 14 = .5s; 15 is max; decreasing divides by two. */
-static int selection_timeout = 14;
-/* Size of event list (per host adapter) */
-static int track_events = 0;
-
-static struct Scsi_Host *first_host = NULL;	/* Head of list of NCR boards */
-static Scsi_Host_Template *the_template = NULL;	
-
-/*
- * KNOWN BUGS :
- * - There is some sort of conflict when the PPP driver is compiled with 
- * 	support for 16 channels?
- * 
- * - On systems which predate the 1.3.x initialization order change,
- *      the NCR driver will cause Cannot get free page messages to appear.  
- *      These are harmless, but I don't know of an easy way to avoid them.
- *
- * - With OPTION_DISCONNECT, on two systems under unknown circumstances,
- *	we get a PHASE MISMATCH with DSA set to zero (suggests that we 
- *	are occurring somewhere in the reselection code) where 
- *	DSP=some value DCMD|DBC=same value.  
- * 	
- *	Closer inspection suggests that we may be trying to execute
- *	some portion of the DSA?
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : no current command : unexpected phase MSGIN.
- *         DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0
- *         DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80
- * scsi0 : DSP->
- * 001c46cc : 0x001c46cc 0x00000000
- * 001c46d4 : 0x001c5ea0 0x000011f8
- *
- *	Changed the print code in the phase_mismatch handler so
- *	that we call print_lots to try to diagnose this.
- *
- */
-
-/* 
- * Possible future direction of architecture for max performance :
- *
- * We're using a single start array for the NCR chip.  This is 
- * sub-optimal, because we cannot add a command which would conflict with 
- * an executing command to this start queue, and therefore must insert the 
- * next command for a given I/T/L combination after the first has completed;
- * incurring our interrupt latency between SCSI commands.
- *
- * To allow further pipelining of the NCR and host CPU operation, we want 
- * to set things up so that immediately on termination of a command destined 
- * for a given LUN, we get that LUN busy again.  
- * 
- * To do this, we need to add a 32 bit pointer to which is jumped to 
- * on completion of a command.  If no new command is available, this 
- * would point to the usual DSA issue queue select routine.
- *
- * If one were, it would point to a per-NCR53c7x0_cmd select routine 
- * which starts execution immediately, inserting the command at the head 
- * of the start queue if the NCR chip is selected or reselected.
- *
- * We would change so that we keep a list of outstanding commands 
- * for each unit, rather than a single running_list.  We'd insert 
- * a new command into the right running list; if the NCR didn't 
- * have something running for that yet, we'd put it in the 
- * start queue as well.  Some magic needs to happen to handle the 
- * race condition between the first command terminating before the 
- * new one is written.
- *
- * Potential for profiling : 
- * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution.
- */
-
-
-/*
- * TODO : 
- * 1.  To support WIDE transfers, not much needs to happen.  We
- *	should do CHMOVE instructions instead of MOVEs when
- *	we have scatter/gather segments of uneven length.  When
- * 	we do this, we need to handle the case where we disconnect
- *	between segments.
- * 
- * 2.  Currently, when Icky things happen we do a FATAL().  Instead,
- *     we want to do an integrity check on the parts of the NCR hostdata
- *     structure which were initialized at boot time; FATAL() if that 
- *     fails, and otherwise try to recover.  Keep track of how many
- *     times this has happened within a single SCSI command; if it 
- *     gets excessive, then FATAL().
- *
- * 3.  Parity checking is currently disabled, and a few things should 
- *     happen here now that we support synchronous SCSI transfers :
- *     1.  On soft-reset, we should set the EPC (Enable Parity Checking)
- *	   and AAP (Assert SATN/ on parity error) bits in SCNTL0.
- *	
- *     2.  We should enable the parity interrupt in the SIEN0 register.
- * 
- *     3.  intr_phase_mismatch() needs to believe that message out is 
- *	   always an "acceptable" phase to have a mismatch in.  If 
- *	   the old phase was MSG_IN, we should send a MESSAGE PARITY 
- *	   error.  If the old phase was something else, we should send
- *	   a INITIATOR_DETECTED_ERROR message.  Note that this could
- *	   cause a RESTORE POINTERS message; so we should handle that 
- *	   correctly first.  Instead, we should probably do an 
- *	   initiator_abort.
- *
- * 4.  MPEE bit of CTEST4 should be set so we get interrupted if 
- *     we detect an error.
- *
- *  
- * 5.  The initial code has been tested on the NCR53c810.  I don't 
- *     have access to NCR53c700, 700-66 (Forex boards), NCR53c710
- *     (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to 
- *     finish development on those platforms.
- *
- *     NCR53c820/825/720 - need to add wide transfer support, including WDTR 
- *     		negotiation, programming of wide transfer capabilities
- *		on reselection and table indirect selection.
- *
- *     NCR53c710 - need to add fatal interrupt or GEN code for 
- *		command completion signaling.   Need to modify all 
- *		SDID, SCID, etc. registers, and table indirect select code 
- *		since these use bit fielded (ie 1<<target) instead of 
- *		binary encoded target ids.  Need to accommodate
- *		different register mappings, probably scan through
- *		the SCRIPT code and change the non SFBR register operand
- *		of all MOVE instructions.
- * 
- *     NCR53c700/700-66 - need to add code to refix addresses on 
- *		every nexus change, eliminate all table indirect code,
- *		very messy.
- *
- * 6.  The NCR53c7x0 series is very popular on other platforms that 
- *     could be running Linux - ie, some high performance AMIGA SCSI 
- *     boards use it.  
- *	
- *     So, I should include #ifdef'd code so that it is 
- *     compatible with these systems.
- *	
- *     Specifically, the little Endian assumptions I made in my 
- *     bit fields need to change, and if the NCR doesn't see memory
- *     the right way, we need to provide options to reverse words
- *     when the scripts are relocated.
- *
- * 7.  Use ioremap() to access memory mapped boards.  
- */
-
-/* 
- * Allow for simultaneous existence of multiple SCSI scripts so we 
- * can have a single driver binary for all of the family.
- *
- * - one for NCR53c700 and NCR53c700-66 chips	(not yet supported)
- * - one for rest (only the NCR53c810, 815, 820, and 825 are currently 
- *	supported)
- * 
- * So that we only need two SCSI scripts, we need to modify things so
- * that we fixup register accesses in READ/WRITE instructions, and 
- * we'll also have to accommodate the bit vs. binary encoding of IDs
- * with the 7xx chips.
- */
-
-/*
- * Use pci_chips_ids to translate in both directions between PCI device ID 
- * and chip numbers.  
- */
-
-static struct {
-    unsigned short pci_device_id;
-    int chip;
-/* 
- * The revision field of the PCI_CLASS_REVISION register is compared 
- * against each of these fields if the field is not -1.  If it
- * is less than min_revision or larger than max_revision, a warning
- * message is printed.
- */
-    int max_revision;
-    int min_revision;
-} pci_chip_ids[] = { 
-    {PCI_DEVICE_ID_NCR_53C810, 810, 2, 1}, 
-    {PCI_DEVICE_ID_NCR_53C815, 815, 3, 2},
-    {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},
-    {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}
-};
-
-#define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))
-
-#define ROUNDUP(adr,type)	\
-  ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
-
-/* 
- * Forced detection and autoprobe code for various hardware.  Currently, 
- * entry points for these are not included in init/main.c because if the 
- * PCI BIOS code isn't working right, you're not going to be able to use 
- * the hardware anyways; this way we force users to solve their 
- * problems rather than forcing detection and blaming us when it 
- * does not work.
- */
-
-static struct override {
-    int chip;	/* 700, 70066, 710, 720, 810, 820 */
-    int board;	/* Any special board level gunk */
-    unsigned pci:1;
-    union {
-	struct {
-	    int base;	/* Memory address - indicates memory mapped regs */
-	    int io_port;/* I/O port address - indicates I/O mapped regs */
-    	    int irq;	/* IRQ line */		
-    	    int dma;	/* DMA channel 		- often none */
-	} normal;
-	struct {
-	    int bus;
-	    int device;
-	    int function;
-	} pci;
-    } data;
-    long long options;
-} overrides [4] = {{0,},};
-static int commandline_current = 0;
-static int no_overrides = 0;
-
-#if 0
-#define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))
-#else
-#define OVERRIDE_LIMIT commandline_current
-#endif
-
-/*
- * Function: issue_to_cmd
- *
- * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd
- *	structure pointer.  
- *
- * Inputs; issue - pointer to start of NOP or JUMP instruction
- *	in issue array.
- *
- * Returns: pointer to command on success; 0 if opcode is NOP.
- */
-
-static inline struct NCR53c7x0_cmd *
-issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
-    u32 *issue)
-{
-    return (issue[0] != hostdata->NOP_insn) ? 
-    /* 
-     * If the IF TRUE bit is set, it's a JUMP instruction.  The
-     * operand is a bus pointer to the dsa_begin routine for this DSA.  The
-     * dsa field of the NCR53c7x0_cmd structure starts with the 
-     * DSA code template.  By converting to a virtual address,
-     * subtracting the code template size, and offset of the 
-     * dsa field, we end up with a pointer to the start of the 
-     * structure (alternatively, we could use the 
-     * dsa_cmnd field, an anachronism from when we weren't
-     * sure what the relationship between the NCR structures
-     * and host structures were going to be.
-     */
-	(struct NCR53c7x0_cmd *) ((char *) bus_to_virt (le32_to_cpu(issue[1])) - 
-	    (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -
-	    offsetof(struct NCR53c7x0_cmd, dsa)) 
-    /* If the IF TRUE bit is not set, it's a NOP */
-	: NULL;
-}
-
-
-/*
- * Function : static internal_setup(int board, int chip, char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : board - currently, unsupported.  chip - 700, 70066, 710, 720
- * 	810, 815, 820, 825, although currently only the NCR53c810 is 
- *	supported.
- * 
- */
-
-static void 
-internal_setup(int board, int chip, char *str, int *ints) {
-    unsigned char pci;		/* Specifies a PCI override, with bus, device,
-				   function */
-
-    pci = (str && !strcmp (str, "pci")) ? 1 : 0;
-    
-/*
- * Override syntaxes are as follows : 
- * ncr53c700,ncr53c700-66,ncr53c710,ncr53c720=mem,io,irq,dma
- * ncr53c810,ncr53c820,ncr53c825=mem,io,irq or pci,bus,device,function
- */
-
-    if (commandline_current < OVERRIDE_LIMIT) {
-	overrides[commandline_current].pci = pci ? 1 : 0;
-	if (!pci) {
-	    overrides[commandline_current].data.normal.base = ints[1];
-	    overrides[commandline_current].data.normal.io_port = ints[2];
-	    overrides[commandline_current].data.normal.irq = ints[3];
-    	    overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?
-    	    	ints[4] : DMA_NONE;
-	    /* FIXME: options is now a long long */
-    	    overrides[commandline_current].options = (ints[0] >= 5) ?
-    	    	ints[5] : 0;
-	} else {
-	    overrides[commandline_current].data.pci.bus = ints[1];
-	    overrides[commandline_current].data.pci.device = ints[2];
-	    overrides[commandline_current].data.pci.function = ints[3];
-	    /* FIXME: options is now a long long */
-    	    overrides[commandline_current].options = (ints[0] >= 4) ?
-    	    	ints[4] : 0;
-	}
-	overrides[commandline_current].board = board;
-	overrides[commandline_current].chip = chip;
-	++commandline_current;
-    	++no_overrides;
-    } else {
-	printk ("53c7,7x0.c:internal_setup() : too many overrides\n");
-    }
-}
-
-/*
- * XXX - we might want to implement a single override function
- *       with a chip type field, revamp the command line configuration,
- * 	 etc.
- */
-
-#define setup_wrapper(x) 				\
-void ncr53c##x##_setup (char *str, int *ints) {		\
-    internal_setup (BOARD_GENERIC, x, str, ints);	\
-}
-
-setup_wrapper(700)
-setup_wrapper(70066)
-setup_wrapper(710)
-setup_wrapper(720)
-setup_wrapper(810)
-setup_wrapper(815)
-setup_wrapper(820)
-setup_wrapper(825)
-
-/* 
- * FIXME: we should junk these, in favor of synchronous_want and 
- * wide_want in the NCR53c7x0_hostdata structure.
- */
-
-/* Template for "preferred" synchronous transfer parameters. */
-
-static const unsigned char sdtr_message[] = {
-#ifdef CONFIG_SCSI_NCR53C7xx_FAST
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 25 /* *4ns */, 8 /* off */ 
-#else
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */ 
-#endif
-};
-
-/* Template to request asynchronous transfers */
-
-static const unsigned char async_message[] = {
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */
-};
-
-/* Template for "preferred" WIDE transfer parameters */
-
-static const unsigned char wdtr_message[] = {
-    EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */
-};
-
-/*
- * Function : struct Scsi_Host *find_host (int host)
- * 
- * Purpose : KGDB support function which translates a host number 
- * 	to a host structure. 
- *
- * Inputs : host - number of SCSI host
- *
- * Returns : NULL on failure, pointer to host structure on success.
- */
-
-#if 0
-static struct Scsi_Host *
-find_host (int host) {
-    struct Scsi_Host *h;
-    for (h = first_host; h && h->host_no != host; h = h->next);
-    if (!h) {
-	printk (KERN_ALERT "scsi%d not found\n", host);
-	return NULL;
-    } else if (h->hostt != the_template) {
-	printk (KERN_ALERT "scsi%d is not a NCR board\n", host);
-	return NULL;
-    }
-    return h;
-}
-
-/*
- * Function : request_synchronous (int host, int target)
- * 
- * Purpose : KGDB interface which will allow us to negotiate for 
- * 	synchronous transfers.  This ill be replaced with a more 
- * 	integrated function; perhaps a new entry in the scsi_host 
- *	structure, accessible via an ioctl() or perhaps /proc/scsi.
- *
- * Inputs : host - number of SCSI host; target - number of target.
- *
- * Returns : 0 when negotiation has been setup for next SCSI command,
- *	-1 on failure.
- */
-
-static int
-request_synchronous (int host, int target) {
-    struct Scsi_Host *h;
-    struct NCR53c7x0_hostdata *hostdata;
-    unsigned long flags;
-    if (target < 0) {
-	printk (KERN_ALERT "target %d is bogus\n", target);
-	return -1;
-    }
-    if (!(h = find_host (host)))
-	return -1;
-    else if (h->this_id == target) {
-	printk (KERN_ALERT "target %d is host ID\n", target);
-	return -1;
-    } 
-    else if (target > h->max_id) {
-	printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
-	    h->max_id);
-	return -1;
-    }
-    hostdata = (struct NCR53c7x0_hostdata *)h->hostdata;
-
-    save_flags(flags);
-    cli();
-    if (hostdata->initiate_sdtr & (1 << target)) {
-	restore_flags(flags);
-	printk (KERN_ALERT "target %d already doing SDTR\n", target);
-	return -1;
-    } 
-    hostdata->initiate_sdtr |= (1 << target);
-    restore_flags(flags);
-    return 0;
-}
-
-/*
- * Function : request_disconnect (int host, int on_or_off)
- * 
- * Purpose : KGDB support function, tells us to allow or disallow 
- *	disconnections.
- *
- * Inputs : host - number of SCSI host; on_or_off - non-zero to allow,
- *	zero to disallow.
- *
- * Returns : 0 on success, *	-1 on failure.
- */
-
-static int 
-request_disconnect (int host, int on_or_off) {
-    struct Scsi_Host *h;
-    struct NCR53c7x0_hostdata *hostdata;
-    if (!(h = find_host (host)))
-	return -1;
-    hostdata = (struct NCR53c7x0_hostdata *) h->hostdata;
-    if (on_or_off) 
-	hostdata->options |= OPTION_DISCONNECT;
-    else
-	hostdata->options &= ~OPTION_DISCONNECT;
-    return 0;
-}
-#endif
-
-/*
- * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
- *
- * Purpose : Initialize internal structures, as required on startup, or 
- *	after a SCSI bus reset.
- * 
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void 
-NCR53c7x0_driver_init (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    int i, j;
-    u32 *curr;
-    for (i = 0; i < 16; ++i) {
-	hostdata->request_sense[i] = 0;
-    	for (j = 0; j < 8; ++j) 
-	    hostdata->busy[i][j] = 0;
-	set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0);
-    }
-    hostdata->issue_queue = NULL;
-    hostdata->running_list = hostdata->finished_queue = 
-	hostdata->curr = NULL;
-    for (i = 0, curr = (u32 *) hostdata->schedule; 
-	i < host->can_queue; ++i, curr += 2) {
-	curr[0] = hostdata->NOP_insn;
-	curr[1] = le32_to_cpu(0xdeadbeef);
-    }
-    curr[0] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE);
-    curr[1] = (u32) le32_to_cpu(virt_to_bus (hostdata->script) +
-	hostdata->E_wait_reselect);
-    hostdata->reconnect_dsa_head = 0;
-    hostdata->addr_reconnect_dsa_head = (u32) 
-	le32_to_cpu(virt_to_bus((void *) &(hostdata->reconnect_dsa_head)));
-    hostdata->expecting_iid = 0;
-    hostdata->expecting_sto = 0;
-    if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS) 
-	hostdata->initiate_sdtr = le32_to_cpu(0xffff); 
-    else
-    	hostdata->initiate_sdtr = 0;
-    hostdata->talked_to = 0;
-    hostdata->idle = 1;
-}
-
-/* 
- * Function : static int ccf_to_clock (int ccf)
- *
- * Purpose :  Return the largest SCSI clock allowable for a given
- *	clock conversion factor, allowing us to do synchronous periods
- *	when we don't know what the SCSI clock is by taking at least 
- *	as long as the device says we can.
- *
- * Inputs : ccf
- *
- * Returns : clock on success, -1 on failure.
- */
-
-static int 
-ccf_to_clock (int ccf) {
-    switch (ccf) {
-    case 1: return 25000000; 	/* Divide by 1.0 */
-    case 2: return 37500000;	/* Divide by 1.5 */
-    case 3: return 50000000;  	/* Divide by 2.0 */
-    case 0: 			/* Divide by 3.0 */
-    case 4: return 66000000; 
-    default: return -1;
-    }
-}
-
-/* 
- * Function : static int clock_to_ccf (int clock)
- *
- * Purpose :  Return the clock conversion factor for a given SCSI clock.
- *
- * Inputs : clock - SCSI clock expressed in Hz.
- *
- * Returns : ccf on success, -1 on failure.
- */
-
-static int 
-clock_to_ccf (int clock) {
-    if (clock < 16666666)
-	return -1;
-    if (clock < 25000000)
-	return 1; 	/* Divide by 1.0 */
-    else if (clock < 37500000)
-	return 2; 	/* Divide by 1.5 */
-    else if (clock < 50000000)
-	return 3;	/* Divide by 2.0 */
-    else if (clock < 66000000)
-	return 4;	/* Divide by 3.0 */
-    else 
-	return -1;
-}
-    
-/* 
- * Function : static int NCR53c7x0_init (struct Scsi_Host *host)
- *
- * Purpose :  initialize the internal structures for a given SCSI host
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : when this function is called, the chip_type 
- * 	field of the hostdata structure MUST have been set.
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-static int 
-NCR53c7x0_init (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    int i, ccf, expected_ccf;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    struct Scsi_Host *search;
-    /* 
-     * There are some things which we need to know about in order to provide
-     * a semblance of support.  Print 'em if they aren't what we expect, 
-     * otherwise don't add to the noise.
-     * 
-     * -1 means we don't know what to expect.
-     */
-    int expected_id = -1;
-    int expected_clock = -1;
-    int uninitialized = 0;
-    /* 
-     * FIXME : this is only on Intel boxes.  On other platforms, this
-     * will differ.
-     */
-    int expected_mapping = OPTION_IO_MAPPED;
-
-    NCR53c7x0_local_setup(host);
-
-    switch (hostdata->chip) {
-    case 820:
-    case 825:
-#ifdef notyet
-	host->max_id = 15;
-#endif
-	/* Fall through */
-    case 810:
-    case 815:
-    	hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;
-    	hostdata->init_save_regs = NULL;
-    	hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;
-    	hostdata->init_fixup = NCR53c8x0_init_fixup;
-    	hostdata->soft_reset = NCR53c8x0_soft_reset;
-	hostdata->run_tests = NCR53c8xx_run_tests;
-/* Is the SCSI clock ever anything else on these chips? */
-	expected_clock = hostdata->scsi_clock = 40000000;
-	expected_id = 7;
-    	break;
-    default:
-	printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
-	    host->host_no, hostdata->chip);
-	scsi_unregister (host);
-	return -1;
-    }
-
-    /* Assign constants accessed by NCR */
-    hostdata->NCR53c7xx_zero = 0;			
-    hostdata->NCR53c7xx_msg_reject = le32_to_cpu(MESSAGE_REJECT);
-    hostdata->NCR53c7xx_msg_abort = le32_to_cpu(ABORT);
-    hostdata->NCR53c7xx_msg_nop = le32_to_cpu(NOP);
-    hostdata->NOP_insn = le32_to_cpu((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24);
-
-    if (expected_mapping == -1 || 
-	(hostdata->options & (OPTION_MEMORY_MAPPED)) != 
-	(expected_mapping & OPTION_MEMORY_MAPPED))
-	printk ("scsi%d : using %s mapped access\n", host->host_no, 
-	    (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" : 
-	    "io");
-
-    hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ? 
-	DMODE_REG_00 : DMODE_REG_10;
-    hostdata->istat = ((hostdata->chip / 100) == 8) ? 
-    	ISTAT_REG_800 : ISTAT_REG_700;
-
-/* Only the ISTAT register is readable when the NCR is running, so make 
-   sure it's halted. */
-    ncr_halt(host);
-
-/* 
- * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
- *	as does the 710 with one bit per SCSI ID.  Conversely, the NCR
- * 	uses a normal, 3 bit binary representation of these values.
- *
- * Get the rest of the NCR documentation, and FIND OUT where the change
- * was.
- */
-#if 0
-    tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
-    for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
-#else
-    host->this_id = NCR53c7x0_read8(SCID_REG) & 15;
-    if (host->this_id == 0)
-	host->this_id = 7;	/* sanitize hostid---0 doesn't make sense */
-    hostdata->this_id_mask = 1 << host->this_id;
-#endif
-
-/*
- * Note : we should never encounter a board setup for ID0.  So,
- * 	if we see ID0, assume that it was uninitialized and set it
- * 	to the industry standard 7.
- */
-    if (!host->this_id) {
-	printk("scsi%d : initiator ID was %d, changing to 7\n",
-	    host->host_no, host->this_id);
-	host->this_id = 7;
-	hostdata->this_id_mask = 1 << 7;
-	uninitialized = 1;
-    };
-
-    if (expected_id == -1 || host->this_id != expected_id)
-    	printk("scsi%d : using initiator ID %d\n", host->host_no,
-    	    host->this_id);
-
-    /*
-     * Save important registers to allow a soft reset.
-     */
-
-    if ((hostdata->chip / 100) == 8) {
-    /* 
-     * CTEST4 controls burst mode disable.
-     */
-	hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) & 
-    	    CTEST4_800_SAVE;
-    } else {
-    /*
-     * CTEST7 controls cache snooping, burst mode, and support for 
-     * external differential drivers.
-     */
-	hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
-    }
-
-    /*
-     * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
-     * on 800 series chips, it allows for a totem-pole IRQ driver.
-     */
-
-    hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
-
-    /* 
-     * DCNTL_800_IRQM controls weather we are using an open drain
-     * driver (reset) or totem pole driver (set).  In all cases, 
-     * it's level active.  I suppose this is an issue when we're trying to 
-     * wire-or the same PCI INTx line?
-     */
-    if ((hostdata->chip / 100) == 8)
-	hostdata->saved_dcntl &= ~DCNTL_800_IRQM;
-
-    /*
-     * DMODE controls DMA burst length, and on 700 series chips,
-     * 286 mode and bus width  
-     */
-    hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
-
-    /* 
-     * Now that burst length and enabled/disabled status is known, 
-     * clue the user in on it.  
-     */
-   
-    if ((hostdata->chip / 100) == 8) {
-	if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {
-	    printk ("scsi%d : burst mode disabled\n", host->host_no);
-	} else {
-	    switch (hostdata->saved_dmode & DMODE_BL_MASK) {
-	    case DMODE_BL_2: i = 2; break;
-	    case DMODE_BL_4: i = 4; break;
-	    case DMODE_BL_8: i = 8; break;
-	    case DMODE_BL_16: i = 16; break;
-            default: i = 0;
-	    }
-	    printk ("scsi%d : burst length %d\n", host->host_no, i);
-	}
-    }
-
-    /*
-     * On NCR53c810 and NCR53c820 chips, SCNTL3 contails the synchronous
-     * and normal clock conversion factors.
-     */
-    if (hostdata->chip / 100 == 8)  {
-	expected_ccf = clock_to_ccf (expected_clock);
-	hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);
-	ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;
-	if (expected_ccf != -1 && ccf != expected_ccf && !ccf) {
-	    hostdata->saved_scntl3 = (hostdata->saved_scntl3 &
-		~SCNTL3_800_CCF_MASK) | expected_ccf;
-	    if (!uninitialized) {
-		printk ("scsi%d : reset ccf to %d from %d\n", 
-		    host->host_no, expected_ccf, ccf);
-		uninitialized = 1;
-	    }
-	}
-    } else
-    	ccf = 0;
-
-    /*
-     * If we don't have a SCSI clock programmed, pick one on the upper
-     * bound of that allowed by NCR so that our transfers err on the 
-     * slow side, since transfer period must be >= the agreed 
-     * upon period.
-     */
-
-    if ((!hostdata->scsi_clock) && (hostdata->scsi_clock = ccf_to_clock (ccf)) 
-	== -1) {
-	printk ("scsi%d : clock conversion factor %d unknown.\n"
-		"         synchronous transfers disabled\n",
-		host->host_no, ccf);
-	hostdata->options &= ~OPTION_SYNCHRONOUS;
-	hostdata->scsi_clock = 0; 
-    }
-
-    if (expected_clock == -1 || hostdata->scsi_clock != expected_clock)
-    	printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no, 
-	    hostdata->scsi_clock / 1000000);
-
-    for (i = 0; i < 16; ++i) 
-	hostdata->cmd_allocated[i] = 0;
-
-    if (hostdata->init_save_regs)
-    	hostdata->init_save_regs (host);
-    if (hostdata->init_fixup)
-    	hostdata->init_fixup (host);
-
-    if (!the_template) {
-	the_template = host->hostt;
-	first_host = host;
-    }
-
-    /* 
-     * Linux SCSI drivers have always been plagued with initialization 
-     * problems - some didn't work with the BIOS disabled since they expected
-     * initialization from it, some didn't work when the networking code
-     * was enabled and registers got scrambled, etc.
-     *
-     * To avoid problems like this, in the future, we will do a soft 
-     * reset on the SCSI chip, taking it back to a sane state.
-     */
-
-    hostdata->soft_reset (host);
-
-#if 1
-    hostdata->debug_count_limit = -1;
-#else
-    hostdata->debug_count_limit = 1;
-#endif
-    hostdata->intrs = -1;
-    hostdata->resets = -1;
-    memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message, 
-	sizeof (hostdata->synchronous_want));
-
-    NCR53c7x0_driver_init (host);
-
-    /*
-     * Set up an interrupt handler if we aren't already sharing an IRQ
-     * with another board.
-     */
-
-    for (search = first_host; search && !(search->hostt == the_template &&
-	search->irq == host->irq && search != host); search=search->next);
-
-    if (!search) {
-#ifdef __powerpc__
-	if (request_irq(host->irq, do_NCR53c7x0_intr, SA_SHIRQ, "53c7,8xx", host)) 
-#else
-	if (request_irq(host->irq, do_NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx", host))
-#endif
-	  {
-	  
-	  
-	    printk("scsi%d : IRQ%d not free, detaching\n"
-	           "         You have either a configuration problem, or a\n"
-                   "         broken BIOS.  You may wish to manually assign\n"
-	           "         an interrupt to the NCR board rather than using\n"
-                   "         an automatic setting.\n", 
-		host->host_no, host->irq);
-	    scsi_unregister (host);
-	    return -1;
-	} 
-    } else {
-	printk("scsi%d : using interrupt handler previously installed for scsi%d\n",
-	    host->host_no, search->host_no);
-    }
-
-
-    if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
-        (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
-    	/* XXX Should disable interrupts, etc. here */
-	scsi_unregister (host);
-    	return -1;
-    } else {
-	if (host->io_port)  {
-	    host->n_io_port = 128;
-	    request_region (host->io_port, host->n_io_port, "ncr53c7,8xx");
-	}
-    }
-    
-    if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {
-	printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);
-	hard_reset (host);
-    }
-    return 0;
-}
-
-/* 
- * Function : static int normal_init(Scsi_Host_Template *tpnt, int board, 
- *	int chip, u32 base, int io_port, int irq, int dma, int pcivalid,
- *      struct pci_dev *pci_dev, long long options);
- *
- * Purpose : initializes a NCR53c7,8x0 based on base addresses,
- *	IRQ, and DMA channel.	
- *	
- *	Useful where a new NCR chip is backwards compatible with
- *	a supported chip, but the DEVICE ID has changed so it 
- *	doesn't show up when the autoprobe does a pci_find_device.
- *
- * Inputs : tpnt - Template for this SCSI adapter, board - board level
- *	product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
- *	device and function encoding as used by PCI BIOS calls.
- * 
- * Returns : 0 on success, -1 on failure.
- *
- */
-
-static int  __init 
-normal_init (Scsi_Host_Template *tpnt, int board, int chip, 
-    u32 base, int io_port, int irq, int dma, int pci_valid, 
-    struct pci_dev *pci_dev, long long options)
-{
-    struct Scsi_Host *instance;
-    struct NCR53c7x0_hostdata *hostdata;
-    char chip_str[80];
-    int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0, 
-	schedule_size = 0, ok = 0;
-    void *tmp;
-
-    options |= perm_options;
-
-    switch (chip) {
-    case 825:
-    case 820:
-    case 815:
-    case 810:
-	schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;
-	script_len = NCR53c8xx_script_len;
-    	dsa_len = NCR53c8xx_dsa_len;
-    	options |= OPTION_INTFLY;
-    	sprintf (chip_str, "NCR53c%d", chip);
-    	break;
-    default:
-    	printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);
-    	return -1;
-    }
-
-    printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",
-    	chip_str, (unsigned) base, io_port, irq);
-    if (dma == DMA_NONE)
-    	printk("\n");
-    else 
-    	printk(", dma %d\n", dma);
-
-    if ((chip / 100 == 8) && !pci_valid) 
-	printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" 
-		"        PCI override instead.\n"
-		"	 Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
-		"                 <bus> and <device> are usually 0.\n");
-
-    if (options & OPTION_DEBUG_PROBE_ONLY) {
-    	printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");
-    	return -1;
-    }
-
-    max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
-    	/* Size of dynamic part of command structure : */
-	2 * /* Worst case : we don't know if we need DATA IN or DATA out */
-		( 2 * /* Current instructions per scatter/gather segment */ 
-        	  tpnt->sg_tablesize + 
-                  3 /* Current startup / termination required per phase */
-		) *
-	8 /* Each instruction is eight bytes */;
-
-    /* Allocate fixed part of hostdata, dynamic part to hold appropriate
-       SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
-
-       We need a NCR53c7x0_cmd structure for scan_scsis() when we are 
-       not loaded as a module, and when we're loaded as a module, we 
-       can't use a non-dynamically allocated structure because modules
-       are vmalloc()'d, which can allow structures to cross page 
-       boundaries and breaks our physical/virtual address assumptions
-       for DMA.
-
-       So, we stick it past the end of our hostdata structure.
-
-       ASSUMPTION : 
-       	 Regardless of how many simultaneous SCSI commands we allow,
-	 the probe code only executes a _single_ instruction at a time,
-	 so we only need one here, and don't need to allocate NCR53c7x0_cmd
-	 structures for each target until we are no longer in scan_scsis
-	 and kmalloc() has become functional (memory_init() happens 
-	 after all device driver initialization).
-    */
-
-    size = sizeof(struct NCR53c7x0_hostdata) + script_len + 
-    /* Note that alignment will be guaranteed, since we put the command
-       allocated at probe time after the fixed-up SCSI script, which 
-       consists of 32 bit words, aligned on a 32 bit boundary.  But
-       on a 64bit machine we need 8 byte alignment for hostdata->free, so
-       we add in another 4 bytes to take care of potential misalignment
-       */
-	(sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;
-
-    instance = scsi_register (tpnt, size);
-    if (!instance)
-	return -1;
-
-    /* FIXME : if we ever support an ISA NCR53c7xx based board, we
-       need to check if the chip is running in a 16 bit mode, and if so 
-       unregister it if it is past the 16M (0x1000000) mark */
-   	
-    hostdata = (struct NCR53c7x0_hostdata *) 
-    	instance->hostdata;
-    hostdata->size = size;
-    hostdata->script_count = script_len / sizeof(u32);
-    hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;
-    hostdata->board = board;
-    hostdata->chip = chip;
-    if ((hostdata->pci_valid = pci_valid)) {
-	hostdata->pci_dev = pci_dev;
-    }
-
-    /*
-     * Being memory mapped is more desirable, since 
-     *
-     * - Memory accesses may be faster.
-     *
-     * - The destination and source address spaces are the same for 
-     *	 all instructions, meaning we don't have to twiddle dmode or 
-     *	 any other registers.
-     *
-     * So, we try for memory mapped, and if we don't get it,
-     * we go for port mapped, and that failing we tell the user
-     * it can't work.
-     */
-
-    if (base) {
-	instance->base = (unsigned long) base;
-	/* Check for forced I/O mapping */
-    	if (!(options & OPTION_IO_MAPPED)) {
-	    options |= OPTION_MEMORY_MAPPED;
-	    ok = 1;
-	}
-    } else {
-	options &= ~OPTION_MEMORY_MAPPED;
-    }
-
-    if (io_port) {
-	instance->io_port = io_port;
-	options |= OPTION_IO_MAPPED;
-	ok = 1;
-    } else {
-	options &= ~OPTION_IO_MAPPED;
-    }
-
-    if (!ok) {
-	printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
-	    instance->host_no);
-	scsi_unregister (instance);
-	return -1;
-    }
-    instance->irq = irq;
-    instance->dma_channel = dma;
-    scsi_set_pci_device(instance, pci_dev);
-
-    hostdata->options = options;
-    hostdata->dsa_len = dsa_len;
-    hostdata->max_cmd_size = max_cmd_size;
-    hostdata->num_cmds = 1;
-    /* Initialize single command */
-    tmp = (hostdata->script + hostdata->script_count);
-    hostdata->free = ROUNDUP(tmp, void *);
-    hostdata->free->real = tmp;
-    hostdata->free->size = max_cmd_size;
-    hostdata->free->free = NULL;
-    hostdata->free->next = NULL;
-    hostdata->extra_allocate = 0;
-
-    /* Allocate command start code space */
-    hostdata->schedule = (chip == 700 || chip == 70066) ?
-	NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);
-
-/* 
- * For diagnostic purposes, we don't really care how fast things blaze.
- * For profiling, we want to access the 800ns resolution system clock,
- * using a 'C' call on the host processor.
- *
- * Therefore, there's no need for the NCR chip to directly manipulate
- * this data, and we should put it wherever is most convenient for 
- * Linux.
- */
-    if (track_events) 
-	hostdata->events = (struct NCR53c7x0_event *) (track_events ? 
-	    vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);
-    else
-	hostdata->events = NULL;
-
-    if (hostdata->events) {
-	memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *
-	    track_events);	
-	hostdata->event_size = track_events;
-	hostdata->event_index = 0;
-    } else 
-	hostdata->event_size = 0;
-
-    return NCR53c7x0_init(instance);
-}
-
-
-/* 
- * Function : static int ncr_pci_init(Scsi_Host_Template *tpnt, int board, 
- *	int chip, int bus, int device_fn, long long options)
- *
- * Purpose : initializes a NCR53c800 family based on the PCI
- *	bus, device, and function location of it.  Allows 
- * 	reprogramming of latency timer and determining addresses
- *	and whether bus mastering, etc. are OK.
- *	
- *	Useful where a new NCR chip is backwards compatible with
- *	a supported chip, but the DEVICE ID has changed so it 
- *	doesn't show up when the autoprobe does a pci_find_device.
- *
- * Inputs : tpnt - Template for this SCSI adapter, board - board level
- *	product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
- *	device and function encoding as used by PCI BIOS calls.
- * 
- * Returns : 0 on success, -1 on failure.
- *
- */
-
-static int  __init 
-ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip, 
-    unsigned char bus, unsigned char device_fn, long long options){
-    unsigned short command;
-    unsigned int base, io_port; 
-    unsigned char revision;
-    int error, expected_chip;
-    int expected_id = -1, max_revision = -1, min_revision = -1;
-    int i, irq;
-    struct pci_dev *pdev = pci_find_slot(bus, device_fn);
-
-    printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
-	bus, (int) (device_fn & 0xf8) >> 3, 
-    	(int) device_fn & 7);
-
-    if (!pdev) {
-	printk("scsi-ncr53c7,8xx : not initializing -- PCI device not found,\n"
-	       "        try using memory, port, irq override instead.\n");
-	return -1;
-    }
-
-    if ((error = pci_read_config_word (pdev, PCI_COMMAND, &command)) ||
-	(error = pci_read_config_byte (pdev, PCI_CLASS_REVISION, &revision))) {
-	printk ("scsi-ncr53c7,8xx : error %d not initializing due to error reading configuration space\n"
-		"	 perhaps you specified an incorrect PCI bus, device, or function.\n", error);
-	return -1;
-    }
-    if (pci_enable_device(pdev))
-	return -1;
-    io_port = pci_resource_start(pdev, 0);
-    base = pci_resource_start(pdev, 1);
-    irq = pdev->irq;
-
-    /* If any one ever clones the NCR chips, this will have to change */
-
-    if (pdev->vendor != PCI_VENDOR_ID_NCR) {
-	printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",
-	    (int) pdev->vendor);
-	return -1;
-    }
-
-    if ( ! (command & PCI_COMMAND_MASTER)) {
-      printk(KERN_INFO "SCSI: PCI Master Bit has not been set. Setting...\n");
-      command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO;
-      pci_write_config_word(pdev, PCI_COMMAND, command);
-    }
-
-#ifdef __powerpc__
-    if (io_port >= 0x10000000 && is_prep ) {
-	      /* Mapping on PowerPC can't handle this! */
-	      unsigned long new_io_port;
-	      new_io_port = (io_port & 0x00FFFFFF) | 0x01000000;
-	      printk("SCSI: I/O moved from %08X to %08x\n", io_port, new_io_port);
-	      io_port = new_io_port;
-	      pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port);
-	      pdev->base_address[0] = io_port;
-    }
-#endif
-
-    /* 
-     * Bit 0 is the address space indicator and must be one for I/O
-     * space mappings, bit 1 is reserved, discard them after checking
-     * that they have the correct value of 1.
-     */
-
-    if (command & PCI_COMMAND_IO) { 
-	if (!(pdev->resource[0].flags & IORESOURCE_IO)) {
-	    printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base "
-		    "address 0\n        contains a non-IO mapping\n");
-	    io_port = 0;
-	}
-    } else {
-    	io_port = 0;
-    }
-
-    if (command & PCI_COMMAND_MEMORY) {
-	if (!(pdev->resource[1].flags & IORESOURCE_MEM)) {
-	    printk("scsi-ncr53c7,8xx : disabling memory mapping since base "
-		   "address 1\n        contains a non-memory mapping\n");
-	    base = 0;
-	}
-    } else {
-	base = 0;
-    }
-	
-    if (!io_port && !base) {
-	printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");
-	return -1;
-    }
-	
-    if (!(command & PCI_COMMAND_MASTER)) {
-	printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");
-	return -1;
-    }
-
-    for (i = 0; i < NPCI_CHIP_IDS; ++i) {
-	if (pdev->device == pci_chip_ids[i].pci_device_id) {
-	    max_revision = pci_chip_ids[i].max_revision;
-	    min_revision = pci_chip_ids[i].min_revision;
-	    expected_chip = pci_chip_ids[i].chip;
-	}
-	if (chip == pci_chip_ids[i].chip)
-	    expected_id = pci_chip_ids[i].pci_device_id;
-    }
-
-    if (chip && pdev->device != expected_id) 
-	printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"
-                "                   match expected 0x%04x\n",
-	    (unsigned int) pdev->device, (unsigned int) expected_id );
-    
-    if (max_revision != -1 && revision > max_revision) 
-	printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",
-	    (int) revision, max_revision);
-    else if (min_revision != -1 && revision < min_revision)
-	printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",
-	    (int) revision, min_revision);
-
-    if (io_port && check_region (io_port, 128)) {
-	printk ("scsi-ncr53c7,8xx : IO region 0x%x to 0x%x is in use\n",
-	    (unsigned) io_port, (unsigned) io_port + 127);
-	return -1;
-    }
-
-    return normal_init (tpnt, board, chip, (int) base, io_port, 
-	(int) irq, DMA_NONE, 1, pdev, options);
-}
-
-
-/* 
- * Function : int NCR53c7xx_detect(Scsi_Host_Template *tpnt)
- *
- * Purpose : detects and initializes NCR53c7,8x0 SCSI chips
- *	that were autoprobed, overridden on the LILO command line, 
- *	or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter
- * 
- * Returns : number of host adapters detected
- *
- */
-
-int __init 
-NCR53c7xx_detect(Scsi_Host_Template *tpnt){
-    int i;
-    int current_override;
-    int count;			/* Number of boards detected */
-    struct pci_dev *pdev = NULL;
-
-    tpnt->proc_name = "ncr53c7xx";
-
-    for (current_override = count = 0; current_override < OVERRIDE_LIMIT; 
-	 ++current_override) {
-	 if (overrides[current_override].pci ? 
-	    !ncr_pci_init (tpnt, overrides[current_override].board,
-		overrides[current_override].chip,
-		(unsigned char) overrides[current_override].data.pci.bus,
-		(((overrides[current_override].data.pci.device
-		<< 3) & 0xf8)|(overrides[current_override].data.pci.function & 
-		7)), overrides[current_override].options):
-	    !normal_init (tpnt, overrides[current_override].board, 
-		overrides[current_override].chip, 
-		overrides[current_override].data.normal.base, 
-		overrides[current_override].data.normal.io_port,
-		overrides[current_override].data.normal.irq,
-		overrides[current_override].data.normal.dma,
-		0 /* PCI data invalid */, 0 /* PCI bus place holder */,  
-		0 /* PCI device_function place holder */,
-                NULL /* PCI pci_dev place holder */,
-    	    	overrides[current_override].options)) {
-    	    ++count;
-	} 
-    }
-
-    if (pci_present()) {
-	for (i = 0; i < NPCI_CHIP_IDS; ++i) 
-	    while ((pdev = pci_find_device (PCI_VENDOR_ID_NCR,
-					    pci_chip_ids[i].pci_device_id,
-					    pdev)))
-		if (!ncr_pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip, 
-		    pdev->bus->number, pdev->devfn, /* no options */ 0))
-		    ++count;
-    }
-    return count;
-}
-
-/* NCR53c810 and NCR53c820 script handling code */
-
-#include "53c8xx_d.h"
-#ifdef A_int_debug_sync
-#define DEBUG_SYNC_INTR A_int_debug_sync
-#endif
-static int NCR53c8xx_script_len = sizeof (SCRIPT);
-static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
-
-/* 
- * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
- *
- * Purpose :  copy and fixup the SCSI SCRIPTS(tm) code for this device.
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- */
-
-static void 
-NCR53c8x0_init_fixup (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned char tmp;
-    int i, ncr_to_memory, memory_to_ncr;
-    u32 base;
-#ifdef __powerpc__
-    unsigned long *script_ptr;
-#endif    
-    NCR53c7x0_local_setup(host);
-
-
-    /* XXX - NOTE : this code MUST be made endian aware */
-    /*  Copy code into buffer that was allocated at detection time.  */
-    memcpy ((void *) hostdata->script, (void *) SCRIPT, 
-	sizeof(SCRIPT));
-    /* Fixup labels */
-    for (i = 0; i < PATCHES; ++i) 
-	hostdata->script[LABELPATCHES[i]] += 
-    	    virt_to_bus(hostdata->script);
-    /* Fixup addresses of constants that used to be EXTERNAL */
-
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort, 
-    	virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject, 
-    	virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero, 
-    	virt_to_bus(&(hostdata->NCR53c7xx_zero)));
-    patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink, 
-    	virt_to_bus(&(hostdata->NCR53c7xx_sink)));
-    patch_abs_32 (hostdata->script, 0, NOP_insn,
-	virt_to_bus(&(hostdata->NOP_insn)));
-    patch_abs_32 (hostdata->script, 0, schedule,
-	virt_to_bus((void *) hostdata->schedule));
-
-    /* Fixup references to external variables: */
-    for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)
-       hostdata->script[EXTERNAL_PATCHES[i].offset] +=
-         virt_to_bus(EXTERNAL_PATCHES[i].address);
-
-    /* 
-     * Fixup absolutes set at boot-time.
-     * 
-     * All non-code absolute variables suffixed with "dsa_" and "int_"
-     * are constants, and need no fixup provided the assembler has done 
-     * it for us (I don't know what the "real" NCR assembler does in 
-     * this case, my assembler does the right magic).
-     */
-
-    patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer, 
-    	Ent_dsa_code_save_data_pointer - Ent_dsa_zero);
-    patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,
-    	Ent_dsa_code_restore_pointers - Ent_dsa_zero);
-    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
-    	Ent_dsa_code_check_reselect - Ent_dsa_zero);
-
-    /*
-     * Just for the hell of it, preserve the settings of 
-     * Burst Length and Enable Read Line bits from the DMODE 
-     * register.  Make sure SCRIPTS start automagically.
-     */
-
-    tmp = NCR53c7x0_read8(DMODE_REG_10);
-    tmp &= (DMODE_800_ERL | DMODE_BL_MASK);
-
-    if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
-    	base = (u32) host->io_port;
-    	memory_to_ncr = tmp|DMODE_800_DIOM;
-    	ncr_to_memory = tmp|DMODE_800_SIOM;
-    } else {
-    	base = virt_to_bus((void *)host->base);
-	memory_to_ncr = ncr_to_memory = tmp;
-    }
-
-    patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
-    patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
-
-    /*
-     * I needed some variables in the script to be accessible to 
-     * both the NCR chip and the host processor. For these variables,
-     * I made the arbitrary decision to store them directly in the 
-     * hostdata structure rather than in the RELATIVE area of the 
-     * SCRIPTS.
-     */
-    
-
-    patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
-    patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
-    patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
-
-    patch_abs_32 (hostdata->script, 0, msg_buf, 
-	virt_to_bus((void *)&(hostdata->msg_buf)));
-    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, 
-    	virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));
-    patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head, 
-	virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));
-    patch_abs_32 (hostdata->script, 0, reselected_identify, 
-    	virt_to_bus((void *)&(hostdata->reselected_identify)));
-/* reselected_tag is currently unused */
-#if 0
-    patch_abs_32 (hostdata->script, 0, reselected_tag, 
-    	virt_to_bus((void *)&(hostdata->reselected_tag)));
-#endif
-
-    patch_abs_32 (hostdata->script, 0, test_dest, 
-	virt_to_bus((void*)&hostdata->test_dest));
-    patch_abs_32 (hostdata->script, 0, test_src, 
-	virt_to_bus(&hostdata->test_source));
-
-    patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, 
-	(unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
-
-/* These are for event logging; the ncr_event enum contains the 
-   actual interrupt numbers. */
-#ifdef A_int_EVENT_SELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);
-#endif
-#ifdef A_int_EVENT_DISCONNECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);
-#endif
-#ifdef A_int_EVENT_RESELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);
-#endif
-#ifdef A_int_EVENT_COMPLETE
-   patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);
-#endif
-#ifdef A_int_EVENT_IDLE
-   patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);
-#endif
-#ifdef A_int_EVENT_SELECT_FAILED
-   patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED, 
-	(u32) EVENT_SELECT_FAILED);
-#endif
-#ifdef A_int_EVENT_BEFORE_SELECT
-   patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,
-	(u32) EVENT_BEFORE_SELECT);
-#endif
-#ifdef A_int_EVENT_RESELECT_FAILED
-   patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED, 
-	(u32) EVENT_RESELECT_FAILED);
-#endif
-
-    /*
-     * Make sure the NCR and Linux code agree on the location of 
-     * certain fields.
-     */
-
-    hostdata->E_accept_message = Ent_accept_message;
-    hostdata->E_command_complete = Ent_command_complete;		
-    hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;
-    hostdata->E_data_transfer = Ent_data_transfer;
-    hostdata->E_debug_break = Ent_debug_break;	
-    hostdata->E_dsa_code_template = Ent_dsa_code_template;
-    hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
-    hostdata->E_end_data_transfer = Ent_end_data_transfer;
-    hostdata->E_initiator_abort = Ent_initiator_abort;
-    hostdata->E_msg_in = Ent_msg_in;
-    hostdata->E_other_transfer = Ent_other_transfer;
-    hostdata->E_other_in = Ent_other_in;
-    hostdata->E_other_out = Ent_other_out;
-    hostdata->E_reject_message = Ent_reject_message;
-    hostdata->E_respond_message = Ent_respond_message;
-    hostdata->E_select = Ent_select;
-    hostdata->E_select_msgout = Ent_select_msgout;
-    hostdata->E_target_abort = Ent_target_abort;
-#ifdef Ent_test_0
-    hostdata->E_test_0 = Ent_test_0;
-#endif
-    hostdata->E_test_1 = Ent_test_1;
-    hostdata->E_test_2 = Ent_test_2;
-#ifdef Ent_test_3
-    hostdata->E_test_3 = Ent_test_3;
-#endif
-    hostdata->E_wait_reselect = Ent_wait_reselect;
-    hostdata->E_dsa_code_begin = Ent_dsa_code_begin;
-
-    hostdata->dsa_cmdout = A_dsa_cmdout;
-    hostdata->dsa_cmnd = A_dsa_cmnd;
-    hostdata->dsa_datain = A_dsa_datain;
-    hostdata->dsa_dataout = A_dsa_dataout;
-    hostdata->dsa_end = A_dsa_end;			
-    hostdata->dsa_msgin = A_dsa_msgin;
-    hostdata->dsa_msgout = A_dsa_msgout;
-    hostdata->dsa_msgout_other = A_dsa_msgout_other;
-    hostdata->dsa_next = A_dsa_next;
-    hostdata->dsa_select = A_dsa_select;
-    hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
-    hostdata->dsa_status = A_dsa_status;
-    hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero + 
-	8 /* destination operand */;
-
-    /* sanity check */
-    if (A_dsa_fields_start != Ent_dsa_code_template_end - 
-    	Ent_dsa_zero) 
-    	printk("scsi%d : NCR dsa_fields start is %d not %d\n",
-    	    host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end - 
-    	    Ent_dsa_zero);
-#ifdef __powerpc__
-/* The PowerPC is Big Endian - adjust script appropriately */
-    script_ptr = hostdata->script;
-    for (i = 0;  i < sizeof(SCRIPT);  i += sizeof(long))
-    {
-        *script_ptr++ = le32_to_cpu(*script_ptr);
-    }
-#endif    	    
-
-    printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
-	virt_to_bus(hostdata->script), hostdata->script);
-}
-
-/*
- * Function : static int NCR53c8xx_run_tests (struct Scsi_Host *host)
- *
- * Purpose : run various verification tests on the NCR chip, 
- *	including interrupt generation, and proper bus mastering
- * 	operation.
- * 
- * Inputs : host - a properly initialized Scsi_Host structure
- *
- * Preconditions : the NCR chip must be in a halted state.
- *
- * Returns : 0 if all tests were successful, -1 on error.
- * 
- */
-
-static int 
-NCR53c8xx_run_tests (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned long timeout;
-    u32 start;
-    int failed, i;
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    /* The NCR chip _must_ be idle to run the test scripts */
-
-    save_flags(flags);
-    cli();
-    if (!hostdata->idle) {
-	printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-	restore_flags(flags);
-	return -1;
-    }
-
-    /* 
-     * Check for functional interrupts, this could work as an
-     * autoprobe routine.
-     */
-
-    if ((hostdata->options & OPTION_DEBUG_TEST1) && 
-	    hostdata->state != STATE_DISABLED) {
-	hostdata->idle = 0;
-	hostdata->test_running = 1;
-	hostdata->test_completed = -1;
-	hostdata->test_dest = 0;
-	hostdata->test_source = 0xdeadbeef;
-	start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
-    	hostdata->state = STATE_RUNNING;
-	printk ("scsi%d : test 1", host->host_no);
-	NCR53c7x0_write32 (DSP_REG, start);
-	printk (" started\n");
-	restore_flags(flags);
-
-	/* 
-	 * This is currently a .5 second timeout, since (in theory) no slow 
-	 * board will take that long.  In practice, we've seen one 
-	 * pentium which occasionally fails with this, but works with 
-	 * 10 times as much?
-	 */
-
-	timeout = jiffies + 5 * HZ / 10;
-	while ((hostdata->test_completed == -1) && time_before(jiffies, timeout)) {
-		barrier();
-		cpu_relax();
-	}
-
-	failed = 1;
-	if (hostdata->test_completed == -1)
-	    printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
-		(hostdata->test_dest == 0xdeadbeef) ? 
-		    " due to lost interrupt.\n"
-		    "         Please verify that the correct IRQ is being used for your board,\n"
-		    "	      and that the motherboard IRQ jumpering matches the PCI setup on\n"
-		    "         PCI systems.\n"
-		    "         If you are using a NCR53c810 board in a PCI system, you should\n" 
-		    "         also verify that the board is jumpered to use PCI INTA, since\n"
-		    "         most PCI motherboards lack support for INTB, INTC, and INTD.\n"
-		    : "");
-      else if (hostdata->test_completed != 1) 
-	    printk ("scsi%d : test 1 bad interrupt value (%d)\n", 
-		host->host_no, hostdata->test_completed);
-	else 
-	    failed = (hostdata->test_dest != 0xdeadbeef);
-
-	if (hostdata->test_dest != 0xdeadbeef) {
-	    printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
-                    "         probable cache invalidation problem.  Please configure caching\n"
-		    "         as write-through or disabled\n",
-		host->host_no, hostdata->test_dest);
-	}
-
-	if (failed) {
-	    printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
-		host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),
-		hostdata->script, start);
-	    printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
-		NCR53c7x0_read32(DSPS_REG));
-	    return -1;
-	}
-    	hostdata->test_running = 0;
-    }
-
-    if ((hostdata->options & OPTION_DEBUG_TEST2) && 
-	hostdata->state != STATE_DISABLED) {
-	u32 dsa[48];
-    	unsigned char identify = IDENTIFY(0, 0);
-	unsigned char cmd[6];
-	unsigned char data[36];
-    	unsigned char status = 0xff;
-    	unsigned char msg = 0xff;
-
-    	cmd[0] = INQUIRY;
-    	cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
-    	cmd[4] = sizeof(data); 
-
-/* Need to adjust for endian-ness */    	
-    	dsa[2] = le32_to_cpu(1);
-    	dsa[3] = le32_to_cpu(virt_to_bus(&identify));
-    	dsa[4] = le32_to_cpu(6);
-    	dsa[5] = le32_to_cpu(virt_to_bus(&cmd));
-    	dsa[6] = le32_to_cpu(sizeof(data));
-    	dsa[7] = le32_to_cpu(virt_to_bus(&data));
-    	dsa[8] = le32_to_cpu(1);
-    	dsa[9] = le32_to_cpu(virt_to_bus(&status));
-    	dsa[10] = le32_to_cpu(1);
-    	dsa[11] = le32_to_cpu(virt_to_bus(&msg));
-
-	for (i = 0; i < 3; ++i) {
-	    cli();
-	    if (!hostdata->idle) {
-		printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-		restore_flags(flags);
-		return -1;
-	    }
-
-	    /*	     SCNTL3         SDID	*/
-	    dsa[0] = le32_to_cpu((0x33 << 24) | (i << 16))  ;
-	    hostdata->idle = 0;
-	    hostdata->test_running = 2;
-	    hostdata->test_completed = -1;
-	    start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
-	    hostdata->state = STATE_RUNNING;
-	    NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
-	    NCR53c7x0_write32 (DSP_REG, start);
-	    restore_flags(flags);
-
-	    timeout = jiffies + 5 * HZ;	/* arbitrary */
-	    while ((hostdata->test_completed == -1) && time_before(jiffies, timeout)) {
-	    	barrier();
-		cpu_relax();
-	    }
-	    NCR53c7x0_write32 (DSA_REG, 0);
-
-	    if (hostdata->test_completed == 2) {
-		data[35] = 0;
-		printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
-		    host->host_no, i, data + 8);
-		printk ("scsi%d : status ", host->host_no);
-		print_status (status);
-		printk ("\nscsi%d : message ", host->host_no);
-		print_msg (&msg);
-		printk ("\n");
-	    } else if (hostdata->test_completed == 3) {
-		printk("scsi%d : test 2 no connection with target %d\n",
-		    host->host_no, i);
-		if (!hostdata->idle) {
-		    printk("scsi%d : not idle\n", host->host_no);
-		    restore_flags(flags);
-		    return -1;
-		}
-	    } else if (hostdata->test_completed == -1) {
-		printk ("scsi%d : test 2 timed out\n", host->host_no);
-		restore_flags(flags);
-		return -1;
-	    } 
-	    hostdata->test_running = 0;
-	}
-    }
-
-    restore_flags(flags);
-    return 0;
-}
-
-/*
- * Function : static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer,
- * 	performing all necessary relocation.
- *
- * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large
- *	enough to hold the NCR53c8xx dsa.
- */
-
-static void 
-NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
-    Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-    	host->hostdata;
-    int i;
-#ifdef __powerpc__
-    int len;
-    unsigned long *dsa_ptr;
-#endif    
-
-    memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
-    	hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
-#ifdef __powerpc__
-    /* Note: the script has already been 'endianized' */
-    dsa_ptr = cmd->dsa;
-    len = hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template;
-    for (i = 0;  i < len;  i += sizeof(long))
-    {
-       *dsa_ptr++ = le32_to_cpu(*dsa_ptr);
-    }
-#endif    	
-
-    /* 
-     * Note : within the NCR 'C' code, dsa points to the _start_
-     * of the DSA structure, and _not_ the offset of dsa_zero within
-     * that structure used to facilitate shorter signed offsets
-     * for the 8 bit ALU.
-     * 
-     * The implications of this are that 
-     * 
-     * - 32 bit A_dsa_* absolute values require an additional 
-     * 	 dsa_zero added to their value to be correct, since they are 
-     *   relative to dsa_zero which is in essentially a separate
-     *   space from the code symbols.
-     *
-     * - All other symbols require no special treatment.
-     */
-
-    patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_lun, c->lun);
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-	dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
-	Ent_dsa_code_template + A_dsa_next);
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), 
-    	dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->target].script));
-    patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_target, c->target);
-    /* XXX - new pointer stuff */
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual));
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_addr_residual, virt_to_bus(&cmd->residual));
-
-    /*  XXX - new start stuff */
-    patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-	dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
-#ifdef __powerpc__
-    dsa_ptr = cmd->dsa;    
-    len = hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template;
-    for (i = 0;  i < len;  i += sizeof(long))
-    {
-       *dsa_ptr++ = le32_to_cpu(*dsa_ptr);
-    }
-#endif    	
-
-}
-
-/* 
- * Function : run_process_issue_queue (void)
- * 
- * Purpose : insure that the coroutine is running and will process our 
- * 	request.  process_issue_queue_running is checked/set here (in an 
- *	inline function) rather than in process_issue_queue itself to reduce 
- * 	the chances of stack overflow.
- *
- */
-
-static volatile int process_issue_queue_running = 0;
-
-static __inline__ void 
-run_process_issue_queue(void) {
-    unsigned long flags;
-    save_flags (flags);
-    cli();
-    if (!process_issue_queue_running) {
-	process_issue_queue_running = 1;
-        process_issue_queue(flags);
-	/* 
-         * process_issue_queue_running is cleared in process_issue_queue 
-	 * once it can't do more work, and process_issue_queue exits with 
-	 * interrupts disabled.
-	 */
-    }
-    restore_flags (flags);
-}
-
-/*
- * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int
- *	result)
- *
- * Purpose : mark SCSI command as finished, OR'ing the host portion 
- *	of the result word into the result field of the corresponding
- *	Scsi_Cmnd structure, and removing it from the internal queues.
- *
- * Inputs : cmd - command, result - entire result field
- *
- * Preconditions : the 	NCR chip should be in a halted state when 
- *	abnormal_finished is run, since it modifies structures which
- *	the NCR expects to have exclusive access to.
- */
-
-static void 
-abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
-    Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-    	host->hostdata;
-    unsigned long flags;
-    int left, found;
-    volatile struct NCR53c7x0_cmd * linux_search;
-    volatile struct NCR53c7x0_cmd * volatile *linux_prev;
-    volatile u32 *ncr_prev, *curr, ncr_search;
-
-#if 0
-    printk ("scsi%d: abnormal finished\n", host->host_no);
-#endif
-
-    save_flags(flags);
-    cli();
-    found = 0;
-    /* 
-     * Traverse the NCR issue array until we find a match or run out 
-     * of instructions.  Instructions in the NCR issue array are 
-     * either JUMP or NOP instructions, which are 2 words in length.
-     */
-
-
-    for (found = 0, left = host->can_queue, curr = hostdata->schedule; 
-	left > 0; --left, curr += 2)
-    {
-	if (issue_to_cmd (host, hostdata, (u32 *) curr) == cmd) 
-	{
-	    curr[0] = hostdata->NOP_insn;
-	    curr[1] = le32_to_cpu(0xdeadbeef);
-	    ++found;
-	    break;
-	}
-    }
-	
-    /* 
-     * Traverse the NCR reconnect list of DSA structures until we find 
-     * a pointer to this dsa or have found too many command structures.  
-     * We let prev point at the next field of the previous element or 
-     * head of the list, so we don't do anything different for removing 
-     * the head element.  
-     */
-
-    for (left = host->can_queue,
-	    ncr_search = le32_to_cpu(hostdata->reconnect_dsa_head), 
-	    ncr_prev = &hostdata->reconnect_dsa_head;
-	left >= 0 && ncr_search && 
-	    ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start) 
-		!= (char *) cmd->dsa;
-	ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) + 
-	    hostdata->dsa_next), ncr_search = le32_to_cpu(*ncr_prev), --left);
-
-    if (left < 0) {
-	printk("scsi%d: loop detected in ncr reconnect list\n",
-	    host->host_no);
-    } else if (ncr_search) {
-	if (found)
-	    printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
-		host->host_no, c->pid);
-	else {
-	    volatile u32 * next = (u32 *) 
-	    	((char *)bus_to_virt(ncr_search) + hostdata->dsa_next);
-	    *ncr_prev = *next;
-/* If we're at the tail end of the issue queue, update that pointer too. */
-	    found = 1;
-	}
-    }
-
-    /*
-     * Traverse the host running list until we find this command or discover
-     * we have too many elements, pointing linux_prev at the next field of the 
-     * linux_previous element or head of the list, search at this element.
-     */
-
-    for (left = host->can_queue, linux_search = hostdata->running_list, 
-	    linux_prev = &hostdata->running_list;
-	left >= 0 && linux_search && linux_search != cmd;
-	linux_prev = &(linux_search->next), 
-	    linux_search = linux_search->next, --left);
-    
-    if (left < 0) 
-	printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
-	    host->host_no, c->pid);
-    else if (linux_search) {
-	*linux_prev = linux_search->next;
-	--hostdata->busy[c->target][c->lun];
-    }
-
-    /* Return the NCR command structure to the free list */
-    cmd->next = hostdata->free;
-    hostdata->free = cmd;
-    c->host_scribble = NULL;
-
-    /* And return */
-    c->result = result;
-    c->scsi_done(c);
-
-    restore_flags(flags);
-    run_process_issue_queue();
-}
-
-/* 
- * Function : static void intr_break (struct Scsi_Host *host,
- * 	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose :  Handler for breakpoint interrupts from a SCSI script
- *
- * Inputs : host - pointer to this host adapter's structure,
- * 	cmd - pointer to the command (if any) dsa was pointing 
- * 	to.
- *
- */
-
-static void 
-intr_break (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_break *bp;
-#if 0
-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
-#endif
-    u32 *dsp;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;		
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    /*
-     * Find the break point corresponding to this address, and 
-     * dump the appropriate debugging information to standard 
-     * output.  
-     */
-    save_flags(flags);
-    cli();
-    dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
-    for (bp = hostdata->breakpoints; bp && bp->address != dsp; 
-    	bp = bp->next);
-    if (!bp) 
-    	panic("scsi%d : break point interrupt from %p with no breakpoint!",
-    	    host->host_no, dsp);
-
-    /*
-     * Configure the NCR chip for manual start mode, so that we can 
-     * point the DSP register at the instruction that follows the 
-     * INT int_debug_break instruction.
-     */
-
-    NCR53c7x0_write8 (hostdata->dmode, 
-	NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
-
-    /*
-     * And update the DSP register, using the size of the old 
-     * instruction in bytes.
-     */
-
-    restore_flags(flags);
-}
-/*
- * Function : static void print_synchronous (const char *prefix, 
- *	const unsigned char *msg)
- * 
- * Purpose : print a pretty, user and machine parsable representation
- *	of a SDTR message, including the "real" parameters, data
- *	clock so we can tell transfer rate at a glance.
- *
- * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes)
- */
-
-static void
-print_synchronous (const char *prefix, const unsigned char *msg) {
-    if (msg[4]) {
-	int Hz = 1000000000 / (msg[3] * 4);
-	int integer = Hz / 1000000;
-	int fraction = (Hz - (integer * 1000000)) / 10000;
-	printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
-	    prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction,
-	    (((msg[3] * 4) < 200) ? "FAST" : "synchronous"),
-	    (((msg[3] * 4) < 200) ? "-II" : ""));
-    } else 
-	printk ("%sasynchronous SCSI\n", prefix);
-}
-
-/*
- * Function : static void set_synchronous (struct Scsi_Host *host, 
- *	 	int target, int sxfer, int scntl3, int now_connected)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and 
- *	target with the given register values; in the indirect
- *	select operand, reselection script, and chip registers.
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- *	sxfer and scntl3 - NCR registers. now_connected - if non-zero, 
- *	we should reprogram the registers now too.
- */
-
-static void
-set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3,
-    int now_connected) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) 
-	host->hostdata;
-    u32 *script;
-    NCR53c7x0_local_setup(host);
-
-    /* These are eight bit registers */
-    sxfer &= 0xff;
-    scntl3 &= 0xff;
-
-    hostdata->sync[target].sxfer_sanity = sxfer;
-    hostdata->sync[target].scntl3_sanity = scntl3;
-
-/* 
- * HARD CODED : synchronous script is EIGHT words long.  This 
- * must agree with 53c7.8xx.h
- */
-
-    if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
-	hostdata->sync[target].select_indirect = (scntl3 << 24) | 
-	    (target << 16) | (sxfer << 8);
-
-	script = (u32 *) hostdata->sync[target].script;
-
-	/* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
-	if ((hostdata->chip / 100) == 8) {
-	    script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
-		DCMD_RWRI_OP_MOVE) << 24) |
-		(SCNTL3_REG_800 << 16) | (scntl3 << 8);
-	    script[1] = 0;
-	    script += 2;
-	}
-
-	script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
-	    DCMD_RWRI_OP_MOVE) << 24) |
-		(SXFER_REG << 16) | (sxfer << 8);
-	script[1] = 0;
-	script += 2;
-
-#ifdef DEBUG_SYNC_INTR
-	if (hostdata->options & OPTION_DEBUG_DISCONNECT) {
-	    script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE;
-	    script[1] = DEBUG_SYNC_INTR;
-	    script += 2;
-	}
-#endif
-
-	script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
-	script[1] = 0;
-	script += 2;
-    }
-
-    if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) 
-	printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
-	host->host_no, target, sxfer, scntl3);
-
-    if (now_connected) {
-	if ((hostdata->chip / 100) == 8) 
-	    NCR53c7x0_write8(SCNTL3_REG_800, scntl3);
-	NCR53c7x0_write8(SXFER_REG, sxfer);
-    }
-}
-
-
-/*
- * Function : static int asynchronous (struct Scsi_Host *host, int target)
- *
- * Purpose : reprogram between the selected SCSI Host adapter and target 
- *      (assumed to be currently connected) for asynchronous transfers.
- *
- * Inputs : host - SCSI host structure, target - numeric target ID.
- *
- * Preconditions : the NCR chip should be in one of the halted states
- */
-    
-static void
-asynchronous (struct Scsi_Host *host, int target) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    NCR53c7x0_local_setup(host);
-    set_synchronous (host, target, /* no offset */ 0, hostdata->saved_scntl3,
-	1);
-    printk ("scsi%d : setting target %d to asynchronous SCSI\n",
-	host->host_no, target);
-}
-
-/* 
- * XXX - do we want to go out of our way (ie, add extra code to selection
- * 	in the NCR53c710/NCR53c720 script) to reprogram the synchronous
- * 	conversion bits, or can we be content in just setting the 
- * 	sxfer bits?
- */
-
-/* Table for NCR53c8xx synchronous values */
-static const struct {
-    int div;		/* Total clock divisor * 10 */
-    unsigned char scf;	/* */
-    unsigned char tp;	/* 4 + tp = xferp divisor */
-} syncs[] = {
-/*	div	scf	tp	div	scf	tp	div	scf	tp */
-    {	40,	1,	0}, {	50,	1,	1}, {	60,	1,	2}, 
-    {	70,	1,	3}, {	75,	2,	1}, {	80,	1,	4},
-    {	90,	1,	5}, {	100,	1,	6}, {	105,	2,	3},
-    {	110,	1,	7}, {	120,	2,	4}, {	135,	2,	5},
-    {	140,	3,	3}, {	150,	2,	6}, {	160,	3,	4},
-    {	165,	2,	7}, {	180,	3,	5}, {	200,	3,	6},
-    {	210,	4,	3}, {	220,	3,	7}, {	240,	4,	4},
-    {	270,	4,	5}, {	300,	4,	6}, {	330,	4,	7}
-};
-
-/*
- * Function : static void synchronous (struct Scsi_Host *host, int target, 
- *	char *msg)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and 
- *	target for synchronous SCSI transfers such that the synchronous 
- *	offset is less than that requested and period at least as long 
- *	as that requested.  Also modify *msg such that it contains 
- *	an appropriate response. 
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- *	msg - synchronous transfer request.
- */
-
-
-static void 
-synchronous (struct Scsi_Host *host, int target, char *msg) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    int desire, divisor, i, limit;
-    unsigned char scntl3, sxfer;
-/* The diagnostic message fits on one line, even with max. width integers */
-    char buf[80];	
-   
-/* Desired transfer clock in Hz */
-    desire = 1000000000L / (msg[3] * 4);
-/* Scale the available SCSI clock by 10 so we get tenths */
-    divisor = (hostdata->scsi_clock * 10) / desire;
-
-/* NCR chips can handle at most an offset of 8 */
-    if (msg[4] > 8)
-	msg[4] = 8;
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-    	printk("scsi%d : optimal synchronous divisor of %d.%01d\n", 
-	    host->host_no, divisor / 10, divisor % 10);
-
-    limit = (sizeof(syncs) / sizeof(syncs[0]) -1);
-    for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-    	printk("scsi%d : selected synchronous divisor of %d.%01d\n", 
-	    host->host_no, syncs[i].div / 10, syncs[i].div % 10);
-
-    msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
-
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-    	printk("scsi%d : selected synchronous period of %dns\n", host->host_no,
-	    msg[3] * 4);
-
-    scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 & 
-	~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
-    sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
-    if (hostdata->options & OPTION_DEBUG_SDTR)
-    	printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n", 
-	    host->host_no, (int) sxfer, (int) scntl3);
-    set_synchronous (host, target, sxfer, scntl3, 1);
-    sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target);
-    print_synchronous (buf, msg);
-}
-
-/* 
- * Function : static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host,
- * 	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose :  Handler for INT generated instructions for the 
- * 	NCR53c810/820 SCSI SCRIPT
- *
- * Inputs : host - pointer to this host adapter's structure,
- * 	cmd - pointer to the command (if any) dsa was pointing 
- * 	to.
- *
- */
-
-static int 
-NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct 
-    NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    int print;
-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;		
-    u32 dsps,*dsp;	/* Argument of the INT instruction */
-    NCR53c7x0_local_setup(host);
-    dsps = NCR53c7x0_read32(DSPS_REG);
-    dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
-    if (hostdata->options & OPTION_DEBUG_INTR)
-	printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
-
-    switch (dsps) {
-    case A_int_msg_1:
-	print = 1;
-	switch (hostdata->msg_buf[0]) {
-	/* 
-	 * Unless we've initiated synchronous negotiation, I don't
-	 * think that this should happen.
-	 */
-	case MESSAGE_REJECT:
-	    hostdata->dsp = hostdata->script + hostdata->E_accept_message /
-		sizeof(u32);
-	    hostdata->dsp_changed = 1;
-	    if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
-		printk ("scsi%d : target %d rejected SDTR\n", host->host_no, 
-		    c->target);
-		cmd->flags &= ~CMD_FLAG_SDTR;
-		asynchronous (host, c->target);
-		print = 0;
-	    } 
-	    break;
-	case INITIATE_RECOVERY:
-	    printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
-		host->host_no);
-	    /* Fall through to default */
-	    hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-		sizeof(u32);
-	    hostdata->dsp_changed = 1;
-	    break;
-	default:
-	    printk ("scsi%d : unsupported message, rejecting\n",
-		host->host_no);
-	    hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-		sizeof(u32);
-	    hostdata->dsp_changed = 1;
-	}
-	if (print) {
-	    printk ("scsi%d : received message", host->host_no);
-	    if (c) 
-	    	printk (" from target %d lun %d ", c->target, c->lun);
-	    print_msg ((unsigned char *) hostdata->msg_buf);
-	    printk("\n");
-	}
-	
-	return SPECIFIC_INT_NOTHING;
-
-
-    case A_int_msg_sdtr:
-/*
- * At this point, hostdata->msg_buf contains
- * 0 EXTENDED MESSAGE
- * 1 length 
- * 2 SDTR
- * 3 period * 4ns
- * 4 offset
- */
-
-	if (cmd) {
-	    char buf[80];
-	    sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->target,
-		(cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
-	    print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
-
-	/* 
-	 * Initiator initiated, won't happen unless synchronous 
-	 * 	transfers are enabled.  If we get a SDTR message in
-	 * 	response to our SDTR, we should program our parameters
-	 * 	such that 
-	 *		offset <= requested offset
-	 *		period >= requested period		 	
-   	 */
-	    if (cmd->flags & CMD_FLAG_SDTR) {
-		cmd->flags &= ~CMD_FLAG_SDTR; 
-		if (hostdata->msg_buf[4]) 
-		    synchronous (host, c->target, (unsigned char *) 
-		    	hostdata->msg_buf);
-		else 
-		    asynchronous (host, c->target);
-		hostdata->dsp = hostdata->script + hostdata->E_accept_message /
-		    sizeof(u32);
-		hostdata->dsp_changed = 1;
-		return SPECIFIC_INT_NOTHING;
-	    } else {
-		if (hostdata->options & OPTION_SYNCHRONOUS)  {
-		    cmd->flags |= CMD_FLAG_DID_SDTR;
-		    synchronous (host, c->target, (unsigned char *) 
-			hostdata->msg_buf);
-		} else {
-		    hostdata->msg_buf[4] = 0;		/* 0 offset = async */
-		    asynchronous (host, c->target);
-		}
-		patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, le32_to_cpu(5));
-		patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32) 
-		    le32_to_cpu(virt_to_bus ((void *)&hostdata->msg_buf)));
-		hostdata->dsp = hostdata->script + 
-		    hostdata->E_respond_message / sizeof(u32);
-		hostdata->dsp_changed = 1;
-	    }
-	    return SPECIFIC_INT_NOTHING;
-	}
-	/* Fall through to abort if we couldn't find a cmd, and 
-	   therefore a dsa structure to twiddle */
-    case A_int_msg_wdtr:
-	hostdata->dsp = hostdata->script + hostdata->E_reject_message /
-	    sizeof(u32);
-	hostdata->dsp_changed = 1;
-	return SPECIFIC_INT_NOTHING;
-    case A_int_err_unexpected_phase:
-	if (hostdata->options & OPTION_DEBUG_INTR) 
-	    printk ("scsi%d : unexpected phase\n", host->host_no);
-	return SPECIFIC_INT_ABORT;
-    case A_int_err_selected:
-	printk ("scsi%d : selected by target %d\n", host->host_no,
-	    (int) NCR53c7x0_read8(SDID_REG_800) &7);
-	hostdata->dsp = hostdata->script + hostdata->E_target_abort / 
-    	    sizeof(u32);
-	hostdata->dsp_changed = 1;
-	return SPECIFIC_INT_NOTHING;
-    case A_int_err_unexpected_reselect:
-	printk ("scsi%d : unexpected reselect by target %d lun %d\n", 
-	    host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7,
-	    hostdata->reselected_identify & 7);
-	hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-    	    sizeof(u32);
-	hostdata->dsp_changed = 1;
-	return SPECIFIC_INT_NOTHING;
-/*
- * Since contingent allegiance conditions are cleared by the next 
- * command issued to a target, we must issue a REQUEST SENSE 
- * command after receiving a CHECK CONDITION status, before
- * another command is issued.
- * 
- * Since this NCR53c7x0_cmd will be freed after use, we don't 
- * care if we step on the various fields, so modify a few things.
- */
-    case A_int_err_check_condition: 
-#if 0
-	if (hostdata->options & OPTION_DEBUG_INTR) 
-#endif
-	    printk ("scsi%d : CHECK CONDITION\n", host->host_no);
-	if (!c) {
-	    printk("scsi%d : CHECK CONDITION with no SCSI command\n",
-		host->host_no);
-	    return SPECIFIC_INT_PANIC;
-	}
-
-	/* 
-	 * FIXME : this uses the normal one-byte selection message.
-	 * 	We may want to renegotiate for synchronous & WIDE transfers
-	 * 	since these could be the crux of our problem.
-	 *
-	 hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll
-	 * 	have to set this up so that the rest of the DSA
-	 *	agrees with this being an untagged queue'd command.
-	 */
-
-    	patch_dsa_32 (cmd->dsa, dsa_msgout, 0, le32_to_cpu(1));
-
-    	/* 
-    	 * Modify the table indirect for COMMAND OUT phase, since 
-    	 * Request Sense is a six byte command.
-    	 */
-
-    	patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, le32_to_cpu(6));
-
-	c->cmnd[0] = REQUEST_SENSE;
-	c->cmnd[1] &= 0xe0;	/* Zero all but LUN */
-	c->cmnd[2] = 0;
-	c->cmnd[3] = 0;
-	c->cmnd[4] = sizeof(c->sense_buffer);
-	c->cmnd[5] = 0; 
-
-	/*
-	 * Disable dataout phase, and program datain to transfer to the 
-	 * sense buffer, and add a jump to other_transfer after the 
-    	 * command so overflow/underrun conditions are detected.
-	 */
-
-    	patch_dsa_32 (cmd->dsa, dsa_dataout, 0, 
-	    le32_to_cpu(virt_to_bus(hostdata->script) + hostdata->E_other_transfer));
-    	patch_dsa_32 (cmd->dsa, dsa_datain, 0, 
-	    le32_to_cpu(virt_to_bus(cmd->data_transfer_start)));
-    	cmd->data_transfer_start[0] = le32_to_cpu((((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | 
-    	    DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer));
-    	cmd->data_transfer_start[1] = (u32) le32_to_cpu(virt_to_bus(c->sense_buffer));
-
-	cmd->data_transfer_start[2] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) 
-    	    << 24) | DBC_TCI_TRUE);
-	cmd->data_transfer_start[3] = (u32) le32_to_cpu(virt_to_bus(hostdata->script) + 
-	    hostdata->E_other_transfer);
-
-    	/*
-    	 * Currently, this command is flagged as completed, ie 
-    	 * it has valid status and message data.  Reflag it as
-    	 * incomplete.  Q - need to do something so that original
-	 * status, etc are used.
-    	 */
-
-	cmd->cmd->result = le32_to_cpu(0xffff);		
-
-	/* 
-	 * Restart command as a REQUEST SENSE.
-	 */
-	hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select /
-	    sizeof(u32);
-	hostdata->dsp_changed = 1;
-	return SPECIFIC_INT_NOTHING;
-    case A_int_debug_break:
-	return SPECIFIC_INT_BREAK;
-    case A_int_norm_aborted:
-	hostdata->dsp = (u32 *) hostdata->schedule;
-	hostdata->dsp_changed = 1;
-	if (cmd)
-	    abnormal_finished (cmd, DID_ERROR << 16);
-	return SPECIFIC_INT_NOTHING;
-    case A_int_test_1:
-    case A_int_test_2:
-	hostdata->idle = 1;
-	hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
-	if (hostdata->options & OPTION_DEBUG_INTR)
-	    printk("scsi%d : test%d complete\n", host->host_no,
-		hostdata->test_completed);
-	return SPECIFIC_INT_NOTHING;
-#ifdef A_int_debug_reselected_ok
-    case A_int_debug_reselected_ok:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-    	    	OPTION_DEBUG_DISCONNECT)) {
-	    /* 
-	     * Note - this dsa is not based on location relative to 
-	     * the command structure, but to location relative to the 
-	     * DSA register 
-	     */	
-	    u32 *dsa;
-	    dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
-	    printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n", 
-		host->host_no, NCR53c7x0_read32(DSA_REG), dsa);
-	    printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
-		    host->host_no, cmd->saved_data_pointer,
-		    bus_to_virt(le32_to_cpu(cmd->saved_data_pointer)));
-	    print_insn (host, hostdata->script + Ent_reselected_ok / 
-    	    	    sizeof(u32), "", 1);
-    	    printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
-		host->host_no, NCR53c7x0_read8(SXFER_REG),
-		NCR53c7x0_read8(SCNTL3_REG_800));
-	    if (c) {
-		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script, "", 1);
-		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script + 2, "", 1);
-	    }
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_reselect_check
-    case A_int_debug_reselect_check:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    u32 *dsa;
-#if 0
-	    u32 *code;
-#endif
-	    /* 
-	     * Note - this dsa is not based on location relative to 
-	     * the command structure, but to location relative to the 
-	     * DSA register 
-	     */	
-	    dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
-	    printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
-		host->host_no, virt_to_bus(dsa), dsa);
-	    if (dsa) {
-		printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
-		    host->host_no, cmd->saved_data_pointer,
-		    bus_to_virt (le32_to_cpu(cmd->saved_data_pointer)));
-#if 0
-		printk("scsi%d : template code :\n", host->host_no);
-		for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero) 
-		    / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32)); 
-		    code += print_insn (host, code, "", 1));
-#endif
-	    }
-	    print_insn (host, hostdata->script + Ent_reselected_ok / 
-    	    	    sizeof(u32), "", 1);
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_schedule
-    case A_int_debug_dsa_schedule:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    u32 *dsa;
-	    /* 
-	     * Note - this dsa is not based on location relative to 
-	     * the command structure, but to location relative to the 
-	     * DSA register 
-	     */	
-	    dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
-	    printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n", 
-		host->host_no, virt_to_bus(dsa), dsa);
-	    if (dsa) 
-		printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
-		       "         (temp was 0x%x (virt 0x%p))\n",
-		    host->host_no, cmd->saved_data_pointer,
-		    bus_to_virt (le32_to_cpu(cmd->saved_data_pointer)),
-		    NCR53c7x0_read32 (TEMP_REG),
-		    bus_to_virt (NCR53c7x0_read32(TEMP_REG)));
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_scheduled
-    case A_int_debug_scheduled:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n", 
-		host->host_no, NCR53c7x0_read32(DSA_REG),
-	    	bus_to_virt(NCR53c7x0_read32(DSA_REG)));
-	}
-	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_idle
-    case A_int_debug_idle:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    printk("scsi%d : idle\n", host->host_no);
-	}
-	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_cmd
-    case A_int_debug_cmd:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    printk("scsi%d : command sent\n");
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_loaded
-    case A_int_debug_dsa_loaded:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no,
-		NCR53c7x0_read32(DSA_REG), 
-		bus_to_virt(NCR53c7x0_read32(DSA_REG)));
-	}
-	return SPECIFIC_INT_RESTART; 
-#endif
-#ifdef A_int_debug_reselected
-    case A_int_debug_reselected:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-	    OPTION_DEBUG_DISCONNECT)) {
-	    printk("scsi%d : reselected by target %d lun %d\n",
-		host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80, 
-		(int) hostdata->reselected_identify & 7);
-	    print_queues(host);
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnect_msg
-    case A_int_debug_disconnect_msg:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
-	    if (c)
-		printk("scsi%d : target %d lun %d disconnecting\n", 
-		    host->host_no, c->target, c->lun);
-	    else
-		printk("scsi%d : unknown target disconnecting\n",
-		    host->host_no);
-	}
-	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnected
-    case A_int_debug_disconnected:
-	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-		OPTION_DEBUG_DISCONNECT)) {
-	    printk ("scsi%d : disconnected, new queues are\n", 
-		host->host_no);
-	    print_queues(host);
-#if 0
-    	    printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
-		host->host_no, NCR53c7x0_read8(SXFER_REG),
-		NCR53c7x0_read8(SCNTL3_REG_800));
-#endif
-	    if (c) {
-		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script, "", 1);
-		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script + 2, "", 1);
-	    }
-	}
-	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_panic
-    case A_int_debug_panic:
-	printk("scsi%d : int_debug_panic received\n", host->host_no);
-	print_lots (host);
-	return SPECIFIC_INT_PANIC;
-#endif
-#ifdef A_int_debug_saved
-    case A_int_debug_saved:
-    	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-    	    OPTION_DEBUG_DISCONNECT)) {
-    	    printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
-    	    	host->host_no, cmd->saved_data_pointer,
-		bus_to_virt (le32_to_cpu(cmd->saved_data_pointer)));
-    	    print_progress (c);
-    	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_restored
-    case A_int_debug_restored:
-    	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-    	    OPTION_DEBUG_DISCONNECT)) {
-    	    if (cmd) {
-		int size;
-    	    	printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
-    	    	    host->host_no, cmd->saved_data_pointer, bus_to_virt (
-		    le32_to_cpu(cmd->saved_data_pointer)));
-		size = print_insn (host, (u32 *) 
-		    bus_to_virt(le32_to_cpu(cmd->saved_data_pointer)), "", 1);
-		size = print_insn (host, (u32 *) 
-		    bus_to_virt(le32_to_cpu(cmd->saved_data_pointer)) + size, "", 1);
-    	    	print_progress (c);
-	    }
-#if 0
-	    printk ("scsi%d : datapath residual %d\n",
-		host->host_no, datapath_residual (host)) ;
-#endif
-    	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_sync
-    case A_int_debug_sync:
-    	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-    	    OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
-	    unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG),
-		scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
-	    if (c) {
-		if (sxfer != hostdata->sync[c->target].sxfer_sanity ||
-		    scntl3 != hostdata->sync[c->target].scntl3_sanity) {
-		   	printk ("scsi%d :  sync sanity check failed sxfer=0x%x, scntl3=0x%x",
-			    host->host_no, sxfer, scntl3);
-			NCR53c7x0_write8 (SXFER_REG, sxfer);
-			NCR53c7x0_write8 (SCNTL3_REG_800, scntl3);
-		    }
-	    } else 
-    	    	printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
-		    host->host_no, (int) sxfer, (int) scntl3);
-	}
-    	return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_datain
-	case A_int_debug_datain:
-	    if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
-		OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
-		int size;
-		printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
-			"         datapath residual=%d\n",
-		    host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
-		    (int) NCR53c7x0_read8(SXFER_REG), 
-		    (int) NCR53c7x0_read8(SCNTL3_REG_800),
-		    datapath_residual (host)) ;
-		print_insn (host, dsp, "", 1);
-		size = print_insn (host, (u32 *) bus_to_virt(le32_to_cpu(dsp[1])), "", 1);
-		print_insn (host, (u32 *) bus_to_virt(le32_to_cpu(dsp[1])) + size, "", 1);
-	   } 
-	return SPECIFIC_INT_RESTART;
-#endif
-/* 
- * FIXME : for 7xx support, we need to read SDID_REG_700 and handle 
- *	the comparison as bitfielded,  not binary.
- */
-#ifdef A_int_debug_check_dsa
-	case A_int_debug_check_dsa:
-	    if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
-		int sdid = NCR53c7x0_read8 (SDID_REG_800) & 15;
-		char *where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8 
-			(DCMD_REG)) == hostdata->script + 
-		    	Ent_select_check_dsa / sizeof(u32) ?
-		    "selection" : "reselection";
-		if (c && sdid != c->target) {
-		    printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
-			host->host_no, sdid, c->target, where);
-		    print_lots(host);
-		    dump_events (host, 20);
-		    return SPECIFIC_INT_PANIC;
-		}
-	    }
-	    return SPECIFIC_INT_RESTART;
-#endif
-    default:
-	if ((dsps & 0xff000000) == 0x03000000) {
-	     printk ("scsi%d : misc debug interrupt 0x%x\n",
-		host->host_no, dsps);
-	    return SPECIFIC_INT_RESTART;
-	} else if ((dsps & 0xff000000) == 0x05000000) {
-	    if (hostdata->events) {
-		struct NCR53c7x0_event *event;
-		++hostdata->event_index;
-		if (hostdata->event_index >= hostdata->event_size)
-		    hostdata->event_index = 0;
-		event = (struct NCR53c7x0_event *) hostdata->events + 
-		    hostdata->event_index;
-		event->event = (enum ncr_event) dsps;
-		event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-	    /* FIXME : this needs to change for the '7xx family */
-		if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) 
-			event->target = NCR53c7x0_read8(SSID_REG_800);
-		else 
-			event->target = 255;
-
-		if (event->event == EVENT_RESELECT)
-		    event->lun = hostdata->reselected_identify & 0xf;
-		else if (c)
-		    event->lun = c->lun;
-		else
-		    event->lun = 255;
-		do_gettimeofday(&(event->time));
-		if (c) {
-		    event->pid = c->pid;
-		    memcpy ((void *) event->cmnd, (void *) c->cmnd, 
-			sizeof (event->cmnd));
-		} else {
-		    event->pid = -1;
-		}
-	    }
-	    return SPECIFIC_INT_RESTART;
-	}
-
-	printk ("scsi%d : unknown user interrupt 0x%x\n", 
-	    host->host_no, (unsigned) dsps);
-	return SPECIFIC_INT_PANIC;
-    }
-}
-
-/* 
- * XXX - the stock NCR assembler won't output the scriptu.h file,
- * which undefine's all #define'd CPP symbols from the script.h
- * file, which will create problems if you use multiple scripts
- * with the same  symbol names.
- *
- * If you insist on using NCR's assembler, you could generate
- * scriptu.h from script.h using something like 
- *
- * grep #define script.h | \
- * sed 's/#define[ 	][ 	]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \
- * > scriptu.h
- */
-
-#include "53c8xx_u.h"
-
-/* XXX - add alternate script handling code here */
-
-
-#ifdef NCR_DEBUG
-/*
- * Debugging without a debugger is no fun. So, I've provided 
- * a debugging interface in the NCR53c7x0 driver.  To avoid
- * kernel cruft, there's just enough here to act as an interface
- * to a user level debugger (aka, GDB).
- *
- *
- * The following restrictions apply to debugger commands : 
- * 1.  The command must be terminated by a newline.
- * 2.  Command length must be less than 80 bytes including the 
- * 	newline.
- * 3.  The entire command must be written with one system call.
- */
-
-static const char debugger_help = 
-"bc <addr> 			- clear breakpoint\n"
-"bl				- list breakpoints\n"
-"bs <addr>			- set breakpoint\n"
-"g				- start\n" 				
-"h				- halt\n"
-"?				- this message\n"
-"i				- info\n"
-"mp <addr> <size> 		- print memory\n"
-"ms <addr> <size> <value>	- store memory\n"
-"rp <num> <size>		- print register\n"
-"rs <num> <size> <value> 	- store register\n"
-"s                              - single step\n"	
-"tb				- begin trace \n"
-"te				- end trace\n";
-
-/*
- * Whenever we change a break point, we should probably 
- * set the NCR up so that it is in a single step mode.
- */
-
-static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
-    u32 args[]) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	instance->hostdata;
-    struct NCR53c7x0_break *bp, **prev;
-    unsigned long flags;
-    save_flags(flags);
-    cli();
-    for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
-	    prev = (struct NCR53c7x0_break **) &instance->breakpoints;
-	    bp; prev = (struct NCR53c7x0_break **) &(bp->next),
-	    bp = (struct NCR53c7x0_break *) bp->next);
-
-    if (!bp) {
-	restore_flags(flags);
-	return -EIO;
-    }
-
-    /* 
-     * XXX - we need to insure that the processor is halted 
-     * here in order to prevent a race condition.
-     */
-    
-    memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
-    if (prev)
-	*prev = bp->next;
-
-    restore_flags(flags);
-    return 0;
-}
-
-
-static int 
-debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
-    u32 args[]) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    struct NCR53c7x0_break *bp;
-    char buf[80];
-    size_t len;
-    unsigned long flags;
-    /* 
-     * XXX - we need to insure that the processor is halted 
-     * here in order to prevent a race condition.  So, if the 
-     * processor isn't halted, print an error message and continue.
-     */
-
-    sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
-	host->host_no);
-    debugger_kernel_write (host, buf, strlen(buf));
-
-    save_flags(flags);
-    cli();
-    for (bp = (struct NCR53c7x0_break *) host->breakpoints;
-	    bp; bp = (struct NCR53c7x0_break *) bp->next) {
-	    sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
-		bp->addr, bp->old[0], bp->old[1]);
-	    len = strlen(buf);
-	    if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
-		(DCMD_TYPE_MMI << 24)) {
-		sprintf(buf + len, "%08x\n", * (u32 *) bp->addr);
-	    } else {
-		sprintf(buf + len, "\n");
-	    }
-	    len = strlen(buf);
-	    debugger_kernel_write (host, buf, len);
-    }
-    restore_flags(flags);
-    return 0;
-}
-
-static int 
-debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
-    u32 args[]) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    struct NCR53c7x0_break *bp;
-    char buf[80];
-    size_t len;
-    unsigned long flags;
-    save_flags(flags);
-    cli();
-
-    if (hostdata->state != STATE_HALTED) {
-	sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
-	debugger_kernel_write (host, buf, strlen(buf));
-	restore_flags(flags);
-	return -1;
-    }
-
-    if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
-	printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
-	    host->host_no, sizeof(struct NCR53c7x0_break));
-	restore_flags(flags);
-	return -1;
-    }
-
-    bp->address = (u32 *) args[0];
-    memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
-    bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
-	DCMD_TYPE_MMI ? 3 : 2;
-    bp->next = hostdata->breakpoints;
-    hostdata->breakpoints = bp->next;
-    memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
-    
-    restore_flags(flags);
-    return 0;
-}
-
-#define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
-static const struct debugger_token {
-    char *name;
-    int numargs;
-    int (*fn)(struct debugger_token *token, u32 args[]);
-} debugger_tokens[] = {
-    TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
-    {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2), 
-    TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
-};
-
-#define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
-
-static struct Scsi_Host * inode_to_host (struct inode *inode) {
-    int dev;
-    struct Scsi_Host *tmp;
-    for (dev = MINOR(inode->rdev), host = first_host;
-	(host->hostt == the_template); --dev, host = host->next)
-	if (!dev) return host;
-    return NULL;
-}
-
-
-static int
-debugger_user_write (struct inode *inode,struct file *filp,
-    char *buf,int count) {
-    struct Scsi_Host *host;			/* This SCSI host */
-    struct NCR53c7x0_hostadata *hostdata;	
-    char input_buf[80], 			/* Kernel space copy of buf */
-	*ptr;					/* Pointer to argument list */
-    u32 args[3];				/* Arguments */
-    int i, j, error, len;
-
-    if (!(host = inode_to_host(inode)))
-	return -ENXIO;
-
-    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
-
-    if (error = verify_area(VERIFY_READ,buf,count))
-	return error;
-
-    if (count > 80) 
-	return -EIO;
-
-    memcpy_from_fs(input_buf, buf, count);
-
-    if (input_buf[count - 1] != '\n')
-	return -EIO;
-
-    input_buf[count - 1]=0;
-
-    for (i = 0; i < NDT; ++i) {
-	len = strlen (debugger_tokens[i].name);
-	if (!strncmp(input_buf, debugger_tokens[i].name, len)) 
-	    break;
-    };
-
-    if (i == NDT) 
-	return -EIO;
-
-    for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
-	if (*ptr == ' ' || *ptr == '\t') {
-	    ++ptr; 
-	} else if (isdigit(*ptr)) {
-	    args[j++] = simple_strtoul (ptr, &ptr, 0);
-	} else {
-	    return -EIO;
-	} 
-    }
-
-    if (j != debugger_tokens[i].nargs)
-	return -EIO;
-
-    return count;
-} 
-
-static int 
-debugger_user_read (struct inode *inode,struct file *filp,
-    char *buf,int count) {
-    struct Scsi_Host *instance;
-    
-}
-
-static int 
-debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
-    buflen) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    int copy, left;
-    unsigned long flags;
-    save_flags(flags);
-    cli();
-    while (buflen) {
-	left = (hostdata->debug_buf + hostdata->debug_size - 1) -
-	    hostdata->debug_write;
-	copy = (buflen <= left) ? buflen : left;
-	memcpy (hostdata->debug_write, buf, copy);
-	buf += copy;
-	buflen -= copy;
-	hostdata->debug_count += copy;
-	if ((hostdata->debug_write += copy) == 
-	    (hostdata->debug_buf + hostdata->debug_size))
-	    hosdata->debug_write = hostdata->debug_buf;
-    }
-    restore_flags(flags);
-}
-
-#endif /* def NCRDEBUG */
-
-/* 
- * Function : static void NCR538xx_soft_reset (struct Scsi_Host *host)
- *
- * Purpose :  perform a soft reset of the NCR53c8xx chip
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : NCR53c7x0_init must have been called for this 
- *      host.
- * 
- */
-
-static void 
-NCR53c8x0_soft_reset (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    NCR53c7x0_local_setup(host);
-
-
-    /*
-     * Do a soft reset of the chip so that everything is 
-     * reinitialized to the power-on state.
-     *
-     * Basically follow the procedure outlined in the NCR53c700
-     * data manual under Chapter Six, How to Use, Steps Necessary to
-     * Start SCRIPTS, with the exception of actually starting the 
-     * script and setting up the synchronous transfer gunk.
-     */
-
-    NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
-    NCR53c7x0_write8(ISTAT_REG_800, 0);
-    NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
-
-
-    /* 
-     * Respond to reselection by targets and use our _initiator_ SCSI ID  
-     * for arbitration. If notyet, also respond to SCSI selection.
-     *
-     * XXX - Note : we must reprogram this when reselecting as 
-     *	a target.
-     */
-
-#ifdef notyet
-    NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
-#else
-    NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
-#endif
-    NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
-
-    /*
-     * Use a maximum (1.6) second handshake to handshake timeout,
-     * and SCSI recommended .5s selection timeout.
-     */
-
-    /*
-     * The new gcc won't recognize preprocessing directives
-     * within macro args.
-     */
-#if 0
-    NCR53c7x0_write8(STIME0_REG_800, 
-    	((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK) 
-	| ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK));
-#else
-/* Disable HTH interrupt */
-    NCR53c7x0_write8(STIME0_REG_800, 
-    	((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK));
-#endif
-
-
-    /*
-     * Enable active negation for happy synchronous transfers.
-     */
-
-    NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
-
-    /*
-     * Enable all interrupts, except parity which we only want when
-     * the user requests it.
-     */
-
-    NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
-		DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
-
-    
-    NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
-	    SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
-    NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
-
-    /* 
-     * Use saved clock frequency divisor and scripts loaded in 16 bit
-     * mode flags from the saved dcntl.
-     */
-
-    NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
-    NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
-
-    /* Enable active negation */
-    NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
-}
-
-/*
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
- * 
- * Purpose : Return the first free NCR53c7x0_cmd structure (which are 
- * 	reused in a LIFO manner to minimize cache thrashing).
- *
- * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd
- *	structures for this device, do so.  Attempt to complete all scheduled
- *	allocations using kmalloc(), putting NCR53c7x0_cmd structures on 
- *	the free list.  Teach programmers not to drink and hack.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd;
- *	NULL on failure.
- */
-
-static struct NCR53c7x0_cmd *
-allocate_cmd (Scsi_Cmnd *cmd) {
-    struct Scsi_Host *host = cmd->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) host->hostdata;
-    void *real;			/* Real address */
-    int size;			/* Size of *tmp */
-    struct NCR53c7x0_cmd *tmp;
-    unsigned long flags;
-
-    if (hostdata->options & OPTION_DEBUG_ALLOCATION)
-	printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
-		"         target = %d, lun = %d, %s\n",
-	    host->host_no, hostdata->num_cmds, host->can_queue,
-	    cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] &
-		(1 << cmd->lun)) ? "already allocated" : "not allocated");
-
-/*
- * If we have not yet reserved commands for this I_T_L nexus, and
- * the device exists (as indicated by permanent Scsi_Cmnd structures
- * being allocated under 1.3.x, or being outside of scan_scsis in 
- * 1.2.x), do so now.
- */
-    if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) &&
-				cmd->device && cmd->device->has_cmdblocks
-	) {
-	if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue) 
-	    hostdata->extra_allocate += host->cmd_per_lun;
-	hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun);
-    }
-
-    for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, 
-    	++hostdata->num_cmds) {
-    /* historically, kmalloc has returned unaligned addresses; pad so we 
-       have enough room to ROUNDUP */
-	size = hostdata->max_cmd_size + sizeof (void *);
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
-	real = kmalloc (size, GFP_ATOMIC);
-	if (!real) {
-	    if (hostdata->options & OPTION_DEBUG_ALLOCATION)
-		printk ("scsi%d : kmalloc(%d) failed\n",
-		    host->host_no, size);
-	    break;
-	}
-	tmp = ROUNDUP(real, void *);
-	tmp->real = real;
-	tmp->size = size;			
-	tmp->free = ((void (*)(void *, int)) kfree);
-	save_flags (flags);
-	cli();
-	tmp->next = hostdata->free;
-	hostdata->free = tmp;
-	restore_flags (flags);
-    }
-    save_flags(flags);
-    cli();
-    tmp = (struct NCR53c7x0_cmd *) hostdata->free;
-    if (tmp) {
-	hostdata->free = tmp->next;
-    }
-    restore_flags(flags);
-    if (!tmp)
-	printk ("scsi%d : can't allocate command for target %d lun %d\n",
-	    host->host_no, cmd->target, cmd->lun);
-    return tmp;
-}
-
-/*
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
- *
- *
- * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the 
- * 	Scsi_Cmnd structure passed in cmd, including dsa and Linux field 
- * 	initialization, and dsa code relocation.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure corresponding to cmd,
- *	NULL on failure.
- */
-
-static struct NCR53c7x0_cmd *
-create_cmd (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->host;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-        host->hostdata;	
-    struct NCR53c7x0_cmd *tmp; 	/* NCR53c7x0_cmd structure for this command */
-    int datain,  		/* Number of instructions per phase */
-	dataout;
-    int data_transfer_instructions, /* Count of dynamic instructions */
-    	i;			/* Counter */
-    u32 *cmd_datain,		/* Address of datain/dataout code */
-	*cmd_dataout;		/* Incremented as we assemble */
-#ifdef notyet
-    unsigned char *msgptr;	/* Current byte in select message */
-    int msglen;			/* Length of whole select message */
-#endif
-    unsigned long flags;
-    NCR53c7x0_local_setup(cmd->host);
-
-    if (!(tmp = allocate_cmd (cmd)))
-	return NULL;
-
-
-    /*
-     * Decide whether we need to generate commands for DATA IN,
-     * DATA OUT, neither, or both based on the SCSI command 
-     */
-
-    switch (cmd->cmnd[0]) {
-    /* These commands do DATA IN */
-    case INQUIRY:
-    case MODE_SENSE:
-    case READ_6:
-    case READ_10:
-    case READ_CAPACITY:
-    case REQUEST_SENSE:
-	datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-    	dataout = 0;
-	break;
-    /* These commands do DATA OUT */
-    case MODE_SELECT: 
-    case WRITE_6:
-    case WRITE_10:
-#if 0
-	printk("scsi%d : command is ", host->host_no);
-	print_command(cmd->cmnd);
-#endif
-#if 0
-	printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
-	    cmd->use_sg);
-#endif
-    	datain = 0;
-	dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-#if 0
-	hostdata->options |= OPTION_DEBUG_INTR;
-#endif
-	break;
-    /* 
-     * These commands do no data transfer, we should force an
-     * interrupt if a data phase is attempted on them.
-     */
-    case START_STOP: /* also SCAN, which may do DATA OUT */
-    case TEST_UNIT_READY:
-    	datain = dataout = 0;
-	break;
-    /*
-     * We don't know about these commands, so generate code to handle
-     * both DATA IN and DATA OUT phases.
-     */
-    default:
-	datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-    }
-
-    /*
-     * New code : so that active pointers work correctly regardless
-     * 	of where the saved data pointer is at, we want to immediately
-     * 	enter the dynamic code after selection, and on a non-data
-     * 	phase perform a CALL to the non-data phase handler, with
-     * 	returns back to this address.
-     *
-     * 	If a phase mismatch is encountered in the middle of a 
-     * 	Block MOVE instruction, we want to _leave_ that instruction
-     *	unchanged as the current case is, modify a temporary buffer,
-     *	and point the active pointer (TEMP) at that.
-     *
-     * 	Furthermore, we want to implement a saved data pointer, 
-     * 	set by the SAVE_DATA_POINTERs message.
-     *
-     * 	So, the data transfer segments will change to 
-     *		CALL data_transfer, WHEN NOT data phase
-     *		MOVE x, x, WHEN data phase
-     *		( repeat )
-     *		JUMP other_transfer
-     */
-
-    data_transfer_instructions = datain + dataout;
-
-    /*
-     * When we perform a request sense, we overwrite various things,
-     * including the data transfer code.  Make sure we have enough
-     * space to do that.
-     */
-
-    if (data_transfer_instructions < 2)
-    	data_transfer_instructions = 2;
-
-
-    /*
-     * The saved data pointer is set up so that a RESTORE POINTERS message 
-     * will start the data transfer over at the beginning.
-     */
-
-    tmp->saved_data_pointer = le32_to_cpu(virt_to_bus (hostdata->script) + 
-	hostdata->E_data_transfer);
-
-    /*
-     * Initialize Linux specific fields.
-     */
-
-    tmp->cmd = cmd;
-    tmp->next = NULL;
-    tmp->flags = 0;
-    tmp->dsa_next_addr = le32_to_cpu(virt_to_bus(tmp->dsa) + hostdata->dsa_next - 
-	hostdata->dsa_start);
-    tmp->dsa_addr = le32_to_cpu(virt_to_bus(tmp->dsa) - hostdata->dsa_start);
-
-    /* 
-     * Calculate addresses of dynamic code to fill in DSA
-     */
-
-    tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end - 
-    	hostdata->dsa_start) / sizeof(u32);
-    tmp->data_transfer_end = tmp->data_transfer_start + 
-    	2 * data_transfer_instructions;
-
-    cmd_datain = datain ? tmp->data_transfer_start : NULL;
-    cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
-    	data_transfer_start) : NULL;
-
-    /*
-     * Fill in the NCR53c7x0_cmd structure as follows
-     * dsa, with fixed up DSA code
-     * datain code
-     * dataout code
-     */
-
-    /* Copy template code into dsa and perform all necessary fixups */
-    if (hostdata->dsa_fixup)
-    	hostdata->dsa_fixup(tmp);
-
-    patch_dsa_32(tmp->dsa, dsa_next, 0, le32_to_cpu(0));
-    patch_dsa_32(tmp->dsa, dsa_cmnd, 0, le32_to_cpu(virt_to_bus(cmd)));
-
-    if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) 
-	if (hostdata->sync[cmd->target].select_indirect != 
-	    ((hostdata->sync[cmd->target].scntl3_sanity << 24) | 
-		(cmd->target << 16) | 
-		(hostdata->sync[cmd->target].sxfer_sanity << 8))) {
-	    printk ("scsi%d :  sanity check failed select_indirect=0x%x\n",
-		host->host_no, hostdata->sync[cmd->target].select_indirect);
-	    FATAL(host);
-
-	}
-
-    patch_dsa_32(tmp->dsa, dsa_select, 0, le32_to_cpu(hostdata->sync[cmd->target].
-    	select_indirect));
-    /*
-     * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
-     * different commands; although it should be trivial to do them
-     * both at the same time.
-     */
-    if (hostdata->initiate_wdtr & (1 << cmd->target)) {
-	memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
-	    sizeof(wdtr_message));
-    	patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(wdtr_message)));
-	save_flags(flags);
-	cli();
-	hostdata->initiate_wdtr &= ~(1 << cmd->target);
-	restore_flags(flags);
-    } else if (hostdata->initiate_sdtr & (1 << cmd->target)) {
-	memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, 
-	    sizeof(sdtr_message));
-    	patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(sdtr_message)));
-	tmp->flags |= CMD_FLAG_SDTR;
-	save_flags(flags);
-	cli();
-	hostdata->initiate_sdtr &= ~(1 << cmd->target);
-	restore_flags(flags);
-    
-    }
-#if 1
-    else if (!(hostdata->talked_to & (1 << cmd->target)) && 
-		!(hostdata->options & OPTION_NO_ASYNC)) {
-	memcpy ((void *) (tmp->select + 1), (void *) async_message, 
-	    sizeof(async_message));
-    	patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(async_message)));
-	tmp->flags |= CMD_FLAG_SDTR;
-    } 
-#endif
-    else 
-    	patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1));
-    hostdata->talked_to |= (1 << cmd->target);
-    tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ? 
-	IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
-    patch_dsa_32(tmp->dsa, dsa_msgout, 1, le32_to_cpu(virt_to_bus(tmp->select)));
-    patch_dsa_32(tmp->dsa, dsa_cmdout, 0, le32_to_cpu(cmd->cmd_len));
-    patch_dsa_32(tmp->dsa, dsa_cmdout, 1, le32_to_cpu(virt_to_bus(cmd->cmnd)));
-    patch_dsa_32(tmp->dsa, dsa_dataout, 0, le32_to_cpu(cmd_dataout ? 
-    	    virt_to_bus (cmd_dataout)
-	: virt_to_bus (hostdata->script) + hostdata->E_other_transfer));
-    patch_dsa_32(tmp->dsa, dsa_datain, 0, le32_to_cpu(cmd_datain ? 
-    	    virt_to_bus (cmd_datain) 
-	: virt_to_bus (hostdata->script) + hostdata->E_other_transfer));
-    /* 
-     * XXX - need to make endian aware, should use separate variables
-     * for both status and message bytes.
-     */
-    patch_dsa_32(tmp->dsa, dsa_msgin, 0, le32_to_cpu(1));
-/* 
- * FIXME : these only works for little endian.  We probably want to 
- * 	provide message and status fields in the NCR53c7x0_cmd 
- *	structure, and assign them to cmd->result when we're done.
- */
-    patch_dsa_32(tmp->dsa, dsa_msgin, 1, le32_to_cpu(virt_to_bus(&cmd->result) + 1));
-    patch_dsa_32(tmp->dsa, dsa_status, 0, le32_to_cpu(1));
-    patch_dsa_32(tmp->dsa, dsa_status, 1, le32_to_cpu(virt_to_bus(&cmd->result)));
-    patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, le32_to_cpu(1));
-    patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, 
-	le32_to_cpu(virt_to_bus(&(hostdata->NCR53c7xx_msg_nop))));
-    
-    /*
-     * Generate code for zero or more of the DATA IN, DATA OUT phases 
-     * in the format 
-     *
-     * CALL data_transfer, WHEN NOT phase
-     * MOVE first buffer length, first buffer address, WHEN phase
-     * ...
-     * MOVE last buffer length, last buffer address, WHEN phase
-     * JUMP other_transfer
-     */
-
-/* 
- * See if we're getting to data transfer by generating an unconditional 
- * interrupt.
- */
-#if 0
-    if (datain) {
-	cmd_datain[0] = 0x98080000;
-	cmd_datain[1] = 0x03ffd00d;
-	cmd_datain += 2;
-    }
-#endif
-
-/* 
- * XXX - I'm undecided whether all of this nonsense is faster
- * in the long run, or whether I should just go and implement a loop
- * on the NCR chip using table indirect mode?
- *
- * In any case, this is how it _must_ be done for 53c700/700-66 chips,
- * so this stays even when we come up with something better.
- *
- * When we're limited to 1 simultaneous command, no overlapping processing,
- * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
- * drive.
- *
- * Not bad, not good. We'll see.
- */
-
-    for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
-	cmd_dataout += 4, ++i) {
-	u32 buf = cmd->use_sg ? 
-	    virt_to_bus(((struct scatterlist *)cmd->buffer)[i].address) :
-	    virt_to_bus(cmd->request_buffer);
-	u32 count = cmd->use_sg ?
-	    ((struct scatterlist *)cmd->buffer)[i].length :
-	    cmd->request_bufflen;
-
-	if (datain) {
-	    /* CALL other_in, WHEN NOT DATA_IN */  
-	    cmd_datain[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
-		DCMD_TCI_IO) << 24) | 
-		DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE);
-	    cmd_datain[1] = le32_to_cpu(virt_to_bus (hostdata->script) + 
-		hostdata->E_other_in);
-	    /* MOVE count, buf, WHEN DATA_IN */
-	    cmd_datain[2] = le32_to_cpu(((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO) 
-    	    	<< 24) | count);
-	    cmd_datain[3] = le32_to_cpu(buf);
-#if 0
-	    print_insn (host, cmd_datain, "dynamic ", 1);
-	    print_insn (host, cmd_datain + 2, "dynamic ", 1);
-#endif
-	}
-	if (dataout) {
-	    /* CALL other_out, WHEN NOT DATA_OUT */
-	    cmd_dataout[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) | 
-		DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE);
-	    cmd_dataout[1] = le32_to_cpu(virt_to_bus(hostdata->script) + 
-    	    	hostdata->E_other_out);
-	    /* MOVE count, buf, WHEN DATA+OUT */
-	    cmd_dataout[2] = le32_to_cpu(((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24) 
-		| count);
-	    cmd_dataout[3] = le32_to_cpu(buf);
-#if 0
-	    print_insn (host, cmd_dataout, "dynamic ", 1);
-	    print_insn (host, cmd_dataout + 2, "dynamic ", 1);
-#endif
-	}
-    }
-
-    /*
-     * Install JUMP instructions after the data transfer routines to return
-     * control to the do_other_transfer routines.
-     */
-  
-    
-    if (datain) {
-	cmd_datain[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
-    	    DBC_TCI_TRUE);
-	cmd_datain[1] = le32_to_cpu(virt_to_bus(hostdata->script) + 
-    	    hostdata->E_other_transfer);
-#if 0
-	print_insn (host, cmd_datain, "dynamic jump ", 1);
-#endif
-	cmd_datain += 2; 
-    }
-#if 0
-    if (datain) {
-	cmd_datain[0] = 0x98080000;
-	cmd_datain[1] = 0x03ffdeed;
-	cmd_datain += 2;
-    }
-#endif
-    if (dataout) {
-	cmd_dataout[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
-    	    DBC_TCI_TRUE);
-	cmd_dataout[1] = le32_to_cpu(virt_to_bus(hostdata->script) + 
-    	    hostdata->E_other_transfer);
-#if 0
-	print_insn (host, cmd_dataout, "dynamic jump ", 1);
-#endif
-	cmd_dataout += 2;
-    }
-    return tmp;
-}
-
-/*
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
- *      void (*done)(Scsi_Cmnd *))
- *
- * Purpose :  enqueues a SCSI command
- *
- * Inputs : cmd - SCSI command, done - function called on completion, with
- *      a pointer to the command descriptor.
- *
- * Returns : 0
- *
- * Side effects :
- *      cmd is added to the per instance driver issue_queue, with major
- *      twiddling done to the host specific fields of cmd.  If the
- *      process_issue_queue coroutine isn't running, it is restarted.
- * 
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to 
- *	hold our own data, and pervert the ptr field of the SCp field
- *	to create a linked list.
- */
-
-int
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
-    struct Scsi_Host *host = cmd->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) host->hostdata;
-    unsigned long flags;
-    Scsi_Cmnd *tmp;
-
-    cmd->scsi_done = done;
-    cmd->host_scribble = NULL;
-    cmd->SCp.ptr = NULL;
-    cmd->SCp.buffer = NULL;
-
-    save_flags(flags);
-    cli();
-    if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) 
-	|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
-	    !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun))) 
-	|| cmd->target > host->max_id
-	|| cmd->target == host->this_id
-	|| hostdata->state == STATE_DISABLED) {
-	printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
-	    cmd->target, cmd->lun);
-	cmd->result = DID_BAD_TARGET << 16;
-    } else if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
-	(hostdata->debug_count_limit == 0)) {
-	printk("scsi%d : maximum commands exceeded\n", host->host_no);
-	cmd->result = DID_BAD_TARGET << 16;
-    } else if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
-	switch (cmd->cmnd[0]) {
-	case WRITE_6:
-	case WRITE_10:
-	    printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
-		host->host_no);
-	    cmd->result = DID_BAD_TARGET << 16;
-	}
-    } else {
-    	if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
-	    hostdata->debug_count_limit != -1) 
-	    --hostdata->debug_count_limit;
-	restore_flags (flags);
-	cmd->result = le32_to_cpu(0xffff);	/* The NCR will overwrite message
-				       and status with valid data */
-	cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
-    }
-    cli();
-    /*
-     * REQUEST SENSE commands are inserted at the head of the queue 
-     * so that we do not clear the contingent allegiance condition
-     * they may be looking at.
-     */
-
-    if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-	cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
-	hostdata->issue_queue = cmd;
-    } else {
-	for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; 
-		tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
-	tmp->SCp.ptr = (unsigned char *) cmd;
-    }
-    restore_flags (flags);
-    run_process_issue_queue();
-    return 0;
-}
-
-/*
- * Function : void to_schedule_list (struct Scsi_Host *host,
- * 	struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : takes a SCSI command which was just removed from the 
- *	issue queue, and deals with it by inserting it in the first
- *	free slot in the schedule list or by terminating it immediately.
- *
- * Inputs : 
- *	host - SCSI host adapter; hostdata - hostdata structure for 
- *	this adapter; cmd - a pointer to the command; should have 
- *	the host_scribble field initialized to point to a valid 
- *	
- * Side effects : 
- *      cmd is added to the per instance schedule list, with minor 
- *      twiddling done to the host specific fields of cmd.
- *
- */
-
-static __inline__ void
-to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
-    struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    Scsi_Cmnd *tmp = cmd->cmd;
-    unsigned long flags;
-    /* dsa start is negative, so subtraction is used */
-    volatile u32 *curr;
-
-    int i;
-    NCR53c7x0_local_setup(host);
-#if 0
-    printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no, 
-	virt_to_bus(dsa), dsa);
-#endif
-
-    save_flags(flags);
-    cli();
-    
-    /* 
-     * Work around race condition : if an interrupt fired and we 
-     * got disabled forget about this command.
-     */
-
-    if (hostdata->state == STATE_DISABLED) {
-	printk("scsi%d : driver disabled\n", host->host_no);
-	tmp->result = DID_BAD_TARGET << 16;
-	cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
-	hostdata->free = cmd;
-	tmp->scsi_done(tmp);
-	restore_flags (flags);
-	return;
-    }
-
-    for (i = host->can_queue, curr = hostdata->schedule; 
-	i > 0  && curr[0] != hostdata->NOP_insn;
-	--i, curr += 2 /* JUMP instructions are two words */);
-
-    if (i > 0) {
-	++hostdata->busy[tmp->target][tmp->lun];
-	cmd->next = hostdata->running_list;
-	hostdata->running_list = cmd;
-
-	/* Restore this instruction to a NOP once the command starts */
-	cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) / 
-	    sizeof(u32)] = (u32) le32_to_cpu(virt_to_bus ((void *)curr));
-	/* Replace the current jump operand.  */
-	curr[1] =
-	    le32_to_cpu(virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
-	    hostdata->E_dsa_code_template);
-	/* Replace the NOP instruction with a JUMP */
-	curr[0] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
-	    DBC_TCI_TRUE);
-    }  else {
-	printk ("scsi%d: no free slot\n", host->host_no);
-	disable(host);
-	tmp->result = DID_ERROR << 16;
-	cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
-	hostdata->free = cmd;
-	tmp->scsi_done(tmp);
-	restore_flags (flags);
-	return;
-    }
-
-    /* 
-     * If the NCR chip is in an idle state, start it running the scheduler
-     * immediately.  Otherwise, signal the chip to jump to schedule as 
-     * soon as it is idle.
-     */
-    if (hostdata->idle) {
-	hostdata->idle = 0;
-	hostdata->state = STATE_RUNNING;
-	NCR53c7x0_write32 (DSP_REG,  virt_to_bus ((void *)hostdata->schedule));
-    } else {
-	NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
-    }
-
-    restore_flags(flags);
-}
-
-/*
- * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata 
- *	*hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : decide if we can pass the given SCSI command on to the 
- *	device in question or not.
- *  
- * Returns : non-zero when we're busy, 0 when we aren't.
- */
-
-static __inline__ int
-busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, 
-    Scsi_Cmnd *cmd) {
-    /* FIXME : in the future, this needs to accommodate SCSI-II tagged
-       queuing, and we may be able to play with fairness here a bit.
-     */
-    return hostdata->busy[cmd->target][cmd->lun];
-}
-
-/*
- * Function : process_issue_queue (void)
- *
- * Purpose : transfer commands from the issue queue to NCR start queue 
- *	of each NCR53c7/8xx in the system, avoiding kernel stack 
- *	overflows when the scsi_done() function is invoked recursively.
- * 
- * NOTE : process_issue_queue exits with interrupts *disabled*, so the 
- *	caller must reenable them if it desires.
- * 
- * NOTE : process_issue_queue should be called from both 
- *	NCR53c7x0_queue_command() and from the interrupt handler 
- *	after command completion in case NCR53c7x0_queue_command()
- * 	isn't invoked again but we've freed up resources that are
- *	needed.
- */
-
-static void 
-process_issue_queue (unsigned long flags) {
-    Scsi_Cmnd *tmp, *prev;
-    struct Scsi_Host *host;
-    struct NCR53c7x0_hostdata *hostdata;
-    int done;
-
-    /*
-     * We run (with interrupts disabled) until we're sure that none of 
-     * the host adapters have anything that can be done, at which point 
-     * we set process_issue_queue_running to 0 and exit.
-     *
-     * Interrupts are enabled before doing various other internal 
-     * instructions, after we've decided that we need to run through
-     * the loop again.
-     *
-     */
-
-    do {
-	cli(); /* Freeze request queues */
-	done = 1;
-	for (host = first_host; host && host->hostt == the_template; 
-	    host = host->next) {
-	    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
-	    cli();
-	    if (hostdata->issue_queue) {
-	    	if (hostdata->state == STATE_DISABLED) {
-		    tmp = (Scsi_Cmnd *) hostdata->issue_queue;
-		    hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
-		    tmp->result = DID_BAD_TARGET << 16;
-		    if (tmp->host_scribble) {
-			((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = 
-			    hostdata->free;
-			hostdata->free = 
-			    (struct NCR53c7x0_cmd *)tmp->host_scribble;
-			tmp->host_scribble = NULL;
-		    }
-		    tmp->scsi_done (tmp);
-		    done = 0;
-		} else 
-		    for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
-			prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
-			tmp->SCp.ptr) 
-			if (!tmp->host_scribble || 
-			    !busyp (host, hostdata, tmp)) {
-				if (prev)
-				    prev->SCp.ptr = tmp->SCp.ptr;
-				else
-				    hostdata->issue_queue = (Scsi_Cmnd *) 
-					tmp->SCp.ptr;
-			    tmp->SCp.ptr = NULL;
-			    if (tmp->host_scribble) {
-				if (hostdata->options & OPTION_DEBUG_QUEUES) 
-				    printk ("scsi%d : moving command for target %d lun %d to start list\n",
-					host->host_no, tmp->target, tmp->lun);
-		
-
-			    	to_schedule_list (host, hostdata, 
-				    (struct NCR53c7x0_cmd *)
-				    tmp->host_scribble);
-			    } else {
-			    	tmp->result = le32_to_cpu(tmp->result);
-				if (((tmp->result & 0xff) == 0xff) ||
-			    	    ((tmp->result & 0xff00) == 0xff00)) {
-				    printk ("scsi%d : danger Will Robinson!\n",
-					host->host_no);
-				    tmp->result = DID_ERROR << 16;
-				    disable (host);
-				}
-				tmp->scsi_done(tmp);
-			    }
-			    done = 0;
-			} /* if target/lun is not busy */
-	    } /* if hostdata->issue_queue */
-	    if (!done)
-		restore_flags (flags);
-    	} /* for host */
-    } while (!done);
-    process_issue_queue_running = 0;
-}
-
-/*
- * Function : static void intr_scsi (struct Scsi_Host *host, 
- * 	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all SCSI interrupts, indicated by the setting 
- * 	of the SIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * 	may be NULL.
- */
-
-static void 
-intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = 
-    	(struct NCR53c7x0_hostdata *) host->hostdata;
-    unsigned char sstat0_sist0, sist1, 		/* Registers */
-	    fatal; 				/* Did a fatal interrupt 
-						   occur ? */
-   
-    int is_8xx_chip;		 
-    NCR53c7x0_local_setup(host);
-
-    fatal = 0;
-
-    is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
-    if (is_8xx_chip) {
-    	sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
-	udelay(1);
-    	sist1 = NCR53c7x0_read8(SIST1_REG_800);
-    } else {
-    	sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
-    	sist1 = 0;
-    }
-
-    if (hostdata->options & OPTION_DEBUG_INTR) 
-	printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
-	    sstat0_sist0, sist1);
-
-    /* 250ms selection timeout */
-    if ((is_8xx_chip && (sist1 & SIST1_800_STO)) || 
-        (!is_8xx_chip && (sstat0_sist0 & SSTAT0_700_STO))) {
-	fatal = 1;
-	if (hostdata->options & OPTION_DEBUG_INTR) {
-	    printk ("scsi%d : Selection Timeout\n", host->host_no);
-    	    if (cmd) {
-    	    	printk("scsi%d : target %d, lun %d, command ",
-    	    	    host->host_no, cmd->cmd->target, cmd->cmd->lun);
-    	    	print_command (cmd->cmd->cmnd);
-		printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
-		    NCR53c7x0_read32(DSP_REG),
-		    bus_to_virt(NCR53c7x0_read32(DSP_REG)));
-    	    } else {
-    	    	printk("scsi%d : no command\n", host->host_no);
-    	    }
-    	}
-/*
- * XXX - question : how do we want to handle the Illegal Instruction
- * 	interrupt, which may occur before or after the Selection Timeout
- * 	interrupt?
- */
-
-	if (1) {
-	    hostdata->idle = 1;
-	    hostdata->expecting_sto = 0;
-
-	    if (hostdata->test_running) {
-		hostdata->test_running = 0;
-		hostdata->test_completed = 3;
-	    } else if (cmd) {
-		abnormal_finished(cmd, DID_BAD_TARGET << 16);
-	    }
-#if 0	    
-	    hostdata->intrs = 0;
-#endif
-	}
-    } 
-
-/*
- * FIXME : in theory, we can also get a UDC when a STO occurs.
- */
-    if (sstat0_sist0 & SSTAT0_UDC) {
-	fatal = 1;
-	if (cmd) {
-	    printk("scsi%d : target %d lun %d unexpected disconnect\n",
-		host->host_no, cmd->cmd->target, cmd->cmd->lun);
-	    print_lots (host);
-	    abnormal_finished(cmd, DID_ERROR << 16);
-	} else 
-	     printk("scsi%d : unexpected disconnect (no command)\n",
-		host->host_no);
-
-	hostdata->dsp = (u32 *) hostdata->schedule;
-	hostdata->dsp_changed = 1;
-    }
-
-    /* SCSI PARITY error */
-    if (sstat0_sist0 & SSTAT0_PAR) {
-	fatal = 1;
-	if (cmd && cmd->cmd) {
-	    printk("scsi%d : target %d lun %d parity error.\n",
-		host->host_no, cmd->cmd->target, cmd->cmd->lun);
-	    abnormal_finished (cmd, DID_PARITY << 16); 
-	} else
-	    printk("scsi%d : parity error\n", host->host_no);
-	/* Should send message out, parity error */
-
-	/* XXX - Reduce synchronous transfer rate! */
-	hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-    	    sizeof(u32);
-	hostdata->dsp_changed = 1; 
-    /* SCSI GROSS error */
-    } 
-
-    if (sstat0_sist0 & SSTAT0_SGE) {
-	fatal = 1;
-	printk("scsi%d : gross error\n", host->host_no);
-	/* Reset SCSI offset */
-	if ((hostdata->chip / 100) == 8) {
-	    NCR53c7x0_write8 (STEST2_REG_800, STEST2_800_ROF);
-	}
-	
-	/* 
-         * A SCSI gross error may occur when we have 
-	 *
-	 * - A synchronous offset which causes the SCSI FIFO to be overwritten.
-	 *
-	 * - A REQ which causes the maximum synchronous offset programmed in 
-	 * 	the SXFER register to be exceeded.
-	 *
-	 * - A phase change with an outstanding synchronous offset.
-	 *
-	 * - Residual data in the synchronous data FIFO, with a transfer
-	 *	other than a synchronous receive is started.$#
-	 */
-		
-
-	/* XXX Should deduce synchronous transfer rate! */
-	hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-    	    sizeof(u32);
-	hostdata->dsp_changed = 1;
-    /* Phase mismatch */
-    } 
-
-    if (sstat0_sist0 & SSTAT0_MA) {
-	fatal = 1;
-	if (hostdata->options & OPTION_DEBUG_INTR)
-	    printk ("scsi%d : SSTAT0_MA\n", host->host_no);
-	intr_phase_mismatch (host, cmd);
-    }
-
-#if 0
-    if (sstat0_sist0 & SIST0_800_RSL) 
-	printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no);
-#endif
-    
-/*
- * If a fatal SCSI interrupt occurs, we must insure that the DMA and
- * SCSI FIFOs were flushed.
- */
-
-    if (fatal) {
-	if (!hostdata->dstat_valid) {
-	    hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-	    hostdata->dstat_valid = 1;
-	}
-
-/* XXX - code check for 700/800 chips */
-	if (!(hostdata->dstat & DSTAT_DFE)) {
-	    printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
-    	    if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
-		printk ("scsi%d: Flushing DMA FIFO\n", 
-			host->host_no);
-    	    	NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
-    	    	while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
-    	    	    DSTAT_DFE));
-    	    } else {
-    	    	NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
-    	    	while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
-    	    }
-	    hostdata->dstat |= DSTAT_DFE;
-    	}
-    }
-}
-
-/*
- * Function : do_NCR53c7x0_intr()
- *
- * Purpose : A quick wrapper function added to grab the io_request_lock
- *      spin lock prior to entering the real interrupt handler.  Needed
- *      for 2.1.95 and above.
- */
-static void
-do_NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs) {
-    unsigned long flags;
-
-    struct Scsi_Host *dev = dev_id;
-    
-    spin_lock_irqsave(dev->host_lock, flags);
-    NCR53c7x0_intr(irq, dev_id, regs);
-    spin_unlock_irqrestore(dev->host_lock, flags);
-}
-
-/*
- * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
- *
- * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
- *	the same IRQ line.  
- * 
- * Inputs : Since we're using the SA_INTERRUPT interrupt handler
- *	semantics, irq indicates the interrupt which invoked 
- *	this handler.  
- */
-
-static void 
-NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host;			/* Host we are looking at */
-    unsigned char istat; 			/* Values of interrupt regs */
-    struct NCR53c7x0_hostdata *hostdata;	/* host->hostdata */
-    struct NCR53c7x0_cmd *cmd,			/* command which halted */
-	**cmd_prev_ptr;
-    u32 *dsa;					/* DSA */
-    int done = 1;				/* Indicates when handler 
-						   should terminate */
-    int interrupted = 0;			/* This HA generated 
-						   an interrupt */
-    int have_intfly;				/* Don't print warning 
-						   messages when we stack
-						   INTFLYs */
-    unsigned long flags;				
-
-#ifdef NCR_DEBUG
-    char buf[80];				/* Debugging sprintf buffer */
-    size_t buflen;				/* Length of same */
-#endif
-    do {
-	done = 1;
-	for (host = first_host; host; host = host->next) 
-	    if (host->hostt == the_template && host->irq == irq) {
-    	    NCR53c7x0_local_setup(host);
-
-	    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
-	    hostdata->dsp_changed = 0;
-	    interrupted = 0;
-	    have_intfly = 0;
-
-	    do {
-		int is_8xx_chip;
-
-		hostdata->dstat_valid = 0;
-		interrupted = 0;
-		/*
-		 * Only read istat once, since reading it again will unstack
-		 * interrupts?
-		 */
-		istat = NCR53c7x0_read8(hostdata->istat);
-
-		/*
-		 * INTFLY interrupts are used by the NCR53c720, NCR53c810,
-		 * and NCR53c820 to signify completion of a command.  Since 
-		 * the SCSI processor continues running, we can't just look
-		 * at the contents of the DSA register and continue running.
-		 */
-/* XXX - this is too big, offends my sense of aesthetics, and should 
-   move to intr_intfly() */
-		is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
-		if ((hostdata->options & OPTION_INTFLY) && 
-		    (is_8xx_chip && (istat & ISTAT_800_INTF))) {
-		    char search_found = 0;	/* Got at least one ? */
-		    done = 0;
-		    interrupted = 1;
-
-		    /* 
-		     * Clear the INTF bit by writing a one.  
-		     * This reset operation is self-clearing.
-		     */
-		    NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
-
-		    if (hostdata->options & OPTION_DEBUG_INTR)
-			printk ("scsi%d : INTFLY\n", host->host_no); 
-
-		    /*
-		     * Traverse our list of running commands, and look
-		     * for those with valid (non-0xff ff) status and message
-		     * bytes encoded in the result which signify command
-		     * completion.
-		     */
-
-
-		    save_flags(flags);
-		    cli();
-restart:
-		    for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) 
-			 &(hostdata->running_list), cmd = 
-			 (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
-			 cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
-    	    	    	 cmd = (struct NCR53c7x0_cmd *) cmd->next) {
-			Scsi_Cmnd *tmp;
-
-			if (!cmd) {
-			    printk("scsi%d : very weird.\n", host->host_no);
-			    break;
-			}
-
-			if (!(tmp = cmd->cmd)) {
-			    printk("scsi%d : weird.  NCR53c7x0_cmd has no Scsi_Cmnd\n",
-				host->host_no);
-				continue;
-			}
-#if 0
-			printk ("scsi%d : looking at result of 0x%x\n",
-			    host->host_no, cmd->cmd->result);
-#endif
-
-#ifdef __powerpc__
-			if (tmp->result == le32_to_cpu(0xffff))
-			    continue;
-			tmp->result = le32_to_cpu(tmp->result);
-#else			
-			if (((tmp->result & 0xff) == 0xff) ||
-			    ((tmp->result & 0xff00) == 0xff00))
-			    continue;
-#endif			    
-
-			search_found = 1;
-
-			/* Important - remove from list _before_ done is called */
-			if (cmd_prev_ptr)
-			    *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
-
-			--hostdata->busy[tmp->target][tmp->lun];
-    	    	    	cmd->next = hostdata->free;
-    	    	    	hostdata->free = cmd;
-
-    	    	    	tmp->host_scribble = NULL;
-
-			if (hostdata->options & OPTION_DEBUG_INTR) {
-			    printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ", 
-				host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
-			    print_command (tmp->cmnd);
-			}
-			
-#if 0
-			hostdata->options &= ~OPTION_DEBUG_INTR;
-#endif
-			tmp->scsi_done(tmp);
-			goto restart;
-
-		    }
-		    restore_flags(flags);
-		   
-    /*
-     * I think that we're stacking INTFLY interrupts; taking care of 
-     * all the finished commands on the first one, and then getting
-     * worried when we see the next one.  The magic with have_intfly
-     * should tell if this is the case..
-     */
-		
-		    if (!search_found && !have_intfly)  {
-			printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
-			    host->host_no);
-		    } else if (!have_intfly)  {
-			have_intfly = 1; 
-    		    	run_process_issue_queue();
-		    }
-		}
-
-		if (istat & (ISTAT_SIP|ISTAT_DIP)) {
-		    done = 0;
-		    interrupted = 1;
-    	    	    hostdata->state = STATE_HALTED;
-
-		    if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
-			SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) 
-			printk ("scsi%d : SCSI FIFO not empty\n", 
-			    host->host_no);
-
-		    /*
-		     * NCR53c700 and NCR53c700-66 change the current SCSI
-		     * process, hostdata->curr, in the Linux driver so
-		     * cmd = hostdata->curr.
-		     *
-		     * With other chips, we must look through the commands
-		     * executing and find the command structure which 
-		     * corresponds to the DSA register.
-		     */
-
-		    if (hostdata->options & OPTION_700) {
-			cmd = (struct NCR53c7x0_cmd *) hostdata->curr;
-		    } else {
-			dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-			for (cmd = (struct NCR53c7x0_cmd *) 
-			    hostdata->running_list; cmd &&
-    	    	    	    (dsa + (hostdata->dsa_start / sizeof(u32))) != 
-    	    	    	    	cmd->dsa;
-			    cmd = (struct NCR53c7x0_cmd *)(cmd->next));
-		    }
-		    if (hostdata->options & OPTION_DEBUG_INTR) {
-			if (cmd) {
-			    printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", 
-				host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
-				(int) cmd->cmd->lun);
-			    print_command (cmd->cmd->cmnd);
-			} else {
-			    printk("scsi%d : no active command\n", host->host_no);
-			}
-		    }
-		    if (istat & ISTAT_SIP) {
-			if (hostdata->options & OPTION_DEBUG_INTR) 
-			    printk ("scsi%d : ISTAT_SIP\n", host->host_no);
-			intr_scsi (host, cmd);
-		    }
-		
-		    if (istat & ISTAT_DIP) {
-			if (hostdata->options & OPTION_DEBUG_INTR) 
-			    printk ("scsi%d : ISTAT_DIP\n", host->host_no);
-			intr_dma (host, cmd);
-		    }
-
-		    if (!hostdata->dstat_valid) {
-			hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-			hostdata->dstat_valid = 1;
-		    }
-
-	    /* XXX - code check for 700/800 chips */
-		    if (!(hostdata->dstat & DSTAT_DFE)) {
-			printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
-			if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
-			    printk ("scsi%d: Flushing DMA FIFO\n", 
-				host->host_no);
-			    NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
-			    while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
-				DSTAT_DFE));
-			} else 
-			{
-			    NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
-			    while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
-			}
-			hostdata->dstat |= DSTAT_DFE;
-		    }
-		}
-	    } while (interrupted);
-
-
-
-	    if (hostdata->intrs != -1)
-		hostdata->intrs++;
-#if 0
-	    if (hostdata->intrs > 40) {
-		printk("scsi%d : too many interrupts, halting", host->host_no);
-		disable(host);
-	    }
-#endif
-
-	    if (!hostdata->idle && hostdata->state == STATE_HALTED) {
-		if (!hostdata->dsp_changed) {
-		    hostdata->dsp = (u32 *) 
-			bus_to_virt(NCR53c7x0_read32(DSP_REG));
-		}
-			
-#if 0
-		printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
-		    host->host_no,  virt_to_bus(hostdata->dsp), hostdata->dsp);
-#endif
-		
-		hostdata->state = STATE_RUNNING;
-		NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
-	    }
-	}
-    } while (!done);
-}
-
-
-/* 
- * Function : static int abort_connected (struct Scsi_Host *host)
- *
- * Purpose : Assuming that the NCR SCSI processor is currently 
- * 	halted, break the currently established nexus.  Clean
- *	up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
- *	be done on receipt of the abort interrupt.
- *
- * Inputs : host - SCSI host
- *
- */
-
-static int 
-abort_connected (struct Scsi_Host *host) {
-#ifdef NEW_ABORT
-    NCR53c7x0_local_declare();
-#endif
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-/* FIXME : this probably should change for production kernels; at the 
-   least, counter should move to a per-host structure. */
-    static int counter = 5;
-#ifdef NEW_ABORT
-    int sstat, phase, offset;
-    u32 *script;
-    NCR53c7x0_local_setup(host);
-#endif
-
-    if (--counter <= 0) {
-	disable(host);
-	return 0;
-    }
-
-    printk ("scsi%d : DANGER : abort_connected() called \n",
-	host->host_no);
-
-#ifdef NEW_ABORT
-
-/*
- * New strategy : Rather than using a generic abort routine,
- * we'll specifically try to source or sink the appropriate
- * amount of data for the phase we're currently in (taking into 
- * account the current synchronous offset) 
- */
-
-    sstat = (NCR53c8x0_read8 ((chip / 100) == 8 ? SSTAT1_REG : SSTAT2_REG);
-    offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
-    phase = sstat & SSTAT2_PHASE_MASK;
-
-/*
- * SET ATN
- * MOVE source_or_sink, WHEN CURRENT PHASE 
- * < repeat for each outstanding byte >
- * JUMP send_abort_message
- */
-
-    script = hostdata->abort_script = kmalloc (
-	8  /* instruction size */ * (
-	    1 /* set ATN */ +
-	    (!offset ? 1 : offset) /* One transfer per outstanding byte */ +
-	    1 /* send abort message */),
-	GFP_ATOMIC);
-
-
-#else /* def NEW_ABORT */
-    hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
-	    sizeof(u32);
-#endif /* def NEW_ABORT */
-    hostdata->dsp_changed = 1;
-
-/* XXX - need to flag the command as aborted after the abort_connected
- 	 code runs 
- */
-    return 0;
-}
-
-/*
- * Function : static int datapath_residual (Scsi_Host *host)
- *
- * Purpose : return residual data count of what's in the chip.
- *
- * Inputs : host - SCSI host
- */
-
-static int
-datapath_residual (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-    	host->hostdata;
-    int count, synchronous, sstat;
-    NCR53c7x0_local_setup(host);
-    /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
-    count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
-	(NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
-    synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
-    /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
-    if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
-    /* Receive */
-	if (synchronous) 
-	    count += (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? 
-		SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
-	else
-	    if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? 
-		SSTAT0_REG : SSTAT1_REG) & SSTAT1_ILF)
-		++count;
-    } else {
-    /* Send */
-	sstat = ((hostdata->chip / 100) == 8) ?  NCR53c7x0_read8 (SSTAT0_REG) :
-	    NCR53c7x0_read8 (SSTAT1_REG);
-	if (sstat & SSTAT1_OLF)
-	    ++count;
-	if (synchronous && (sstat & SSTAT1_ORF))
-	    ++count;
-    }
-    return count;
-}
-
-/* 
- * Function : static const char * sbcl_to_phase (int sbcl)_
- *
- * Purpose : Convert SBCL register to user-parsable phase representation
- *
- * Inputs : sbcl - value of sbcl register
- */
-
-
-static const char *
-sbcl_to_phase (int sbcl) {
-    switch (sbcl & SBCL_PHASE_MASK) {
-    case SBCL_PHASE_DATAIN:
-	return "DATAIN";
-    case SBCL_PHASE_DATAOUT:
-	return "DATAOUT";
-    case SBCL_PHASE_MSGIN:
-	return "MSGIN";
-    case SBCL_PHASE_MSGOUT:
-	return "MSGOUT";
-    case SBCL_PHASE_CMDOUT:
-	return "CMDOUT";
-    case SBCL_PHASE_STATIN:
-	return "STATUSIN";
-    default:
-	return "unknown";
-    }
-}
-
-/* 
- * Function : static const char * sstat2_to_phase (int sstat)_
- *
- * Purpose : Convert SSTAT2 register to user-parsable phase representation
- *
- * Inputs : sstat - value of sstat register
- */
-
-
-static const char *
-sstat2_to_phase (int sstat) {
-    switch (sstat & SSTAT2_PHASE_MASK) {
-    case SSTAT2_PHASE_DATAIN:
-	return "DATAIN";
-    case SSTAT2_PHASE_DATAOUT:
-	return "DATAOUT";
-    case SSTAT2_PHASE_MSGIN:
-	return "MSGIN";
-    case SSTAT2_PHASE_MSGOUT:
-	return "MSGOUT";
-    case SSTAT2_PHASE_CMDOUT:
-	return "CMDOUT";
-    case SSTAT2_PHASE_STATIN:
-	return "STATUSIN";
-    default:
-	return "unknown";
-    }
-}
-
-/* 
- * Function : static void intr_phase_mismatch (struct Scsi_Host *host, 
- *	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : Handle phase mismatch interrupts
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * 	may be NULL.
- *
- * Side effects : The abort_connected() routine is called or the NCR chip 
- *	is restarted, jumping to the command_complete entry point, or 
- *	patching the address and transfer count of the current instruction 
- *	and calling the msg_in entry point as appropriate.
- */
-
-static void 
-intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    u32 dbc_dcmd, *dsp, *dsp_next;
-    unsigned char dcmd, sbcl;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-    	host->hostdata;
-    int residual;
-    enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action = 
-	ACTION_ABORT_PRINT;
-    const char *where = NULL;
-    NCR53c7x0_local_setup(host);
-
-    /*
-     * Corrective action is based on where in the SCSI SCRIPT(tm) the error 
-     * occurred, as well as which SCSI phase we are currently in.
-     */
-    dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
-    /* 
-     * Fetch the current instruction, and remove the operands for easier 
-     * interpretation.
-     */
-    dbc_dcmd = NCR53c7x0_read32(DBC_REG);
-    dcmd = (dbc_dcmd & 0xff000000) >> 24;
-    /*
-     * Like other processors, the NCR adjusts the instruction pointer before
-     * instruction decode.  Set the DSP address back to what it should
-     * be for this instruction based on its size (2 or 3 32 bit words).
-     */
-    dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
-
-
-    /*
-     * Read new SCSI phase from the SBCL lines.  Since all of our code uses 
-     * a WHEN conditional instead of an IF conditional, we don't need to 
-     * wait for a new REQ.
-     */
-    sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
-
-    if (!cmd) {
-	action = ACTION_ABORT_PRINT;
-	where = "no current command";
-    /*
-     * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
-     * mismatches should only occur where we're doing a multi-byte  
-     * BMI instruction.  Specifically, this means 
-     *
-     *  - select messages (a SCSI-I target may ignore additional messages
-     * 		after the IDENTIFY; any target may reject a SDTR or WDTR)
-     *
-     *  - command out (targets may send a message to signal an error 
-     * 		condition, or go into STATUSIN after they've decided 
-     *		they don't like the command.
-     *
-     *	- reply_message (targets may reject a multi-byte message in the 
-     *		middle)
-     *
-     * 	- data transfer routines (command completion with buffer space
-     *		left, disconnect message, or error message)
-     */
-    } else if (((dsp >= cmd->data_transfer_start && 
-	dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
-	if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
-		DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
-		DCMD_BMI_OP_MOVE_I)) {
-	    residual = datapath_residual (host);
-	    if (hostdata->options & OPTION_DEBUG_DISCONNECT)
-	    	printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n", 
-		    host->host_no, residual);
-
-	    /*
-	     * The first instruction is a CALL to the alternate handler for 
-	     * this data transfer phase, so we can do calls to 
-	     * munge_msg_restart as we would if control were passed 
-	     * from normal dynamic code.
-	     */
-	    if (dsp != cmd->residual + 2) {
-		cmd->residual[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
-			((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) | 
-		    DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE);
-		cmd->residual[1] = le32_to_cpu(virt_to_bus(hostdata->script)
-		    + ((dcmd & DCMD_BMI_IO)
-		       ? hostdata->E_other_in : hostdata->E_other_out));
-	    }
-
-	    /*
-	     * The second instruction is the a data transfer block
-	     * move instruction, reflecting the pointer and count at the 
-	     * time of the phase mismatch.
-	     */
-	    cmd->residual[2] = le32_to_cpu(dbc_dcmd + residual);
-	    cmd->residual[3] = le32_to_cpu(NCR53c7x0_read32(DNAD_REG) - residual);
-
-	    /*
-	     * The third and final instruction is a jump to the instruction
-	     * which follows the instruction which had to be 'split'
-	     */
-	    if (dsp != cmd->residual + 2) {
-		cmd->residual[4] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) 
-		    << 24) | DBC_TCI_TRUE);
-		cmd->residual[5] = le32_to_cpu(virt_to_bus(dsp_next));
-	    }
-
-	    /*
-	     * For the sake of simplicity, transfer control to the 
-	     * conditional CALL at the start of the residual buffer.
-	     */
-	    hostdata->dsp = cmd->residual;
-	    hostdata->dsp_changed = 1;
-	    action = ACTION_CONTINUE;
-	} else {
-	    where = "non-BMI dynamic DSA code";
-	    action = ACTION_ABORT_PRINT;
-	}
-    } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4)) {
-	/* Release ATN */
-	NCR53c7x0_write8 (SOCL_REG, 0);
-	switch (sbcl) {
-    /* 
-     * Some devices (SQ555 come to mind) grab the IDENTIFY message
-     * sent on selection, and decide to go into COMMAND OUT phase
-     * rather than accepting the rest of the messages or rejecting
-     * them.  Handle these devices gracefully.
-     */
-	case SBCL_PHASE_CMDOUT:
-	    hostdata->dsp = dsp + 2 /* two _words_ */;
-	    hostdata->dsp_changed = 1;
-	    printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n", 
-		host->host_no, cmd->cmd->target);
-	    cmd->flags &= ~CMD_FLAG_SDTR;
-	    action = ACTION_CONTINUE;
-	    break;
-	case SBCL_PHASE_MSGIN:
-	    hostdata->dsp = hostdata->script + hostdata->E_msg_in / 
-		sizeof(u32);
-	    hostdata->dsp_changed = 1;
-	    action = ACTION_CONTINUE;
-	    break;
-	default:
-	    where="select message out";
-	    action = ACTION_ABORT_PRINT;
-	}
-    /*
-     * Some SCSI devices will interpret a command as they read the bytes
-     * off the SCSI bus, and may decide that the command is Bogus before 
-     * they've read the entire command off the bus.
-     */
-    } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof 
-	(u32)) {
-	hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
-	    sizeof (u32);
-	hostdata->dsp_changed = 1;
-	action = ACTION_CONTINUE;
-    /* FIXME : we need to handle message reject, etc. within msg_respond. */
-#ifdef notyet
-    } else if (dsp == hostdata->script + hostdata->E_reply_message) {
-	switch (sbcl) {
-    /* Any other phase mismatches abort the currently executing command.  */
-#endif
-    } else {
-	where = "unknown location";
-	action = ACTION_ABORT_PRINT;
-    }
-
-    /* Flush DMA FIFO */
-    if (!hostdata->dstat_valid) {
-	hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-	hostdata->dstat_valid = 1;
-    }
-    if (!(hostdata->dstat & DSTAT_DFE)) {
-	if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
-	    printk ("scsi%d: Flushing DMA FIFO\n", 
-		    host->host_no);
-	    NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
-	    /* FIXME : what about stacked DMA interrupts? */
-	    while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
-		DSTAT_DFE));
-	} else {
-	    NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
-	    while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
-	}
-	hostdata->dstat |= DSTAT_DFE;
-    }
-
-    switch (action) {
-    case ACTION_ABORT_PRINT:
-	printk("scsi%d : %s : unexpected phase %s.\n",
-	     host->host_no, where ? where : "unknown location", 
-	     sbcl_to_phase(sbcl));
-	print_lots (host);
-    /* Fall through to ACTION_ABORT */
-    case ACTION_ABORT:
-	abort_connected (host);
-	break;
-    case ACTION_CONTINUE:
-	break;
-    }
-
-#if 0
-    if (hostdata->dsp_changed) {
-	printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp);
-	print_insn (host, hostdata->dsp, "", 1);
-    }
-#endif
-    
-}
-
-/*
- * Function : static void intr_bf (struct Scsi_Host *host, 
- * 	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle BUS FAULT interrupts 
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * 	may be NULL.
- */
-
-static void
-intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	    host->hostdata;
-    u32 *dsp,
-	*next_dsp,		/* Current dsp */
-    	*dsa,
-	dbc_dcmd;		/* DCMD (high eight bits) + DBC */
-    unsigned short pci_status;
-    int tmp;
-    unsigned long flags;
-    char *reason = NULL;
-    /* Default behavior is for a silent error, with a retry until we've
-       exhausted retries. */
-    enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
-    int report = 0;
-    NCR53c7x0_local_setup(host);
-
-    dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
-    next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
-    dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* FIXME - check chip type  */
-    dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
-    /*
-     * Bus faults can be caused by either a Bad Address or 
-     * Target Abort. We should check the Received Target Abort
-     * bit of the PCI status register and Master Abort Bit.
-     *
-     * 	- Master Abort bit indicates that no device claimed
-     *		the address with DEVSEL within five clocks
-     *
-     *	- Target Abort bit indicates that a target claimed it,
-     *		but changed its mind once it saw the byte enables.
-     *
-     */
-
-    if ((hostdata->chip / 100) == 8) {
-	save_flags (flags);
-	cli();
-	tmp = pci_read_config_word (hostdata->pcidev, PCI_STATUS, &pci_status);
-	restore_flags (flags);
-	if (tmp == PCIBIOS_SUCCESSFUL) {
-	    if (pci_status & PCI_STATUS_REC_TARGET_ABORT) {
-		reason = "PCI target abort";
-		pci_status &= ~PCI_STATUS_REC_TARGET_ABORT;
-	    } else if (pci_status & PCI_STATUS_REC_MASTER_ABORT) {
-		reason = "No device asserted PCI DEVSEL within five bus clocks";
-		pci_status &= ~PCI_STATUS_REC_MASTER_ABORT;
-	    } else if (pci_status & PCI_STATUS_PARITY) {
-		report = 1;   
-		pci_status &= ~PCI_STATUS_PARITY;
-	    }
-	} else {
-	    printk ("scsi%d : couldn't read status register : error %d\n",
-		host->host_no, tmp);
-	    retry = NEVER;
-	}
-    }
-
-#ifndef notyet
-    report = 1;
-#endif
-    if (report && reason) {
-	printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n",
-	     host->host_no, reason ? reason : "unknown");
-	print_lots (host);
-    }
-
-#ifndef notyet
-    retry = NEVER;
-#endif
-
-    /* 
-     * TODO : we should attempt to recover from any spurious bus 
-     * faults.  After X retries, we should figure that things are 
-     * sufficiently wedged, and call NCR53c7xx_reset.
-     *
-     * This code should only get executed once we've decided that we 
-     * cannot retry.
-     */
-
-    if (retry == NEVER) {
-    	printk(KERN_ALERT "          mail drew@PoohSticks.ORG\n");
-    	FATAL (host);
-    }
-}
-
-/*
- * Function : static void intr_dma (struct Scsi_Host *host, 
- * 	struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all DMA interrupts, indicated by the setting 
- * 	of the DIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * 	may be NULL.
- */
-
-static void 
-intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned char dstat;	/* DSTAT */	
-    u32 *dsp,
-	*next_dsp,		/* Current dsp */
-    	*dsa,
-	dbc_dcmd;		/* DCMD (high eight bits) + DBC */
-    int tmp;
-    unsigned long flags;
-    NCR53c7x0_local_setup(host);
-
-    if (!hostdata->dstat_valid) {
-	hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
-	hostdata->dstat_valid = 1;
-    }
-    
-    dstat = hostdata->dstat;
-    
-    if (hostdata->options & OPTION_DEBUG_INTR)
-	printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
-
-    dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
-    next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
-    dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* XXX - check chip type */
-    dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-
-    /*
-     * DSTAT_ABRT is the aborted interrupt.  This is set whenever the 
-     * SCSI chip is aborted.  
-     * 
-     * With NCR53c700 and NCR53c700-66 style chips, we should only 
-     * get this when the chip is currently running the accept 
-     * reselect/select code and we have set the abort bit in the 
-     * ISTAT register.
-     *
-     */
-    
-    if (dstat & DSTAT_ABRT) {
-#if 0
-	/* XXX - add code here to deal with normal abort */
-	if ((hostdata->options & OPTION_700) && (hostdata->state ==
-	    STATE_ABORTING)) {
-	} else 
-#endif
-	{
-	    printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n" 
-		   "         ", host->host_no);
-	    print_insn (host, dsp, KERN_ALERT "s ", 1);
-	    FATAL (host);
-	}
-    }
-
-    /*
-     * DSTAT_SSI is the single step interrupt.  Should be generated 
-     * whenever we have single stepped or are tracing.
-     */
-
-    if (dstat & DSTAT_SSI) {
-	if (hostdata->options & OPTION_DEBUG_TRACE) {
-	} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
-	    print_insn (host, dsp, "s ", 0);
-	    save_flags(flags);
-	    cli();
-/* XXX - should we do this, or can we get away with writing dsp? */
-
-	    NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
-    	    	~DCNTL_SSM) | DCNTL_STD);
-	    restore_flags(flags);
-	} else {
-	    printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
-		   "         ", host->host_no);
-	    print_insn (host, dsp, KERN_ALERT "", 1);
-	    printk(KERN_ALERT "         mail drew@PoohSticks.ORG\n");
-    	    FATAL (host);
-    	}
-    }
-
-    /*
-     * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name 
-     * is different) is generated whenever an illegal instruction is 
-     * encountered.  
-     * 
-     * XXX - we may want to emulate INTFLY here, so we can use 
-     *    the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810  
-     *	  chips.
-     */
-
-    if (dstat & DSTAT_OPC) {
-    /* 
-     * Ascertain if this IID interrupts occurred before or after a STO 
-     * interrupt.  Since the interrupt handling code now leaves 
-     * DSP unmodified until _after_ all stacked interrupts have been
-     * processed, reading the DSP returns the original DSP register.
-     * This means that if dsp lies between the select code, and 
-     * message out following the selection code (where the IID interrupt
-     * would have to have occurred by due to the implicit wait for REQ),
-     * we have an IID interrupt resulting from a STO condition and 
-     * can ignore it.
-     */
-
-	if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
-	    (dsp <= (hostdata->script + hostdata->E_select_msgout / 
-    	    sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
-	    if (hostdata->options & OPTION_DEBUG_INTR) 
-		printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
-		    host->host_no);
-	    if (hostdata->expecting_iid) {
-		hostdata->expecting_iid = 0;
-		hostdata->idle = 1;
-		if (hostdata->test_running == 2) {
-		    hostdata->test_running = 0;
-		    hostdata->test_completed = 3;
-		} else if (cmd) 
-			abnormal_finished (cmd, DID_BAD_TARGET << 16);
-	    } else {
-		hostdata->expecting_sto = 1;
-	    }
-    /*
-     * We can't guarantee we'll be able to execute the WAIT DISCONNECT
-     * instruction within the 3.4us of bus free and arbitration delay
-     * that a target can RESELECT in and assert REQ after we've dropped
-     * ACK.  If this happens, we'll get an illegal instruction interrupt.
-     * Doing away with the WAIT DISCONNECT instructions broke everything,
-     * so instead I'll settle for moving one WAIT DISCONNECT a few 
-     * instructions closer to the CLEAR ACK before it to minimize the
-     * chances of this happening, and handle it if it occurs anyway.
-     *
-     * Simply continue with what we were doing, and control should
-     * be transferred to the schedule routine which will ultimately
-     * pass control onto the reselection or selection (not yet)
-     * code.
-     */
-	} else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
-	    SBCL_REQ)) {
-	    if (!(hostdata->options & OPTION_NO_PRINT_RACE))
-	    {
-		printk("scsi%d: REQ before WAIT DISCONNECT IID\n", 
-		    host->host_no);
-		hostdata->options |= OPTION_NO_PRINT_RACE;
-	    }
-	} else {
-	    printk(KERN_ALERT "scsi%d : illegal instruction\n", host->host_no);
-	    print_lots (host);
-	    printk(KERN_ALERT "         mail drew@PoohSticks.ORG with ALL\n"
-		              "         boot messages and diagnostic output\n");
-    	    FATAL (host);
-	}
-    }
-
-    /* 
-     * DSTAT_BF are bus fault errors
-     */
-    
-    if (dstat & DSTAT_800_BF) {
-	intr_bf (host, cmd);
-    }
-	
-
-    /* 
-     * DSTAT_SIR interrupts are generated by the execution of 
-     * the INT instruction.  Since the exact values available 
-     * are determined entirely by the SCSI script running, 
-     * and are local to a particular script, a unique handler
-     * is called for each script.
-     */
-
-    if (dstat & DSTAT_SIR) {
-	if (hostdata->options & OPTION_DEBUG_INTR)
-	    printk ("scsi%d : DSTAT_SIR\n", host->host_no);
-	switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
-	case SPECIFIC_INT_NOTHING:
-	case SPECIFIC_INT_RESTART:
-	    break;
-	case SPECIFIC_INT_ABORT:
-	    abort_connected(host);
-	    break;
-	case SPECIFIC_INT_PANIC:
-	    printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
-	    print_insn (host, dsp, KERN_ALERT "", 1);
-	    printk(KERN_ALERT "          dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
-    	    FATAL (host);
-	    break;
-	case SPECIFIC_INT_BREAK:
-	    intr_break (host, cmd);
-	    break;
-	default:
-	    printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
-	    print_insn (host, dsp, KERN_ALERT "", 1);
-	    printk(KERN_ALERT"          dstat_sir_intr() returned unknown value %d\n", 
-		tmp);
-    	    FATAL (host);
-	}
-    } 
-
-    if ((hostdata->chip / 100) == 8 && (dstat & DSTAT_800_MDPE)) {
-	printk(KERN_ALERT "scsi%d : Master Data Parity Error\n",
-	    host->host_no);
-	FATAL (host);
-    }
-}
-
-/*
- * Function : static int print_insn (struct Scsi_Host *host, 
- * 	u32 *insn, int kernel)
- *
- * Purpose : print numeric representation of the instruction pointed
- * 	to by insn to the debugging or kernel message buffer
- *	as appropriate.  
- *
- * 	If desired, a user level program can interpret this 
- * 	information.
- *
- * Inputs : host, insn - host, pointer to instruction, prefix - 
- *	string to prepend, kernel - use printk instead of debugging buffer.
- *
- * Returns : size, in u32s, of instruction printed.
- */
-
-/*
- * FIXME: should change kernel parameter so that it takes an ENUM
- * 	specifying severity - either KERN_ALERT or KERN_PANIC so
- *	all panic messages are output with the same severity.
- */
-
-static int 
-print_insn (struct Scsi_Host *host, const u32 *insn, 
-    const char *prefix, int kernel) {
-    char buf[160], 		/* Temporary buffer and pointer.  ICKY 
-				   arbitrary length.  */
-
-		
-	*tmp;			
-    unsigned char dcmd;		/* dcmd register for *insn */
-    int size;
-
-    /* 
-     * Check to see if the instruction pointer is not bogus before 
-     * indirecting through it; avoiding red-zone at start of 
-     * memory.
-     *
-     * FIXME: icky magic needs to happen here on non-intel boxes which
-     * don't have kernel memory mapped in like this.  Might be reasonable
-     * to use vverify()?
-     */
-
-    if (virt_to_phys((void *)insn) < PAGE_SIZE || 
-	virt_to_phys((void *)(insn + 8)) > virt_to_phys(high_memory) ||
-	((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
-	virt_to_phys((void *)(insn + 12)) > virt_to_phys(high_memory))) {
-	size = 0;
-	sprintf (buf, "%s%p: address out of range\n",
-	    prefix, insn);
-    } else {
-/* 
- * FIXME : (void *) cast in virt_to_bus should be unnecessary, because
- * 	it should take const void * as argument.
- */
-	sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)", 
-	    (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,  
-	    insn[0], insn[1], bus_to_virt (le32_to_cpu(insn[1])));
-	tmp = buf + strlen(buf);
-	if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)  {
-	    sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2], 
-		bus_to_virt(le32_to_cpu(insn[2])));
-	    size = 3;
-	} else {
-	    sprintf (tmp, "\n");
-	    size = 2;
-	}
-    }
-
-    if (kernel) 
-	printk ("%s", buf);
-#ifdef NCR_DEBUG
-    else {
-	size_t len = strlen(buf);
-	debugger_kernel_write(host, buf, len);
-    }
-#endif
-    return size;
-}
-
-/*
- * Function : static const char *ncr_state (int state)
- *
- * Purpose : convert state (probably from hostdata->state) to a string
- *
- * Inputs : state
- *
- * Returns : char * representation of state, "unknown" on error.
- */
-
-#if 0
-static const char *
-ncr_state (int state) {
-    switch (state) {
-    case STATE_HALTED: return "halted";
-    case STATE_WAITING: return "waiting";
-    case STATE_RUNNING: return "running";
-    case STATE_ABORTING: return "aborting";
-    case STATE_DISABLED: return "disabled";
-    default: return "unknown";
-    }
-}
-#endif
-
-/*
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
- * 
- * Purpose : Abort an errant SCSI command, doing all necessary
- *	cleanup of the issue_queue, running_list, shared Linux/NCR
- *	dsa issue and reconnect queues.
- *
- * Inputs : cmd - command to abort, code - entire result field
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-int 
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->host;
-    struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) 
-	host->hostdata : NULL;
-    unsigned long flags;
-    unsigned long result;
-    struct NCR53c7x0_cmd *curr, **prev;
-    Scsi_Cmnd *me, **last;
-#if 0
-    static long cache_pid = -1;
-#endif
-
-
-    if (!host) {
-	printk ("Bogus SCSI command pid %ld; no host structure\n",
-	    cmd->pid);
-	return SCSI_ABORT_ERROR;
-    } else if (!hostdata) {
-	printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
-	return SCSI_ABORT_ERROR;
-    }
-    NCR53c7x0_local_setup(host);
-
-/*
- * CHECK : I don't think that reading ISTAT will unstack any interrupts,
- *	since we need to write the INTF bit to clear it, and SCSI/DMA
- * 	interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
- *	
- *	See that this is the case.
- *
- * I suspect that several of our failures may be coming from a new fatal
- * interrupt (possibly due to a phase mismatch) happening after we've left
- * the interrupt handler, but before the PIC has had the interrupt condition
- * cleared.
- */
-
-    if (NCR53c7x0_read8(hostdata->istat) & 
-	(ISTAT_DIP|ISTAT_SIP|
-	    (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) {
-	printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
-	    cmd->pid);
-	NCR53c7x0_intr (host->irq, NULL, NULL);
-	return SCSI_ABORT_BUSY;
-    }
-	
-    save_flags(flags);
-    cli();
-#if 0
-    if (cache_pid == cmd->pid) 
-	panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
-    else
-	cache_pid = cmd->pid;
-#endif
-	
-
-/*
- * The command could be hiding in the issue_queue.  This would be very
- * nice, as commands can't be moved from the high level driver's issue queue 
- * into the shared queue until an interrupt routine is serviced, and this
- * moving is atomic.  
- *
- * If this is the case, we don't have to worry about anything - we simply
- * pull the command out of the old queue, and call it aborted.
- */
-
-    for (me = (Scsi_Cmnd *) hostdata->issue_queue, 
-         last = (Scsi_Cmnd **) &(hostdata->issue_queue);
-	 me && me != cmd;  last = (Scsi_Cmnd **)&(me->SCp.ptr), 
-	 me = (Scsi_Cmnd *)me->SCp.ptr);
-
-    if (me) {
-	*last = (Scsi_Cmnd *) me->SCp.ptr;
-	if (me->host_scribble) {
-	    ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
-	    hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
-	    me->host_scribble = NULL;
-	}
-	cmd->result = DID_ABORT << 16;
-	cmd->scsi_done(cmd);
-	printk ("scsi%d : found command %ld in Linux issue queue\n", 
-	    host->host_no, me->pid);
-	restore_flags(flags);
-    	run_process_issue_queue();
-	return SCSI_ABORT_SUCCESS;
-    }
-
-/* 
- * That failing, the command could be in our list of already executing 
- * commands.  If this is the case, drastic measures are called for.  
- */ 
-
-    for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, 
-    	 prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
-	 curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) 
-         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
-
-    if (curr) {
-	result = le32_to_cpu(cmd->result);
-	if ((result & 0xff) != 0xff && (result & 0xff00) != 0xff00) {
-	    if (prev)
-		*prev = (struct NCR53c7x0_cmd *) curr->next;
-	    curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
-	    cmd->host_scribble = NULL;
-	    hostdata->free = curr;
-	    cmd->scsi_done(cmd);
-	printk ("scsi%d : found finished command %ld in running list\n", 
-	    host->host_no, cmd->pid);
-	    restore_flags(flags);
-	    return SCSI_ABORT_NOT_RUNNING;
-	} else {
-	    printk ("scsi%d : DANGER : command running, can not abort.\n",
-		cmd->host->host_no);
-	    restore_flags(flags);
-	    return SCSI_ABORT_BUSY;
-	}
-    }
-
-/* 
- * And if we couldn't find it in any of our queues, it must have been 
- * a dropped interrupt.
- */
-
-    curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-    if (curr) {
-	curr->next = hostdata->free;
-	hostdata->free = curr;
-	cmd->host_scribble = NULL;
-    }
-
-    result = le32_to_cpu(cmd->result);
-    if (((result & 0xff00) == 0xff00) ||
-	((result & 0xff) == 0xff)) {
-	printk ("scsi%d : did this command ever run?\n", host->host_no);
-	cmd->result = DID_ABORT << 16;
-    } else {
-	printk ("scsi%d : probably lost INTFLY, normal completion\n", 
-	    host->host_no);
-/* 
- * FIXME : We need to add an additional flag which indicates if a 
- * command was ever counted as BUSY, so if we end up here we can
- * decrement the busy count if and only if it is necessary.
- */
-        --hostdata->busy[cmd->target][cmd->lun];
-    }
-    restore_flags(flags);
-    cmd->scsi_done(cmd);
-
-/* 
- * We need to run process_issue_queue since termination of this command 
- * may allow another queued command to execute first? 
- */
-    return SCSI_ABORT_NOT_RUNNING;
-}
-
-/*
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) 
- * 
- * Purpose : perform a hard reset of the SCSI bus and NCR
- * 	chip.
- *
- * Inputs : cmd - command which caused the SCSI RESET
- *
- * Returns : 0 on success.
- */
- 
-int 
-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    int found = 0;
-    struct NCR53c7x0_cmd * c;
-    Scsi_Cmnd *tmp;
-    /*
-     * When we call scsi_done(), it's going to wake up anything sleeping on the
-     * resources which were in use by the aborted commands, and we'll start to 
-     * get new commands.
-     *
-     * We can't let this happen until after we've re-initialized the driver
-     * structures, and can't reinitialize those structures until after we've 
-     * dealt with their contents.
-     *
-     * So, we need to find all of the commands which were running, stick
-     * them on a linked list of completed commands (we'll use the host_scribble
-     * pointer), do our reinitialization, and then call the done function for
-     * each command.  
-     */
-    Scsi_Cmnd *nuke_list = NULL;
-    struct Scsi_Host *host = cmd->host;
-    struct NCR53c7x0_hostdata *hostdata = 
-    	(struct NCR53c7x0_hostdata *) host->hostdata;
-
-    NCR53c7x0_local_setup(host);
-    save_flags(flags);
-    cli();
-    ncr_halt (host);
-    print_lots (host);
-    dump_events (host, 30);
-    ncr_scsi_reset (host);
-    for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
-	0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
-	if (tmp == cmd) {
-	    found = 1;
-	    break;
-	}
-	    
-    /* 
-     * If we didn't find the command which caused this reset in our running
-     * list, then we've lost it.  See that it terminates normally anyway.
-     */
-    if (!found) {
-    	c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-    	if (c) {
-	    cmd->host_scribble = NULL;
-    	    c->next = hostdata->free;
-    	    hostdata->free = c;
-    	} else
-	    printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid);
-	cmd->SCp.buffer = (struct scatterlist *) nuke_list;
-	nuke_list = cmd;
-    }
-
-    NCR53c7x0_driver_init (host);
-    hostdata->soft_reset (host);
-    if (hostdata->resets == 0) 
-	disable(host);
-    else if (hostdata->resets != -1)
-	--hostdata->resets;
-    restore_flags(flags);
-    for (; nuke_list; nuke_list = tmp) {
-	tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
-    	nuke_list->result = DID_RESET << 16;
-	nuke_list->scsi_done (nuke_list);
-    }
-    restore_flags(flags);
-    return SCSI_RESET_SUCCESS;
-}
-
-/*
- * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and 
- * therefore shares the scsicam_bios_param function.
- */
-
-/*
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
- *
- * Purpose : convert instructions stored at NCR pointer into data 
- *	pointer offset.
- * 
- * Inputs : cmd - SCSI command; insn - pointer to instruction.  Either current
- *	DSP, or saved data pointer.
- *
- * Returns : offset on success, -1 on failure.
- */
-
-
-static int 
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
-    struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) cmd->host->hostdata;
-    struct NCR53c7x0_cmd *ncmd = 
-	(struct NCR53c7x0_cmd *) cmd->host_scribble;
-    int offset = 0, buffers;
-    struct scatterlist *segment;
-    char *ptr;
-    int found = 0;
-
-/*
- * With the current code implementation, if the insn is inside dynamically 
- * generated code, the data pointer will be the instruction preceding 
- * the next transfer segment.
- */
-
-    if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
-	((insn >= ncmd->data_transfer_start &&  
-    	    insn < ncmd->data_transfer_end) ||
-    	(insn >= ncmd->residual &&
-    	    insn < (ncmd->residual + 
-    	    	sizeof(ncmd->residual))))) {
-	    ptr = bus_to_virt(le32_to_cpu(insn[3]));
-
-	    if ((buffers = cmd->use_sg)) {
-    	    	for (offset = 0, 
-		     	segment = (struct scatterlist *) cmd->buffer;
-    	    	     buffers && !((found = ((ptr >= segment->address) && 
-    	    	    	    (ptr < (segment->address + segment->length)))));
-    	    	     --buffers, offset += segment->length, ++segment)
-#if 0
-		    printk("scsi%d: comparing 0x%p to 0x%p\n", 
-			cmd->host->host_no, saved, segment->address);
-#else
-		    ;
-#endif
-    	    	    offset += ptr - segment->address;
-    	    } else {
-		found = 1;
-    	    	offset = ptr - (char *) (cmd->request_buffer);
-    	    }
-    } else if ((insn >= hostdata->script + 
-		hostdata->E_data_transfer / sizeof(u32)) &&
-	       (insn <= hostdata->script +
-		hostdata->E_end_data_transfer / sizeof(u32))) {
-    	found = 1;
-	offset = 0;
-    }
-    return found ? offset : -1;
-}
-
-
-
-/*
- * Function : void print_progress (Scsi_Cmnd *cmd) 
- * 
- * Purpose : print the current location of the saved data pointer
- *
- * Inputs : cmd - command we are interested in
- *
- */
-
-static void 
-print_progress (Scsi_Cmnd *cmd) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_cmd *ncmd = 
-	(struct NCR53c7x0_cmd *) cmd->host_scribble;
-    int offset, i;
-    char *where;
-    u32 *ptr;
-    NCR53c7x0_local_setup (cmd->host);
-    for (i = 0; i < 2; ++i) {
-	if (check_address ((unsigned long) ncmd, 
-	    sizeof (struct NCR53c7x0_cmd)) == -1) 
-	    continue;
-	if (!i) {
-	    where = "saved";
-	    ptr = bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer));
-	} else {
-	    where = "active";
-	    ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
-		NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
-		sizeof(u32));
-	} 
-	offset = insn_to_offset (cmd, ptr);
-
-	if (offset != -1) 
-	    printk ("scsi%d : %s data pointer at offset %d\n",
-		cmd->host->host_no, where, offset);
-	else {
-	    int size;
-	    printk ("scsi%d : can't determine %s data pointer offset\n",
-		cmd->host->host_no, where);
-	    if (ncmd) {
-		size = print_insn (cmd->host, 
-		    bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer)), "", 1);
-		print_insn (cmd->host, 
-		    bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer)) + size * sizeof(u32),
-		    "", 1);
-	    }
-	}
-    }
-}
-
-
-static void 
-print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    int i, len;
-    char *ptr;
-    Scsi_Cmnd *cmd;
-
-    if (check_address ((unsigned long) dsa, hostdata->dsa_end - 
-	hostdata->dsa_start) == -1) {
-	printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa);
-	return;
-    }
-    printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
-	    "        + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
-    	    prefix ? prefix : "",
-    	    host->host_no,  virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
-    	    le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]),
-	    le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1]),
-	    bus_to_virt (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1])));
-
-    /* 
-     * Only print messages if they're sane in length so we don't
-     * blow the kernel printk buffer on something which won't buy us
-     * anything.
-     */
-
-    if (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]) < 
-	    sizeof (hostdata->free->select)) 
-	for (i = le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]),
-	    ptr = bus_to_virt (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1])); 
-	    i > 0 && !check_address ((unsigned long) ptr, 1);
-	    ptr += len, i -= len) {
-	    printk("               ");
-	    len = print_msg (ptr);
-	    printk("\n");
-	    if (!len)
-		break;
-	}
-
-    printk("        + %d : select_indirect = 0x%x\n",
-	hostdata->dsa_select, le32_to_cpu(dsa[hostdata->dsa_select / sizeof(u32)]));
-    cmd = (Scsi_Cmnd *) bus_to_virt(le32_to_cpu(dsa[hostdata->dsa_cmnd / sizeof(u32)]));
-    printk("        + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
-	   (u32) virt_to_bus(cmd));
-    if (cmd) {
-	printk("               result = 0x%x, target = %d, lun = %d, cmd = ",
-	    cmd->result, cmd->target, cmd->lun);
-	print_command(cmd->cmnd);
-    } else
-	printk("\n");
-    printk("        + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
-	le32_to_cpu(dsa[hostdata->dsa_next / sizeof(u32)]));
-    if (cmd) { 
-	printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
-	       "                   script : ",
-	    host->host_no, cmd->target,
-	    hostdata->sync[cmd->target].sxfer_sanity,
-	    hostdata->sync[cmd->target].scntl3_sanity);
-	for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i)
-	    printk ("0x%x ", hostdata->sync[cmd->target].script[i]);
-	printk ("\n");
-    	print_progress (cmd);
-    }
-}
-/*
- * Function : void print_queues (Scsi_Host *host) 
- * 
- * Purpose : print the contents of the NCR issue and reconnect queues
- *
- * Inputs : host - SCSI host we are interested in
- *
- */
-
-static void 
-print_queues (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    u32 *dsa, *next_dsa;
-    volatile u32 *curr;
-    int left;
-    Scsi_Cmnd *cmd, *next_cmd;
-    unsigned long flags;
-
-    printk ("scsi%d : issue queue\n", host->host_no);
-
-    for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; 
-	    left >= 0 && cmd; 
-	    cmd = next_cmd) {
-	next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
-	save_flags(flags);
-	cli();
-	if (cmd->host_scribble) {
-	    if (check_address ((unsigned long) (cmd->host_scribble), 
-		sizeof (cmd->host_scribble)) == -1)
-		printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n",
-		    host->host_no, cmd->pid);
-	    /* print_dsa does sanity check on address, no need to check */
-	    else
-	    	print_dsa (host, bus_to_virt(le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa)), "");
-	} else 
-	    printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
-		host->host_no, cmd->pid, cmd->target, cmd->lun);
-	restore_flags(flags);
-    }
-
-    if (left <= 0) {
-	printk ("scsi%d : loop detected in issue queue\n",
-	    host->host_no);
-    }
-
-    /*
-     * Traverse the NCR reconnect and start DSA structures, printing out 
-     * each element until we hit the end or detect a loop.  Currently,
-     * the reconnect structure is a linked list; and the start structure
-     * is an array.  Eventually, the reconnect structure will become a 
-     * list as well, since this simplifies the code.
-     */
-
-    printk ("scsi%d : schedule dsa array :\n", host->host_no);
-    for (left = host->can_queue, curr = hostdata->schedule;
-	    left > 0; curr += 2, --left)
-	if (curr[0] != hostdata->NOP_insn) 
-/* FIXME : convert pointer to dsa_begin to pointer to dsa. */
-	    print_dsa (host, bus_to_virt (le32_to_cpu(curr[1]) - 
-		(hostdata->E_dsa_code_begin - 
-		hostdata->E_dsa_code_template)), "");
-    printk ("scsi%d : end schedule dsa array\n", host->host_no);
-    
-    printk ("scsi%d : reconnect_dsa_head :\n", host->host_no);
-	    
-    for (left = host->can_queue, 
-	dsa = bus_to_virt (le32_to_cpu(hostdata->reconnect_dsa_head));
-	left >= 0 && dsa; 
-	dsa = next_dsa) {
-	save_flags (flags);
-	cli();
-	if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
-	    printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
-		dsa);
-	    next_dsa = NULL;
-	}
-	else 
-	{
-	    next_dsa = bus_to_virt(le32_to_cpu(dsa[hostdata->dsa_next / sizeof(u32)]));
-	    print_dsa (host, dsa, "");
-	}
-	restore_flags(flags);
-    }
-    printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
-    if (left < 0)
-	printk("scsi%d: possible loop in ncr reconnect list\n",
-	    host->host_no);
-}
-
-static void
-print_lots (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) host->hostdata;
-    u32 *dsp_next, *dsp, *dsa, dbc_dcmd;
-    unsigned char dcmd, sbcl;
-    int i, size;
-    NCR53c7x0_local_setup(host);
-
-    if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) {
-    	dbc_dcmd = NCR53c7x0_read32(DBC_REG);
-    	dcmd = (dbc_dcmd & 0xff000000) >> 24;
-    	dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
-	dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-	sbcl = NCR53c7x0_read8 (SBCL_REG);
-	    
-	
-    	printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
-		"         DSA=0x%lx (virt 0x%p)\n"
-	        "         DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n"
-		"         SXFER=0x%x, SCNTL3=0x%x\n"
-		"         %s%s%sphase=%s, %d bytes in SCSI FIFO\n"
-		"         STEST0=0x%x\n",
-	    host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG), 
-		bus_to_virt(NCR53c7x0_read32(DNAD_REG)),
-	    virt_to_bus(dsa), dsa, 
-	    NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG), 
-	    bus_to_virt (NCR53c7x0_read32(TEMP_REG)),
-	    (int) NCR53c7x0_read8(hostdata->dmode),
-	    (int) NCR53c7x0_read8(SXFER_REG), 
-	    (int) NCR53c7x0_read8(SCNTL3_REG_800),
-	    (sbcl & SBCL_BSY) ? "BSY " : "",
-	    (sbcl & SBCL_SEL) ? "SEL " : "",
-	    (sbcl & SBCL_REQ) ? "REQ " : "",
-	    sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ?
-	    	SSTAT1_REG : SSTAT2_REG)),
-	    (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? 
-		SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT,
-	    NCR53c7x0_read8 (STEST0_REG_800));
-	printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host->host_no, 
-	    virt_to_bus(dsp), dsp);
-    	for (i = 6; i > 0; --i, dsp += size)
-	    size = print_insn (host, dsp, "", 1);
-	if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON)  {
-	    printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n",
-		host->host_no, NCR53c7x0_read8 (SDID_REG_800),
-		NCR53c7x0_read8 (SSID_REG_800));
-	    print_dsa (host, dsa, "");
-	}
-
-#if 1
-	print_queues (host);
-#endif
-    }
-}
-
-/*
- * Function : static int shutdown (struct Scsi_Host *host)
- * 
- * Purpose : does a clean (we hope) shutdown of the NCR SCSI 
- *	chip.  Use prior to dumping core, unloading the NCR driver,
- * 
- * Returns : 0 on success
- */
-static int 
-shutdown (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    NCR53c7x0_local_setup(host);
-    save_flags (flags);
-    cli();
-/* Get in a state where we can reset the SCSI bus */
-    ncr_halt (host);
-    ncr_scsi_reset (host);
-    hostdata->soft_reset(host);
-
-    disable (host);
-    restore_flags (flags);
-    return 0;
-}
-
-/*
- * Function : void ncr_scsi_reset (struct Scsi_Host *host)
- *
- * Purpose : reset the SCSI bus.
- */
-
-static void 
-ncr_scsi_reset (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned long flags;
-    int sien = 0;
-    NCR53c7x0_local_setup(host);
-    save_flags (flags);
-    cli();
-    if ((hostdata->chip / 100) == 8) {
-	sien = NCR53c7x0_read8(SIEN0_REG_800);
-	NCR53c7x0_write8(SIEN0_REG_800, sien & ~SIEN_RST);
-    }
-    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
-    udelay(25);	/* Minimum amount of time to assert RST */
-    NCR53c7x0_write8(SCNTL1_REG, 0);
-    if ((hostdata->chip / 100) == 8) {
-	NCR53c7x0_write8(SIEN0_REG_800, sien);
-    }
-    restore_flags (flags);
-}
-
-/* 
- * Function : void hard_reset (struct Scsi_Host *host)
- *
- */
-
-static void 
-hard_reset (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned long flags;
-    save_flags (flags);
-    cli();
-    ncr_scsi_reset(host);
-    NCR53c7x0_driver_init (host);
-    if (hostdata->soft_reset)
-	hostdata->soft_reset (host);
-    restore_flags(flags);
-}
-
-
-/*
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
- *	int free, int issue)
- *
- * Purpose : return a linked list (using the SCp.buffer field as next,
- *	so we don't perturb hostdata.  We don't use a field of the 
- *	NCR53c7x0_cmd structure since we may not have allocated one 
- *	for the command causing the reset.) of Scsi_Cmnd structures that 
- *  	had propagated below the Linux issue queue level.  If free is set, 
- *	free the NCR53c7x0_cmd structures which are associated with 
- *	the Scsi_Cmnd structures, and clean up any internal 
- *	NCR lists that the commands were on.  If issue is set,
- *	also return commands in the issue queue.
- *
- * Returns : linked list of commands
- *
- * NOTE : the caller should insure that the NCR chip is halted
- *	if the free flag is set. 
- */
-
-static Scsi_Cmnd *
-return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    struct NCR53c7x0_cmd *c;
-    int i;
-    u32 *curr;
-    Scsi_Cmnd *list = NULL, *tmp;
-    for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; 
-    	c = (struct NCR53c7x0_cmd *) c->next)  {
-	if (c->cmd->SCp.buffer) {
-	    printk ("scsi%d : loop detected in running list!\n", host->host_no);
-	    break;
-	} else {
-	    printk ("Duh? Bad things happening in the NCR driver\n");
-	    break;
-	}
-
-	c->cmd->SCp.buffer = (struct scatterlist *) list;
-	list = c->cmd;
-	if (free) {
-    	    c->next = hostdata->free;
-    	    hostdata->free = c;
-	}
-    }
-
-    if (free) { 
-	for (i = 0, curr = (u32 *) hostdata->schedule; 
-	    i < host->can_queue; ++i, curr += 2) {
-	    curr[0] = hostdata->NOP_insn;
-	    curr[1] = le32_to_cpu(0xdeadbeef);
-	}
-	hostdata->curr = NULL;
-    }
-
-    if (issue) {
-	for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
-	    if (tmp->SCp.buffer) {
-		printk ("scsi%d : loop detected in issue queue!\n", 
-			host->host_no);
-		break;
-	    }
-	    tmp->SCp.buffer = (struct scatterlist *) list;
-	    list = tmp;
-	}
-	if (free)
-	    hostdata->issue_queue = NULL;
-		
-    }
-    return list;
-}
-
-/* 
- * Function : static int disable (struct Scsi_Host *host)
- *
- * Purpose : disables the given NCR host, causing all commands
- * 	to return a driver error.  Call this so we can unload the
- * 	module during development and try again.  Eventually, 
- * 	we should be able to find clean workarounds for these
- * 	problems.
- *
- * Inputs : host - hostadapter to twiddle
- *
- * Returns : 0 on success.
- */
-
-static int 
-disable (struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    unsigned long flags;
-    Scsi_Cmnd *nuke_list, *tmp;
-    save_flags(flags);
-    cli();
-    if (hostdata->state != STATE_HALTED)
-	ncr_halt (host);
-    nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
-    hard_reset (host);
-    hostdata->state = STATE_DISABLED;
-    restore_flags(flags);
-    printk ("scsi%d : nuking commands\n", host->host_no);
-    for (; nuke_list; nuke_list = tmp) {
-	    tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
-	    nuke_list->result = DID_ERROR << 16;
-	    nuke_list->scsi_done(nuke_list);
-    }
-    printk ("scsi%d : done. \n", host->host_no);
-    printk (KERN_ALERT "scsi%d : disabled.  Unload and reload\n",
-    	host->host_no);
-    return 0;
-}
-
-/*
- * Function : static int ncr_halt (struct Scsi_Host *host)
- * 
- * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
- *
- * Inputs : host - SCSI chip to halt
- *
- * Returns : 0 on success
- */
-
-static int 
-ncr_halt (struct Scsi_Host *host) {
-    NCR53c7x0_local_declare();
-    unsigned long flags;
-    unsigned char istat, tmp;
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    int stage;
-    NCR53c7x0_local_setup(host);
-
-    save_flags(flags);
-    cli();
-    /* Stage 0 : eat all interrupts
-       Stage 1 : set ABORT
-       Stage 2 : eat all but abort interrupts
-       Stage 3 : eat all interrupts
-     */
-    for (stage = 0;;) {
-	if (stage == 1) {
-	    NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
-	    ++stage;
-	}
-	istat = NCR53c7x0_read8 (hostdata->istat);
-	if (istat & ISTAT_SIP) {
-	    if ((hostdata->chip / 100) == 8) {
-		tmp = NCR53c7x0_read8(SIST0_REG_800);
-		udelay(1);
-		tmp = NCR53c7x0_read8(SIST1_REG_800);
-	    } else {
-		tmp = NCR53c7x0_read8(SSTAT0_REG);
-	    }
-	} else if (istat & ISTAT_DIP) {
-	    tmp = NCR53c7x0_read8(DSTAT_REG);
-	    if (stage == 2) {
-		if (tmp & DSTAT_ABRT) {
-		    NCR53c7x0_write8(hostdata->istat, 0);
-		    ++stage;
-		} else {
-		    printk(KERN_ALERT "scsi%d : could not halt NCR chip\n", 
-			host->host_no);
-		    disable (host);
-	    	}
-    	    }
-	}
-	if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
-	    if (stage == 0)
-	    	++stage;
-	    else if (stage == 3)
-		break;
-	}
-    }
-    hostdata->state = STATE_HALTED;
-    restore_flags(flags);
-#if 0
-    print_lots (host);
-#endif
-    return 0;
-}
-
-/* 
- * Function: event_name (int event)
- * 
- * Purpose: map event enum into user-readable strings.
- */
-
-static const char *
-event_name (int event) {
-    switch (event) {
-    case EVENT_NONE:		return "none";
-    case EVENT_ISSUE_QUEUE:	return "to issue queue";
-    case EVENT_START_QUEUE:	return "to start queue";
-    case EVENT_SELECT:		return "selected";
-    case EVENT_DISCONNECT:	return "disconnected";
-    case EVENT_RESELECT:	return "reselected";
-    case EVENT_COMPLETE:	return "completed";
-    case EVENT_IDLE:		return "idle";
-    case EVENT_SELECT_FAILED:	return "select failed";
-    case EVENT_BEFORE_SELECT:	return "before select";
-    case EVENT_RESELECT_FAILED:	return "reselect failed";
-    default:			return "unknown";
-    }
-}
-
-/*
- * Function : void dump_events (struct Scsi_Host *host, count)
- *
- * Purpose : print last count events which have occurred.
- */ 
-static void
-dump_events (struct Scsi_Host *host, int count) {
-    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
-	host->hostdata;
-    struct NCR53c7x0_event event;
-    int i;
-    unsigned long flags;
-    if (hostdata->events) {
-	if (count > hostdata->event_size)
-	    count = hostdata->event_size;
-	for (i = hostdata->event_index; count > 0; 
-	    i = (i ? i - 1 : hostdata->event_size -1), --count) {
-	    save_flags(flags);
-/*
- * By copying the event we're currently examining with interrupts
- * disabled, we can do multiple printk(), etc. operations and 
- * still be guaranteed that they're happening on the same 
- * event structure.
- */
-	    cli();
-#if 0
-	    event = hostdata->events[i];
-#else
-	    memcpy ((void *) &event, (void *) &(hostdata->events[i]),
-		sizeof(event));
-#endif
-
-	    restore_flags(flags);
-	    printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
-		host->host_no, event_name (event.event), count,
-		(long) event.time.tv_sec, (long) event.time.tv_usec,
-		event.target, event.lun);
-	    if (event.dsa) 
-		printk ("         event for dsa 0x%lx (virt 0x%p)\n", 
-		    virt_to_bus(event.dsa), event.dsa);
-	    if (event.pid != -1) {
-		printk ("         event for pid %ld ", event.pid);
-		print_command (event.cmnd);
-	    }
-	}
-    }
-}
-
-/*
- * Function: check_address
- *
- * Purpose: Check to see if a possibly corrupt pointer will fault the 
- *	kernel.
- *
- * Inputs: addr - address; size - size of area
- *
- * Returns: 0 if area is OK, -1 on error.
- *
- * NOTES: should be implemented in terms of vverify on kernels 
- *	that have it.
- */
-
-static int 
-check_address (unsigned long addr, int size) {
-    return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ?  -1 : 0);
-}
-
-#ifdef MODULE
-int 
-NCR53c7x0_release(struct Scsi_Host *host) {
-    struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) host->hostdata;
-    struct NCR53c7x0_cmd *cmd, *tmp;
-    shutdown (host);
-    if (host->irq != IRQ_NONE)
-	{
-	    int irq_count;
-	    struct Scsi_Host *tmp;
-	    for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
-		if (tmp->hostt == the_template && tmp->irq == host->irq)
-		    ++irq_count;
-	    if (irq_count == 1)
-		free_irq(host->irq, NULL);
-	}
-    if (host->dma_channel != DMA_NONE)
-	free_dma(host->dma_channel);
-    if (host->io_port)
-	release_region(host->io_port, host->n_io_port);
-    
-    for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, 
-	--hostdata->num_cmds) {
-	tmp = (struct NCR53c7x0_cmd *) cmd->next;
-    /* 
-     * If we're going to loop, try to stop it to get a more accurate
-     * count of the leaked commands.
-     */
-	cmd->next = NULL;
-	if (cmd->free)
-	    cmd->free ((void *) cmd->real, cmd->size);
-    }
-    if (hostdata->num_cmds)
-	printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
-	    host->host_no, hostdata->num_cmds);
-    if (hostdata->events) 
-	vfree ((void *)hostdata->events);
-    return 1;
-}
-#endif /* def MODULE */
-MODULE_LICENSE("GPL");
-
-static Scsi_Host_Template driver_template = NCR53c7xx;
-#include "scsi_module.c"
diff -Nru a/drivers/scsi/53c7,8xx.h b/drivers/scsi/53c7,8xx.h
--- a/drivers/scsi/53c7,8xx.h	Mon Feb 10 10:39:30 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1529 +0,0 @@
-/*
- * NCR 53c{7,8}0x0 driver, header file
- *
- * Sponsored by
- *      iX Multiuser Multitasking Magazine
- *	Hannover, Germany
- *	hm@ix.de	
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt
- *      Visionary Computing 
- *      (Unix and Linux consulting and custom programming)
- *      drew@PoohSticks.ORG
- *	+1 (303) 786-7975
- *
- * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
- * 
- * PRE-ALPHA
- *
- * For more information, please consult 
- *
- * NCR 53C700/53C700-66
- * SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor 
- * Data Manual
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * +1 (719) 578-3400
- *
- * Toll free literature number
- * +1 (800) 334-5454
- *
- */
-
-#ifndef NCR53c7x0_H
-#define NCR53c7x0_H
-#include <linux/version.h>
-
-/* 
- * Prevent name space pollution in hosts.c, and only provide the 
- * define we need to get the NCR53c7x0 driver into the host template
- * array.
- */
-
-#include <scsi/scsicam.h>
-
-extern int NCR53c7xx_abort(Scsi_Cmnd *);
-extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
-extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-#ifdef MODULE
-extern int NCR53c7xx_release(struct Scsi_Host *);
-#else
-#define NCR53c7xx_release NULL
-#endif
-
-#define NCR53c7xx {					\
-          .name           = "NCR53c{7,8}xx (rel 17)",	\
-	  .detect         = NCR53c7xx_detect,		\
-	  .queuecommand   = NCR53c7xx_queue_command,	\
-	  .abort          = NCR53c7xx_abort,		\
-	  .reset          = NCR53c7xx_reset,		\
-	  .can_queue      = 24,				\
-	  .this_id        = 7,				\
-	  .sg_tablesize   = 127,				\
-	  .cmd_per_lun    = 3,				\
-	  .use_clustering = DISABLE_CLUSTERING} 
-
-#ifndef HOSTS_C
-
-/* Register addresses, ordered numerically */
-
-/* SCSI control 0 rw, default = 0xc0 */ 
-#define SCNTL0_REG 		0x00	
-#define SCNTL0_ARB1		0x80	/* 0 0 = simple arbitration */
-#define SCNTL0_ARB2		0x40	/* 1 1 = full arbitration */
-#define SCNTL0_STRT		0x20	/* Start Sequence */
-#define SCNTL0_WATN		0x10	/* Select with ATN */
-#define SCNTL0_EPC		0x08	/* Enable parity checking */
-/* Bit 2 is reserved on 800 series chips */
-#define SCNTL0_EPG_700		0x04	/* Enable parity generation */
-#define SCNTL0_AAP		0x02	/*  ATN/ on parity error */
-#define SCNTL0_TRG		0x01	/* Target mode */
-
-/* SCSI control 1 rw, default = 0x00 */
-
-#define SCNTL1_REG 		0x01	
-#define SCNTL1_EXC		0x80	/* Extra Clock Cycle of Data setup */
-#define SCNTL1_ADB		0x40	/*  contents of SODL on bus */
-#define SCNTL1_ESR_700		0x20	/* Enable SIOP response to selection 
-					   and reselection */
-#define SCNTL1_DHP_800		0x20	/* Disable halt on parity error or ATN
-					   target mode only */
-#define SCNTL1_CON		0x10	/* Connected */
-#define SCNTL1_RST		0x08	/* SCSI RST/ */
-#define SCNTL1_AESP		0x04	/* Force bad parity */
-#define SCNTL1_SND_700		0x02	/* Start SCSI send */
-#define SCNTL1_IARB_800		0x02	/* Immediate Arbitration, start
-					   arbitration immediately after
-					   busfree is detected */
-#define SCNTL1_RCV_700		0x01	/* Start SCSI receive */
-#define SCNTL1_SST_800		0x01	/* Start SCSI transfer */
-
-/* SCSI control 2 rw, */
-
-#define SCNTL2_REG_800		0x02	
-#define SCNTL2_800_SDU		0x80	/* SCSI disconnect unexpected */
-
-/* SCSI control 3 rw */
-
-#define SCNTL3_REG_800 		0x03	
-#define SCNTL3_800_SCF_SHIFT	4
-#define SCNTL3_800_SCF_MASK	0x70
-#define SCNTL3_800_SCF2		0x40	/* Synchronous divisor */
-#define SCNTL3_800_SCF1		0x20	/* 0x00 = SCLK/3 */
-#define SCNTL3_800_SCF0		0x10	/* 0x10 = SCLK/1 */
-					/* 0x20 = SCLK/1.5 
-					   0x30 = SCLK/2 
-					   0x40 = SCLK/3 */
-	    
-#define SCNTL3_800_CCF_SHIFT	0
-#define SCNTL3_800_CCF_MASK	0x07
-#define SCNTL3_800_CCF2		0x04	/* 0x00 50.01 to 66 */
-#define SCNTL3_800_CCF1		0x02	/* 0x01 16.67 to 25 */
-#define SCNTL3_800_CCF0		0x01	/* 0x02	25.01 - 37.5 
-					   0x03	37.51 - 50 
-					   0x04 50.01 - 66 */
-
-/*  
- * SCSI destination ID rw - the appropriate bit is set for the selected
- * target ID.  This is written by the SCSI SCRIPTS processor.
- * default = 0x00
- */
-#define SDID_REG_700  		0x02	
-#define SDID_REG_800		0x06
-
-#define GP_REG_800		0x07	/* General purpose IO */
-#define GP_800_IO1		0x02
-#define GP_800_IO2		0x01
-
-
-/* SCSI interrupt enable rw, default = 0x00 */
-#define SIEN_REG_700		0x03	
-#define SIEN0_REG_800		0x40
-#define SIEN_MA			0x80	/* Phase mismatch (ini) or ATN (tgt) */
-#define SIEN_FC			0x40	/* Function complete */
-#define SIEN_700_STO		0x20	/* Selection or reselection timeout */
-#define SIEN_800_SEL		0x20	/* Selected */
-#define SIEN_700_SEL		0x10	/* Selected or reselected */
-#define SIEN_800_RESEL		0x10	/* Reselected */
-#define SIEN_SGE		0x08	/* SCSI gross error */
-#define SIEN_UDC		0x04	/* Unexpected disconnect */
-#define SIEN_RST		0x02	/* SCSI RST/ received */
-#define SIEN_PAR		0x01	/* Parity error */
-
-/* 
- * SCSI chip ID rw
- * NCR53c700 : 
- * 	When arbitrating, the highest bit is used, when reselection or selection
- * 	occurs, the chip responds to all IDs for which a bit is set.
- * 	default = 0x00 
- * NCR53c810 : 
- *	Uses bit mapping
- */
-#define SCID_REG		0x04	
-/* Bit 7 is reserved on 800 series chips */
-#define SCID_800_RRE		0x40	/* Enable response to reselection */
-#define SCID_800_SRE		0x20	/* Enable response to selection */
-/* Bits four and three are reserved on 800 series chips */
-#define SCID_800_ENC_MASK	0x07	/* Encoded SCSI ID */
-
-/* SCSI transfer rw, default = 0x00 */
-#define SXFER_REG		0x05
-#define SXFER_DHP		0x80	/* Disable halt on parity */
-
-#define SXFER_TP2		0x40	/* Transfer period msb */
-#define SXFER_TP1		0x20
-#define SXFER_TP0		0x10	/* lsb */
-#define SXFER_TP_MASK		0x70
-/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */
-#define SXFER_TP_SHIFT		5
-#define SXFER_TP_4		0x00	/* Divisors */
-#define SXFER_TP_5		0x10<<1
-#define SXFER_TP_6		0x20<<1
-#define SXFER_TP_7		0x30<<1
-#define SXFER_TP_8		0x40<<1
-#define SXFER_TP_9		0x50<<1
-#define SXFER_TP_10		0x60<<1
-#define SXFER_TP_11		0x70<<1
-
-#define SXFER_MO3		0x08	/* Max offset msb */
-#define SXFER_MO2		0x04
-#define SXFER_MO1		0x02
-#define SXFER_MO0		0x01	/* lsb */
-#define SXFER_MO_MASK		0x0f
-#define SXFER_MO_SHIFT		0
-
-/* 
- * SCSI output data latch rw
- * The contents of this register are driven onto the SCSI bus when 
- * the Assert Data Bus bit of the SCNTL1 register is set and 
- * the CD, IO, and MSG bits of the SOCL register match the SCSI phase
- */
-#define SODL_REG_700		0x06	
-#define SODL_REG_800		0x54
-
-
-/* 
- * SCSI output control latch rw, default = 0 
- * Note that when the chip is being manually programmed as an initiator,
- * the MSG, CD, and IO bits must be set correctly for the phase the target
- * is driving the bus in.  Otherwise no data transfer will occur due to 
- * phase mismatch.
- */
-
-#define SBCL_REG		0x0b
-#define SBCL_REQ		0x80	/*  REQ */
-#define SBCL_ACK		0x40	/*  ACK */
-#define SBCL_BSY		0x20	/*  BSY */
-#define SBCL_SEL		0x10	/*  SEL */
-#define SBCL_ATN		0x08	/*  ATN */
-#define SBCL_MSG		0x04	/*  MSG */
-#define SBCL_CD			0x02	/*  C/D */
-#define SBCL_IO			0x01	/*  I/O */
-#define SBCL_PHASE_CMDOUT	SBCL_CD
-#define SBCL_PHASE_DATAIN	SBCL_IO
-#define SBCL_PHASE_DATAOUT	0
-#define SBCL_PHASE_MSGIN	(SBCL_CD|SBCL_IO|SBCL_MSG)
-#define SBCL_PHASE_MSGOUT	(SBCL_CD|SBCL_MSG)
-#define SBCL_PHASE_STATIN	(SBCL_CD|SBCL_IO)
-#define SBCL_PHASE_MASK		(SBCL_CD|SBCL_IO|SBCL_MSG)
-
-/* 
- * SCSI first byte received latch ro 
- * This register contains the first byte received during a block MOVE 
- * SCSI SCRIPTS instruction, including
- * 
- * Initiator mode	Target mode
- * Message in		Command
- * Status		Message out
- * Data in		Data out
- *
- * It also contains the selecting or reselecting device's ID and our 
- * ID.
- *
- * Note that this is the register the various IF conditionals can 
- * operate on.
- */
-#define SFBR_REG		0x08	
-
-/* 
- * SCSI input data latch ro
- * In initiator mode, data is latched into this register on the rising
- * edge of REQ/. In target mode, data is latched on the rising edge of 
- * ACK/
- */
-#define SIDL_REG_700		0x09
-#define SIDL_REG_800		0x50
-
-/* 
- * SCSI bus data lines ro 
- * This register reflects the instantaneous status of the SCSI data 
- * lines.  Note that SCNTL0 must be set to disable parity checking, 
- * otherwise reading this register will latch new parity.
- */
-#define SBDL_REG_700		0x0a
-#define SBDL_REG_800		0x58
-
-#define SSID_REG_800		0x0a
-#define SSID_800_VAL		0x80	/* Exactly two bits asserted at sel */
-#define SSID_800_ENCID_MASK	0x07	/* Device which performed operation */
-
-
-/* 
- * SCSI bus control lines rw, 
- * instantaneous readout of control lines 
- */
-#define SOCL_REG		0x0b 	
-#define SOCL_REQ		0x80	/*  REQ ro */
-#define SOCL_ACK		0x40	/*  ACK ro */
-#define SOCL_BSY		0x20	/*  BSY ro */
-#define SOCL_SEL		0x10	/*  SEL ro */
-#define SOCL_ATN		0x08	/*  ATN ro */
-#define SOCL_MSG		0x04	/*  MSG ro */
-#define SOCL_CD			0x02	/*  C/D ro */
-#define SOCL_IO			0x01	/*  I/O ro */
-/* 
- * Synchronous SCSI Clock Control bits 
- * 0 - set by DCNTL 
- * 1 - SCLK / 1.0
- * 2 - SCLK / 1.5
- * 3 - SCLK / 2.0 
- */
-#define SBCL_SSCF1		0x02	/* wo, -66 only */
-#define SBCL_SSCF0		0x01	/* wo, -66 only */
-#define SBCL_SSCF_MASK		0x03
-
-/* 
- * XXX note : when reading the DSTAT and STAT registers to clear interrupts,
- * insure that 10 clocks elapse between the two  
- */
-/* DMA status ro */
-#define DSTAT_REG		0x0c	
-#define DSTAT_DFE		0x80	/* DMA FIFO empty */
-#define DSTAT_800_MDPE		0x40	/* Master Data Parity Error */
-#define DSTAT_800_BF		0x20	/* Bus Fault */
-#define DSTAT_ABRT		0x10	/* Aborted - set on error */
-#define DSTAT_SSI		0x08	/* SCRIPTS single step interrupt */
-#define DSTAT_SIR		0x04	/* SCRIPTS interrupt received - 
-					   set when INT instruction is 
-					   executed */
-#define DSTAT_WTD		0x02	/* Watchdog timeout detected */
-#define DSTAT_OPC		0x01	/* Illegal instruction */
-#define DSTAT_800_IID		0x01	/* Same thing, different name */
-
-
-/* NCR53c800 moves this stuff into SIST0 */
-#define SSTAT0_REG		0x0d	/* SCSI status 0 ro */
-#define SIST0_REG_800		0x42	
-#define SSTAT0_MA		0x80	/* ini : phase mismatch,
-					 * tgt : ATN/ asserted 
-					 */
-#define SSTAT0_CMP		0x40	/* function complete */
-#define SSTAT0_700_STO		0x20	/* Selection or reselection timeout */
-#define SIST0_800_SEL		0x20	/* Selected */
-#define SSTAT0_700_SEL		0x10	/* Selected or reselected */
-#define SIST0_800_RSL		0x10	/* Reselected */
-#define SSTAT0_SGE		0x08	/* SCSI gross error */
-#define SSTAT0_UDC		0x04	/* Unexpected disconnect */
-#define SSTAT0_RST		0x02	/* SCSI RST/ received */
-#define SSTAT0_PAR		0x01	/* Parity error */
-
-/* And uses SSTAT0 for what was SSTAT1 */
-
-#define SSTAT1_REG		0x0e	/* SCSI status 1 ro */
-#define SSTAT1_ILF		0x80	/* SIDL full */
-#define SSTAT1_ORF		0x40	/* SODR full */
-#define SSTAT1_OLF		0x20	/* SODL full */
-#define SSTAT1_AIP		0x10	/* Arbitration in progress */
-#define SSTAT1_LOA		0x08	/* Lost arbitration */
-#define SSTAT1_WOA		0x04	/* Won arbitration */
-#define SSTAT1_RST		0x02	/* Instant readout of RST/ */
-#define SSTAT1_SDP		0x01	/* Instant readout of SDP/ */
-
-#define SSTAT2_REG		0x0f	/* SCSI status 2 ro */
-#define SSTAT2_FF3		0x80 	/* number of bytes in synchronous */
-#define SSTAT2_FF2		0x40	/* data FIFO */
-#define SSTAT2_FF1		0x20	
-#define SSTAT2_FF0		0x10
-#define SSTAT2_FF_MASK		0xf0
-#define SSTAT2_FF_SHIFT		4
-
-/* 
- * Latched signals, latched on the leading edge of REQ/ for initiators,
- * ACK/ for targets.
- */
-#define SSTAT2_SDP		0x08	/* SDP */
-#define SSTAT2_MSG		0x04	/* MSG */
-#define SSTAT2_CD		0x02	/* C/D */
-#define SSTAT2_IO		0x01	/* I/O */
-#define SSTAT2_PHASE_CMDOUT	SSTAT2_CD
-#define SSTAT2_PHASE_DATAIN	SSTAT2_IO
-#define SSTAT2_PHASE_DATAOUT	0
-#define SSTAT2_PHASE_MSGIN	(SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-#define SSTAT2_PHASE_MSGOUT	(SSTAT2_CD|SSTAT2_MSG)
-#define SSTAT2_PHASE_STATIN	(SSTAT2_CD|SSTAT2_IO)
-#define SSTAT2_PHASE_MASK	(SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHA_REG_00		0x10    /* through  0x13 Scratch A rw */
-/* NCR53c710 and higher */
-#define DSA_REG			0x10	/* DATA structure address */
-
-#define CTEST0_REG_700		0x14	/* Chip test 0 ro */
-#define CTEST0_REG_800		0x18	/* Chip test 0 rw, general purpose */
-/* 0x80 - 0x04 are reserved */
-#define CTEST0_700_RTRG		0x02	/* Real target mode */
-#define CTEST0_700_DDIR		0x01	/* Data direction, 1 = 
-					 * SCSI bus to host, 0  =
-					 * host to SCSI.
-					 */
-
-#define CTEST1_REG_700		0x15	/* Chip test 1 ro */
-#define CTEST1_REG_800		0x19	/* Chip test 1 ro */
-#define CTEST1_FMT3		0x80	/* Identify which byte lanes are empty */
-#define CTEST1_FMT2		0x40 	/* in the DMA FIFO */
-#define CTEST1_FMT1		0x20
-#define CTEST1_FMT0		0x10
-
-#define CTEST1_FFL3		0x08	/* Identify which bytes lanes are full */
-#define CTEST1_FFL2		0x04	/* in the DMA FIFO */
-#define CTEST1_FFL1		0x02
-#define CTEST1_FFL0		0x01
-
-#define CTEST2_REG_700		0x16	/* Chip test 2 ro */
-#define CTEST2_REG_800		0x1a	/* Chip test 2 ro */
-
-#define CTEST2_800_DDIR		0x80	/* 1 = SCSI->host */
-#define CTEST2_800_SIGP		0x40	/* A copy of SIGP in ISTAT.
-					   Reading this register clears */
-#define CTEST2_800_CIO		0x20	/* Configured as IO */.
-#define CTEST2_800_CM		0x10	/* Configured as memory */
-
-/* 0x80 - 0x40 are reserved on 700 series chips */
-#define CTEST2_700_SOFF		0x20	/* SCSI Offset Compare,
-					 * As an initiator, this bit is 
-					 * one when the synchronous offset
-					 * is zero, as a target this bit 
-					 * is one when the synchronous 
-					 * offset is at the maximum
-					 * defined in SXFER
-					 */
-#define CTEST2_700_SFP		0x10	/* SCSI FIFO parity bit,
-					 * reading CTEST3 unloads a byte
-					 * from the FIFO and sets this
-					 */
-#define CTEST2_700_DFP		0x08	/* DMA FIFO parity bit,
-					 * reading CTEST6 unloads a byte
-					 * from the FIFO and sets this
-					 */
-#define CTEST2_TEOP		0x04	/* SCSI true end of process,
-					 * indicates a totally finished
-					 * transfer
-					 */
-#define CTEST2_DREQ		0x02	/* Data request signal */
-/* 0x01 is reserved on 700 series chips */
-#define CTEST2_800_DACK		0x01	
-
-/* 
- * Chip test 3 ro 
- * Unloads the bottom byte of the eight deep SCSI synchronous FIFO,
- * check SSTAT2 FIFO full bits to determine size.  Note that a GROSS
- * error results if a read is attempted on this register.  Also note 
- * that 16 and 32 bit reads of this register will cause corruption.
- */
-#define CTEST3_REG_700		0x17	
-/*  Chip test 3 rw */
-#define CTEST3_REG_800		0x1b
-#define CTEST3_800_V3		0x80	/* Chip revision */
-#define CTEST3_800_V2		0x40
-#define CTEST3_800_V1		0x20
-#define CTEST3_800_V0		0x10
-#define CTEST3_800_FLF		0x08	/* Flush DMA FIFO */
-#define CTEST3_800_CLF		0x04	/* Clear DMA FIFO */
-#define CTEST3_800_FM		0x02	/* Fetch mode pin */
-/* bit 0 is reserved on 800 series chips */
-
-#define CTEST4_REG_700		0x18	/* Chip test 4 rw */
-#define CTEST4_REG_800		0x21	/* Chip test 4 rw */
-/* 0x80 is reserved on 700 series chips */
-#define CTEST4_800_BDIS		0x80	/* Burst mode disable */
-#define CTEST4_ZMOD		0x40	/* High impedance mode */
-#define CTEST4_SZM		0x20	/* SCSI bus high impedance */
-#define CTEST4_700_SLBE		0x10	/* SCSI loopback enabled */
-#define CTEST4_800_SRTM		0x10	/* Shadow Register Test Mode */
-#define CTEST4_700_SFWR		0x08	/* SCSI FIFO write enable, 
-					 * redirects writes from SODL
-					 * to the SCSI FIFO.
-					 */
-#define CTEST4_800_MPEE		0x08	/* Enable parity checking
-					   during master cycles on PCI
-					   bus */
-
-/* 
- * These bits send the contents of the CTEST6 register to the appropriate
- * byte lane of the 32 bit DMA FIFO.  Normal operation is zero, otherwise 
- * the high bit means the low two bits select the byte lane.
- */
-#define CTEST4_FBL2		0x04	
-#define CTEST4_FBL1		0x02
-#define CTEST4_FBL0		0x01	
-#define CTEST4_FBL_MASK		0x07
-#define CTEST4_FBL_0		0x04	/* Select DMA FIFO byte lane 0 */
-#define CTEST4_FBL_1		0x05	/* Select DMA FIFO byte lane 1 */
-#define CTEST4_FBL_2		0x06	/* Select DMA FIFO byte lane 2 */
-#define CTEST4_FBL_3		0x07	/* Select DMA FIFO byte lane 3 */
-#define CTEST4_800_SAVE		(CTEST4_800_BDIS)
-
-
-#define CTEST5_REG_700		0x19	/* Chip test 5 rw */
-#define CTEST5_REG_800		0x22	/* Chip test 5 rw */
-/* 
- * Clock Address Incrementor.  When set, it increments the 
- * DNAD register to the next bus size boundary.  It automatically 
- * resets itself when the operation is complete.
- */
-#define CTEST5_ADCK		0x80
-/*
- * Clock Byte Counter.  When set, it decrements the DBC register to
- * the next bus size boundary.
- */
-#define CTEST5_BBCK		0x40
-/*
- * Reset SCSI Offset.  Setting this bit to 1 clears the current offset
- * pointer in the SCSI synchronous offset counter (SSTAT).  This bit
- * is set to 1 if a SCSI Gross Error Condition occurs.  The offset should
- * be cleared when a synchronous transfer fails.  When written, it is 
- * automatically cleared after the SCSI synchronous offset counter is 
- * reset.
- */
-/* Bit 5 is reserved on 800 series chips */
-#define CTEST5_700_ROFF		0x20
-/* 
- * Master Control for Set or Reset pulses. When 1, causes the low 
- * four bits of register to set when set, 0 causes the low bits to
- * clear when set.
- */
-#define CTEST5_MASR 		0x10	
-#define CTEST5_DDIR		0x08	/* DMA direction */
-/*
- * Bits 2-0 are reserved on 800 series chips
- */
-#define CTEST5_700_EOP		0x04	/* End of process */
-#define CTEST5_700_DREQ		0x02	/* Data request */
-#define CTEST5_700_DACK		0x01	/* Data acknowledge */
-
-/* 
- * Chip test 6 rw - writing to this register writes to the byte 
- * lane in the DMA FIFO as determined by the FBL bits in the CTEST4
- * register.
- */
-#define CTEST6_REG_700		0x1a
-#define CTEST6_REG_800		0x23
-
-#define CTEST7_REG		0x1b	/* Chip test 7 rw */
-/* 0x80 - 0x40 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define CTEST7_10_CDIS		0x80	/* Cache burst disable */
-#define CTEST7_10_SC1		0x40	/* Snoop control bits */
-#define CTEST7_10_SC0		0x20	
-#define CTEST7_10_SC_MASK	0x60
-/* 0x20 is reserved on the NCR53c700 */
-#define CTEST7_0060_FM		0x20	/* Fetch mode */
-#define CTEST7_STD		0x10	/* Selection timeout disable */
-#define CTEST7_DFP		0x08	/* DMA FIFO parity bit for CTEST6 */
-#define CTEST7_EVP		0x04	/* 1 = host bus even parity, 0 = odd */
-#define CTEST7_10_TT1		0x02	/* Transfer type */
-#define CTEST7_00_DC		0x02	/* Set to drive DC low during instruction 
-					   fetch */
-#define CTEST7_DIFF		0x01	/* Differential mode */
-
-#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF )
-
-
-#define TEMP_REG		0x1c	/* through 0x1f Temporary stack rw */
-
-#define DFIFO_REG		0x20	/* DMA FIFO rw */
-/* 
- * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been
- * moved into the CTEST8 register.
- */
-#define DFIFO_00_FLF		0x80	/* Flush DMA FIFO to memory */
-#define DFIFO_00_CLF		0x40	/* Clear DMA and SCSI FIFOs */
-#define DFIFO_BO6		0x40
-#define DFIFO_BO5		0x20
-#define DFIFO_BO4		0x10
-#define DFIFO_BO3		0x08
-#define DFIFO_BO2		0x04 
-#define DFIFO_BO1		0x02
-#define DFIFO_BO0		0x01
-#define DFIFO_10_BO_MASK	0x7f	/* 7 bit counter */
-#define DFIFO_00_BO_MASK	0x3f	/* 6 bit counter */
-
-/* 
- * Interrupt status rw 
- * Note that this is the only register which can be read while SCSI
- * SCRIPTS are being executed.
- */
-#define ISTAT_REG_700		0x21
-#define ISTAT_REG_800		0x14
-#define ISTAT_ABRT		0x80	/* Software abort, write 
-					 *1 to abort, wait for interrupt. */
-/* 0x40 and 0x20 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define ISTAT_10_SRST		0x40	/* software reset */
-#define ISTAT_10_SIGP		0x20	/* signal script */
-/* 0x10 is reserved on NCR53c700 series chips */
-#define ISTAT_800_SEM		0x10	/* semaphore */
-#define ISTAT_CON		0x08	/* 1 when connected */
-#define ISTAT_800_INTF		0x04	/* Interrupt on the fly */
-#define ISTAT_700_PRE		0x04	/* Pointer register empty.
-					 * Set to 1 when DSPS and DSP
-					 * registers are empty in pipeline
-					 * mode, always set otherwise.
-					 */
-#define ISTAT_SIP		0x02	/* SCSI interrupt pending from
-					 * SCSI portion of SIOP see
-					 * SSTAT0
-					 */
-#define ISTAT_DIP		0x01	/* DMA interrupt pending 
-					 * see DSTAT
-					 */
-
-/* NCR53c700-66 and NCR53c710 only */
-#define CTEST8_REG		0x22	/* Chip test 8 rw */
-#define CTEST8_0066_EAS		0x80	/* Enable alternate SCSI clock,
-					 * ie read from SCLK/ rather than CLK/
-					 */
-#define CTEST8_0066_EFM		0x40	/* Enable fetch and master outputs */
-#define CTEST8_0066_GRP		0x20	/* Generate Receive Parity for 
-					 * pass through.  This insures that 
-					 * bad parity won't reach the host 
-					 * bus.
-					 */
-#define CTEST8_0066_TE		0x10	/* TolerANT enable.  Enable 
-					 * active negation, should only
-					 * be used for slow SCSI 
-					 * non-differential.
-					 */
-#define CTEST8_0066_HSC		0x08	/* Halt SCSI clock */
-#define CTEST8_0066_SRA		0x04	/* Shorten REQ/ACK filtering,
-					 * must be set for fast SCSI-II
-					 * speeds.
-					 */
-#define CTEST8_0066_DAS		0x02	/* Disable automatic target/initiator
-					 * switching.
-					 */
-#define CTEST8_0066_LDE		0x01	/* Last disconnect enable.
-					 * The status of pending 
-					 * disconnect is maintained by
-					 * the core, eliminating
-					 * the possibility of missing a 
-					 * selection or reselection
-					 * while waiting to fetch a 
-					 * WAIT DISCONNECT opcode.
-					 */
-
-#define CTEST8_10_V3		0x80	/* Chip revision */
-#define CTEST8_10_V2		0x40
-#define CTEST8_10_V1		0x20	
-#define CTEST8_10_V0		0x10
-#define CTEST8_10_V_MASK	0xf0	
-#define CTEST8_10_FLF		0x08	/* Flush FIFOs */
-#define CTEST8_10_CLF		0x04	/* Clear FIFOs */
-#define CTEST8_10_FM		0x02	/* Fetch pin mode */
-#define CTEST8_10_SM		0x01	/* Snoop pin mode */
-
-
-/* 
- * The CTEST9 register may be used to differentiate between a
- * NCR53c700 and a NCR53c710.  
- *
- * Write 0xff to this register.
- * Read it.
- * If the contents are 0xff, it is a NCR53c700
- * If the contents are 0x00, it is a NCR53c700-66 first revision
- * If the contents are some other value, it is some other NCR53c700-66
- */
-#define CTEST9_REG_00		0x23	/* Chip test 9 ro */
-#define LCRC_REG_10		0x23	
-
-/*
- * 0x24 through 0x27 are the DMA byte counter register.  Instructions
- * write their high 8 bits into the DCMD register, the low 24 bits into
- * the DBC register.
- *
- * Function is dependent on the command type being executed.
- */
-
- 
-#define DBC_REG			0x24
-/* 
- * For Block Move Instructions, DBC is a 24 bit quantity representing 
- *     the number of bytes to transfer.
- * For Transfer Control Instructions, DBC is bit fielded as follows : 
- */
-/* Bits 20 - 23 should be clear */
-#define DBC_TCI_TRUE		(1 << 19) 	/* Jump when true */
-#define DBC_TCI_COMPARE_DATA	(1 << 18)	/* Compare data */
-#define DBC_TCI_COMPARE_PHASE	(1 << 17)	/* Compare phase with DCMD field */
-#define DBC_TCI_WAIT_FOR_VALID	(1 << 16)	/* Wait for REQ */
-/* Bits 8 - 15 are reserved on some implementations ? */
-#define DBC_TCI_MASK_MASK	0xff00 		/* Mask for data compare */
-#define DBC_TCI_MASK_SHIFT	8
-#define DBC_TCI_DATA_MASK	0xff		/* Data to be compared */ 
-#define DBC_TCI_DATA_SHIFT	0
-
-#define DBC_RWRI_IMMEDIATE_MASK	0xff00		/* Immediate data */
-#define DBC_RWRI_IMMEDIATE_SHIFT 8		/* Amount to shift */
-#define DBC_RWRI_ADDRESS_MASK	0x3f0000	/* Register address */
-#define DBC_RWRI_ADDRESS_SHIFT 	16
-
-
-/*
- * DMA command r/w
- */
-#define DCMD_REG		0x27	
-#define DCMD_TYPE_MASK		0xc0	/* Masks off type */
-#define DCMD_TYPE_BMI		0x00	/* Indicates a Block Move instruction */
-#define DCMD_BMI_IO		0x01	/* I/O, CD, and MSG bits selecting   */
-#define DCMD_BMI_CD		0x02	/* the phase for the block MOVE      */
-#define DCMD_BMI_MSG		0x04	/* instruction 			     */
-
-#define DCMD_BMI_OP_MASK	0x18	/* mask for opcode */
-#define DCMD_BMI_OP_MOVE_T	0x00	/* MOVE */
-#define DCMD_BMI_OP_MOVE_I	0x08	/* MOVE Initiator */
-
-#define DCMD_BMI_INDIRECT	0x20	/*  Indirect addressing */
-
-#define DCMD_TYPE_TCI		0x80	/* Indicates a Transfer Control 
-					   instruction */
-#define DCMD_TCI_IO		0x01	/* I/O, CD, and MSG bits selecting   */
-#define DCMD_TCI_CD		0x02	/* the phase for the block MOVE      */
-#define DCMD_TCI_MSG		0x04	/* instruction 			     */
-#define DCMD_TCI_OP_MASK	0x38	/* mask for opcode */
-#define DCMD_TCI_OP_JUMP	0x00	/* JUMP */
-#define DCMD_TCI_OP_CALL	0x08	/* CALL */
-#define DCMD_TCI_OP_RETURN	0x10	/* RETURN */
-#define DCMD_TCI_OP_INT		0x18	/* INT */
-
-#define DCMD_TYPE_RWRI		0x40	/* Indicates I/O or register Read/Write
-					   instruction */
-#define DCMD_RWRI_OPC_MASK	0x38	/* Opcode mask */
-#define DCMD_RWRI_OPC_WRITE	0x28	/* Write SFBR to register */
-#define DCMD_RWRI_OPC_READ	0x30	/* Read register to SFBR */
-#define DCMD_RWRI_OPC_MODIFY	0x38	/* Modify in place */
-
-#define DCMD_RWRI_OP_MASK	0x07
-#define DCMD_RWRI_OP_MOVE	0x00
-#define DCMD_RWRI_OP_SHL	0x01
-#define DCMD_RWRI_OP_OR		0x02
-#define DCMD_RWRI_OP_XOR	0x03
-#define DCMD_RWRI_OP_AND	0x04
-#define DCMD_RWRI_OP_SHR	0x05
-#define DCMD_RWRI_OP_ADD	0x06
-#define DCMD_RWRI_OP_ADDC	0x07
-
-#define DCMD_TYPE_MMI		0xc0	/* Indicates a Memory Move instruction 
-					   (three words) */
-
-
-#define DNAD_REG		0x28	/* through 0x2b DMA next address for 
-					   data */
-#define DSP_REG			0x2c	/* through 0x2f DMA SCRIPTS pointer rw */
-#define DSPS_REG		0x30	/* through 0x33 DMA SCRIPTS pointer 
-					   save rw */
-#define DMODE_REG_00		0x34 	/* DMA mode rw */
-#define DMODE_00_BL1	0x80	/* Burst length bits */
-#define DMODE_00_BL0	0x40
-#define DMODE_BL_MASK	0xc0
-/* Burst lengths (800) */
-#define DMODE_BL_2	0x00	/* 2 transfer */
-#define DMODE_BL_4	0x40	/* 4 transfers */
-#define DMODE_BL_8	0x80	/* 8 transfers */
-#define DMODE_BL_16	0xc0	/* 16 transfers */
-
-#define DMODE_700_BW16	0x20	/* Host buswidth = 16 */
-#define DMODE_700_286	0x10	/* 286 mode */
-#define DMODE_700_IOM	0x08	/* Transfer to IO port */
-#define DMODE_700_FAM	0x04	/* Fixed address mode */
-#define DMODE_700_PIPE	0x02	/* Pipeline mode disables 
-					 * automatic fetch / exec 
-					 */
-#define DMODE_MAN	0x01		/* Manual start mode, 
-					 * requires a 1 to be written
-					 * to the start DMA bit in the DCNTL
-					 * register to run scripts 
-					 */
-
-#define DMODE_700_SAVE ( DMODE_00_BL_MASK | DMODE_00_BW16 | DMODE_00_286 )
-
-/* NCR53c800 series only */
-#define SCRATCHA_REG_800	0x34	/* through 0x37 Scratch A rw */
-/* NCR53c710 only */
-#define SCRATCB_REG_10		0x34	/* through 0x37 scratch B rw */
-
-#define DMODE_REG_10    	0x38	/* DMA mode rw, NCR53c710 and newer */
-#define DMODE_800_SIOM		0x20	/* Source IO = 1 */
-#define DMODE_800_DIOM		0x10	/* Destination IO = 1 */
-#define DMODE_800_ERL		0x08	/* Enable Read Line */
-
-/* 35-38 are reserved on 700 and 700-66 series chips */
-#define DIEN_REG		0x39	/* DMA interrupt enable rw */
-/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */
-#define DIEN_800_MDPE		0x40	/* Master data parity error */
-#define DIEN_800_BF		0x20	/* BUS fault */
-#define DIEN_ABRT		0x10	/* Enable aborted interrupt */
-#define DIEN_SSI		0x08	/* Enable single step interrupt */
-#define DIEN_SIR		0x04	/* Enable SCRIPTS INT command 
-					 * interrupt
-					 */
-/* 0x02 is reserved on 800 series chips */
-#define DIEN_700_WTD		0x02	/* Enable watchdog timeout interrupt */
-#define DIEN_700_OPC		0x01	/* Enable illegal instruction 
-					 * interrupt 
-					 */
-#define DIEN_800_IID		0x01	/*  Same meaning, different name */ 
-
-/*
- * DMA watchdog timer rw
- * set in 16 CLK input periods.
- */
-#define DWT_REG			0x3a
-
-/* DMA control rw */
-#define DCNTL_REG		0x3b
-#define DCNTL_700_CF1		0x80	/* Clock divisor bits */
-#define DCNTL_700_CF0		0x40
-#define DCNTL_700_CF_MASK	0xc0
-/* Clock divisors 			   Divisor SCLK range (MHZ) */
-#define DCNTL_700_CF_2		0x00    /* 2.0	   37.51-50.00 */
-#define DCNTL_700_CF_1_5	0x40	/* 1.5	   25.01-37.50 */
-#define DCNTL_700_CF_1		0x80	/* 1.0     16.67-25.00 */
-#define DCNTL_700_CF_3		0xc0	/* 3.0	   50.01-66.67 (53c700-66) */
-
-#define DCNTL_700_S16		0x20	/* Load scripts 16 bits at a time */
-#define DCNTL_SSM		0x10	/* Single step mode */
-#define DCNTL_700_LLM		0x08	/* Low level mode, can only be set 
-					 * after selection */
-#define DCNTL_800_IRQM		0x08	/* Totem pole IRQ pin */
-#define DCNTL_STD		0x04	/* Start DMA / SCRIPTS */
-/* 0x02 is reserved */
-#define DCNTL_00_RST		0x01	/* Software reset, resets everything
-					 * but 286 mode bit  in DMODE. On the
-					 * NCR53c710, this bit moved to CTEST8
-					 */
-#define DCNTL_10_COM		0x01	/* 700 software compatibility mode */
-
-#define DCNTL_700_SAVE ( DCNTL_CF_MASK | DCNTL_S16)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHB_REG_00		0x3c	/* through 0x3f scratch b rw */
-#define SCRATCHB_REG_800	0x5c	/* through 0x5f scratch b rw */
-/* NCR53c710 only */
-#define ADDER_REG_10		0x3c	/* Adder, NCR53c710 only */
-
-#define SIEN1_REG_800		0x41
-#define SIEN1_800_STO		0x04	/* selection/reselection timeout */
-#define SIEN1_800_GEN		0x02	/* general purpose timer */
-#define SIEN1_800_HTH		0x01	/* handshake to handshake */
-
-#define SIST1_REG_800		0x43
-#define SIST1_800_STO		0x04	/* selection/reselection timeout */
-#define SIST1_800_GEN		0x02	/* general purpose timer */
-#define SIST1_800_HTH		0x01	/* handshake to handshake */
-
-#define SLPAR_REG_800		0x44	/* Parity */
-
-#define MACNTL_REG_800		0x46	/* Memory access control */
-#define MACNTL_800_TYP3		0x80
-#define MACNTL_800_TYP2		0x40
-#define MACNTL_800_TYP1		0x20
-#define MACNTL_800_TYP0		0x10
-#define MACNTL_800_DWR		0x08
-#define MACNTL_800_DRD		0x04
-#define MACNTL_800_PSCPT	0x02
-#define MACNTL_800_SCPTS	0x01
-
-#define GPCNTL_REG_800		0x47	/* General Purpose Pin Control */
-
-/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */
-#define STIME0_REG_800		0x48	/* SCSI Timer Register 0 */
-#define STIME0_800_HTH_MASK	0xf0	/* Handshake to Handshake timeout */
-#define STIME0_800_HTH_SHIFT	4
-#define STIME0_800_SEL_MASK	0x0f	/* Selection timeout */
-#define STIME0_800_SEL_SHIFT	0
-
-#define STIME1_REG_800		0x49
-#define STIME1_800_GEN_MASK	0x0f	/* General purpose timer */
-
-#define RESPID_REG_800		0x4a	/* Response ID, bit fielded.  8
-					   bits on narrow chips, 16 on WIDE */
-
-#define STEST0_REG_800		0x4c	
-#define STEST0_800_SLT		0x08	/* Selection response logic test */
-#define STEST0_800_ART		0x04	/* Arbitration priority encoder test */
-#define STEST0_800_SOZ		0x02	/* Synchronous offset zero */
-#define STEST0_800_SOM		0x01	/* Synchronous offset maximum */
-
-#define STEST1_REG_800		0x4d
-#define STEST1_800_SCLK		0x80	/* Disable SCSI clock */
-
-#define STEST2_REG_800		0x4e	
-#define STEST2_800_SCE		0x80	/* Enable SOCL/SODL */
-#define STEST2_800_ROF		0x40	/* Reset SCSI sync offset */
-#define STEST2_800_SLB		0x10	/* Enable SCSI loopback mode */
-#define STEST2_800_SZM		0x08	/* SCSI high impedance mode */
-#define STEST2_800_EXT		0x02	/* Extend REQ/ACK filter 30 to 60ns */
-#define STEST2_800_LOW		0x01	/* SCSI low level mode */
-
-#define STEST3_REG_800		0x4f	 
-#define STEST3_800_TE		0x80	/* Enable active negation */
-#define STEST3_800_STR		0x40	/* SCSI FIFO test read */
-#define STEST3_800_HSC		0x20	/* Halt SCSI clock */
-#define STEST3_800_DSI		0x10	/* Disable single initiator response */
-#define STEST3_800_TTM		0x04	/* Time test mode */
-#define STEST3_800_CSF		0x02	/* Clear SCSI FIFO */
-#define STEST3_800_STW		0x01	/* SCSI FIFO test write */
-
-#define OPTION_PARITY 		0x1	/* Enable parity checking */
-#define OPTION_TAGGED_QUEUE	0x2	/* Enable SCSI-II tagged queuing */
-#define OPTION_700		0x8	/* Always run NCR53c700 scripts */
-#define OPTION_INTFLY		0x10	/* Use INTFLY interrupts */
-#define OPTION_DEBUG_INTR	0x20	/* Debug interrupts */
-#define OPTION_DEBUG_INIT_ONLY	0x40	/* Run initialization code and 
-					   simple test code, return
-					   DID_NO_CONNECT if any SCSI
-					   commands are attempted. */
-#define OPTION_DEBUG_READ_ONLY	0x80	/* Return DID_ERROR if any 
-					   SCSI write is attempted */
-#define OPTION_DEBUG_TRACE	0x100	/* Animated trace mode, print 
-					   each address and instruction 
-					   executed to debug buffer. */
-#define OPTION_DEBUG_SINGLE	0x200	/* stop after executing one 
-					   instruction */
-#define OPTION_SYNCHRONOUS	0x400	/* Enable sync SCSI.  */
-#define OPTION_MEMORY_MAPPED	0x800	/* NCR registers have valid 
-					   memory mapping */
-#define OPTION_IO_MAPPED	0x1000  /* NCR registers have valid
-					     I/O mapping */
-#define OPTION_DEBUG_PROBE_ONLY	0x2000  /* Probe only, don't even init */
-#define OPTION_DEBUG_TESTS_ONLY	0x4000  /* Probe, init, run selected tests */
-#define OPTION_DEBUG_TEST0	0x08000 /* Run test 0 */
-#define OPTION_DEBUG_TEST1	0x10000 /* Run test 1 */
-#define OPTION_DEBUG_TEST2	0x20000 /* Run test 2 */
-#define OPTION_DEBUG_DUMP	0x40000 /* Dump commands */
-#define OPTION_DEBUG_TARGET_LIMIT 0x80000 /* Only talk to target+luns specified */
-#define OPTION_DEBUG_NCOMMANDS_LIMIT 0x100000 /* Limit the number of commands */
-#define OPTION_DEBUG_SCRIPT 0x200000 /* Print when checkpoints are passed */
-#define OPTION_DEBUG_FIXUP 0x400000 /* print fixup values */
-#define OPTION_DEBUG_DSA 0x800000
-#define OPTION_DEBUG_CORRUPTION	0x1000000	/* Detect script corruption */
-#define OPTION_DEBUG_SDTR       0x2000000	/* Debug SDTR problem */
-#define OPTION_DEBUG_MISMATCH 	0x4000000 	/* Debug phase mismatches */
-#define OPTION_DISCONNECT	0x8000000	/* Allow disconnect */
-#define OPTION_DEBUG_DISCONNECT 0x10000000	
-#define OPTION_ALWAYS_SYNCHRONOUS 0x20000000	/* Negotiate sync. transfers
-						   on power up */
-#define OPTION_DEBUG_QUEUES	0x80000000	
-#define OPTION_DEBUG_ALLOCATION 0x100000000LL
-#define OPTION_DEBUG_SYNCHRONOUS 0x200000000LL	/* Sanity check SXFER and 
-						   SCNTL3 registers */
-#define OPTION_NO_ASYNC	0x400000000LL		/* Don't automagically send
-						   SDTR for async transfers when
-						   we haven't been told to do
-						   a synchronous transfer. */
-#define OPTION_NO_PRINT_RACE 0x800000000LL	/* Don't print message when
-						   the reselect/WAIT DISCONNECT
-						   race condition hits */
-#if !defined(PERM_OPTIONS)
-#define PERM_OPTIONS 0
-#endif
-				
-struct NCR53c7x0_synchronous {
-    u32 select_indirect;		/* Value used for indirect selection */
-    u32 script[8];			/* Size ?? Script used when target is 
-						reselected */
-    unsigned char synchronous_want[5];	/* Per target desired SDTR */
-/* 
- * Set_synchronous programs these, select_indirect and current settings after
- * int_debug_should show a match.
- */
-    unsigned char sxfer_sanity, scntl3_sanity;
-};
-
-#define CMD_FLAG_SDTR 		1	/* Initiating synchronous 
-					   transfer negotiation */
-#define CMD_FLAG_WDTR		2	/* Initiating wide transfer
-					   negotiation */
-#define CMD_FLAG_DID_SDTR	4	/* did SDTR */
-#define CMD_FLAG_DID_WDTR	8	/* did WDTR */
-
-struct NCR53c7x0_table_indirect {
-    u32 count;
-    void *address;
-};
-
-enum ncr_event { 
-    EVENT_NONE = 0,
-/* 
- * Order is IMPORTANT, since these must correspond to the event interrupts
- * in 53c7,8xx.scr 
- */
-
-    EVENT_ISSUE_QUEUE = 0x5000000,	/* Command was added to issue queue */
-    EVENT_START_QUEUE,			/* Command moved to start queue */
-    EVENT_SELECT,			/* Command completed selection */
-    EVENT_DISCONNECT,			/* Command disconnected */
-    EVENT_RESELECT,			/* Command reselected */
-    EVENT_COMPLETE,		        /* Command completed */
-    EVENT_IDLE,
-    EVENT_SELECT_FAILED,
-    EVENT_BEFORE_SELECT,
-    EVENT_RESELECT_FAILED
-};
-
-struct NCR53c7x0_event {
-    enum ncr_event event;	/* What type of event */
-    unsigned char target;
-    unsigned char lun;
-    struct timeval time;	
-    u32 *dsa;			/* What's in the DSA register now (virt) */
-/* 
- * A few things from that SCSI pid so we know what happened after 
- * the Scsi_Cmnd structure in question may have disappeared.
- */
-    unsigned long pid;		/* The SCSI PID which caused this 
-				   event */
-    unsigned char cmnd[12];
-};
-
-/*
- * Things in the NCR53c7x0_cmd structure are split into two parts :
- *
- * 1.  A fixed portion, for things which are not accessed directly by static NCR
- *	code (ie, are referenced only by the Linux side of the driver,
- *	or only by dynamically generated code).  
- *
- * 2.  The DSA portion, for things which are accessed directly by static NCR
- *	code.
- *
- * This is a little ugly, but it 
- * 1.  Avoids conflicts between the NCR code's picture of the structure, and 
- * 	Linux code's idea of what it looks like.
- *
- * 2.  Minimizes the pain in the Linux side of the code needed 
- * 	to calculate real dsa locations for things, etc.
- * 
- */
-
-struct NCR53c7x0_cmd {
-    void *real;				/* Real, unaligned address for
-					   free function */
-    void (* free)(void *, int);		/* Command to deallocate; NULL
-					   for structures allocated with
-					   scsi_register, etc. */
-    Scsi_Cmnd *cmd;			/* Associated Scsi_Cmnd 
-					   structure, Scsi_Cmnd points
-					   at NCR53c7x0_cmd using 
-					   host_scribble structure */
-
-    int size;				/* scsi_malloc'd size of this 
-					   structure */
-
-    int flags;				/* CMD_* flags */
-
-/*
- * SDTR and WIDE messages are an either/or affair
- * in this message, since we will go into message out and send
- * _the whole mess_ without dropping out of message out to 
- * let the target go into message in after sending the first 
- * message.
- */
-
-    unsigned char select[11];		/* Select message, includes
-					   IDENTIFY
-					   (optional) QUEUE TAG
- 				 	   (optional) SDTR or WDTR
-					 */
-
-
-    volatile struct NCR53c7x0_cmd *next; /* Linux maintained lists (free,
-					    running, eventually finished */
-    					 
-
-    u32 *data_transfer_start;		/* Start of data transfer routines */
-    u32 *data_transfer_end;		/* Address after end of data transfer o
-    	    	    	    	    	   routines */
-/* 
- * The following three fields were moved from the DSA proper to here
- * since only dynamically generated NCR code refers to them, meaning
- * we don't need dsa_* absolutes, and it is simpler to let the 
- * host code refer to them directly.
- */
-
-/* 
- * HARD CODED : residual and saved_residual need to agree with the sizes
- * used in NCR53c7,8xx.scr.  
- * 
- * FIXME: we want to consider the case where we have odd-length 
- *	scatter/gather buffers and a WIDE transfer, in which case 
- *	we'll need to use the CHAIN MOVE instruction.  Ick.
- */
-    u32 residual[6];			/* Residual data transfer which
-					   allows pointer code to work
-					   right.
-
-    	    	    	    	    	    [0-1] : Conditional call to 
-    	    	    	    	    	    	appropriate other transfer 
-    	    	    	    	    	    	routine.
-    	    	    	    	    	    [2-3] : Residual block transfer
-    	    	    	    	    	    	instruction.
-    	    	    	    	    	    [4-5] : Jump to instruction
-    	    	    	    	    	    	after splice.
-					 */
-    u32 saved_residual[6]; 		/* Copy of old residual, so we 
-					   can get another partial 
-					   transfer and still recover 
-    	    	    	    	    	 */
-    	    	
-    u32 saved_data_pointer;		/* Saved data pointer */
-
-    u32 dsa_next_addr;		        /* _Address_ of dsa_next field  
-					   in this dsa for RISCy 
-					   style constant. */
-
-    u32 dsa_addr;			/* Address of dsa; RISCy style
-					   constant */
-
-    u32 dsa[0];				/* Variable length (depending
-					   on host type, number of scatter /
-					   gather buffers, etc).  */
-};
-
-struct NCR53c7x0_break {
-    u32 *address, old_instruction[2];
-    struct NCR53c7x0_break *next;
-    unsigned char old_size;		/* Size of old instruction */
-};
-
-/* Indicates that the NCR is not executing code */
-#define STATE_HALTED	0		
-/* 
- * Indicates that the NCR is executing the wait for select / reselect 
- * script.  Only used when running NCR53c700 compatible scripts, only 
- * state during which an ABORT is _not_ considered an error condition.
- */
-#define STATE_WAITING	1		
-/* Indicates that the NCR is executing other code. */
-#define STATE_RUNNING	2		
-/* 
- * Indicates that the NCR was being aborted.
- */
-#define STATE_ABORTING	3
-/* Indicates that the NCR was successfully aborted. */
-#define STATE_ABORTED 4
-/* Indicates that the NCR has been disabled due to a fatal error */
-#define STATE_DISABLED 5
-
-/* 
- * Where knowledge of SCSI SCRIPT(tm) specified values are needed 
- * in an interrupt handler, an interrupt handler exists for each 
- * different SCSI script so we don't have name space problems.
- * 
- * Return values of these handlers are as follows : 
- */
-#define SPECIFIC_INT_NOTHING 	0	/* don't even restart */
-#define SPECIFIC_INT_RESTART	1	/* restart at the next instruction */
-#define SPECIFIC_INT_ABORT	2	/* recoverable error, abort cmd */
-#define SPECIFIC_INT_PANIC	3	/* unrecoverable error, panic */
-#define SPECIFIC_INT_DONE	4	/* normal command completion */
-#define SPECIFIC_INT_BREAK	5	/* break point encountered */
-
-struct NCR53c7x0_hostdata {
-    int size;				/* Size of entire Scsi_Host
-					   structure */
-    int board;				/* set to board type, useful if 
-					   we have host specific things,
-					   ie, a general purpose I/O 
-					   bit is being used to enable
-					   termination, etc. */
-
-    int chip;				/* set to chip type; 700-66 is
-					   700-66, rest are last three
-					   digits of part number */
-    /*
-     * PCI device, only for NCR53c8x0 chips.
-     * pci_valid indicates that the PCI configuration information
-     * is valid, and we can twiddle MAX_LAT, etc. as recommended
-     * for maximum performance in the NCR documentation.
-     */
-    struct pci_dev *pci_dev;
-    unsigned pci_valid:1;
-
-    u32 *dsp;				/* dsp to restart with after
-					   all stacked interrupts are
-					   handled. */
-
-    unsigned dsp_changed:1;		/* Has dsp changed within this
-					   set of stacked interrupts ? */
-
-    unsigned char dstat;		/* Most recent value of dstat */
-    unsigned dstat_valid:1;
-
-    unsigned expecting_iid:1;		/* Expect IID interrupt */
-    unsigned expecting_sto:1;		/* Expect STO interrupt */
-    
-    /* 
-     * The code stays cleaner if we use variables with function
-     * pointers and offsets that are unique for the different
-     * scripts rather than having a slew of switch(hostdata->chip) 
-     * statements.
-     * 
-     * It also means that the #defines from the SCSI SCRIPTS(tm)
-     * don't have to be visible outside of the script-specific
-     * instructions, preventing name space pollution.
-     */
-
-    void (* init_fixup)(struct Scsi_Host *host);
-    void (* init_save_regs)(struct Scsi_Host *host);
-    void (* dsa_fixup)(struct NCR53c7x0_cmd *cmd);
-    void (* soft_reset)(struct Scsi_Host *host);
-    int (* run_tests)(struct Scsi_Host *host);
-
-    /*
-     * Called when DSTAT_SIR is set, indicating an interrupt generated
-     * by the INT instruction, where values are unique for each SCSI
-     * script.  Should return one of the SPEC_* values.
-     */
-
-    int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-
-    int dsa_len; /* Size of DSA structure */
-
-    /*
-     * Location of DSA fields for the SCSI SCRIPT corresponding to this 
-     * chip.  
-     */
-
-    s32 dsa_start;			
-    s32 dsa_end;			
-    s32 dsa_next;
-    s32 dsa_prev;
-    s32 dsa_cmnd;
-    s32 dsa_select;
-    s32 dsa_msgout;
-    s32 dsa_cmdout;
-    s32 dsa_dataout;
-    s32 dsa_datain;
-    s32 dsa_msgin;
-    s32 dsa_msgout_other;
-    s32 dsa_write_sync;
-    s32 dsa_write_resume;
-    s32 dsa_check_reselect;
-    s32 dsa_status;
-    s32 dsa_saved_pointer;
-    s32 dsa_jump_dest;
-
-    /* 
-     * Important entry points that generic fixup code needs
-     * to know about, fixed up.
-     */
-
-    s32 E_accept_message;
-    s32 E_command_complete;		
-    s32 E_data_transfer;
-    s32 E_dsa_code_template;
-    s32 E_dsa_code_template_end;
-    s32 E_end_data_transfer;
-    s32 E_msg_in;
-    s32 E_initiator_abort;
-    s32 E_other_transfer;
-    s32 E_other_in;
-    s32 E_other_out;
-    s32 E_target_abort;
-    s32 E_debug_break;	
-    s32 E_reject_message;
-    s32 E_respond_message;
-    s32 E_select;
-    s32 E_select_msgout;
-    s32 E_test_0;
-    s32 E_test_1;
-    s32 E_test_2;
-    s32 E_test_3;
-    s32 E_dsa_zero;
-    s32 E_cmdout_cmdout;
-    s32 E_wait_reselect;
-    s32 E_dsa_code_begin;
-
-    long long options;			/* Bitfielded set of options enabled */
-    volatile u32 test_completed;	/* Test completed */
-    int test_running;			/* Test currently running */
-    s32 test_source;
-    volatile s32 test_dest;
-
-    volatile int state;			/* state of driver, only used for 
-					   OPTION_700 */
-
-    unsigned char  dmode;		/* 
-					 * set to the address of the DMODE 
-					 * register for this chip.
-					 */
-    unsigned char istat;		/* 
-    	    	    	    	    	 * set to the address of the ISTAT 
-    	    	    	    	    	 * register for this chip.
-    	    	    	    	    	 */
-  
-    int scsi_clock;			/* 
-					 * SCSI clock in HZ. 0 may be used 
-					 * for unknown, although this will
-					 * disable synchronous negotiation.
-					 */
-
-    volatile int intrs;			/* Number of interrupts */
-    volatile int resets;		/* Number of SCSI resets */
-    unsigned char saved_dmode;	
-    unsigned char saved_ctest4;
-    unsigned char saved_ctest7;
-    unsigned char saved_dcntl;
-    unsigned char saved_scntl3;
-
-    unsigned char this_id_mask;
-
-    /* Debugger information */
-    struct NCR53c7x0_break *breakpoints, /* Linked list of all break points */
-	*breakpoint_current;		/* Current breakpoint being stepped 
-					   through, NULL if we are running 
-					   normally. */
-#ifdef NCR_DEBUG
-    int debug_size;			/* Size of debug buffer */
-    volatile int debug_count;		/* Current data count */
-    volatile char *debug_buf;		/* Output ring buffer */
-    volatile char *debug_write;		/* Current write pointer */
-    volatile char *debug_read;		/* Current read pointer */
-#endif /* def NCR_DEBUG */
-
-    /* XXX - primitive debugging junk, remove when working ? */
-    int debug_print_limit;		/* Number of commands to print
-					   out exhaustive debugging
-					   information for if 
-					   OPTION_DEBUG_DUMP is set */ 
-
-    unsigned char debug_lun_limit[16];	/* If OPTION_DEBUG_TARGET_LIMIT
-					   set, puke if commands are sent
-					   to other target/lun combinations */
-
-    int debug_count_limit;		/* Number of commands to execute
-					   before puking to limit debugging 
-					   output */
-				    
-
-    volatile unsigned idle:1;			/* set to 1 if idle */
-
-    /* 
-     * Table of synchronous+wide transfer parameters set on a per-target
-     * basis.
-     */
-    
-    volatile struct NCR53c7x0_synchronous sync[16];
-
-    volatile Scsi_Cmnd *issue_queue;
-						/* waiting to be issued by
-						   Linux driver */
-    volatile struct NCR53c7x0_cmd *running_list;	
-						/* commands running, maintained
-						   by Linux driver */
-
-    volatile struct NCR53c7x0_cmd *curr;	/* currently connected 
-						   nexus, ONLY valid for
-						   NCR53c700/NCR53c700-66
-						 */
-
-    volatile struct NCR53c7x0_cmd *spare;	/* pointer to spare,
-    	    	    	    	    	    	   allocated at probe time,
-    	    	    	    	    	    	   which we can use for 
-						   initialization */
-    volatile struct NCR53c7x0_cmd *free;
-    int max_cmd_size;				/* Maximum size of NCR53c7x0_cmd
-					    	   based on number of 
-						   scatter/gather segments, etc.
-						   */
-    volatile int num_cmds;			/* Number of commands 
-						   allocated */
-    volatile int extra_allocate;
-    volatile unsigned char cmd_allocated[16];	/* Have we allocated commands
-						   for this target yet?  If not,
-						   do so ASAP */
-    volatile unsigned char busy[16][8];     	/* number of commands 
-						   executing on each target
-    	    	    	    	    	    	 */
-    /* 
-     * Eventually, I'll switch to a coroutine for calling 
-     * cmd->done(cmd), etc. so that we can overlap interrupt
-     * processing with this code for maximum performance.
-     */
-    
-    volatile struct NCR53c7x0_cmd *finished_queue;	
-						
-
-    /* Shared variables between SCRIPT and host driver */
-    volatile u32 *schedule;			/* Array of JUMPs to dsa_begin
-						   routines of various DSAs.  
-						   When not in use, replace
-						   with jump to next slot */
-
-
-    volatile unsigned char msg_buf[16];		/* buffer for messages
-						   other than the command
-						   complete message */
-
-    /* Per-target default synchronous and WIDE messages */
-    volatile unsigned char synchronous_want[16][5];
-    volatile unsigned char wide_want[16][4];
-
-    /* Bit fielded set of targets we want to speak synchronously with */ 
-    volatile u16 initiate_sdtr;	
-    /* Bit fielded set of targets we want to speak wide with */
-    volatile u16 initiate_wdtr;
-    /* Bit fielded list of targets we've talked to. */
-    volatile u16 talked_to;
-
-    /* Array of bit-fielded lun lists that we need to request_sense */
-    volatile unsigned char request_sense[16];
-
-    u32 addr_reconnect_dsa_head;		/* RISCy style constant,
-						   address of following */
-    volatile u32 reconnect_dsa_head;	
-    /* Data identifying nexus we are trying to match during reselection */
-    volatile unsigned char reselected_identify; /* IDENTIFY message */
-    volatile unsigned char reselected_tag;	/* second byte of queue tag 
-						   message or 0 */
-    /* These were static variables before we moved them */
-
-    s32 NCR53c7xx_zero;
-    s32 NCR53c7xx_sink;
-    u32 NOP_insn;
-    char NCR53c7xx_msg_reject;
-    char NCR53c7xx_msg_abort;
-    char NCR53c7xx_msg_nop;
-
-    volatile int event_size, event_index;
-    volatile struct NCR53c7x0_event *events;
-
-    /* If we need to generate code to kill off the currently connected 
-       command, this is where we do it. Should have a BMI instruction
-       to source or sink the current data, followed by a JUMP
-       to abort_connected */
-
-    u32 *abort_script;
-
-    int script_count;				/* Size of script in words */
-    u32 script[0];				/* Relocated SCSI script */
-
-};
-
-#define IRQ_NONE	255
-#define DMA_NONE	255
-#define IRQ_AUTO	254
-#define DMA_AUTO	254
-
-#define BOARD_GENERIC	0
-
-#define NCR53c7x0_insn_size(insn)					\
-    (((insn) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI ? 3 : 2)
-    
-
-#define NCR53c7x0_local_declare()					\
-    volatile unsigned char *NCR53c7x0_address_memory;			\
-    unsigned int NCR53c7x0_address_io;					\
-    int NCR53c7x0_memory_mapped
-
-#define NCR53c7x0_local_setup(host)					\
-    NCR53c7x0_address_memory = (void *) (host)->base;			\
-    NCR53c7x0_address_io = (unsigned int) (host)->io_port;		\
-    NCR53c7x0_memory_mapped = ((struct NCR53c7x0_hostdata *) 		\
-	host->hostdata)-> options & OPTION_MEMORY_MAPPED 
-
-#define NCR53c7x0_read8(address) 					\
-    (NCR53c7x0_memory_mapped ? 						\
-	(unsigned int)readb(NCR53c7x0_address_memory + (address)) :	\
-	inb(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read16(address) 					\
-    (NCR53c7x0_memory_mapped ? 						\
-	(unsigned int)readw(NCR53c7x0_address_memory + (address)) :	\
-	inw(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read32(address) 					\
-    (NCR53c7x0_memory_mapped ? 						\
-	(unsigned int) readl(NCR53c7x0_address_memory + (address)) : 	\
-	inl(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write8(address,value) 				\
-    (NCR53c7x0_memory_mapped ? 						\
-     ({writeb((value), NCR53c7x0_address_memory + (address)); mb();}) :	\
-	outb((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write16(address,value) 				\
-    (NCR53c7x0_memory_mapped ? 						\
-     ({writew((value), NCR53c7x0_address_memory + (address)); mb();}) :	\
-	outw((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write32(address,value) 				\
-    (NCR53c7x0_memory_mapped ? 						\
-     ({writel((value), NCR53c7x0_address_memory + (address)); mb();}) :	\
-	outl((value), NCR53c7x0_address_io + (address)))
-
-/* Patch arbitrary 32 bit words in the script */
-#define patch_abs_32(script, offset, symbol, value)			\
-    	for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof 		\
-    	    (u32)); ++i) {					\
-	    (script)[A_##symbol##_used[i] - (offset)] += (value);	\
-	    if (hostdata->options & OPTION_DEBUG_FIXUP) 		\
-	      printk("scsi%d : %s reference %d at 0x%x in %s is now 0x%x\n",\
-		host->host_no, #symbol, i, A_##symbol##_used[i] - 	\
-		(int)(offset), #script, (script)[A_##symbol##_used[i] -	\
-		(offset)]);						\
-    	}
-
-/* Patch read/write instruction immediate field */
-#define patch_abs_rwri_data(script, offset, symbol, value)		\
-    	for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof 		\
-    	    (u32)); ++i)					\
-    	    (script)[A_##symbol##_used[i] - (offset)] =			\
-	    	((script)[A_##symbol##_used[i] - (offset)] & 		\
-	    	~DBC_RWRI_IMMEDIATE_MASK) | 				\
-    	    	(((value) << DBC_RWRI_IMMEDIATE_SHIFT) &		\
-		 DBC_RWRI_IMMEDIATE_MASK)
-
-/* Patch transfer control instruction data field */
-#define patch_abs_tci_data(script, offset, symbol, value)	        \
-    	for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof 		\
-    	    (u32)); ++i)					\
-    	    (script)[A_##symbol##_used[i] - (offset)] =			\
-	    	((script)[A_##symbol##_used[i] - (offset)] & 		\
-	    	~DBC_TCI_DATA_MASK) | 					\
-    	    	(((value) << DBC_TCI_DATA_SHIFT) &			\
-		 DBC_TCI_DATA_MASK)
-
-/* Patch field in dsa structure (assignment should be +=?) */
-#define patch_dsa_32(dsa, symbol, word, value)				\
-	{								\
-	(dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32)	\
-	    + (word)] = (value);					\
-	if (hostdata->options & OPTION_DEBUG_DSA)			\
-	    printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n",	\
-		#dsa, #symbol, hostdata->symbol, 			\
-		(word), (u32) le32_to_cpu(value));			\
-	}
-
-/* Paranoid people could use panic() here. */
-#define FATAL(host) shutdown((host));
-
-#endif /* NCR53c7x0_C */
-#endif /* NCR53c7x0_H */
diff -Nru a/drivers/scsi/53c7,8xx.scr b/drivers/scsi/53c7,8xx.scr
--- a/drivers/scsi/53c7,8xx.scr	Mon Feb 10 10:39:33 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1304 +0,0 @@
-#undef DEBUG
-#undef EVENTS
-; NCR 53c810 driver, main script
-; Sponsored by 
-;	iX Multiuser Multitasking Magazine
-;	hm@ix.de
-;
-; Copyright 1993, 1994, 1995 Drew Eckhardt
-;      Visionary Computing 
-;      (Unix and Linux consulting and custom programming)
-;      drew@PoohSticks.ORG
-;      +1 (303) 786-7975
-;
-; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
-;
-; PRE-ALPHA
-;
-; For more information, please consult 
-;
-; NCR 53C810
-; PCI-SCSI I/O Processor
-; Data Manual
-;
-; NCR 53C710 
-; SCSI I/O Processor
-; Programmers Guide
-;
-; NCR Microelectronics
-; 1635 Aeroplaza Drive
-; Colorado Springs, CO 80916
-; 1+ (719) 578-3400
-;
-; Toll free literature number
-; +1 (800) 334-5454
-;
-; IMPORTANT : This code is self modifying due to the limitations of 
-;	the NCR53c7,8xx series chips.  Persons debugging this code with
-;	the remote debugger should take this into account, and NOT set
-;	breakpoints in modified instructions.
-;
-; Design:
-; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
-; microcontroller using a simple instruction set.   
-;
-; So, to minimize the effects of interrupt latency, and to maximize 
-; throughput, this driver offloads the practical maximum amount 
-; of processing to the SCSI chip while still maintaining a common
-; structure.
-;
-; Where tradeoffs were needed between efficiency on the older
-; chips and the newer NCR53c800 series, the NCR53c800 series 
-; was chosen.
-;
-; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
-; automate SCSI transfers without host processor intervention, this 
-; isn't the case with the NCR53c710 and newer chips which allow 
-;
-; - reads and writes to the internal registers from within the SCSI
-; 	scripts, allowing the SCSI SCRIPTS(tm) code to save processor
-; 	state so that multiple threads of execution are possible, and also
-; 	provide an ALU for loop control, etc.
-; 
-; - table indirect addressing for some instructions. This allows 
-;	pointers to be located relative to the DSA ((Data Structure
-;	Address) register.
-;
-; These features make it possible to implement a mailbox style interface,
-; where the same piece of code is run to handle I/O for multiple threads
-; at once minimizing our need to relocate code.  Since the NCR53c700/
-; NCR53c800 series have a unique combination of features, making a 
-; a standard ingoing/outgoing mailbox system, costly, I've modified it.
-;
-; - Mailboxes are a mixture of code and data.  This lets us greatly
-; 	simplify the NCR53c810 code and do things that would otherwise
-;	not be possible.
-;
-; The saved data pointer is now implemented as follows :
-;
-; 	Control flow has been architected such that if control reaches
-;	munge_save_data_pointer, on a restore pointers message or 
-;	reconnection, a jump to the address formerly in the TEMP register
-;	will allow the SCSI command to resume execution.
-;
-
-;
-; Note : the DSA structures must be aligned on 32 bit boundaries,
-; since the source and destination of MOVE MEMORY instructions 
-; must share the same alignment and this is the alignment of the
-; NCR registers.
-;
-
-ABSOLUTE dsa_temp_lun = 0		; Patch to lun for current dsa
-ABSOLUTE dsa_temp_next = 0		; Patch to dsa next for current dsa
-ABSOLUTE dsa_temp_addr_next = 0		; Patch to address of dsa next address 
-					; 	for current dsa
-ABSOLUTE dsa_temp_sync = 0		; Patch to address of per-target
-					;	sync routine
-ABSOLUTE dsa_temp_target = 0		; Patch to id for current dsa
-ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
-					; 	saved data pointer
-ABSOLUTE dsa_temp_addr_residual = 0	; Patch to address of per-command
-					;	current residual code
-ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
-					; saved residual code
-ABSOLUTE dsa_temp_addr_new_value = 0	; Address of value for JUMP operand
-ABSOLUTE dsa_temp_addr_array_value = 0 	; Address to copy to
-ABSOLUTE dsa_temp_addr_dsa_value = 0	; Address of this DSA value
-
-;
-; Once a device has initiated reselection, we need to compare it 
-; against the singly linked list of commands which have disconnected
-; and are pending reselection.  These commands are maintained in 
-; an unordered singly linked list of DSA structures, through the
-; DSA pointers at their 'centers' headed by the reconnect_dsa_head
-; pointer.
-; 
-; To avoid complications in removing commands from the list,
-; I minimize the amount of expensive (at eight operations per
-; addition @ 500-600ns each) pointer operations which must
-; be done in the NCR driver by precomputing them on the 
-; host processor during dsa structure generation.
-;
-; The fixed-up per DSA code knows how to recognize the nexus
-; associated with the corresponding SCSI command, and modifies
-; the source and destination pointers for the MOVE MEMORY 
-; instruction which is executed when reselected_ok is called
-; to remove the command from the list.  Similarly, DSA is 
-; loaded with the address of the next DSA structure and
-; reselected_check_next is called if a failure occurs.
-;
-; Perhaps more concisely, the net effect of the mess is 
-;
-; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
-;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
-; 	src = &dsa->next;
-; 	if (target_id == dsa->id && target_lun == dsa->lun) {
-; 		*dest = *src;
-; 		break;
-;         }	
-; }
-;
-; if (!dsa)
-;           error (int_err_unexpected_reselect);
-; else  
-;     longjmp (dsa->jump_resume, 0);
-;
-; 	
-
-#if (CHIP != 700) && (CHIP != 70066)
-; Define DSA structure used for mailboxes
-ENTRY dsa_code_template
-dsa_code_template:
-ENTRY dsa_code_begin
-dsa_code_begin:
-	MOVE dmode_memory_to_ncr TO DMODE
-	MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
-	MOVE dmode_memory_to_memory TO DMODE
-	CALL scratch_to_dsa
-	CALL select
-; Handle the phase mismatch which may have resulted from the 
-; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN 
-; may or may not be necessary, and we should update script_asm.pl
-; to handle multiple pieces.
-    CLEAR ATN
-    CLEAR ACK
-
-; Replace second operand with address of JUMP instruction dest operand
-; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.
-ENTRY dsa_code_fix_jump
-dsa_code_fix_jump:
-	MOVE MEMORY 4, NOP_insn, 0
-	JUMP select_done
-
-; wrong_dsa loads the DSA register with the value of the dsa_next
-; field.
-;
-wrong_dsa:
-;		Patch the MOVE MEMORY INSTRUCTION such that 
-;		the destination address is the address of the OLD 
-;		next pointer.
-;
-	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8
-	MOVE dmode_memory_to_ncr TO DMODE	
-;
-; 	Move the _contents_ of the next pointer into the DSA register as 
-;	the next I_T_L or I_T_L_Q tupple to check against the established
-;	nexus.
-;
-	MOVE MEMORY 4, dsa_temp_next, addr_scratch
-	MOVE dmode_memory_to_memory TO DMODE
-	CALL scratch_to_dsa
-	JUMP reselected_check_next
-
-ABSOLUTE dsa_save_data_pointer = 0
-ENTRY dsa_code_save_data_pointer
-dsa_code_save_data_pointer:
-    	MOVE dmode_ncr_to_memory TO DMODE
-    	MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
-    	MOVE dmode_memory_to_memory TO DMODE
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-    	MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-        CLEAR ACK
-#ifdef DEBUG
-        INT int_debug_saved
-#endif
-    	RETURN
-ABSOLUTE dsa_restore_pointers = 0
-ENTRY dsa_code_restore_pointers
-dsa_code_restore_pointers:
-    	MOVE dmode_memory_to_ncr TO DMODE
-    	MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
-    	MOVE dmode_memory_to_memory TO DMODE
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-    	MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-        CLEAR ACK
-#ifdef DEBUG
-        INT int_debug_restored
-#endif
-    	RETURN
-
-ABSOLUTE dsa_check_reselect = 0
-; dsa_check_reselect determines whether or not the current target and
-; lun match the current DSA
-ENTRY dsa_code_check_reselect
-dsa_code_check_reselect:
-	MOVE SSID TO SFBR		; SSID contains 3 bit target ID
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-	JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
-;
-; Hack - move to scratch first, since SFBR is not writeable
-; 	via the CPU and hence a MOVE MEMORY instruction.
-;
-	MOVE dmode_memory_to_ncr TO DMODE
-	MOVE MEMORY 1, reselected_identify, addr_scratch
-	MOVE dmode_memory_to_memory TO DMODE
-	MOVE SCRATCH0 TO SFBR
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-	JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
-;		Patch the MOVE MEMORY INSTRUCTION such that
-;		the source address is the address of this dsa's
-;		next pointer.
-	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4
-	CALL reselected_ok
-	CALL dsa_temp_sync	
-; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
-; transfer parameters! 
-	CLEAR ACK
-; Implicitly restore pointers on reselection, so a RETURN
-; will transfer control back to the right spot.
-    	CALL REL (dsa_code_restore_pointers)
-    	RETURN
-ENTRY dsa_zero
-dsa_zero:
-ENTRY dsa_code_template_end
-dsa_code_template_end:
-
-; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
-; dsa_zero, puke.
-
-ABSOLUTE dsa_fields_start =  0	; Sanity marker
-				; 	pad 48 bytes (fix this RSN)
-ABSOLUTE dsa_next = 48		; len 4 Next DSA
- 				; del 4 Previous DSA address
-ABSOLUTE dsa_cmnd = 56		; len 4 Scsi_Cmnd * for this thread.
-ABSOLUTE dsa_select = 60	; len 4 Device ID, Period, Offset for 
-			 	;	table indirect select
-ABSOLUTE dsa_msgout = 64	; len 8 table indirect move parameter for 
-				;       select message
-ABSOLUTE dsa_cmdout = 72	; len 8 table indirect move parameter for 
-				;	command
-ABSOLUTE dsa_dataout = 80	; len 4 code pointer for dataout
-ABSOLUTE dsa_datain = 84	; len 4 code pointer for datain
-ABSOLUTE dsa_msgin = 88		; len 8 table indirect move for msgin
-ABSOLUTE dsa_status = 96 	; len 8 table indirect move for status byte
-ABSOLUTE dsa_msgout_other = 104	; len 8 table indirect for normal message out
-				; (Synchronous transfer negotiation, etc).
-ABSOLUTE dsa_end = 112
-
-ABSOLUTE schedule = 0 		; Array of JUMP dsa_begin or JUMP (next),
-				; terminated by a call to JUMP wait_reselect
-
-; Linked lists of DSA structures
-ABSOLUTE reconnect_dsa_head = 0	; Link list of DSAs which can reconnect
-ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
-				; address of reconnect_dsa_head
-
-; These select the source and destination of a MOVE MEMORY instruction
-ABSOLUTE dmode_memory_to_memory = 0x0
-ABSOLUTE dmode_memory_to_ncr = 0x0
-ABSOLUTE dmode_ncr_to_memory = 0x0
-
-ABSOLUTE addr_scratch = 0x0
-ABSOLUTE addr_temp = 0x0
-#endif /* CHIP != 700 && CHIP != 70066 */
-
-; Interrupts - 
-; MSB indicates type
-; 0	handle error condition
-; 1 	handle message 
-; 2 	handle normal condition
-; 3	debugging interrupt
-; 4 	testing interrupt 
-; Next byte indicates specific error
-
-; XXX not yet implemented, I'm not sure if I want to - 
-; Next byte indicates the routine the error occurred in
-; The LSB indicates the specific place the error occurred
- 
-ABSOLUTE int_err_unexpected_phase = 0x00000000	; Unexpected phase encountered
-ABSOLUTE int_err_selected = 0x00010000		; SELECTED (nee RESELECTED)
-ABSOLUTE int_err_unexpected_reselect = 0x00020000 
-ABSOLUTE int_err_check_condition = 0x00030000	
-ABSOLUTE int_err_no_phase = 0x00040000
-ABSOLUTE int_msg_wdtr = 0x01000000		; WDTR message received
-ABSOLUTE int_msg_sdtr = 0x01010000		; SDTR received
-ABSOLUTE int_msg_1 = 0x01020000			; single byte special message
-						; received
-
-ABSOLUTE int_norm_select_complete = 0x02000000	; Select complete, reprogram
-						; registers.
-ABSOLUTE int_norm_reselect_complete = 0x02010000	; Nexus established
-ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
-ABSOLUTE int_norm_disconnected = 0x02030000	; Disconnected 
-ABSOLUTE int_norm_aborted =0x02040000		; Aborted *dsa
-ABSOLUTE int_norm_reset = 0x02050000		; Generated BUS reset.
-ABSOLUTE int_debug_break = 0x03000000		; Break point
-#ifdef DEBUG
-ABSOLUTE int_debug_scheduled = 0x03010000	; new I/O scheduled 
-ABSOLUTE int_debug_idle = 0x03020000		; scheduler is idle
-ABSOLUTE int_debug_dsa_loaded = 0x03030000	; dsa reloaded
-ABSOLUTE int_debug_reselected = 0x03040000	; NCR reselected
-ABSOLUTE int_debug_head = 0x03050000		; issue head overwritten
-ABSOLUTE int_debug_disconnected = 0x03060000	; disconnected
-ABSOLUTE int_debug_disconnect_msg = 0x03070000	; got message to disconnect
-ABSOLUTE int_debug_dsa_schedule = 0x03080000	; in dsa_schedule
-ABSOLUTE int_debug_reselect_check = 0x03090000  ; Check for reselection of DSA
-ABSOLUTE int_debug_reselected_ok = 0x030a0000 	; Reselection accepted
-#endif
-ABSOLUTE int_debug_panic = 0x030b0000		; Panic driver
-#ifdef DEBUG
-ABSOLUTE int_debug_saved = 0x030c0000 		; save/restore pointers
-ABSOLUTE int_debug_restored = 0x030d0000
-ABSOLUTE int_debug_sync = 0x030e0000		; Sanity check synchronous 
-						; parameters. 
-ABSOLUTE int_debug_datain = 0x030f0000		; going into data in phase 
-						; now.
-ABSOLUTE int_debug_check_dsa = 0x03100000	; Sanity check DSA against
-						; SDID.
-#endif
-
-ABSOLUTE int_test_1 = 0x04000000		; Test 1 complete
-ABSOLUTE int_test_2 = 0x04010000		; Test 2 complete
-ABSOLUTE int_test_3 = 0x04020000		; Test 3 complete
-
-
-; These should start with 0x05000000, with low bits incrementing for 
-; each one.
-
-#ifdef EVENTS
-ABSOLUTE int_EVENT_SELECT = 0
-ABSOLUTE int_EVENT_DISCONNECT = 0
-ABSOLUTE int_EVENT_RESELECT = 0
-ABSOLUTE int_EVENT_COMPLETE = 0
-ABSOLUTE int_EVENT_IDLE = 0
-ABSOLUTE int_EVENT_SELECT_FAILED = 0
-ABSOLUTE int_EVENT_BEFORE_SELECT = 0
-ABSOLUTE int_EVENT_RESELECT_FAILED = 0
-#endif
-						
-ABSOLUTE NCR53c7xx_msg_abort = 0	; Pointer to abort message
-ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
-ABSOLUTE NCR53c7xx_zero	= 0		; long with zero in it, use for source
-ABSOLUTE NCR53c7xx_sink = 0		; long to dump worthless data in
-ABSOLUTE NOP_insn = 0			; NOP instruction
-
-; Pointer to message, potentially multi-byte
-ABSOLUTE msg_buf = 0
-
-; Pointer to holding area for reselection information
-ABSOLUTE reselected_identify = 0
-ABSOLUTE reselected_tag = 0
-
-; Request sense command pointer, it's a 6 byte command, should
-; be constant for all commands since we always want 16 bytes of 
-; sense and we don't need to change any fields as we did under 
-; SCSI-I when we actually cared about the LUN field.
-;EXTERNAL NCR53c7xx_sense		; Request sense command
-
-#if (CHIP != 700) && (CHIP != 70066)
-; dsa_schedule  
-; PURPOSE : after a DISCONNECT message has been received, and pointers
-;	saved, insert the current DSA structure at the head of the 
-; 	disconnected queue and fall through to the scheduler.
-;
-; CALLS : OK
-;
-; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
-;	of disconnected commands
-;
-; MODIFIES : SCRATCH, reconnect_dsa_head
-; 
-; EXITS : always passes control to schedule
-
-ENTRY dsa_schedule
-dsa_schedule:
-#if 0
-    INT int_debug_dsa_schedule
-#endif
-
-;
-; Calculate the address of the next pointer within the DSA 
-; structure of the command that is currently disconnecting
-;
-    CALL dsa_to_scratch
-    MOVE SCRATCH0 + dsa_next TO SCRATCH0
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-; Point the next field of this DSA structure at the current disconnected 
-; list
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
-    MOVE dmode_memory_to_memory TO DMODE
-dsa_schedule_insert:
-    MOVE MEMORY 4, reconnect_dsa_head, 0 
-
-; And update the head pointer.
-    CALL dsa_to_scratch
-    MOVE dmode_ncr_to_memory TO DMODE	
-    MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
-    MOVE dmode_memory_to_memory TO DMODE
-/* Temporarily, see what happens. */
-#ifndef ORIGINAL
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-    CLEAR ACK
-#endif
-    WAIT DISCONNECT
-#ifdef EVENTS
-    INT int_EVENT_DISCONNECT;
-#endif
-#if 0
-    INT int_debug_disconnected
-#endif
-    JUMP schedule
-#endif 
-
-;
-; select
-;
-; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
-;	On success, the current DSA structure is removed from the issue 
-;	queue.  Usually, this is entered as a fall-through from schedule,
-;	although the contingent allegiance handling code will write
-;	the select entry address to the DSP to restart a command as a 
-;	REQUEST SENSE.  A message is sent (usually IDENTIFY, although
-;	additional SDTR or WDTR messages may be sent).  COMMAND OUT
-;	is handled.
-;
-; INPUTS : DSA - SCSI command, issue_dsa_head
-;
-; CALLS : NOT OK
-;
-; MODIFIES : SCRATCH, issue_dsa_head
-;
-; EXITS : on reselection or selection, go to select_failed
-;	otherwise, RETURN so control is passed back to 
-;	dsa_begin.
-;
-
-ENTRY select
-select:
-
-#if 0
-#ifdef EVENTS
-    INT int_EVENT_BEFORE_SELECT
-#endif
-#endif
-
-#if 0
-#ifdef DEBUG
-    INT int_debug_scheduled
-#endif
-#endif
-    CLEAR TARGET
-
-; XXX
-;
-; In effect, SELECTION operations are backgrounded, with execution
-; continuing until code which waits for REQ or a fatal interrupt is 
-; encountered.
-;
-; So, for more performance, we could overlap the code which removes 
-; the command from the NCRs issue queue with the selection, but 
-; at this point I don't want to deal with the error recovery.
-;
-
-#if (CHIP != 700) && (CHIP != 70066)
-    SELECT ATN FROM dsa_select, select_failed
-    JUMP select_msgout, WHEN MSG_OUT
-ENTRY select_msgout
-select_msgout:
-    MOVE FROM dsa_msgout, WHEN MSG_OUT
-#else
-ENTRY select_msgout
-    SELECT ATN 0, select_failed
-select_msgout:
-    MOVE 0, 0, WHEN MSGOUT
-#endif
-
-#ifdef EVENTS
-   INT int_EVENT_SELECT
-#endif
-   RETURN
-
-; 
-; select_done
-; 
-; PURPOSE: continue on to normal data transfer; called as the exit 
-;	point from dsa_begin.
-;
-; INPUTS: dsa
-;
-; CALLS: OK
-;
-;
-
-select_done:
-
-#ifdef DEBUG
-ENTRY select_check_dsa
-select_check_dsa:
-    INT int_debug_check_dsa
-#endif
-
-; After a successful selection, we should get either a CMD phase or 
-; some transfer request negotiation message.
-
-    JUMP cmdout, WHEN CMD
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN 
-
-select_msg_in:
-    CALL msg_in, WHEN MSG_IN
-    JUMP select_msg_in, WHEN MSG_IN
-
-cmdout:
-    INT int_err_unexpected_phase, WHEN NOT CMD
-#if (CHIP == 700)
-    INT int_norm_selected
-#endif
-ENTRY cmdout_cmdout
-cmdout_cmdout:
-#if (CHIP != 700) && (CHIP != 70066)
-    MOVE FROM dsa_cmdout, WHEN CMD
-#else
-    MOVE 0, 0, WHEN CMD
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-;
-; data_transfer  
-; other_out
-; other_in
-; other_transfer
-;
-; PURPOSE : handle the main data transfer for a SCSI command in 
-;	several parts.  In the first part, data_transfer, DATA_IN
-;	and DATA_OUT phases are allowed, with the user provided
-;	code (usually dynamically generated based on the scatter/gather
-;	list associated with a SCSI command) called to handle these 
-;	phases.
-;
-;	After control has passed to one of the user provided 
-;	DATA_IN or DATA_OUT routines, back calls are made to 
-;	other_transfer_in or other_transfer_out to handle non-DATA IN
-;	and DATA OUT phases respectively, with the state of the active
-;	data pointer being preserved in TEMP.
-;
-;	On completion, the user code passes control to other_transfer
-;	which causes DATA_IN and DATA_OUT to result in unexpected_phase
-;	interrupts so that data overruns may be trapped.
-;
-; INPUTS : DSA - SCSI command
-;
-; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
-;	other_transfer
-;
-; MODIFIES : SCRATCH
-;
-; EXITS : if STATUS IN is detected, signifying command completion,
-;	the NCR jumps to command_complete.  If MSG IN occurs, a 
-;	CALL is made to msg_in.  Otherwise, other_transfer runs in 
-;	an infinite loop.
-;	
-
-ENTRY data_transfer
-data_transfer:
-    JUMP cmdout_cmdout, WHEN CMD
-    CALL msg_in, WHEN MSG_IN
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    JUMP do_dataout, WHEN DATA_OUT
-    JUMP do_datain, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP data_transfer
-ENTRY end_data_transfer
-end_data_transfer:
-
-;
-; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain 
-; should be fixed up whenever the nexus changes so it can point to the 
-; correct routine for that command.
-;
-
-#if (CHIP != 700) && (CHIP != 70066)
-; Nasty jump to dsa->dataout
-do_dataout:
-    CALL dsa_to_scratch
-    MOVE SCRATCH0 + dsa_dataout TO SCRATCH0	
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
-    MOVE dmode_memory_to_memory TO DMODE
-dataout_to_jump:
-    MOVE MEMORY 4, 0, dataout_jump + 4 
-dataout_jump:
-    JUMP 0
-
-; Nasty jump to dsa->dsain
-do_datain:
-    CALL dsa_to_scratch
-    MOVE SCRATCH0 + dsa_datain TO SCRATCH0	
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
-    MOVE dmode_memory_to_memory TO DMODE		
-ENTRY datain_to_jump
-datain_to_jump:
-    MOVE MEMORY 4, 0, datain_jump + 4
-#if 0
-    INT int_debug_datain
-#endif
-datain_jump:
-    JUMP 0
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-
-; Note that other_out and other_in loop until a non-data phase
-; is discovered, so we only execute return statements when we
-; can go on to the next data phase block move statement.
-
-ENTRY other_out
-other_out:
-#if 0
-    INT 0x03ffdead
-#endif
-    INT int_err_unexpected_phase, WHEN CMD
-    JUMP msg_in_restart, WHEN MSG_IN 
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP other_out, WHEN NOT DATA_OUT
-    RETURN
-
-ENTRY other_in
-other_in:
-#if 0
-    INT 0x03ffdead
-#endif
-    INT int_err_unexpected_phase, WHEN CMD
-    JUMP msg_in_restart, WHEN MSG_IN 
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-    JUMP command_complete, WHEN STATUS
-    JUMP other_in, WHEN NOT DATA_IN
-    RETURN
-
-
-ENTRY other_transfer
-other_transfer:
-    INT int_err_unexpected_phase, WHEN CMD
-    CALL msg_in, WHEN MSG_IN
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-    INT int_err_unexpected_phase, WHEN DATA_IN
-    JUMP command_complete, WHEN STATUS
-    JUMP other_transfer
-
-;
-; msg_in_restart
-; msg_in
-; munge_msg
-;
-; PURPOSE : process messages from a target.  msg_in is called when the 
-;	caller hasn't read the first byte of the message.  munge_message
-;	is called when the caller has read the first byte of the message,
-;	and left it in SFBR.  msg_in_restart is called when the caller 
-;	hasn't read the first byte of the message, and wishes RETURN
-;	to transfer control back to the address of the conditional
-;	CALL instruction rather than to the instruction after it.
-;
-;	Various int_* interrupts are generated when the host system
-;	needs to intervene, as is the case with SDTR, WDTR, and
-;	INITIATE RECOVERY messages.
-;
-;	When the host system handles one of these interrupts,
-;	it can respond by reentering at reject_message, 
-;	which rejects the message and returns control to
-;	the caller of msg_in or munge_msg, accept_message
-;	which clears ACK and returns control, or reply_message
-;	which sends the message pointed to by the DSA 
-;	msgout_other table indirect field.
-;
-;	DISCONNECT messages are handled by moving the command
-;	to the reconnect_dsa_queue.
-;
-; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
-;	only)
-;
-; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
-;
-; MODIFIES : SCRATCH, DSA on DISCONNECT
-;
-; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
-;	and normal return from message handlers running under
-;	Linux, control is returned to the caller.  Receipt
-;	of DISCONNECT messages pass control to dsa_schedule.
-;
-ENTRY msg_in_restart
-msg_in_restart:
-; XXX - hackish
-;
-; Since it's easier to debug changes to the statically 
-; compiled code, rather than the dynamically generated 
-; stuff, such as
-;
-; 	MOVE x, y, WHEN data_phase
-; 	CALL other_z, WHEN NOT data_phase
-; 	MOVE x, y, WHEN data_phase
-;
-; I'd like to have certain routines (notably the message handler)
-; restart on the conditional call rather than the next instruction.
-;
-; So, subtract 8 from the return address
-
-    MOVE TEMP0 + 0xf8 TO TEMP0
-    MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
-    MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
-    MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
-
-ENTRY msg_in
-msg_in:
-    MOVE 1, msg_buf, WHEN MSG_IN
-
-munge_msg:
-    JUMP munge_extended, IF 0x01		; EXTENDED MESSAGE
-    JUMP munge_2, IF 0x20, AND MASK 0xdf	; two byte message
-;
-; XXX - I've seen a handful of broken SCSI devices which fail to issue
-; 	a SAVE POINTERS message before disconnecting in the middle of 
-; 	a transfer, assuming that the DATA POINTER will be implicitly 
-; 	restored.  
-;
-; Historically, I've often done an implicit save when the DISCONNECT
-; message is processed.  We may want to consider having the option of 
-; doing that here. 
-;
-    JUMP munge_save_data_pointer, IF 0x02	; SAVE DATA POINTER
-    JUMP munge_restore_pointers, IF 0x03	; RESTORE POINTERS 
-    JUMP munge_disconnect, IF 0x04		; DISCONNECT
-    INT int_msg_1, IF 0x07			; MESSAGE REJECT
-    INT int_msg_1, IF 0x0f			; INITIATE RECOVERY
-#ifdef EVENTS 
-    INT int_EVENT_SELECT_FAILED 
-#endif
-    JUMP reject_message
-
-munge_2:
-    JUMP reject_message
-;
-; The SCSI standard allows targets to recover from transient 
-; error conditions by backing up the data pointer with a 
-; RESTORE POINTERS message.  
-;	
-; So, we must save and restore the _residual_ code as well as 
-; the current instruction pointer.  Because of this messiness,
-; it is simpler to put dynamic code in the dsa for this and to
-; just do a simple jump down there. 
-;
-
-munge_save_data_pointer:
-    MOVE DSA0 + dsa_save_data_pointer TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY 
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH3
-
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
-    MOVE dmode_memory_to_memory TO DMODE
-jump_dsa_save:
-    JUMP 0
-
-munge_restore_pointers:
-    MOVE DSA0 + dsa_restore_pointers TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-    MOVE SFBR TO SCRATCH3
-
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
-    MOVE dmode_memory_to_memory TO DMODE
-jump_dsa_restore:
-    JUMP 0
-
-
-munge_disconnect:
-#if 0
-    INT int_debug_disconnect_msg
-#endif
-
-/* 
- * Before, we overlapped processing with waiting for disconnect, but
- * debugging was beginning to appear messy.  Temporarily move things
- * to just before the WAIT DISCONNECT.
- */
- 
-#ifdef ORIGINAL
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-    CLEAR ACK
-#endif
-
-#if (CHIP != 700) && (CHIP != 70066)
-    JUMP dsa_schedule
-#else
-    WAIT DISCONNECT
-    INT int_norm_disconnected
-#endif
-
-munge_extended:
-    CLEAR ACK
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN
-    MOVE 1, msg_buf + 1, WHEN MSG_IN
-    JUMP munge_extended_2, IF 0x02
-    JUMP munge_extended_3, IF 0x03 
-    JUMP reject_message
-
-munge_extended_2:
-    CLEAR ACK
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-    JUMP reject_message, IF NOT 0x02	; Must be WDTR
-    CLEAR ACK
-    MOVE 1, msg_buf + 3, WHEN MSG_IN
-    INT int_msg_wdtr
-
-munge_extended_3:
-    CLEAR ACK
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-    JUMP reject_message, IF NOT 0x01	; Must be SDTR
-    CLEAR ACK
-    MOVE 2, msg_buf + 3, WHEN MSG_IN
-    INT int_msg_sdtr
-
-ENTRY reject_message
-reject_message:
-    SET ATN
-    CLEAR ACK
-    MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
-    RETURN
-
-ENTRY accept_message
-accept_message:
-    CLEAR ATN
-    CLEAR ACK
-    RETURN
-
-ENTRY respond_message
-respond_message:
-    SET ATN
-    CLEAR ACK
-    MOVE FROM dsa_msgout_other, WHEN MSG_OUT
-    RETURN
-
-;
-; command_complete
-;
-; PURPOSE : handle command termination when STATUS IN is detected by reading
-;	a status byte followed by a command termination message. 
-;
-;	Normal termination results in an INTFLY instruction, and 
-;	the host system can pick out which command terminated by 
-;	examining the MESSAGE and STATUS buffers of all currently 
-;	executing commands;
-;
-;	Abnormal (CHECK_CONDITION) termination results in an
-;	int_err_check_condition interrupt so that a REQUEST SENSE
-;	command can be issued out-of-order so that no other command
-;	clears the contingent allegiance condition.
-;	
-;
-; INPUTS : DSA - command	
-;
-; CALLS : OK
-;
-; EXITS : On successful termination, control is passed to schedule.
-;	On abnormal termination, the user will usually modify the 
-;	DSA fields and corresponding buffers and return control
-;	to select.
-;
-
-ENTRY command_complete
-command_complete:
-    MOVE FROM dsa_status, WHEN STATUS
-#if (CHIP != 700) && (CHIP != 70066)
-    MOVE SFBR TO SCRATCH0		; Save status
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-ENTRY command_complete_msgin
-command_complete_msgin:
-    MOVE FROM dsa_msgin, WHEN MSG_IN
-; Indicate that we should be expecting a disconnect
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-    CLEAR ACK
-#if (CHIP != 700) && (CHIP != 70066)
-    WAIT DISCONNECT
-
-;
-; The SCSI specification states that when a UNIT ATTENTION condition
-; is pending, as indicated by a CHECK CONDITION status message,
-; the target shall revert to asynchronous transfers.  Since
-; synchronous transfers parameters are maintained on a per INITIATOR/TARGET 
-; basis, and returning control to our scheduler could work on a command
-; running on another lun on that target using the old parameters, we must
-; interrupt the host processor to get them changed, or change them ourselves.
-;
-; Once SCSI-II tagged queueing is implemented, things will be even more
-; hairy, since contingent allegiance conditions exist on a per-target/lun
-; basis, and issuing a new command with a different tag would clear it.
-; In these cases, we must interrupt the host processor to get a request 
-; added to the HEAD of the queue with the request sense command, or we
-; must automatically issue the request sense command.
-
-#if 0
-    MOVE SCRATCH0 TO SFBR			
-    JUMP command_failed, IF 0x02
-#endif
-    INTFLY
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-#ifdef EVENTS
-    INT int_EVENT_COMPLETE
-#endif
-#if (CHIP != 700) && (CHIP != 70066)
-    JUMP schedule
-command_failed:
-    INT int_err_check_condition
-#else
-    INT int_norm_command_complete
-#endif
-
-;
-; wait_reselect
-;
-; PURPOSE : This is essentially the idle routine, where control lands
-;	when there are no new processes to schedule.  wait_reselect
-;	waits for reselection, selection, and new commands.
-;
-;	When a successful reselection occurs, with the aid 
-;	of fixed up code in each DSA, wait_reselect walks the 
-;	reconnect_dsa_queue, asking each dsa if the target ID
-;	and LUN match its.
-;
-;	If a match is found, a call is made back to reselected_ok,
-;	which through the miracles of self modifying code, extracts
-;	the found DSA from the reconnect_dsa_queue and then 
-;	returns control to the DSAs thread of execution.
-;
-; INPUTS : NONE
-;
-; CALLS : OK
-;
-; MODIFIES : DSA,
-;
-; EXITS : On successful reselection, control is returned to the 
-;	DSA which called reselected_ok.  If the WAIT RESELECT
-;	was interrupted by a new commands arrival signaled by 
-;	SIG_P, control is passed to schedule.  If the NCR is 
-;	selected, the host system is interrupted with an 
-;	int_err_selected which is usually responded to by
-;	setting DSP to the target_abort address.
-
-ENTRY wait_reselect
-wait_reselect:
-#ifdef EVENTS
-    int int_EVENT_IDLE
-#endif
-#if 0
-    int int_debug_idle
-#endif
-    WAIT RESELECT wait_reselect_failed
-
-reselected:
-#ifdef EVENTS
-    int int_EVENT_RESELECT
-#endif
-    CLEAR TARGET
-    MOVE dmode_memory_to_memory TO DMODE
-    ; Read all data needed to reestablish the nexus - 
-    MOVE 1, reselected_identify, WHEN MSG_IN
-    ; We used to CLEAR ACK here.
-#if (CHIP != 700) && (CHIP != 70066)
-#if 0
-    int int_debug_reselected
-#endif
-
-    ; Point DSA at the current head of the disconnected queue.
-    MOVE dmode_memory_to_ncr  TO DMODE
-    MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
-    MOVE dmode_memory_to_memory TO DMODE
-    CALL scratch_to_dsa
-
-    ; Fix the update-next pointer so that the reconnect_dsa_head
-    ; pointer is the one that will be updated if this DSA is a hit 
-    ; and we remove it from the queue.
-
-    MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8
-
-ENTRY reselected_check_next
-reselected_check_next:
-#if 0
-    INT int_debug_reselect_check
-#endif
-    ; Check for a NULL pointer.
-    MOVE DSA0 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA1 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA2 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    MOVE DSA3 TO SFBR
-    JUMP reselected_not_end, IF NOT 0
-    INT int_err_unexpected_reselect
-
-reselected_not_end:
-    ;
-    ; XXX the ALU is only eight bits wide, and the assembler
-    ; wont do the dirt work for us.  As long as dsa_check_reselect
-    ; is negative, we need to sign extend with 1 bits to the full
-    ; 32 bit width of the address.
-    ;
-    ; A potential work around would be to have a known alignment 
-    ; of the DSA structure such that the base address plus 
-    ; dsa_check_reselect doesn't require carrying from bytes 
-    ; higher than the LSB.
-    ;
-
-    MOVE DSA0 TO SFBR
-    MOVE SFBR + dsa_check_reselect TO SCRATCH0
-    MOVE DSA1 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
-    MOVE DSA2 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
-    MOVE DSA3 TO SFBR
-    MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
-
-    MOVE dmode_ncr_to_memory TO DMODE
-    MOVE MEMORY 4, addr_scratch, reselected_check + 4
-    MOVE dmode_memory_to_memory TO DMODE
-reselected_check:
-    JUMP 0
-
-
-;
-;
-ENTRY reselected_ok
-reselected_ok:
-    MOVE MEMORY 4, 0, 0				; Patched : first word
-						; 	is address of 
-						;       successful dsa_next
-						; Second word is last 
-						;	unsuccessful dsa_next,
-						;	starting with 
-						;       dsa_reconnect_head
-    ; We used to CLEAR ACK here.
-#if 0
-    INT int_debug_reselected_ok
-#endif
-#ifdef DEBUG
-    INT int_debug_check_dsa
-#endif
-    RETURN					; Return control to where
-#else
-    INT int_norm_reselected
-#endif /* (CHIP != 700) && (CHIP != 70066) */
-
-selected:
-    INT int_err_selected;
-
-;
-; A select or reselect failure can be caused by one of two conditions : 
-; 1.  SIG_P was set.  This will be the case if the user has written
-;	a new value to a previously NULL head of the issue queue.
-;
-; 2.  The NCR53c810 was selected or reselected by another device.
-;
-; 3.  The bus was already busy since we were selected or reselected
-;	before starting the command.
-
-wait_reselect_failed:
-#ifdef EVENTS 
-	INT int_EVENT_RESELECT_FAILED
-#endif
-; Check selected bit.  
-    MOVE SIST0 & 0x20 TO SFBR
-    JUMP selected, IF 0x20
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR	
-    JUMP schedule, IF 0x40
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-    MOVE ISTAT & 0x08 TO SFBR
-    JUMP reselected, IF 0x08
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-#if 0
-    JUMP schedule
-#else
-    INT int_debug_panic
-#endif
-
-
-select_failed:
-#ifdef EVENTS
-  int int_EVENT_SELECT_FAILED
-#endif
-; Otherwise, mask the selected and reselected bits off SIST0
-    MOVE SIST0 & 0x30 TO SFBR
-    JUMP selected, IF 0x20
-    JUMP reselected, IF 0x10 
-; If SIGP is set, the user just gave us another command, and
-; we should restart or return to the scheduler.
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR	
-    JUMP select, IF 0x40
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-; FIXME: is this really necessary? 
-    MOVE ISTAT & 0x08 TO SFBR
-    JUMP reselected, IF 0x08
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-#if 0
-    JUMP schedule
-#else
-    INT int_debug_panic
-#endif
-
-;
-; test_1
-; test_2
-;
-; PURPOSE : run some verification tests on the NCR.  test_1
-;	copies test_src to test_dest and interrupts the host
-;	processor, testing for cache coherency and interrupt
-; 	problems in the processes.
-;
-;	test_2 runs a command with offsets relative to the 
-;	DSA on entry, and is useful for miscellaneous experimentation.
-;
-
-; Verify that interrupts are working correctly and that we don't 
-; have a cache invalidation problem.
-
-ABSOLUTE test_src = 0, test_dest = 0
-ENTRY test_1
-test_1:
-    MOVE MEMORY 4, test_src, test_dest
-    INT int_test_1
-
-;
-; Run arbitrary commands, with test code establishing a DSA
-;
- 
-ENTRY test_2
-test_2:
-    CLEAR TARGET
-    SELECT ATN FROM 0, test_2_fail
-    JUMP test_2_msgout, WHEN MSG_OUT
-ENTRY test_2_msgout
-test_2_msgout:
-    MOVE FROM 8, WHEN MSG_OUT
-    MOVE FROM 16, WHEN CMD 
-    MOVE FROM 24, WHEN DATA_IN
-    MOVE FROM 32, WHEN STATUS
-    MOVE FROM 40, WHEN MSG_IN
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-    CLEAR ACK
-    WAIT DISCONNECT
-test_2_fail:
-    INT int_test_2
-
-ENTRY debug_break
-debug_break:
-    INT int_debug_break
-
-;
-; initiator_abort
-; target_abort
-;
-; PURPOSE : Abort the currently established nexus from with initiator
-;	or target mode.
-;
-;  
-
-ENTRY target_abort
-target_abort:
-    SET TARGET
-    DISCONNECT
-    CLEAR TARGET
-    JUMP schedule
-    
-ENTRY initiator_abort
-initiator_abort:
-    SET ATN
-;
-; The SCSI-I specification says that targets may go into MSG out at 
-; their leisure upon receipt of the ATN single.  On all versions of the 
-; specification, we can't change phases until REQ transitions true->false, 
-; so we need to sink/source one byte of data to allow the transition.
-;
-; For the sake of safety, we'll only source one byte of data in all 
-; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  
-; arbitrary number of bytes.
-    JUMP spew_cmd, WHEN CMD
-    JUMP eat_msgin, WHEN MSG_IN
-    JUMP eat_datain, WHEN DATA_IN
-    JUMP eat_status, WHEN STATUS
-    JUMP spew_dataout, WHEN DATA_OUT
-    JUMP sated
-spew_cmd:
-    MOVE 1, NCR53c7xx_zero, WHEN CMD
-    JUMP sated
-eat_msgin:
-    MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
-    JUMP eat_msgin, WHEN MSG_IN
-    JUMP sated
-eat_status:
-    MOVE 1, NCR53c7xx_sink, WHEN STATUS
-    JUMP eat_status, WHEN STATUS
-    JUMP sated
-eat_datain:
-    MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
-    JUMP eat_datain, WHEN DATA_IN
-    JUMP sated
-spew_dataout:
-    MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
-sated:
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-    MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
-    WAIT DISCONNECT
-    INT int_norm_aborted
-
-;
-; dsa_to_scratch
-; scratch_to_dsa
-;
-; PURPOSE :
-; 	The NCR chips cannot do a move memory instruction with the DSA register 
-; 	as the source or destination.  So, we provide a couple of subroutines
-; 	that let us switch between the DSA register and scratch register.
-;
-; 	Memory moves to/from the DSPS  register also don't work, but we 
-; 	don't use them.
-;
-;
-
- 
-dsa_to_scratch:
-    MOVE DSA0 TO SFBR
-    MOVE SFBR TO SCRATCH0
-    MOVE DSA1 TO SFBR
-    MOVE SFBR TO SCRATCH1
-    MOVE DSA2 TO SFBR
-    MOVE SFBR TO SCRATCH2
-    MOVE DSA3 TO SFBR
-    MOVE SFBR TO SCRATCH3
-    RETURN
-
-scratch_to_dsa:
-    MOVE SCRATCH0 TO SFBR
-    MOVE SFBR TO DSA0
-    MOVE SCRATCH1 TO SFBR
-    MOVE SFBR TO DSA1
-    MOVE SCRATCH2 TO SFBR
-    MOVE SFBR TO DSA2
-    MOVE SCRATCH3 TO SFBR
-    MOVE SFBR TO DSA3
-    RETURN
-    
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/53c700.c	Mon Feb 10 10:39:23 2003
@@ -765,8 +765,8 @@
 	__u8 pun = 0xff, lun = 0xff;
 
 	if(SCp != NULL) {
-		pun = SCp->target;
-		lun = SCp->lun;
+		pun = SCp->device->id;
+		lun = SCp->device->lun;
 	}
 
 	switch(hostdata->msgin[2]) {
@@ -846,8 +846,8 @@
 	__u8 pun = 0xff, lun = 0xff;
 
 	if(SCp != NULL) {
-		pun = SCp->target;
-		lun = SCp->lun;
+		pun = SCp->device->id;
+		lun = SCp->device->lun;
 	}
 
 #ifdef NCR_700_DEBUG
@@ -874,7 +874,7 @@
 			/* rejected our first simple tag message */
 			printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
 			NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-			hostdata->tag_negotiated &= ~(1<<SCp->target);
+			hostdata->tag_negotiated &= ~(1<<SCp->device->id);
 			SCp->device->tagged_supported = 0;
 			scsi_deactivate_tcq(SCp->device, host->cmd_per_lun);
 		} else {
@@ -928,8 +928,8 @@
 	__u8 pun = 0xff, lun=0xff;
 
 	if(SCp != NULL) {
-		pun = SCp->target;
-		lun = SCp->lun;
+		pun = SCp->device->id;
+		lun = SCp->device->lun;
 	}
 
 	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
@@ -963,7 +963,7 @@
 				NCR_700_unmap(hostdata, SCp, slot);
 
 				SCp->cmnd[0] = REQUEST_SENSE;
-				SCp->cmnd[1] = (SCp->lun & 0x7) << 5;
+				SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5;
 				SCp->cmnd[2] = 0;
 				SCp->cmnd[3] = 0;
 				SCp->cmnd[4] = sizeof(SCp->sense_buffer);
@@ -1010,11 +1010,11 @@
 			//			    DMA_FROM_DEVICE);
 			//	if(((char *)SCp->request_buffer)[7] & 0x02) {
 			//		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
-			//		hostdata->tag_negotiated |= (1<<SCp->target);
+			//		hostdata->tag_negotiated |= (1<<SCp->device->id);
 			//		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
 			//	} else {
 			//		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-			//		hostdata->tag_negotiated &= ~(1<<SCp->target);
+			//		hostdata->tag_negotiated &= ~(1<<SCp->device->id);
 			//	}
 			//}
 			NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
@@ -1352,7 +1352,7 @@
 	struct NCR_700_command_slot *slot =
 		(struct NCR_700_command_slot *)SCp->host_scribble;
 	struct NCR_700_Host_Parameters *hostdata =
-		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+		(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
 	__u16 count = 1;	/* for IDENTIFY message */
 	
 	if(hostdata->state != NCR_700_HOST_FREE) {
@@ -1362,7 +1362,7 @@
 		slot->state = NCR_700_SLOT_QUEUED;
 
 		DEBUG(("scsi%d: host busy, queueing command %p, slot %p\n",
-		       SCp->host->host_no, slot->cmnd, slot));
+		       SCp->device->host->host_no, slot->cmnd, slot));
 		return 0;
 	}
 	hostdata->state = NCR_700_HOST_BUSY;
@@ -1372,7 +1372,7 @@
 	 * set up so we cannot take a selection interrupt */
 
 	hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
-					       SCp->lun);
+					       SCp->device->lun);
 	/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
 	 * if the negotiated transfer parameters still hold, so
 	 * always renegotiate them */
@@ -1384,7 +1384,7 @@
 	 * If a contingent allegiance condition exists, the device
 	 * will refuse all tags, so send the request sense as untagged
 	 * */
-	if((hostdata->tag_negotiated & (1<<SCp->target))
+	if((hostdata->tag_negotiated & (1<<SCp->device->id))
 	   && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
 		count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
 	}
@@ -1401,7 +1401,7 @@
 
 
 	script_patch_ID(hostdata->script,
-			Device_ID, 1<<SCp->target);
+			Device_ID, 1<<SCp->device->id);
 
 	script_patch_32_abs(hostdata->script, CommandAddress, 
 			    slot->pCmd);
@@ -1410,7 +1410,7 @@
 	 * */
 	script_patch_32_abs(hostdata->script, SGScriptStartAddress,
 			    to32bit(&slot->pSG[0].ins));
-	NCR_700_clear_fifo(SCp->host);
+	NCR_700_clear_fifo(SCp->device->host);
 
 	if(slot->resume_offset == 0)
 		slot->resume_offset = hostdata->pScript;
@@ -1423,9 +1423,9 @@
 
 	/* set the synchronous period/offset */
 	NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
-		       SCp->host, SXFER_REG);
-	NCR_700_writel(slot->temp, SCp->host, TEMP_REG);
-	NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG);
+		       SCp->device->host, SXFER_REG);
+	NCR_700_writel(slot->temp, SCp->device->host, TEMP_REG);
+	NCR_700_writel(slot->resume_offset, SCp->device->host, DSP_REG);
 
 	return 1;
 }
@@ -1479,8 +1479,8 @@
 		       dsp, dsps));
 
 		if(SCp != NULL) {
-			pun = SCp->target;
-			lun = SCp->lun;
+			pun = SCp->device->id;
+			lun = SCp->device->lun;
 		}
 
 		if(sstat0 & SCSI_RESET_DETECTED) {
@@ -1718,10 +1718,10 @@
 	hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0];
 	len += sprintf(&buf[len], "Total commands outstanding: %d\n", hostdata->command_slot_count);
 	len += sprintf(&buf[len],"\
-Target	Depth  Active  Next Tag\n\
-======	=====  ======  ========\n");
+Target	Active  Next Tag\n\
+======	======  ========\n");
 	list_for_each_entry(SDp, &host->my_devices, siblings) {
-		len += sprintf(&buf[len]," %2d:%2d   %4d    %4d      %4d\n", SDp->id, SDp->lun, SDp->current_queue_depth, NCR_700_get_depth(SDp), SDp->current_tag);
+		len += sprintf(&buf[len]," %2d:%2d   %4d      %4d\n", SDp->id, SDp->lun, NCR_700_get_depth(SDp), SDp->current_tag);
 	}
 	if((len -= offset) <= 0)
 		return 0;
@@ -1735,7 +1735,7 @@
 NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 {
 	struct NCR_700_Host_Parameters *hostdata = 
-		(struct NCR_700_Host_Parameters *)SCp->host->hostdata[0];
+		(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
 	__u32 move_ins;
 	enum dma_data_direction direction;
 	struct NCR_700_command_slot *slot;
@@ -1743,7 +1743,7 @@
 	if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
 		/* We're over our allocation, this should never happen
 		 * since we report the max allocation to the mid layer */
-		printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->host->host_no);
+		printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->device->host->host_no);
 		return 1;
 	}
 	/* check for untagged commands.  We cannot have any outstanding
@@ -1753,16 +1753,16 @@
 	 * - The blk layer sent and untagged command
 	 */
 	if(NCR_700_get_depth(SCp->device) != 0
-	   && (!(hostdata->tag_negotiated & (1<<SCp->target))
+	   && (!(hostdata->tag_negotiated & (1<<SCp->device->id))
 	       || !blk_rq_tagged(SCp->request))) {
 		DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
-		       SCp->host->host_no, SCp->target, SCp->lun,
+		       SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
 		       NCR_700_get_depth(SCp->device)));
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 	if(NCR_700_get_depth(SCp->device) >= NCR_700_MAX_TAGS) {
 		DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
-		       SCp->host->host_no, SCp->target, SCp->lun,
+		       SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
 		       NCR_700_get_depth(SCp->device)));
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
@@ -1781,11 +1781,11 @@
 	SCp->SCp.buffer = NULL;
 
 #ifdef NCR_700_DEBUG
-	printk("53c700: scsi%d, command ", SCp->host->host_no);
+	printk("53c700: scsi%d, command ", SCp->device->host->host_no);
 	print_command(SCp->cmnd);
 #endif
 	if(SCp->device->tagged_supported && !SCp->device->tagged_queue
-	   && (hostdata->tag_negotiated &(1<<SCp->target)) == 0
+	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
 	   && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
 		/* upper layer has indicated tags are supported.  We don't
 		 * necessarily believe it yet.
@@ -1797,9 +1797,9 @@
 	}
 
 	if(blk_rq_tagged(SCp->request)
-	   && (hostdata->tag_negotiated &(1<<SCp->target)) == 0) {
-		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun);
-		hostdata->tag_negotiated |= (1<<SCp->target);
+	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0) {
+		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
+		hostdata->tag_negotiated |= (1<<SCp->device->id);
 		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
 	}
 
@@ -1810,15 +1810,15 @@
 	 * FIXME: This will royally screw up on multiple LUN devices
 	 * */
 	if(!blk_rq_tagged(SCp->request)
-	   && (hostdata->tag_negotiated &(1<<SCp->target))) {
-		printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun);
-		hostdata->tag_negotiated &= ~(1<<SCp->target);
+	   && (hostdata->tag_negotiated &(1<<SCp->device->id))) {
+		printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
+		hostdata->tag_negotiated &= ~(1<<SCp->device->id);
 	}
 
-	if((hostdata->tag_negotiated &(1<<SCp->target))) {
+	if((hostdata->tag_negotiated &(1<<SCp->device->id))) {
 		slot->tag = SCp->request->tag;
 		DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n",
-		       SCp->host->host_no, SCp->target, SCp->lun, slot->tag,
+		       SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag,
 		       slot));
 	} else {
 		slot->tag = SCSI_NO_TAG;
@@ -1920,7 +1920,7 @@
 	struct NCR_700_command_slot *slot;
 
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
-	       SCp->host->host_no, SCp->target, SCp->lun);
+	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
 	print_command(SCp->cmnd);
 
 	slot = (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1939,7 +1939,7 @@
 		 * occupying a slot.  Rather than allow this to
 		 * happen, we issue a bus reset to force all
 		 * outstanding commands to terminate here. */
-		NCR_700_internal_bus_reset(SCp->host);
+		NCR_700_internal_bus_reset(SCp->device->host);
 		/* still drop through and return failed */
 	}
 	return FAILED;
@@ -1950,9 +1950,9 @@
 NCR_700_bus_reset(Scsi_Cmnd * SCp)
 {
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
-	       SCp->host->host_no, SCp->target, SCp->lun, SCp);
+	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
 	print_command(SCp->cmnd);
-	NCR_700_internal_bus_reset(SCp->host);
+	NCR_700_internal_bus_reset(SCp->device->host);
 	return SUCCESS;
 }
 
@@ -1960,7 +1960,7 @@
 NCR_700_dev_reset(Scsi_Cmnd * SCp)
 {
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
-	       SCp->host->host_no, SCp->target, SCp->lun);
+	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
 	print_command(SCp->cmnd);
 	
 	return FAILED;
@@ -1970,11 +1970,11 @@
 NCR_700_host_reset(Scsi_Cmnd * SCp)
 {
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
-	       SCp->host->host_no, SCp->target, SCp->lun);
+	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
 	print_command(SCp->cmnd);
 
-	NCR_700_internal_bus_reset(SCp->host);
-	NCR_700_chip_reset(SCp->host);
+	NCR_700_internal_bus_reset(SCp->device->host);
+	NCR_700_chip_reset(SCp->device->host);
 	return SUCCESS;
 }
 
diff -Nru a/drivers/scsi/53c8xx_d.h_shipped b/drivers/scsi/53c8xx_d.h_shipped
--- a/drivers/scsi/53c8xx_d.h_shipped	Mon Feb 10 10:39:25 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2678 +0,0 @@
-/* DO NOT EDIT - Generated automatically by script_asm.pl */
-static u32 SCRIPT[] = {
-/*
-
-
-; NCR 53c810 driver, main script
-; Sponsored by 
-;	iX Multiuser Multitasking Magazine
-;	hm@ix.de
-;
-; Copyright 1993, 1994, 1995 Drew Eckhardt
-;      Visionary Computing 
-;      (Unix and Linux consulting and custom programming)
-;      drew@PoohSticks.ORG
-;      +1 (303) 786-7975
-;
-; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
-;
-; PRE-ALPHA
-;
-; For more information, please consult 
-;
-; NCR 53C810
-; PCI-SCSI I/O Processor
-; Data Manual
-;
-; NCR 53C710 
-; SCSI I/O Processor
-; Programmers Guide
-;
-; NCR Microelectronics
-; 1635 Aeroplaza Drive
-; Colorado Springs, CO 80916
-; 1+ (719) 578-3400
-;
-; Toll free literature number
-; +1 (800) 334-5454
-;
-; IMPORTANT : This code is self modifying due to the limitations of 
-;	the NCR53c7,8xx series chips.  Persons debugging this code with
-;	the remote debugger should take this into account, and NOT set
-;	breakpoints in modified instructions.
-;
-; Design:
-; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard 
-; microcontroller using a simple instruction set.   
-;
-; So, to minimize the effects of interrupt latency, and to maximize 
-; throughput, this driver offloads the practical maximum amount 
-; of processing to the SCSI chip while still maintaining a common
-; structure.
-;
-; Where tradeoffs were needed between efficiency on the older
-; chips and the newer NCR53c800 series, the NCR53c800 series 
-; was chosen.
-;
-; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
-; automate SCSI transfers without host processor intervention, this 
-; isn't the case with the NCR53c710 and newer chips which allow 
-;
-; - reads and writes to the internal registers from within the SCSI
-; 	scripts, allowing the SCSI SCRIPTS(tm) code to save processor
-; 	state so that multiple threads of execution are possible, and also
-; 	provide an ALU for loop control, etc.
-; 
-; - table indirect addressing for some instructions. This allows 
-;	pointers to be located relative to the DSA ((Data Structure
-;	Address) register.
-;
-; These features make it possible to implement a mailbox style interface,
-; where the same piece of code is run to handle I/O for multiple threads
-; at once minimizing our need to relocate code.  Since the NCR53c700/
-; NCR53c800 series have a unique combination of features, making a 
-; a standard ingoing/outgoing mailbox system, costly, I've modified it.
-;
-; - Mailboxes are a mixture of code and data.  This lets us greatly
-; 	simplify the NCR53c810 code and do things that would otherwise
-;	not be possible.
-;
-; The saved data pointer is now implemented as follows :
-;
-; 	Control flow has been architected such that if control reaches
-;	munge_save_data_pointer, on a restore pointers message or 
-;	reconnection, a jump to the address formerly in the TEMP register
-;	will allow the SCSI command to resume execution.
-;
-
-;
-; Note : the DSA structures must be aligned on 32 bit boundaries,
-; since the source and destination of MOVE MEMORY instructions 
-; must share the same alignment and this is the alignment of the
-; NCR registers.
-;
-
-ABSOLUTE dsa_temp_lun = 0		; Patch to lun for current dsa
-ABSOLUTE dsa_temp_next = 0		; Patch to dsa next for current dsa
-ABSOLUTE dsa_temp_addr_next = 0		; Patch to address of dsa next address 
-					; 	for current dsa
-ABSOLUTE dsa_temp_sync = 0		; Patch to address of per-target
-					;	sync routine
-ABSOLUTE dsa_temp_target = 0		; Patch to id for current dsa
-ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
-					; 	saved data pointer
-ABSOLUTE dsa_temp_addr_residual = 0	; Patch to address of per-command
-					;	current residual code
-ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
-					; saved residual code
-ABSOLUTE dsa_temp_addr_new_value = 0	; Address of value for JUMP operand
-ABSOLUTE dsa_temp_addr_array_value = 0 	; Address to copy to
-ABSOLUTE dsa_temp_addr_dsa_value = 0	; Address of this DSA value
-
-;
-; Once a device has initiated reselection, we need to compare it 
-; against the singly linked list of commands which have disconnected
-; and are pending reselection.  These commands are maintained in 
-; an unordered singly linked list of DSA structures, through the
-; DSA pointers at their 'centers' headed by the reconnect_dsa_head
-; pointer.
-; 
-; To avoid complications in removing commands from the list,
-; I minimize the amount of expensive (at eight operations per
-; addition @ 500-600ns each) pointer operations which must
-; be done in the NCR driver by precomputing them on the 
-; host processor during dsa structure generation.
-;
-; The fixed-up per DSA code knows how to recognize the nexus
-; associated with the corresponding SCSI command, and modifies
-; the source and destination pointers for the MOVE MEMORY 
-; instruction which is executed when reselected_ok is called
-; to remove the command from the list.  Similarly, DSA is 
-; loaded with the address of the next DSA structure and
-; reselected_check_next is called if a failure occurs.
-;
-; Perhaps more concisely, the net effect of the mess is 
-;
-; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, 
-;     src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
-; 	src = &dsa->next;
-; 	if (target_id == dsa->id && target_lun == dsa->lun) {
-; 		*dest = *src;
-; 		break;
-;         }	
-; }
-;
-; if (!dsa)
-;           error (int_err_unexpected_reselect);
-; else  
-;     longjmp (dsa->jump_resume, 0);
-;
-; 	
-
-
-; Define DSA structure used for mailboxes
-ENTRY dsa_code_template
-dsa_code_template:
-ENTRY dsa_code_begin
-dsa_code_begin:
-	MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000000 : */	0x78380000,0x00000000,
-/*
-	MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
-
-at 0x00000002 : */	0xc0000004,0x00000000,0x00000000,
-/*
-	MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000005 : */	0x78380000,0x00000000,
-/*
-	CALL scratch_to_dsa
-
-at 0x00000007 : */	0x88080000,0x00000980,
-/*
-	CALL select
-
-at 0x00000009 : */	0x88080000,0x000001fc,
-/*
-; Handle the phase mismatch which may have resulted from the 
-; MOVE FROM dsa_msgout if we returned here.  The CLEAR ATN 
-; may or may not be necessary, and we should update script_asm.pl
-; to handle multiple pieces.
-    CLEAR ATN
-
-at 0x0000000b : */	0x60000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x0000000d : */	0x60000040,0x00000000,
-/*
-
-; Replace second operand with address of JUMP instruction dest operand
-; in schedule table for this DSA.  Becomes dsa_jump_dest in 53c7,8xx.c.
-ENTRY dsa_code_fix_jump
-dsa_code_fix_jump:
-	MOVE MEMORY 4, NOP_insn, 0
-
-at 0x0000000f : */	0xc0000004,0x00000000,0x00000000,
-/*
-	JUMP select_done
-
-at 0x00000012 : */	0x80080000,0x00000224,
-/*
-
-; wrong_dsa loads the DSA register with the value of the dsa_next
-; field.
-;
-wrong_dsa:
-;		Patch the MOVE MEMORY INSTRUCTION such that 
-;		the destination address is the address of the OLD 
-;		next pointer.
-;
-	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8
-
-at 0x00000014 : */	0xc0000004,0x00000000,0x00000758,
-/*
-	MOVE dmode_memory_to_ncr TO DMODE	
-
-at 0x00000017 : */	0x78380000,0x00000000,
-/*
-;
-; 	Move the _contents_ of the next pointer into the DSA register as 
-;	the next I_T_L or I_T_L_Q tupple to check against the established
-;	nexus.
-;
-	MOVE MEMORY 4, dsa_temp_next, addr_scratch
-
-at 0x00000019 : */	0xc0000004,0x00000000,0x00000000,
-/*
-	MOVE dmode_memory_to_memory TO DMODE
-
-at 0x0000001c : */	0x78380000,0x00000000,
-/*
-	CALL scratch_to_dsa
-
-at 0x0000001e : */	0x88080000,0x00000980,
-/*
-	JUMP reselected_check_next
-
-at 0x00000020 : */	0x80080000,0x000006a4,
-/*
-
-ABSOLUTE dsa_save_data_pointer = 0
-ENTRY dsa_code_save_data_pointer
-dsa_code_save_data_pointer:
-    	MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000022 : */	0x78380000,0x00000000,
-/*
-    	MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
-
-at 0x00000024 : */	0xc0000004,0x00000000,0x00000000,
-/*
-    	MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000027 : */	0x78380000,0x00000000,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-    	MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-
-at 0x00000029 : */	0xc0000018,0x00000000,0x00000000,
-/*
-        CLEAR ACK
-
-at 0x0000002c : */	0x60000040,0x00000000,
-/*
-
-
-
-    	RETURN
-
-at 0x0000002e : */	0x90080000,0x00000000,
-/*
-ABSOLUTE dsa_restore_pointers = 0
-ENTRY dsa_code_restore_pointers
-dsa_code_restore_pointers:
-    	MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000030 : */	0x78380000,0x00000000,
-/*
-    	MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
-
-at 0x00000032 : */	0xc0000004,0x00000000,0x00000000,
-/*
-    	MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000035 : */	0x78380000,0x00000000,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
-    	MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-
-at 0x00000037 : */	0xc0000018,0x00000000,0x00000000,
-/*
-        CLEAR ACK
-
-at 0x0000003a : */	0x60000040,0x00000000,
-/*
-
-
-
-    	RETURN
-
-at 0x0000003c : */	0x90080000,0x00000000,
-/*
-
-ABSOLUTE dsa_check_reselect = 0
-; dsa_check_reselect determines whether or not the current target and
-; lun match the current DSA
-ENTRY dsa_code_check_reselect
-dsa_code_check_reselect:
-	MOVE SSID TO SFBR		; SSID contains 3 bit target ID
-
-at 0x0000003e : */	0x720a0000,0x00000000,
-/*
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-	JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
-
-at 0x00000040 : */	0x8084f800,0x00ffff48,
-/*
-;
-; Hack - move to scratch first, since SFBR is not writeable
-; 	via the CPU and hence a MOVE MEMORY instruction.
-;
-	MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000042 : */	0x78380000,0x00000000,
-/*
-	MOVE MEMORY 1, reselected_identify, addr_scratch
-
-at 0x00000044 : */	0xc0000001,0x00000000,0x00000000,
-/*
-	MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000047 : */	0x78380000,0x00000000,
-/*
-	MOVE SCRATCH0 TO SFBR
-
-at 0x00000049 : */	0x72340000,0x00000000,
-/*
-; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips
-	JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
-
-at 0x0000004b : */	0x8084f800,0x00ffff1c,
-/*
-;		Patch the MOVE MEMORY INSTRUCTION such that
-;		the source address is the address of this dsa's
-;		next pointer.
-	MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4
-
-at 0x0000004d : */	0xc0000004,0x00000000,0x00000754,
-/*
-	CALL reselected_ok
-
-at 0x00000050 : */	0x88080000,0x00000750,
-/*
-	CALL dsa_temp_sync	
-
-at 0x00000052 : */	0x88080000,0x00000000,
-/*
-; Release ACK on the IDENTIFY message _after_ we've set the synchronous 
-; transfer parameters! 
-	CLEAR ACK
-
-at 0x00000054 : */	0x60000040,0x00000000,
-/*
-; Implicitly restore pointers on reselection, so a RETURN
-; will transfer control back to the right spot.
-    	CALL REL (dsa_code_restore_pointers)
-
-at 0x00000056 : */	0x88880000,0x00ffff60,
-/*
-    	RETURN
-
-at 0x00000058 : */	0x90080000,0x00000000,
-/*
-ENTRY dsa_zero
-dsa_zero:
-ENTRY dsa_code_template_end
-dsa_code_template_end:
-
-; Perform sanity check for dsa_fields_start == dsa_code_template_end - 
-; dsa_zero, puke.
-
-ABSOLUTE dsa_fields_start =  0	; Sanity marker
-				; 	pad 48 bytes (fix this RSN)
-ABSOLUTE dsa_next = 48		; len 4 Next DSA
- 				; del 4 Previous DSA address
-ABSOLUTE dsa_cmnd = 56		; len 4 Scsi_Cmnd * for this thread.
-ABSOLUTE dsa_select = 60	; len 4 Device ID, Period, Offset for 
-			 	;	table indirect select
-ABSOLUTE dsa_msgout = 64	; len 8 table indirect move parameter for 
-				;       select message
-ABSOLUTE dsa_cmdout = 72	; len 8 table indirect move parameter for 
-				;	command
-ABSOLUTE dsa_dataout = 80	; len 4 code pointer for dataout
-ABSOLUTE dsa_datain = 84	; len 4 code pointer for datain
-ABSOLUTE dsa_msgin = 88		; len 8 table indirect move for msgin
-ABSOLUTE dsa_status = 96 	; len 8 table indirect move for status byte
-ABSOLUTE dsa_msgout_other = 104	; len 8 table indirect for normal message out
-				; (Synchronous transfer negotiation, etc).
-ABSOLUTE dsa_end = 112
-
-ABSOLUTE schedule = 0 		; Array of JUMP dsa_begin or JUMP (next),
-				; terminated by a call to JUMP wait_reselect
-
-; Linked lists of DSA structures
-ABSOLUTE reconnect_dsa_head = 0	; Link list of DSAs which can reconnect
-ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing
-				; address of reconnect_dsa_head
-
-; These select the source and destination of a MOVE MEMORY instruction
-ABSOLUTE dmode_memory_to_memory = 0x0
-ABSOLUTE dmode_memory_to_ncr = 0x0
-ABSOLUTE dmode_ncr_to_memory = 0x0
-
-ABSOLUTE addr_scratch = 0x0
-ABSOLUTE addr_temp = 0x0
-
-
-; Interrupts - 
-; MSB indicates type
-; 0	handle error condition
-; 1 	handle message 
-; 2 	handle normal condition
-; 3	debugging interrupt
-; 4 	testing interrupt 
-; Next byte indicates specific error
-
-; XXX not yet implemented, I'm not sure if I want to - 
-; Next byte indicates the routine the error occurred in
-; The LSB indicates the specific place the error occurred
- 
-ABSOLUTE int_err_unexpected_phase = 0x00000000	; Unexpected phase encountered
-ABSOLUTE int_err_selected = 0x00010000		; SELECTED (nee RESELECTED)
-ABSOLUTE int_err_unexpected_reselect = 0x00020000 
-ABSOLUTE int_err_check_condition = 0x00030000	
-ABSOLUTE int_err_no_phase = 0x00040000
-ABSOLUTE int_msg_wdtr = 0x01000000		; WDTR message received
-ABSOLUTE int_msg_sdtr = 0x01010000		; SDTR received
-ABSOLUTE int_msg_1 = 0x01020000			; single byte special message
-						; received
-
-ABSOLUTE int_norm_select_complete = 0x02000000	; Select complete, reprogram
-						; registers.
-ABSOLUTE int_norm_reselect_complete = 0x02010000	; Nexus established
-ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
-ABSOLUTE int_norm_disconnected = 0x02030000	; Disconnected 
-ABSOLUTE int_norm_aborted =0x02040000		; Aborted *dsa
-ABSOLUTE int_norm_reset = 0x02050000		; Generated BUS reset.
-ABSOLUTE int_debug_break = 0x03000000		; Break point
-
-ABSOLUTE int_debug_panic = 0x030b0000		; Panic driver
-
-
-ABSOLUTE int_test_1 = 0x04000000		; Test 1 complete
-ABSOLUTE int_test_2 = 0x04010000		; Test 2 complete
-ABSOLUTE int_test_3 = 0x04020000		; Test 3 complete
-
-
-; These should start with 0x05000000, with low bits incrementing for 
-; each one.
-
-
-						
-ABSOLUTE NCR53c7xx_msg_abort = 0	; Pointer to abort message
-ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
-ABSOLUTE NCR53c7xx_zero	= 0		; long with zero in it, use for source
-ABSOLUTE NCR53c7xx_sink = 0		; long to dump worthless data in
-ABSOLUTE NOP_insn = 0			; NOP instruction
-
-; Pointer to message, potentially multi-byte
-ABSOLUTE msg_buf = 0
-
-; Pointer to holding area for reselection information
-ABSOLUTE reselected_identify = 0
-ABSOLUTE reselected_tag = 0
-
-; Request sense command pointer, it's a 6 byte command, should
-; be constant for all commands since we always want 16 bytes of 
-; sense and we don't need to change any fields as we did under 
-; SCSI-I when we actually cared about the LUN field.
-;EXTERNAL NCR53c7xx_sense		; Request sense command
-
-
-; dsa_schedule  
-; PURPOSE : after a DISCONNECT message has been received, and pointers
-;	saved, insert the current DSA structure at the head of the 
-; 	disconnected queue and fall through to the scheduler.
-;
-; CALLS : OK
-;
-; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
-;	of disconnected commands
-;
-; MODIFIES : SCRATCH, reconnect_dsa_head
-; 
-; EXITS : always passes control to schedule
-
-ENTRY dsa_schedule
-dsa_schedule:
-
-
-
-
-;
-; Calculate the address of the next pointer within the DSA 
-; structure of the command that is currently disconnecting
-;
-    CALL dsa_to_scratch
-
-at 0x0000005a : */	0x88080000,0x00000938,
-/*
-    MOVE SCRATCH0 + dsa_next TO SCRATCH0
-
-at 0x0000005c : */	0x7e343000,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-
-at 0x0000005e : */	0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-
-at 0x00000060 : */	0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-at 0x00000062 : */	0x7f370000,0x00000000,
-/*
-
-; Point the next field of this DSA structure at the current disconnected 
-; list
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000064 : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
-
-at 0x00000066 : */	0xc0000004,0x00000000,0x000001b4,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000069 : */	0x78380000,0x00000000,
-/*
-dsa_schedule_insert:
-    MOVE MEMORY 4, reconnect_dsa_head, 0 
-
-at 0x0000006b : */	0xc0000004,0x00000000,0x00000000,
-/*
-
-; And update the head pointer.
-    CALL dsa_to_scratch
-
-at 0x0000006e : */	0x88080000,0x00000938,
-/*
-    MOVE dmode_ncr_to_memory TO DMODE	
-
-at 0x00000070 : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
-
-at 0x00000072 : */	0xc0000004,0x00000000,0x00000000,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000075 : */	0x78380000,0x00000000,
-/*
-
-
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000077 : */	0x7c027f00,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000079 : */	0x60000040,0x00000000,
-/*
-
-    WAIT DISCONNECT
-
-at 0x0000007b : */	0x48000000,0x00000000,
-/*
-
-
-
-
-
-
-    JUMP schedule
-
-at 0x0000007d : */	0x80080000,0x00000000,
-/*
-
-
-;
-; select
-;
-; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
-;	On success, the current DSA structure is removed from the issue 
-;	queue.  Usually, this is entered as a fall-through from schedule,
-;	although the contingent allegiance handling code will write
-;	the select entry address to the DSP to restart a command as a 
-;	REQUEST SENSE.  A message is sent (usually IDENTIFY, although
-;	additional SDTR or WDTR messages may be sent).  COMMAND OUT
-;	is handled.
-;
-; INPUTS : DSA - SCSI command, issue_dsa_head
-;
-; CALLS : NOT OK
-;
-; MODIFIES : SCRATCH, issue_dsa_head
-;
-; EXITS : on reselection or selection, go to select_failed
-;	otherwise, RETURN so control is passed back to 
-;	dsa_begin.
-;
-
-ENTRY select
-select:
-
-
-
-
-
-
-
-
-
-
-
-
-    CLEAR TARGET
-
-at 0x0000007f : */	0x60000200,0x00000000,
-/*
-
-; XXX
-;
-; In effect, SELECTION operations are backgrounded, with execution
-; continuing until code which waits for REQ or a fatal interrupt is 
-; encountered.
-;
-; So, for more performance, we could overlap the code which removes 
-; the command from the NCRs issue queue with the selection, but 
-; at this point I don't want to deal with the error recovery.
-;
-
-
-    SELECT ATN FROM dsa_select, select_failed
-
-at 0x00000081 : */	0x4300003c,0x000007a4,
-/*
-    JUMP select_msgout, WHEN MSG_OUT
-
-at 0x00000083 : */	0x860b0000,0x00000214,
-/*
-ENTRY select_msgout
-select_msgout:
-    MOVE FROM dsa_msgout, WHEN MSG_OUT
-
-at 0x00000085 : */	0x1e000000,0x00000040,
-/*
-
-
-
-
-
-
-
-
-
-
-   RETURN
-
-at 0x00000087 : */	0x90080000,0x00000000,
-/*
-
-; 
-; select_done
-; 
-; PURPOSE: continue on to normal data transfer; called as the exit 
-;	point from dsa_begin.
-;
-; INPUTS: dsa
-;
-; CALLS: OK
-;
-;
-
-select_done:
-
-
-
-
-
-
-
-; After a successful selection, we should get either a CMD phase or 
-; some transfer request negotiation message.
-
-    JUMP cmdout, WHEN CMD
-
-at 0x00000089 : */	0x820b0000,0x00000244,
-/*
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN 
-
-at 0x0000008b : */	0x9f030000,0x00000000,
-/*
-
-select_msg_in:
-    CALL msg_in, WHEN MSG_IN
-
-at 0x0000008d : */	0x8f0b0000,0x00000404,
-/*
-    JUMP select_msg_in, WHEN MSG_IN
-
-at 0x0000008f : */	0x870b0000,0x00000234,
-/*
-
-cmdout:
-    INT int_err_unexpected_phase, WHEN NOT CMD
-
-at 0x00000091 : */	0x9a030000,0x00000000,
-/*
-
-
-
-ENTRY cmdout_cmdout
-cmdout_cmdout:
-
-    MOVE FROM dsa_cmdout, WHEN CMD
-
-at 0x00000093 : */	0x1a000000,0x00000048,
-/*
-
-
-
-
-;
-; data_transfer  
-; other_out
-; other_in
-; other_transfer
-;
-; PURPOSE : handle the main data transfer for a SCSI command in 
-;	several parts.  In the first part, data_transfer, DATA_IN
-;	and DATA_OUT phases are allowed, with the user provided
-;	code (usually dynamically generated based on the scatter/gather
-;	list associated with a SCSI command) called to handle these 
-;	phases.
-;
-;	After control has passed to one of the user provided 
-;	DATA_IN or DATA_OUT routines, back calls are made to 
-;	other_transfer_in or other_transfer_out to handle non-DATA IN
-;	and DATA OUT phases respectively, with the state of the active
-;	data pointer being preserved in TEMP.
-;
-;	On completion, the user code passes control to other_transfer
-;	which causes DATA_IN and DATA_OUT to result in unexpected_phase
-;	interrupts so that data overruns may be trapped.
-;
-; INPUTS : DSA - SCSI command
-;
-; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
-;	other_transfer
-;
-; MODIFIES : SCRATCH
-;
-; EXITS : if STATUS IN is detected, signifying command completion,
-;	the NCR jumps to command_complete.  If MSG IN occurs, a 
-;	CALL is made to msg_in.  Otherwise, other_transfer runs in 
-;	an infinite loop.
-;	
-
-ENTRY data_transfer
-data_transfer:
-    JUMP cmdout_cmdout, WHEN CMD
-
-at 0x00000095 : */	0x820b0000,0x0000024c,
-/*
-    CALL msg_in, WHEN MSG_IN
-
-at 0x00000097 : */	0x8f0b0000,0x00000404,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x00000099 : */	0x9e0b0000,0x00000000,
-/*
-    JUMP do_dataout, WHEN DATA_OUT
-
-at 0x0000009b : */	0x800b0000,0x0000028c,
-/*
-    JUMP do_datain, WHEN DATA_IN
-
-at 0x0000009d : */	0x810b0000,0x000002e4,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x0000009f : */	0x830b0000,0x0000060c,
-/*
-    JUMP data_transfer
-
-at 0x000000a1 : */	0x80080000,0x00000254,
-/*
-ENTRY end_data_transfer
-end_data_transfer:
-
-;
-; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain 
-; should be fixed up whenever the nexus changes so it can point to the 
-; correct routine for that command.
-;
-
-
-; Nasty jump to dsa->dataout
-do_dataout:
-    CALL dsa_to_scratch
-
-at 0x000000a3 : */	0x88080000,0x00000938,
-/*
-    MOVE SCRATCH0 + dsa_dataout TO SCRATCH0	
-
-at 0x000000a5 : */	0x7e345000,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-
-at 0x000000a7 : */	0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-
-at 0x000000a9 : */	0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-
-at 0x000000ab : */	0x7f370000,0x00000000,
-/*
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000000ad : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
-
-at 0x000000af : */	0xc0000004,0x00000000,0x000002d4,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000000b2 : */	0x78380000,0x00000000,
-/*
-dataout_to_jump:
-    MOVE MEMORY 4, 0, dataout_jump + 4 
-
-at 0x000000b4 : */	0xc0000004,0x00000000,0x000002e0,
-/*
-dataout_jump:
-    JUMP 0
-
-at 0x000000b7 : */	0x80080000,0x00000000,
-/*
-
-; Nasty jump to dsa->dsain
-do_datain:
-    CALL dsa_to_scratch
-
-at 0x000000b9 : */	0x88080000,0x00000938,
-/*
-    MOVE SCRATCH0 + dsa_datain TO SCRATCH0	
-
-at 0x000000bb : */	0x7e345400,0x00000000,
-/*
-    MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY 
-
-at 0x000000bd : */	0x7f350000,0x00000000,
-/*
-    MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY 
-
-at 0x000000bf : */	0x7f360000,0x00000000,
-/*
-    MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY 
-
-at 0x000000c1 : */	0x7f370000,0x00000000,
-/*
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000000c3 : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
-
-at 0x000000c5 : */	0xc0000004,0x00000000,0x0000032c,
-/*
-    MOVE dmode_memory_to_memory TO DMODE		
-
-at 0x000000c8 : */	0x78380000,0x00000000,
-/*
-ENTRY datain_to_jump
-datain_to_jump:
-    MOVE MEMORY 4, 0, datain_jump + 4
-
-at 0x000000ca : */	0xc0000004,0x00000000,0x00000338,
-/*
-
-
-
-datain_jump:
-    JUMP 0
-
-at 0x000000cd : */	0x80080000,0x00000000,
-/*
-
-
-
-; Note that other_out and other_in loop until a non-data phase
-; is discovered, so we only execute return statements when we
-; can go on to the next data phase block move statement.
-
-ENTRY other_out
-other_out:
-
-
-
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000cf : */	0x9a0b0000,0x00000000,
-/*
-    JUMP msg_in_restart, WHEN MSG_IN 
-
-at 0x000000d1 : */	0x870b0000,0x000003e4,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000d3 : */	0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000d5 : */	0x990b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000d7 : */	0x830b0000,0x0000060c,
-/*
-    JUMP other_out, WHEN NOT DATA_OUT
-
-at 0x000000d9 : */	0x80030000,0x0000033c,
-/*
-    RETURN
-
-at 0x000000db : */	0x90080000,0x00000000,
-/*
-
-ENTRY other_in
-other_in:
-
-
-
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000dd : */	0x9a0b0000,0x00000000,
-/*
-    JUMP msg_in_restart, WHEN MSG_IN 
-
-at 0x000000df : */	0x870b0000,0x000003e4,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000e1 : */	0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000e3 : */	0x980b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000e5 : */	0x830b0000,0x0000060c,
-/*
-    JUMP other_in, WHEN NOT DATA_IN
-
-at 0x000000e7 : */	0x81030000,0x00000374,
-/*
-    RETURN
-
-at 0x000000e9 : */	0x90080000,0x00000000,
-/*
-
-
-ENTRY other_transfer
-other_transfer:
-    INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000eb : */	0x9a0b0000,0x00000000,
-/*
-    CALL msg_in, WHEN MSG_IN
-
-at 0x000000ed : */	0x8f0b0000,0x00000404,
-/*
-    INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000ef : */	0x9e0b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000f1 : */	0x980b0000,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000f3 : */	0x990b0000,0x00000000,
-/*
-    JUMP command_complete, WHEN STATUS
-
-at 0x000000f5 : */	0x830b0000,0x0000060c,
-/*
-    JUMP other_transfer
-
-at 0x000000f7 : */	0x80080000,0x000003ac,
-/*
-
-;
-; msg_in_restart
-; msg_in
-; munge_msg
-;
-; PURPOSE : process messages from a target.  msg_in is called when the 
-;	caller hasn't read the first byte of the message.  munge_message
-;	is called when the caller has read the first byte of the message,
-;	and left it in SFBR.  msg_in_restart is called when the caller 
-;	hasn't read the first byte of the message, and wishes RETURN
-;	to transfer control back to the address of the conditional
-;	CALL instruction rather than to the instruction after it.
-;
-;	Various int_* interrupts are generated when the host system
-;	needs to intervene, as is the case with SDTR, WDTR, and
-;	INITIATE RECOVERY messages.
-;
-;	When the host system handles one of these interrupts,
-;	it can respond by reentering at reject_message, 
-;	which rejects the message and returns control to
-;	the caller of msg_in or munge_msg, accept_message
-;	which clears ACK and returns control, or reply_message
-;	which sends the message pointed to by the DSA 
-;	msgout_other table indirect field.
-;
-;	DISCONNECT messages are handled by moving the command
-;	to the reconnect_dsa_queue.
-;
-; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
-;	only)
-;
-; CALLS : NO.  The TEMP register isn't backed up to allow nested calls.
-;
-; MODIFIES : SCRATCH, DSA on DISCONNECT
-;
-; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
-;	and normal return from message handlers running under
-;	Linux, control is returned to the caller.  Receipt
-;	of DISCONNECT messages pass control to dsa_schedule.
-;
-ENTRY msg_in_restart
-msg_in_restart:
-; XXX - hackish
-;
-; Since it's easier to debug changes to the statically 
-; compiled code, rather than the dynamically generated 
-; stuff, such as
-;
-; 	MOVE x, y, WHEN data_phase
-; 	CALL other_z, WHEN NOT data_phase
-; 	MOVE x, y, WHEN data_phase
-;
-; I'd like to have certain routines (notably the message handler)
-; restart on the conditional call rather than the next instruction.
-;
-; So, subtract 8 from the return address
-
-    MOVE TEMP0 + 0xf8 TO TEMP0
-
-at 0x000000f9 : */	0x7e1cf800,0x00000000,
-/*
-    MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
-
-at 0x000000fb : */	0x7f1dff00,0x00000000,
-/*
-    MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
-
-at 0x000000fd : */	0x7f1eff00,0x00000000,
-/*
-    MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
-
-at 0x000000ff : */	0x7f1fff00,0x00000000,
-/*
-
-ENTRY msg_in
-msg_in:
-    MOVE 1, msg_buf, WHEN MSG_IN
-
-at 0x00000101 : */	0x0f000001,0x00000000,
-/*
-
-munge_msg:
-    JUMP munge_extended, IF 0x01		; EXTENDED MESSAGE
-
-at 0x00000103 : */	0x800c0001,0x00000524,
-/*
-    JUMP munge_2, IF 0x20, AND MASK 0xdf	; two byte message
-
-at 0x00000105 : */	0x800cdf20,0x0000044c,
-/*
-;
-; XXX - I've seen a handful of broken SCSI devices which fail to issue
-; 	a SAVE POINTERS message before disconnecting in the middle of 
-; 	a transfer, assuming that the DATA POINTER will be implicitly 
-; 	restored.  
-;
-; Historically, I've often done an implicit save when the DISCONNECT
-; message is processed.  We may want to consider having the option of 
-; doing that here. 
-;
-    JUMP munge_save_data_pointer, IF 0x02	; SAVE DATA POINTER
-
-at 0x00000107 : */	0x800c0002,0x00000454,
-/*
-    JUMP munge_restore_pointers, IF 0x03	; RESTORE POINTERS 
-
-at 0x00000109 : */	0x800c0003,0x000004b8,
-/*
-    JUMP munge_disconnect, IF 0x04		; DISCONNECT
-
-at 0x0000010b : */	0x800c0004,0x0000051c,
-/*
-    INT int_msg_1, IF 0x07			; MESSAGE REJECT
-
-at 0x0000010d : */	0x980c0007,0x01020000,
-/*
-    INT int_msg_1, IF 0x0f			; INITIATE RECOVERY
-
-at 0x0000010f : */	0x980c000f,0x01020000,
-/*
-
-
-
-    JUMP reject_message
-
-at 0x00000111 : */	0x80080000,0x000005b4,
-/*
-
-munge_2:
-    JUMP reject_message
-
-at 0x00000113 : */	0x80080000,0x000005b4,
-/*
-;
-; The SCSI standard allows targets to recover from transient 
-; error conditions by backing up the data pointer with a 
-; RESTORE POINTERS message.  
-;	
-; So, we must save and restore the _residual_ code as well as 
-; the current instruction pointer.  Because of this messiness,
-; it is simpler to put dynamic code in the dsa for this and to
-; just do a simple jump down there. 
-;
-
-munge_save_data_pointer:
-    MOVE DSA0 + dsa_save_data_pointer TO SFBR
-
-at 0x00000115 : */	0x76100000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x00000117 : */	0x6a340000,0x00000000,
-/*
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x00000119 : */	0x7711ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x0000011b : */	0x6a350000,0x00000000,
-/*
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY 
-
-at 0x0000011d : */	0x7712ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x0000011f : */	0x6a360000,0x00000000,
-/*
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x00000121 : */	0x7713ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x00000123 : */	0x6a370000,0x00000000,
-/*
-
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000125 : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
-
-at 0x00000127 : */	0xc0000004,0x00000000,0x000004b4,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x0000012a : */	0x78380000,0x00000000,
-/*
-jump_dsa_save:
-    JUMP 0
-
-at 0x0000012c : */	0x80080000,0x00000000,
-/*
-
-munge_restore_pointers:
-    MOVE DSA0 + dsa_restore_pointers TO SFBR
-
-at 0x0000012e : */	0x76100000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x00000130 : */	0x6a340000,0x00000000,
-/*
-    MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x00000132 : */	0x7711ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x00000134 : */	0x6a350000,0x00000000,
-/*
-    MOVE DSA2 + 0xff TO SFBR WITH CARRY
-
-at 0x00000136 : */	0x7712ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x00000138 : */	0x6a360000,0x00000000,
-/*
-    MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x0000013a : */	0x7713ff00,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x0000013c : */	0x6a370000,0x00000000,
-/*
-
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x0000013e : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
-
-at 0x00000140 : */	0xc0000004,0x00000000,0x00000518,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000143 : */	0x78380000,0x00000000,
-/*
-jump_dsa_restore:
-    JUMP 0
-
-at 0x00000145 : */	0x80080000,0x00000000,
-/*
-
-
-munge_disconnect:
-
-
-
-
-
-
-
-
-
- 
-
-
-
-
-
-
-    JUMP dsa_schedule
-
-at 0x00000147 : */	0x80080000,0x00000168,
-/*
-
-
-
-
-
-munge_extended:
-    CLEAR ACK
-
-at 0x00000149 : */	0x60000040,0x00000000,
-/*
-    INT int_err_unexpected_phase, WHEN NOT MSG_IN
-
-at 0x0000014b : */	0x9f030000,0x00000000,
-/*
-    MOVE 1, msg_buf + 1, WHEN MSG_IN
-
-at 0x0000014d : */	0x0f000001,0x00000001,
-/*
-    JUMP munge_extended_2, IF 0x02
-
-at 0x0000014f : */	0x800c0002,0x00000554,
-/*
-    JUMP munge_extended_3, IF 0x03 
-
-at 0x00000151 : */	0x800c0003,0x00000584,
-/*
-    JUMP reject_message
-
-at 0x00000153 : */	0x80080000,0x000005b4,
-/*
-
-munge_extended_2:
-    CLEAR ACK
-
-at 0x00000155 : */	0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x00000157 : */	0x0f000001,0x00000002,
-/*
-    JUMP reject_message, IF NOT 0x02	; Must be WDTR
-
-at 0x00000159 : */	0x80040002,0x000005b4,
-/*
-    CLEAR ACK
-
-at 0x0000015b : */	0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 3, WHEN MSG_IN
-
-at 0x0000015d : */	0x0f000001,0x00000003,
-/*
-    INT int_msg_wdtr
-
-at 0x0000015f : */	0x98080000,0x01000000,
-/*
-
-munge_extended_3:
-    CLEAR ACK
-
-at 0x00000161 : */	0x60000040,0x00000000,
-/*
-    MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x00000163 : */	0x0f000001,0x00000002,
-/*
-    JUMP reject_message, IF NOT 0x01	; Must be SDTR
-
-at 0x00000165 : */	0x80040001,0x000005b4,
-/*
-    CLEAR ACK
-
-at 0x00000167 : */	0x60000040,0x00000000,
-/*
-    MOVE 2, msg_buf + 3, WHEN MSG_IN
-
-at 0x00000169 : */	0x0f000002,0x00000003,
-/*
-    INT int_msg_sdtr
-
-at 0x0000016b : */	0x98080000,0x01010000,
-/*
-
-ENTRY reject_message
-reject_message:
-    SET ATN
-
-at 0x0000016d : */	0x58000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x0000016f : */	0x60000040,0x00000000,
-/*
-    MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
-
-at 0x00000171 : */	0x0e000001,0x00000000,
-/*
-    RETURN
-
-at 0x00000173 : */	0x90080000,0x00000000,
-/*
-
-ENTRY accept_message
-accept_message:
-    CLEAR ATN
-
-at 0x00000175 : */	0x60000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000177 : */	0x60000040,0x00000000,
-/*
-    RETURN
-
-at 0x00000179 : */	0x90080000,0x00000000,
-/*
-
-ENTRY respond_message
-respond_message:
-    SET ATN
-
-at 0x0000017b : */	0x58000008,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x0000017d : */	0x60000040,0x00000000,
-/*
-    MOVE FROM dsa_msgout_other, WHEN MSG_OUT
-
-at 0x0000017f : */	0x1e000000,0x00000068,
-/*
-    RETURN
-
-at 0x00000181 : */	0x90080000,0x00000000,
-/*
-
-;
-; command_complete
-;
-; PURPOSE : handle command termination when STATUS IN is detected by reading
-;	a status byte followed by a command termination message. 
-;
-;	Normal termination results in an INTFLY instruction, and 
-;	the host system can pick out which command terminated by 
-;	examining the MESSAGE and STATUS buffers of all currently 
-;	executing commands;
-;
-;	Abnormal (CHECK_CONDITION) termination results in an
-;	int_err_check_condition interrupt so that a REQUEST SENSE
-;	command can be issued out-of-order so that no other command
-;	clears the contingent allegiance condition.
-;	
-;
-; INPUTS : DSA - command	
-;
-; CALLS : OK
-;
-; EXITS : On successful termination, control is passed to schedule.
-;	On abnormal termination, the user will usually modify the 
-;	DSA fields and corresponding buffers and return control
-;	to select.
-;
-
-ENTRY command_complete
-command_complete:
-    MOVE FROM dsa_status, WHEN STATUS
-
-at 0x00000183 : */	0x1b000000,0x00000060,
-/*
-
-    MOVE SFBR TO SCRATCH0		; Save status
-
-at 0x00000185 : */	0x6a340000,0x00000000,
-/*
-
-ENTRY command_complete_msgin
-command_complete_msgin:
-    MOVE FROM dsa_msgin, WHEN MSG_IN
-
-at 0x00000187 : */	0x1f000000,0x00000058,
-/*
-; Indicate that we should be expecting a disconnect
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000189 : */	0x7c027f00,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x0000018b : */	0x60000040,0x00000000,
-/*
-
-    WAIT DISCONNECT
-
-at 0x0000018d : */	0x48000000,0x00000000,
-/*
-
-;
-; The SCSI specification states that when a UNIT ATTENTION condition
-; is pending, as indicated by a CHECK CONDITION status message,
-; the target shall revert to asynchronous transfers.  Since
-; synchronous transfers parameters are maintained on a per INITIATOR/TARGET 
-; basis, and returning control to our scheduler could work on a command
-; running on another lun on that target using the old parameters, we must
-; interrupt the host processor to get them changed, or change them ourselves.
-;
-; Once SCSI-II tagged queueing is implemented, things will be even more
-; hairy, since contingent allegiance conditions exist on a per-target/lun
-; basis, and issuing a new command with a different tag would clear it.
-; In these cases, we must interrupt the host processor to get a request 
-; added to the HEAD of the queue with the request sense command, or we
-; must automatically issue the request sense command.
-
-
-
-
-
-    INTFLY
-
-at 0x0000018f : */	0x98180000,0x00000000,
-/*
-
-
-
-
-
-    JUMP schedule
-
-at 0x00000191 : */	0x80080000,0x00000000,
-/*
-command_failed:
-    INT int_err_check_condition
-
-at 0x00000193 : */	0x98080000,0x00030000,
-/*
-
-
-
-
-;
-; wait_reselect
-;
-; PURPOSE : This is essentially the idle routine, where control lands
-;	when there are no new processes to schedule.  wait_reselect
-;	waits for reselection, selection, and new commands.
-;
-;	When a successful reselection occurs, with the aid 
-;	of fixed up code in each DSA, wait_reselect walks the 
-;	reconnect_dsa_queue, asking each dsa if the target ID
-;	and LUN match its.
-;
-;	If a match is found, a call is made back to reselected_ok,
-;	which through the miracles of self modifying code, extracts
-;	the found DSA from the reconnect_dsa_queue and then 
-;	returns control to the DSAs thread of execution.
-;
-; INPUTS : NONE
-;
-; CALLS : OK
-;
-; MODIFIES : DSA,
-;
-; EXITS : On successful reselection, control is returned to the 
-;	DSA which called reselected_ok.  If the WAIT RESELECT
-;	was interrupted by a new commands arrival signaled by 
-;	SIG_P, control is passed to schedule.  If the NCR is 
-;	selected, the host system is interrupted with an 
-;	int_err_selected which is usually responded to by
-;	setting DSP to the target_abort address.
-
-ENTRY wait_reselect
-wait_reselect:
-
-
-
-
-
-
-    WAIT RESELECT wait_reselect_failed
-
-at 0x00000195 : */	0x50000000,0x0000076c,
-/*
-
-reselected:
-
-
-
-    CLEAR TARGET
-
-at 0x00000197 : */	0x60000200,0x00000000,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000199 : */	0x78380000,0x00000000,
-/*
-    ; Read all data needed to reestablish the nexus - 
-    MOVE 1, reselected_identify, WHEN MSG_IN
-
-at 0x0000019b : */	0x0f000001,0x00000000,
-/*
-    ; We used to CLEAR ACK here.
-
-
-
-
-
-    ; Point DSA at the current head of the disconnected queue.
-    MOVE dmode_memory_to_ncr  TO DMODE
-
-at 0x0000019d : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
-
-at 0x0000019f : */	0xc0000004,0x00000000,0x00000000,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000001a2 : */	0x78380000,0x00000000,
-/*
-    CALL scratch_to_dsa
-
-at 0x000001a4 : */	0x88080000,0x00000980,
-/*
-
-    ; Fix the update-next pointer so that the reconnect_dsa_head
-    ; pointer is the one that will be updated if this DSA is a hit 
-    ; and we remove it from the queue.
-
-    MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8
-
-at 0x000001a6 : */	0xc0000004,0x00000000,0x00000758,
-/*
-
-ENTRY reselected_check_next
-reselected_check_next:
-
-
-
-    ; Check for a NULL pointer.
-    MOVE DSA0 TO SFBR
-
-at 0x000001a9 : */	0x72100000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001ab : */	0x80040000,0x000006ec,
-/*
-    MOVE DSA1 TO SFBR
-
-at 0x000001ad : */	0x72110000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001af : */	0x80040000,0x000006ec,
-/*
-    MOVE DSA2 TO SFBR
-
-at 0x000001b1 : */	0x72120000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001b3 : */	0x80040000,0x000006ec,
-/*
-    MOVE DSA3 TO SFBR
-
-at 0x000001b5 : */	0x72130000,0x00000000,
-/*
-    JUMP reselected_not_end, IF NOT 0
-
-at 0x000001b7 : */	0x80040000,0x000006ec,
-/*
-    INT int_err_unexpected_reselect
-
-at 0x000001b9 : */	0x98080000,0x00020000,
-/*
-
-reselected_not_end:
-    ;
-    ; XXX the ALU is only eight bits wide, and the assembler
-    ; wont do the dirt work for us.  As long as dsa_check_reselect
-    ; is negative, we need to sign extend with 1 bits to the full
-    ; 32 bit width of the address.
-    ;
-    ; A potential work around would be to have a known alignment 
-    ; of the DSA structure such that the base address plus 
-    ; dsa_check_reselect doesn't require carrying from bytes 
-    ; higher than the LSB.
-    ;
-
-    MOVE DSA0 TO SFBR
-
-at 0x000001bb : */	0x72100000,0x00000000,
-/*
-    MOVE SFBR + dsa_check_reselect TO SCRATCH0
-
-at 0x000001bd : */	0x6e340000,0x00000000,
-/*
-    MOVE DSA1 TO SFBR
-
-at 0x000001bf : */	0x72110000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
-
-at 0x000001c1 : */	0x6f35ff00,0x00000000,
-/*
-    MOVE DSA2 TO SFBR
-
-at 0x000001c3 : */	0x72120000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
-
-at 0x000001c5 : */	0x6f36ff00,0x00000000,
-/*
-    MOVE DSA3 TO SFBR
-
-at 0x000001c7 : */	0x72130000,0x00000000,
-/*
-    MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
-
-at 0x000001c9 : */	0x6f37ff00,0x00000000,
-/*
-
-    MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000001cb : */	0x78380000,0x00000000,
-/*
-    MOVE MEMORY 4, addr_scratch, reselected_check + 4
-
-at 0x000001cd : */	0xc0000004,0x00000000,0x0000074c,
-/*
-    MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000001d0 : */	0x78380000,0x00000000,
-/*
-reselected_check:
-    JUMP 0
-
-at 0x000001d2 : */	0x80080000,0x00000000,
-/*
-
-
-;
-;
-ENTRY reselected_ok
-reselected_ok:
-    MOVE MEMORY 4, 0, 0				; Patched : first word
-
-at 0x000001d4 : */	0xc0000004,0x00000000,0x00000000,
-/*
-						; 	is address of 
-						;       successful dsa_next
-						; Second word is last 
-						;	unsuccessful dsa_next,
-						;	starting with 
-						;       dsa_reconnect_head
-    ; We used to CLEAR ACK here.
-
-
-
-
-
-
-    RETURN					; Return control to where
-
-at 0x000001d7 : */	0x90080000,0x00000000,
-/*
-
-
-
-
-selected:
-    INT int_err_selected;
-
-at 0x000001d9 : */	0x98080000,0x00010000,
-/*
-
-;
-; A select or reselect failure can be caused by one of two conditions : 
-; 1.  SIG_P was set.  This will be the case if the user has written
-;	a new value to a previously NULL head of the issue queue.
-;
-; 2.  The NCR53c810 was selected or reselected by another device.
-;
-; 3.  The bus was already busy since we were selected or reselected
-;	before starting the command.
-
-wait_reselect_failed:
-
-
-
-; Check selected bit.  
-    MOVE SIST0 & 0x20 TO SFBR
-
-at 0x000001db : */	0x74422000,0x00000000,
-/*
-    JUMP selected, IF 0x20
-
-at 0x000001dd : */	0x800c0020,0x00000764,
-/*
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR	
-
-at 0x000001df : */	0x741a4000,0x00000000,
-/*
-    JUMP schedule, IF 0x40
-
-at 0x000001e1 : */	0x800c0040,0x00000000,
-/*
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-    MOVE ISTAT & 0x08 TO SFBR
-
-at 0x000001e3 : */	0x74140800,0x00000000,
-/*
-    JUMP reselected, IF 0x08
-
-at 0x000001e5 : */	0x800c0008,0x0000065c,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
-    INT int_debug_panic
-
-at 0x000001e7 : */	0x98080000,0x030b0000,
-/*
-
-
-
-select_failed:
-
-
-
-; Otherwise, mask the selected and reselected bits off SIST0
-    MOVE SIST0 & 0x30 TO SFBR
-
-at 0x000001e9 : */	0x74423000,0x00000000,
-/*
-    JUMP selected, IF 0x20
-
-at 0x000001eb : */	0x800c0020,0x00000764,
-/*
-    JUMP reselected, IF 0x10 
-
-at 0x000001ed : */	0x800c0010,0x0000065c,
-/*
-; If SIGP is set, the user just gave us another command, and
-; we should restart or return to the scheduler.
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
-    MOVE CTEST2 & 0x40 TO SFBR	
-
-at 0x000001ef : */	0x741a4000,0x00000000,
-/*
-    JUMP select, IF 0x40
-
-at 0x000001f1 : */	0x800c0040,0x000001fc,
-/*
-; Check connected bit.  
-; FIXME: this needs to change if we support target mode
-; FIXME: is this really necessary? 
-    MOVE ISTAT & 0x08 TO SFBR
-
-at 0x000001f3 : */	0x74140800,0x00000000,
-/*
-    JUMP reselected, IF 0x08
-
-at 0x000001f5 : */	0x800c0008,0x0000065c,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
-    INT int_debug_panic
-
-at 0x000001f7 : */	0x98080000,0x030b0000,
-/*
-
-
-;
-; test_1
-; test_2
-;
-; PURPOSE : run some verification tests on the NCR.  test_1
-;	copies test_src to test_dest and interrupts the host
-;	processor, testing for cache coherency and interrupt
-; 	problems in the processes.
-;
-;	test_2 runs a command with offsets relative to the 
-;	DSA on entry, and is useful for miscellaneous experimentation.
-;
-
-; Verify that interrupts are working correctly and that we don't 
-; have a cache invalidation problem.
-
-ABSOLUTE test_src = 0, test_dest = 0
-ENTRY test_1
-test_1:
-    MOVE MEMORY 4, test_src, test_dest
-
-at 0x000001f9 : */	0xc0000004,0x00000000,0x00000000,
-/*
-    INT int_test_1
-
-at 0x000001fc : */	0x98080000,0x04000000,
-/*
-
-;
-; Run arbitrary commands, with test code establishing a DSA
-;
- 
-ENTRY test_2
-test_2:
-    CLEAR TARGET
-
-at 0x000001fe : */	0x60000200,0x00000000,
-/*
-    SELECT ATN FROM 0, test_2_fail
-
-at 0x00000200 : */	0x43000000,0x00000850,
-/*
-    JUMP test_2_msgout, WHEN MSG_OUT
-
-at 0x00000202 : */	0x860b0000,0x00000810,
-/*
-ENTRY test_2_msgout
-test_2_msgout:
-    MOVE FROM 8, WHEN MSG_OUT
-
-at 0x00000204 : */	0x1e000000,0x00000008,
-/*
-    MOVE FROM 16, WHEN CMD 
-
-at 0x00000206 : */	0x1a000000,0x00000010,
-/*
-    MOVE FROM 24, WHEN DATA_IN
-
-at 0x00000208 : */	0x19000000,0x00000018,
-/*
-    MOVE FROM 32, WHEN STATUS
-
-at 0x0000020a : */	0x1b000000,0x00000020,
-/*
-    MOVE FROM 40, WHEN MSG_IN
-
-at 0x0000020c : */	0x1f000000,0x00000028,
-/*
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x0000020e : */	0x7c027f00,0x00000000,
-/*
-    CLEAR ACK
-
-at 0x00000210 : */	0x60000040,0x00000000,
-/*
-    WAIT DISCONNECT
-
-at 0x00000212 : */	0x48000000,0x00000000,
-/*
-test_2_fail:
-    INT int_test_2
-
-at 0x00000214 : */	0x98080000,0x04010000,
-/*
-
-ENTRY debug_break
-debug_break:
-    INT int_debug_break
-
-at 0x00000216 : */	0x98080000,0x03000000,
-/*
-
-;
-; initiator_abort
-; target_abort
-;
-; PURPOSE : Abort the currently established nexus from with initiator
-;	or target mode.
-;
-;  
-
-ENTRY target_abort
-target_abort:
-    SET TARGET
-
-at 0x00000218 : */	0x58000200,0x00000000,
-/*
-    DISCONNECT
-
-at 0x0000021a : */	0x48000000,0x00000000,
-/*
-    CLEAR TARGET
-
-at 0x0000021c : */	0x60000200,0x00000000,
-/*
-    JUMP schedule
-
-at 0x0000021e : */	0x80080000,0x00000000,
-/*
-    
-ENTRY initiator_abort
-initiator_abort:
-    SET ATN
-
-at 0x00000220 : */	0x58000008,0x00000000,
-/*
-;
-; The SCSI-I specification says that targets may go into MSG out at 
-; their leisure upon receipt of the ATN single.  On all versions of the 
-; specification, we can't change phases until REQ transitions true->false, 
-; so we need to sink/source one byte of data to allow the transition.
-;
-; For the sake of safety, we'll only source one byte of data in all 
-; cases, but to accommodate the SCSI-I dain bramage, we'll sink an  
-; arbitrary number of bytes.
-    JUMP spew_cmd, WHEN CMD
-
-at 0x00000222 : */	0x820b0000,0x000008b8,
-/*
-    JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000224 : */	0x870b0000,0x000008c8,
-/*
-    JUMP eat_datain, WHEN DATA_IN
-
-at 0x00000226 : */	0x810b0000,0x000008f8,
-/*
-    JUMP eat_status, WHEN STATUS
-
-at 0x00000228 : */	0x830b0000,0x000008e0,
-/*
-    JUMP spew_dataout, WHEN DATA_OUT
-
-at 0x0000022a : */	0x800b0000,0x00000910,
-/*
-    JUMP sated
-
-at 0x0000022c : */	0x80080000,0x00000918,
-/*
-spew_cmd:
-    MOVE 1, NCR53c7xx_zero, WHEN CMD
-
-at 0x0000022e : */	0x0a000001,0x00000000,
-/*
-    JUMP sated
-
-at 0x00000230 : */	0x80080000,0x00000918,
-/*
-eat_msgin:
-    MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
-
-at 0x00000232 : */	0x0f000001,0x00000000,
-/*
-    JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000234 : */	0x870b0000,0x000008c8,
-/*
-    JUMP sated
-
-at 0x00000236 : */	0x80080000,0x00000918,
-/*
-eat_status:
-    MOVE 1, NCR53c7xx_sink, WHEN STATUS
-
-at 0x00000238 : */	0x0b000001,0x00000000,
-/*
-    JUMP eat_status, WHEN STATUS
-
-at 0x0000023a : */	0x830b0000,0x000008e0,
-/*
-    JUMP sated
-
-at 0x0000023c : */	0x80080000,0x00000918,
-/*
-eat_datain:
-    MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
-
-at 0x0000023e : */	0x09000001,0x00000000,
-/*
-    JUMP eat_datain, WHEN DATA_IN
-
-at 0x00000240 : */	0x810b0000,0x000008f8,
-/*
-    JUMP sated
-
-at 0x00000242 : */	0x80080000,0x00000918,
-/*
-spew_dataout:
-    MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
-
-at 0x00000244 : */	0x08000001,0x00000000,
-/*
-sated:
-    MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000246 : */	0x7c027f00,0x00000000,
-/*
-    MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
-
-at 0x00000248 : */	0x0e000001,0x00000000,
-/*
-    WAIT DISCONNECT
-
-at 0x0000024a : */	0x48000000,0x00000000,
-/*
-    INT int_norm_aborted
-
-at 0x0000024c : */	0x98080000,0x02040000,
-/*
-
-;
-; dsa_to_scratch
-; scratch_to_dsa
-;
-; PURPOSE :
-; 	The NCR chips cannot do a move memory instruction with the DSA register 
-; 	as the source or destination.  So, we provide a couple of subroutines
-; 	that let us switch between the DSA register and scratch register.
-;
-; 	Memory moves to/from the DSPS  register also don't work, but we 
-; 	don't use them.
-;
-;
-
- 
-dsa_to_scratch:
-    MOVE DSA0 TO SFBR
-
-at 0x0000024e : */	0x72100000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH0
-
-at 0x00000250 : */	0x6a340000,0x00000000,
-/*
-    MOVE DSA1 TO SFBR
-
-at 0x00000252 : */	0x72110000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH1
-
-at 0x00000254 : */	0x6a350000,0x00000000,
-/*
-    MOVE DSA2 TO SFBR
-
-at 0x00000256 : */	0x72120000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH2
-
-at 0x00000258 : */	0x6a360000,0x00000000,
-/*
-    MOVE DSA3 TO SFBR
-
-at 0x0000025a : */	0x72130000,0x00000000,
-/*
-    MOVE SFBR TO SCRATCH3
-
-at 0x0000025c : */	0x6a370000,0x00000000,
-/*
-    RETURN
-
-at 0x0000025e : */	0x90080000,0x00000000,
-/*
-
-scratch_to_dsa:
-    MOVE SCRATCH0 TO SFBR
-
-at 0x00000260 : */	0x72340000,0x00000000,
-/*
-    MOVE SFBR TO DSA0
-
-at 0x00000262 : */	0x6a100000,0x00000000,
-/*
-    MOVE SCRATCH1 TO SFBR
-
-at 0x00000264 : */	0x72350000,0x00000000,
-/*
-    MOVE SFBR TO DSA1
-
-at 0x00000266 : */	0x6a110000,0x00000000,
-/*
-    MOVE SCRATCH2 TO SFBR
-
-at 0x00000268 : */	0x72360000,0x00000000,
-/*
-    MOVE SFBR TO DSA2
-
-at 0x0000026a : */	0x6a120000,0x00000000,
-/*
-    MOVE SCRATCH3 TO SFBR
-
-at 0x0000026c : */	0x72370000,0x00000000,
-/*
-    MOVE SFBR TO DSA3
-
-at 0x0000026e : */	0x6a130000,0x00000000,
-/*
-    RETURN
-
-at 0x00000270 : */	0x90080000,0x00000000,
-};
-
-#define A_NCR53c7xx_msg_abort	0x00000000
-static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = {
-	0x00000249,
-};
-
-#define A_NCR53c7xx_msg_reject	0x00000000
-static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = {
-	0x00000172,
-};
-
-#define A_NCR53c7xx_sink	0x00000000
-static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = {
-	0x00000233,
-	0x00000239,
-	0x0000023f,
-};
-
-#define A_NCR53c7xx_zero	0x00000000
-static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = {
-	0x0000022f,
-	0x00000245,
-};
-
-#define A_NOP_insn	0x00000000
-static u32 A_NOP_insn_used[] __attribute((unused)) = {
-	0x00000010,
-};
-
-#define A_addr_reconnect_dsa_head	0x00000000
-static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = {
-	0x000001a7,
-};
-
-#define A_addr_scratch	0x00000000
-static u32 A_addr_scratch_used[] __attribute((unused)) = {
-	0x00000004,
-	0x0000001b,
-	0x00000046,
-	0x00000067,
-	0x00000073,
-	0x000000b0,
-	0x000000c6,
-	0x00000128,
-	0x00000141,
-	0x000001a1,
-	0x000001ce,
-};
-
-#define A_addr_temp	0x00000000
-static u32 A_addr_temp_used[] __attribute((unused)) = {
-	0x00000025,
-	0x00000034,
-};
-
-#define A_dmode_memory_to_memory	0x00000000
-static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = {
-	0x00000005,
-	0x0000001c,
-	0x00000027,
-	0x00000035,
-	0x00000047,
-	0x00000069,
-	0x00000075,
-	0x000000b2,
-	0x000000c8,
-	0x0000012a,
-	0x00000143,
-	0x00000199,
-	0x000001a2,
-	0x000001d0,
-};
-
-#define A_dmode_memory_to_ncr	0x00000000
-static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = {
-	0x00000000,
-	0x00000017,
-	0x00000030,
-	0x00000042,
-	0x0000019d,
-};
-
-#define A_dmode_ncr_to_memory	0x00000000
-static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = {
-	0x00000022,
-	0x00000064,
-	0x00000070,
-	0x000000ad,
-	0x000000c3,
-	0x00000125,
-	0x0000013e,
-	0x000001cb,
-};
-
-#define A_dsa_check_reselect	0x00000000
-static u32 A_dsa_check_reselect_used[] __attribute((unused)) = {
-	0x000001bd,
-};
-
-#define A_dsa_cmdout	0x00000048
-static u32 A_dsa_cmdout_used[] __attribute((unused)) = {
-	0x00000094,
-};
-
-#define A_dsa_cmnd	0x00000038
-static u32 A_dsa_cmnd_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_datain	0x00000054
-static u32 A_dsa_datain_used[] __attribute((unused)) = {
-	0x000000bb,
-};
-
-#define A_dsa_dataout	0x00000050
-static u32 A_dsa_dataout_used[] __attribute((unused)) = {
-	0x000000a5,
-};
-
-#define A_dsa_end	0x00000070
-static u32 A_dsa_end_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_fields_start	0x00000000
-static u32 A_dsa_fields_start_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_msgin	0x00000058
-static u32 A_dsa_msgin_used[] __attribute((unused)) = {
-	0x00000188,
-};
-
-#define A_dsa_msgout	0x00000040
-static u32 A_dsa_msgout_used[] __attribute((unused)) = {
-	0x00000086,
-};
-
-#define A_dsa_msgout_other	0x00000068
-static u32 A_dsa_msgout_other_used[] __attribute((unused)) = {
-	0x00000180,
-};
-
-#define A_dsa_next	0x00000030
-static u32 A_dsa_next_used[] __attribute((unused)) = {
-	0x0000005c,
-};
-
-#define A_dsa_restore_pointers	0x00000000
-static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = {
-	0x0000012e,
-};
-
-#define A_dsa_save_data_pointer	0x00000000
-static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = {
-	0x00000115,
-};
-
-#define A_dsa_select	0x0000003c
-static u32 A_dsa_select_used[] __attribute((unused)) = {
-	0x00000081,
-};
-
-#define A_dsa_status	0x00000060
-static u32 A_dsa_status_used[] __attribute((unused)) = {
-	0x00000184,
-};
-
-#define A_dsa_temp_addr_array_value	0x00000000
-static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_temp_addr_dsa_value	0x00000000
-static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = {
-	0x00000003,
-};
-
-#define A_dsa_temp_addr_new_value	0x00000000
-static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_temp_addr_next	0x00000000
-static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = {
-	0x00000015,
-	0x0000004e,
-};
-
-#define A_dsa_temp_addr_residual	0x00000000
-static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = {
-	0x0000002a,
-	0x00000039,
-};
-
-#define A_dsa_temp_addr_saved_pointer	0x00000000
-static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = {
-	0x00000026,
-	0x00000033,
-};
-
-#define A_dsa_temp_addr_saved_residual	0x00000000
-static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = {
-	0x0000002b,
-	0x00000038,
-};
-
-#define A_dsa_temp_lun	0x00000000
-static u32 A_dsa_temp_lun_used[] __attribute((unused)) = {
-	0x0000004b,
-};
-
-#define A_dsa_temp_next	0x00000000
-static u32 A_dsa_temp_next_used[] __attribute((unused)) = {
-	0x0000001a,
-};
-
-#define A_dsa_temp_sync	0x00000000
-static u32 A_dsa_temp_sync_used[] __attribute((unused)) = {
-	0x00000053,
-};
-
-#define A_dsa_temp_target	0x00000000
-static u32 A_dsa_temp_target_used[] __attribute((unused)) = {
-	0x00000040,
-};
-
-#define A_int_debug_break	0x03000000
-static u32 A_int_debug_break_used[] __attribute((unused)) = {
-	0x00000217,
-};
-
-#define A_int_debug_panic	0x030b0000
-static u32 A_int_debug_panic_used[] __attribute((unused)) = {
-	0x000001e8,
-	0x000001f8,
-};
-
-#define A_int_err_check_condition	0x00030000
-static u32 A_int_err_check_condition_used[] __attribute((unused)) = {
-	0x00000194,
-};
-
-#define A_int_err_no_phase	0x00040000
-static u32 A_int_err_no_phase_used[] __attribute((unused)) = {
-};
-
-#define A_int_err_selected	0x00010000
-static u32 A_int_err_selected_used[] __attribute((unused)) = {
-	0x000001da,
-};
-
-#define A_int_err_unexpected_phase	0x00000000
-static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = {
-	0x0000008c,
-	0x00000092,
-	0x0000009a,
-	0x000000d0,
-	0x000000d4,
-	0x000000d6,
-	0x000000de,
-	0x000000e2,
-	0x000000e4,
-	0x000000ec,
-	0x000000f0,
-	0x000000f2,
-	0x000000f4,
-	0x0000014c,
-};
-
-#define A_int_err_unexpected_reselect	0x00020000
-static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = {
-	0x000001ba,
-};
-
-#define A_int_msg_1	0x01020000
-static u32 A_int_msg_1_used[] __attribute((unused)) = {
-	0x0000010e,
-	0x00000110,
-};
-
-#define A_int_msg_sdtr	0x01010000
-static u32 A_int_msg_sdtr_used[] __attribute((unused)) = {
-	0x0000016c,
-};
-
-#define A_int_msg_wdtr	0x01000000
-static u32 A_int_msg_wdtr_used[] __attribute((unused)) = {
-	0x00000160,
-};
-
-#define A_int_norm_aborted	0x02040000
-static u32 A_int_norm_aborted_used[] __attribute((unused)) = {
-	0x0000024d,
-};
-
-#define A_int_norm_command_complete	0x02020000
-static u32 A_int_norm_command_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_disconnected	0x02030000
-static u32 A_int_norm_disconnected_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_reselect_complete	0x02010000
-static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_reset	0x02050000
-static u32 A_int_norm_reset_used[] __attribute((unused)) = {
-};
-
-#define A_int_norm_select_complete	0x02000000
-static u32 A_int_norm_select_complete_used[] __attribute((unused)) = {
-};
-
-#define A_int_test_1	0x04000000
-static u32 A_int_test_1_used[] __attribute((unused)) = {
-	0x000001fd,
-};
-
-#define A_int_test_2	0x04010000
-static u32 A_int_test_2_used[] __attribute((unused)) = {
-	0x00000215,
-};
-
-#define A_int_test_3	0x04020000
-static u32 A_int_test_3_used[] __attribute((unused)) = {
-};
-
-#define A_msg_buf	0x00000000
-static u32 A_msg_buf_used[] __attribute((unused)) = {
-	0x00000102,
-	0x0000014e,
-	0x00000158,
-	0x0000015e,
-	0x00000164,
-	0x0000016a,
-};
-
-#define A_reconnect_dsa_head	0x00000000
-static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = {
-	0x0000006c,
-	0x00000074,
-	0x000001a0,
-};
-
-#define A_reselected_identify	0x00000000
-static u32 A_reselected_identify_used[] __attribute((unused)) = {
-	0x00000045,
-	0x0000019c,
-};
-
-#define A_reselected_tag	0x00000000
-static u32 A_reselected_tag_used[] __attribute((unused)) = {
-};
-
-#define A_schedule	0x00000000
-static u32 A_schedule_used[] __attribute((unused)) = {
-	0x0000007e,
-	0x00000192,
-	0x000001e2,
-	0x0000021f,
-};
-
-#define A_test_dest	0x00000000
-static u32 A_test_dest_used[] __attribute((unused)) = {
-	0x000001fb,
-};
-
-#define A_test_src	0x00000000
-static u32 A_test_src_used[] __attribute((unused)) = {
-	0x000001fa,
-};
-
-#define Ent_accept_message	0x000005d4
-#define Ent_cmdout_cmdout	0x0000024c
-#define Ent_command_complete	0x0000060c
-#define Ent_command_complete_msgin	0x0000061c
-#define Ent_data_transfer	0x00000254
-#define Ent_datain_to_jump	0x00000328
-#define Ent_debug_break	0x00000858
-#define Ent_dsa_code_begin	0x00000000
-#define Ent_dsa_code_check_reselect	0x000000f8
-#define Ent_dsa_code_fix_jump	0x0000003c
-#define Ent_dsa_code_restore_pointers	0x000000c0
-#define Ent_dsa_code_save_data_pointer	0x00000088
-#define Ent_dsa_code_template	0x00000000
-#define Ent_dsa_code_template_end	0x00000168
-#define Ent_dsa_schedule	0x00000168
-#define Ent_dsa_zero	0x00000168
-#define Ent_end_data_transfer	0x0000028c
-#define Ent_initiator_abort	0x00000880
-#define Ent_msg_in	0x00000404
-#define Ent_msg_in_restart	0x000003e4
-#define Ent_other_in	0x00000374
-#define Ent_other_out	0x0000033c
-#define Ent_other_transfer	0x000003ac
-#define Ent_reject_message	0x000005b4
-#define Ent_reselected_check_next	0x000006a4
-#define Ent_reselected_ok	0x00000750
-#define Ent_respond_message	0x000005ec
-#define Ent_select	0x000001fc
-#define Ent_select_msgout	0x00000214
-#define Ent_target_abort	0x00000860
-#define Ent_test_1	0x000007e4
-#define Ent_test_2	0x000007f8
-#define Ent_test_2_msgout	0x00000810
-#define Ent_wait_reselect	0x00000654
-static u32 LABELPATCHES[] __attribute((unused)) = {
-	0x00000008,
-	0x0000000a,
-	0x00000013,
-	0x00000016,
-	0x0000001f,
-	0x00000021,
-	0x0000004f,
-	0x00000051,
-	0x0000005b,
-	0x00000068,
-	0x0000006f,
-	0x00000082,
-	0x00000084,
-	0x0000008a,
-	0x0000008e,
-	0x00000090,
-	0x00000096,
-	0x00000098,
-	0x0000009c,
-	0x0000009e,
-	0x000000a0,
-	0x000000a2,
-	0x000000a4,
-	0x000000b1,
-	0x000000b6,
-	0x000000ba,
-	0x000000c7,
-	0x000000cc,
-	0x000000d2,
-	0x000000d8,
-	0x000000da,
-	0x000000e0,
-	0x000000e6,
-	0x000000e8,
-	0x000000ee,
-	0x000000f6,
-	0x000000f8,
-	0x00000104,
-	0x00000106,
-	0x00000108,
-	0x0000010a,
-	0x0000010c,
-	0x00000112,
-	0x00000114,
-	0x00000129,
-	0x00000142,
-	0x00000148,
-	0x00000150,
-	0x00000152,
-	0x00000154,
-	0x0000015a,
-	0x00000166,
-	0x00000196,
-	0x000001a5,
-	0x000001a8,
-	0x000001ac,
-	0x000001b0,
-	0x000001b4,
-	0x000001b8,
-	0x000001cf,
-	0x000001de,
-	0x000001e6,
-	0x000001ec,
-	0x000001ee,
-	0x000001f2,
-	0x000001f6,
-	0x00000201,
-	0x00000203,
-	0x00000223,
-	0x00000225,
-	0x00000227,
-	0x00000229,
-	0x0000022b,
-	0x0000022d,
-	0x00000231,
-	0x00000235,
-	0x00000237,
-	0x0000023b,
-	0x0000023d,
-	0x00000241,
-	0x00000243,
-};
-
-static struct {
-	u32	offset;
-	void		*address;
-} EXTERNAL_PATCHES[] __attribute((unused)) = {
-};
-
-static u32 INSTRUCTIONS __attribute((unused))	= 301;
-static u32 PATCHES __attribute((unused))	= 81;
-static u32 EXTERNAL_PATCHES_LEN __attribute((unused))	= 0;
diff -Nru a/drivers/scsi/53c8xx_u.h_shipped b/drivers/scsi/53c8xx_u.h_shipped
--- a/drivers/scsi/53c8xx_u.h_shipped	Mon Feb 10 10:39:29 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,97 +0,0 @@
-#undef A_NCR53c7xx_msg_abort
-#undef A_NCR53c7xx_msg_reject
-#undef A_NCR53c7xx_sink
-#undef A_NCR53c7xx_zero
-#undef A_NOP_insn
-#undef A_addr_reconnect_dsa_head
-#undef A_addr_scratch
-#undef A_addr_temp
-#undef A_dmode_memory_to_memory
-#undef A_dmode_memory_to_ncr
-#undef A_dmode_ncr_to_memory
-#undef A_dsa_check_reselect
-#undef A_dsa_cmdout
-#undef A_dsa_cmnd
-#undef A_dsa_datain
-#undef A_dsa_dataout
-#undef A_dsa_end
-#undef A_dsa_fields_start
-#undef A_dsa_msgin
-#undef A_dsa_msgout
-#undef A_dsa_msgout_other
-#undef A_dsa_next
-#undef A_dsa_restore_pointers
-#undef A_dsa_save_data_pointer
-#undef A_dsa_select
-#undef A_dsa_status
-#undef A_dsa_temp_addr_array_value
-#undef A_dsa_temp_addr_dsa_value
-#undef A_dsa_temp_addr_new_value
-#undef A_dsa_temp_addr_next
-#undef A_dsa_temp_addr_residual
-#undef A_dsa_temp_addr_saved_pointer
-#undef A_dsa_temp_addr_saved_residual
-#undef A_dsa_temp_lun
-#undef A_dsa_temp_next
-#undef A_dsa_temp_sync
-#undef A_dsa_temp_target
-#undef A_int_debug_break
-#undef A_int_debug_panic
-#undef A_int_err_check_condition
-#undef A_int_err_no_phase
-#undef A_int_err_selected
-#undef A_int_err_unexpected_phase
-#undef A_int_err_unexpected_reselect
-#undef A_int_msg_1
-#undef A_int_msg_sdtr
-#undef A_int_msg_wdtr
-#undef A_int_norm_aborted
-#undef A_int_norm_command_complete
-#undef A_int_norm_disconnected
-#undef A_int_norm_reselect_complete
-#undef A_int_norm_reset
-#undef A_int_norm_select_complete
-#undef A_int_test_1
-#undef A_int_test_2
-#undef A_int_test_3
-#undef A_msg_buf
-#undef A_reconnect_dsa_head
-#undef A_reselected_identify
-#undef A_reselected_tag
-#undef A_schedule
-#undef A_test_dest
-#undef A_test_src
-#undef Ent_accept_message
-#undef Ent_cmdout_cmdout
-#undef Ent_command_complete
-#undef Ent_command_complete_msgin
-#undef Ent_data_transfer
-#undef Ent_datain_to_jump
-#undef Ent_debug_break
-#undef Ent_dsa_code_begin
-#undef Ent_dsa_code_check_reselect
-#undef Ent_dsa_code_fix_jump
-#undef Ent_dsa_code_restore_pointers
-#undef Ent_dsa_code_save_data_pointer
-#undef Ent_dsa_code_template
-#undef Ent_dsa_code_template_end
-#undef Ent_dsa_schedule
-#undef Ent_dsa_zero
-#undef Ent_end_data_transfer
-#undef Ent_initiator_abort
-#undef Ent_msg_in
-#undef Ent_msg_in_restart
-#undef Ent_other_in
-#undef Ent_other_out
-#undef Ent_other_transfer
-#undef Ent_reject_message
-#undef Ent_reselected_check_next
-#undef Ent_reselected_ok
-#undef Ent_respond_message
-#undef Ent_select
-#undef Ent_select_msgout
-#undef Ent_target_abort
-#undef Ent_test_1
-#undef Ent_test_2
-#undef Ent_test_2_msgout
-#undef Ent_wait_reselect
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/AM53C974.c	Mon Feb 10 10:39:27 2003
@@ -897,7 +897,7 @@
 static int AM53C974_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
 	unsigned long flags;
-	struct Scsi_Host *instance = cmd->host;
+	struct Scsi_Host *instance = cmd->device->host;
 	struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp;
 
@@ -906,7 +906,7 @@
 	DEB_QUEUE(printk(SEPARATOR_LINE));
 	DEB_QUEUE(printk("scsi%d: AM53C974_queue_command called\n", instance->host_no));
 	DEB_QUEUE(printk("cmd=%02x target=%02x lun=%02x bufflen=%d use_sg = %02x\n",
-			 cmd->cmnd[0], cmd->target, cmd->lun, cmd->request_bufflen, cmd->use_sg));
+			 cmd->cmnd[0], cmd->target, cmd->device->lun, cmd->request_bufflen, cmd->use_sg));
 
 /* We use the host_scribble field as a pointer to the next command in a queue */
 	cmd->host_scribble = NULL;
@@ -978,7 +978,7 @@
 				for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp;
 				     prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) {
 					/*  When we find one, remove it from the issue queue. */
-					if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
+					if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
 						if (prev) {
 							REMOVE(prev, (Scsi_Cmnd *) (prev->host_scribble), tmp,
 							       (Scsi_Cmnd *) (tmp->host_scribble));
@@ -1127,7 +1127,7 @@
 #endif
 		printk("scsi%d : PARITY error\n", instance->host_no);
 		if (hostdata->connected)
-			hostdata->sync_off[hostdata->connected->target] = 0;	/* setup asynchronous transfer */
+			hostdata->sync_off[hostdata->connected->device->id] = 0;	/* setup asynchronous transfer */
 		hostdata->aborted = 1;
 	}
 	if (statreg & STATREG_IOE) {
@@ -1209,7 +1209,7 @@
 			  (hostdata->sel_cmd->cmnd[0] == REQUEST_SENSE) ?
 					TAG_NONE : TAG_NEXT);
 			hostdata->selecting = 0;
-			AM53C974_set_sync(instance, hostdata->sel_cmd->target);
+			AM53C974_set_sync(instance, hostdata->sel_cmd->device->id);
 			restore_flags(flags);
 			return;
 		}
@@ -1243,7 +1243,7 @@
 #ifdef SCSI2
 				if (!hostdata->connected->device->tagged_queue)
 #endif
-					hostdata->busy[hostdata->connected->target] |= (1 << hostdata->connected->lun);
+					hostdata->busy[hostdata->connected->device->id] |= (1 << hostdata->connected->device->lun);
 				/* very strange -- use_sg is sometimes nonzero for request sense commands !! */
 				if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) {
 					DEB(printk("scsi%d: REQUEST_SENSE command with nonzero use_sg\n", instance->host_no));
@@ -1318,9 +1318,9 @@
 	if (hostdata->disconnecting) {
 		/* target sent disconnect message, so we are prepared */
 		cmd = (Scsi_Cmnd *) hostdata->connected;
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		DEB_INTR(printk("scsi%d : disc. from cmnd %d for ta %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->target, cmd->device->lun));
 		if (cmd->device->disconnect) {
 			/* target wants to reselect later */
 			DEB_INTR(printk("ok, re-enabling selection\n"));
@@ -1329,7 +1329,7 @@
 			hostdata->disconnected_queue = cmd;
 			DEB_QUEUE(printk("scsi%d : command for target %d lun %d this %d was moved from connected to"
 					 "  the disconnected_queue\n", instance->host_no, cmd->target,
-					 cmd->lun, hostdata->disconnected_queue->SCp.this_residual));
+					 cmd->device->lun, hostdata->disconnected_queue->SCp.this_residual));
 			DEB_QUEUE(AM53C974_print_queues(instance));
 			goto EXIT_UNFINISHED;
 		} else {
@@ -1355,9 +1355,9 @@
 #ifdef AM53C974_DEBUG
 		deb_stop = 1;
 #endif
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		printk("scsi%d: Unexpected disconnect; phase: %d; target: %d; this_residual: %d; buffers_residual: %d; message: %d\n",
-		       instance->host_no, cmd->SCp.phase, cmd->target, cmd->SCp.this_residual, cmd->SCp.buffers_residual,
+		       instance->host_no, cmd->SCp.phase, cmd->device->id, cmd->SCp.this_residual, cmd->SCp.buffers_residual,
 		       cmd->SCp.Message);
 		printk("cmdreg: 0x%02x; statreg: 0x%02x; isreg: 0x%02x; cfifo: 0x%02x\n",
 		       AM53C974_read_8(CMDREG), AM53C974_read_8(STATREG), AM53C974_read_8(ISREG),
@@ -1366,7 +1366,7 @@
 		if ((hostdata->last_message[0] == EXTENDED_MESSAGE) &&
 		    (hostdata->last_message[2] == EXTENDED_SDTR)) {
 			/* sync. negotiation was aborted, setup asynchronous transfer with target */
-			hostdata->sync_off[cmd->target] = 0;
+			hostdata->sync_off[cmd->device->id] = 0;
 		}
 		if (hostdata->aborted || hostdata->msgout[0] == ABORT)
 			cmd->result = DID_ABORT << 16;
@@ -1382,14 +1382,14 @@
 	hostdata->selecting = 0;
 	hostdata->disconnecting = 0;
 	hostdata->dma_busy = 0;
-	hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+	hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 	AM53C974_write_8(CMDREG, CMDREG_CFIFO);
 	DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
 		   (long) hostdata->issue_queue, (long) hostdata->disconnected_queue));
 	cmd->scsi_done(cmd);
 
 	if (!hostdata->selecting) {
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		AM53C974_write_8(CMDREG, CMDREG_ESR);
 	}			/* allow reselect */
 	return;
@@ -1405,7 +1405,7 @@
 	DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
 		   (long) hostdata->issue_queue, (long) hostdata->disconnected_queue));
 	if (!hostdata->selecting) {
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		AM53C974_write_8(CMDREG, CMDREG_ESR);
 	}			/* allow reselect */
 	return;
@@ -1573,7 +1573,7 @@
 		case PHASE_MSGIN:
 		    DEB_INFO(printk("Message-In phase; cmd=0x%lx, sel_cmd=0x%lx\n",
 		  (long) hostdata->connected, (long) hostdata->sel_cmd));
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		if (cmd->SCp.phase == PHASE_DATAIN)
 			AM53C974_dma_blast(instance, dmastatus, statreg);
 		if ((cmd->SCp.phase == PHASE_DATAOUT) && (AM53C974_read_8(DMACMD) & DMACMD_START)) {
@@ -1603,13 +1603,13 @@
 			ret = AM53C974_message(instance, cmd, cmd->SCp.Message);
 		}
 		cmd->SCp.phase = PHASE_MSGIN;
-		AM53C974_set_sync(instance, cmd->target);
+		AM53C974_set_sync(instance, cmd->device->id);
 		break;
 		case PHASE_MSGOUT:
 		    DEB_INFO(printk("Message-Out phase; cfifo=%d; msgout[0]=0x%02x\n",
 				    AM53C974_read_8(CFIREG) & CFIREG_CF, hostdata->msgout[0]));
 		AM53C974_write_8(DMACMD, DMACMD_IDLE);
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		for (i = 0; i < sizeof(hostdata->last_message); i++)
 			hostdata->last_message[i] = hostdata->msgout[i];
 		if ((hostdata->msgout[0] == 0) || INSIDE(hostdata->msgout[0], 0x02, 0x1F) ||
@@ -1635,24 +1635,24 @@
 		AM53C974_write_8(CMDREG, CMDREG_IT);
 		cmd->SCp.phase = PHASE_MSGOUT;
 		hostdata->msgout[0] = NOP;
-		AM53C974_set_sync(instance, cmd->target);
+		AM53C974_set_sync(instance, cmd->device->id);
 		break;
 
 		case PHASE_CMDOUT:
 		    DEB_INFO(printk("Command-Out phase\n"));
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		for (i = 0; i < cmd->cmd_len; i++)
 			AM53C974_write_8(FFREG, cmd->cmnd[i]);
 		AM53C974_write_8(CMDREG, CMDREG_IT);
 		cmd->SCp.phase = PHASE_CMDOUT;
-		AM53C974_set_sync(instance, cmd->target);
+		AM53C974_set_sync(instance, cmd->device->id);
 		break;
 
 		case PHASE_STATIN:
 		    DEB_INFO(printk("Status phase\n"));
 		if (cmd->SCp.phase == PHASE_DATAIN)
 			AM53C974_dma_blast(instance, dmastatus, statreg);
-		AM53C974_set_async(instance, cmd->target);
+		AM53C974_set_async(instance, cmd->device->id);
 		if (cmd->SCp.phase == PHASE_DATAOUT) {
 			unsigned long residual;
 
@@ -1724,12 +1724,12 @@
 		    case LINKED_FLG_CMD_COMPLETE:
 		/* Accept message by releasing ACK */
 		    DEB_LINKED(printk("scsi%d : target %d lun %d linked command complete.\n",
-			      instance->host_no, cmd->target, cmd->lun));
+			      instance->host_no, cmd->device->id, cmd->device->lun));
 		/* Sanity check : A linked command should only terminate with
 		 * one of these messages if there are more linked commands available. */
 		if (!cmd->next_link) {
 			printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
-			       instance->host_no, cmd->target, cmd->lun);
+			       instance->host_no, cmd->device->id, cmd->device->lun);
 			hostdata->aborted = 1;
 			AM53C974_write_8(CMDREG, CMDREG_SATN);
 			AM53C974_write_8(CMDREG, CMDREG_MA);
@@ -1747,7 +1747,7 @@
 		cmd->next_link->tag = cmd->tag;
 		cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
 		DEB_LINKED(printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
-			      instance->host_no, cmd->target, cmd->lun));
+			      instance->host_no, cmd->device->id, cmd->device->lun));
 		cmd->scsi_done(cmd);
 		cmd = hostdata->connected;
 		break;
@@ -1757,7 +1757,7 @@
 		case ABORT:
 		    case COMMAND_COMPLETE:
 		    DEB_MSG(printk("scsi%d: command complete message received; cmd %d for target %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun));
 		hostdata->disconnecting = 1;
 		cmd->device->disconnect = 0;
 
@@ -1807,22 +1807,22 @@
 
 		case MESSAGE_REJECT:
 		    DEB_MSG(printk("scsi%d: reject message received; cmd %d for target %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun));
 		switch (hostdata->last_message[0]) {
 			case EXTENDED_MESSAGE:
 			    if (hostdata->last_message[2] == EXTENDED_SDTR) {
 				/* sync. negotiation was rejected, setup asynchronous transfer with target */
 				printk("\ntarget %d: rate=%d Mhz, asynchronous (sync. negotiation rejected)\n",
-				       cmd->target, DEF_CLK / DEF_STP);
-				hostdata->sync_off[cmd->target] = 0;
-				hostdata->sync_per[cmd->target] = DEF_STP;
+				       cmd->device->id, DEF_CLK / DEF_STP);
+				hostdata->sync_off[cmd->device->id] = 0;
+				hostdata->sync_per[cmd->device->id] = DEF_STP;
 			}
 			break;
 			case HEAD_OF_QUEUE_TAG:
 			    case ORDERED_QUEUE_TAG:
 			    case SIMPLE_QUEUE_TAG:
 			    cmd->device->tagged_queue = 0;
-			hostdata->busy[cmd->target] |= (1 << cmd->lun);
+			hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 			break;
 			default:
 			    break;
@@ -1834,7 +1834,7 @@
 
 		case DISCONNECT:
 		    DEB_MSG(printk("scsi%d: disconnect message received; cmd %d for target %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun));
 		cmd->device->disconnect = 1;
 		hostdata->disconnecting = 1;
 		AM53C974_write_8(CMDREG, CMDREG_MA);	/* Accept message by clearing ACK */
@@ -1843,7 +1843,7 @@
 		case SAVE_POINTERS:
 		    case RESTORE_POINTERS:
 		    DEB_MSG(printk("scsi%d: save/restore pointers message received; cmd %d for target %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun));
 		/* The SCSI data pointer is *IMPLICITLY* saved on a disconnect
 		 * operation, in violation of the SCSI spec so we can safely 
 		 * ignore SAVE/RESTORE pointers calls.
@@ -1862,7 +1862,7 @@
 
 		case EXTENDED_MESSAGE:
 		    DEB_MSG(printk("scsi%d: extended message received; cmd %d for target %d, lun %d\n",
-		instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
+		instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun));
 		/* Extended messages are sent in the following format :
 		 * Byte    
 		 * 0           EXTENDED_MESSAGE == 1
@@ -1907,7 +1907,7 @@
 
 		/* check message */
 		if (extended_msg[2] == EXTENDED_SDTR)
-			ret = AM53C974_sync_neg(instance, cmd->target, extended_msg);
+			ret = AM53C974_sync_neg(instance, cmd->device->id, extended_msg);
 		if (ret || hostdata->aborted)
 			AM53C974_write_8(CMDREG, CMDREG_SATN);
 
@@ -1962,9 +1962,9 @@
 		AM53C974_write_8(CMDREG, CMDREG_CFIFO);		/* clear FIFO */
 	}
 #ifdef AM53C974_PROHIBIT_DISCONNECT
-	tmp[0] = IDENTIFY(0, cmd->lun);
+	tmp[0] = IDENTIFY(0, cmd->device->lun);
 #else
-	tmp[0] = IDENTIFY(1, cmd->lun);
+	tmp[0] = IDENTIFY(1, cmd->device->lun);
 #endif
 
 #ifdef SCSI2
@@ -1995,16 +1995,16 @@
 /* in case of an inquiry or req. sense command with no sync. neg performed yet, we start
    sync negotiation via start stops and transfer the command in cmdout phase */
 	if (((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REQUEST_SENSE)) &&
-	    !(hostdata->sync_neg[cmd->target]) && hostdata->sync_en[cmd->target]) {
-		hostdata->sync_neg[cmd->target] = 1;
+	    !(hostdata->sync_neg[cmd->device->id]) && hostdata->sync_en[cmd->device->id]) {
+		hostdata->sync_neg[cmd->device->id] = 1;
 		hostdata->msgout[0] = EXTENDED_MESSAGE;
 		hostdata->msgout[1] = 3;
 		hostdata->msgout[2] = EXTENDED_SDTR;
-		hostdata->msgout[3] = 250 / (int) hostdata->max_rate[cmd->target];
-		hostdata->msgout[4] = hostdata->max_offset[cmd->target];
+		hostdata->msgout[3] = 250 / (int) hostdata->max_rate[cmd->device->id];
+		hostdata->msgout[4] = hostdata->max_offset[cmd->device->id];
 		len += 5;
 	}
-	AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->target);	/* setup dest. id  */
+	AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->device->id);	/* setup dest. id  */
 	AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT);	/* setup timeout reg */
 	switch (len) {
 	case 1:
@@ -2110,7 +2110,7 @@
  * just reestablished, and remove it from the disconnected queue. */
 	for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
 	     tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
-		if ((target == tmp->target) && (lun == tmp->lun)
+		if ((target == tmp->device->id) && (lun == tmp->device->lun)
 #ifdef SCSI2
 		    && (tag == tmp->tag)
 #endif
@@ -2279,7 +2279,7 @@
 {
 	AM53C974_local_declare();
 	unsigned long flags;
-	struct Scsi_Host *instance = cmd->host;
+	struct Scsi_Host *instance = cmd->device->host;
 	struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp, **prev;
 
@@ -2388,7 +2388,7 @@
 	AM53C974_local_declare();
 	unsigned long flags;
 	int i;
-	struct Scsi_Host *instance = cmd->host;
+	struct Scsi_Host *instance = cmd->device->host;
 	struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata;
 	AM53C974_setio(instance);
 
diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
--- a/drivers/scsi/BusLogic.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/BusLogic.c	Mon Feb 10 10:39:32 2003
@@ -3471,15 +3471,15 @@
 			  void (*CompletionRoutine)(SCSI_Command_T *))
 {
   BusLogic_HostAdapter_T *HostAdapter =
-    (BusLogic_HostAdapter_T *) Command->host->hostdata;
+    (BusLogic_HostAdapter_T *) Command->device->host->hostdata;
   BusLogic_TargetFlags_T *TargetFlags =
-    &HostAdapter->TargetFlags[Command->target];
+    &HostAdapter->TargetFlags[Command->device->id];
   BusLogic_TargetStatistics_T *TargetStatistics =
     HostAdapter->TargetStatistics;
   unsigned char *CDB = Command->cmnd;
   int CDB_Length = Command->cmd_len;
-  int TargetID = Command->target;
-  int LogicalUnit = Command->lun;
+  int TargetID = Command->device->id;
+  int LogicalUnit = Command->device->lun;
   void *BufferPointer = Command->request_buffer;
   int BufferLength = Command->request_bufflen;
   int SegmentCount = Command->use_sg;
@@ -3708,8 +3708,9 @@
 int BusLogic_AbortCommand(SCSI_Command_T *Command)
 {
   BusLogic_HostAdapter_T *HostAdapter =
-    (BusLogic_HostAdapter_T *) Command->host->hostdata;
-  int TargetID = Command->target;
+    (BusLogic_HostAdapter_T *) Command->device->host->hostdata;
+
+  int TargetID = Command->device->id;
   BusLogic_CCB_T *CCB;
   int Result;
   BusLogic_IncrementErrorCounter(
@@ -3835,7 +3836,7 @@
   else
     {
       BusLogic_IncrementErrorCounter(
-	&HostAdapter->TargetStatistics[Command->target]
+	&HostAdapter->TargetStatistics[Command->device->id]
 		      .HostAdapterResetsRequested);
       HardReset = true;
     }
@@ -3845,7 +3846,7 @@
   */
   if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
     {
-      TargetID = Command->target;
+      TargetID = Command->device->id;
       if (Command->serial_number != Command->serial_number_at_timeout)
 	{
 	  BusLogic_Warning("Unable to Reset Command to Target %d - "
@@ -3890,9 +3891,9 @@
   else
     {
       BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
-		       HostAdapter->FullModelName, Command->target);
+		       HostAdapter->FullModelName, Command->device->id);
       BusLogic_IncrementErrorCounter(
-	&HostAdapter->TargetStatistics[Command->target]
+	&HostAdapter->TargetStatistics[Command->device->id]
 		      .HostAdapterResetsAttempted);
     }
   /*
@@ -3908,7 +3909,7 @@
     }
   if (Command != NULL)
     BusLogic_IncrementErrorCounter(
-      &HostAdapter->TargetStatistics[Command->target]
+      &HostAdapter->TargetStatistics[Command->device->id]
 		    .HostAdapterResetsCompleted);
   /*
     Mark all currently executing CCBs as having been Reset.
@@ -3975,7 +3976,7 @@
 				       SCSI_Command_T *Command,
 				       unsigned int ResetFlags)
 {
-  int TargetID = Command->target;
+  int TargetID = Command->device->id;
   BusLogic_CCB_T *CCB, *XCCB;
   int Result = -1;
   BusLogic_IncrementErrorCounter(
@@ -4152,8 +4153,8 @@
 int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
 {
   BusLogic_HostAdapter_T *HostAdapter =
-    (BusLogic_HostAdapter_T *) Command->host->hostdata;
-  int TargetID = Command->target;
+    (BusLogic_HostAdapter_T *) Command->device->host->hostdata;
+  int TargetID = Command->device->id;
   BusLogic_ErrorRecoveryStrategy_T
     ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
   /*
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/Kconfig	Mon Feb 10 10:39:32 2003
@@ -13,7 +13,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.o.  If you want to compile it as a
+	  The module will be called sd_mod.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
 	  module if your root file system (the one containing the directory /)
@@ -32,7 +32,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st.o. If you want to compile it as a
+	  The module will be called st. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -57,7 +57,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called osst.o. If you want to compile it as a
+	  The module will be called osst. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -72,7 +72,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod.o. If you want to compile it as a
+	  The module will be called sr_mod. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt> and
 	  <file:Documentation/scsi/scsi.txt>.
 
@@ -108,7 +108,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.o.
+	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
 	  If unsure, say N.
 
 comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
@@ -176,6 +176,9 @@
 config SGIWD93_SCSI
 	tristate "SGI WD93C93 SCSI Driver"
 	depends on SGI_IP22 && SCSI
+  	help
+	  If you have a Western Digital WD93 SCSI controller on
+	  an SGI MIPS system, say Y.  Otherwise, say N.
 
 config SCSI_DECNCR
 	tristate "DEC NCR53C94 Scsi Driver"
@@ -211,7 +214,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wd7000.o.  If you want to compile it as a
+	  The module will be called wd7000.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_ACARD
@@ -222,7 +225,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called atp870u.o. If you want to compile it as a
+	  The module will be called atp870u. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_AHA152X
@@ -239,7 +242,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aha152x.o. If you want to compile it as a
+	  The module will be called aha152x. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_AHA1542
@@ -256,7 +259,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called aha1542.o.
+	  will be called aha1542.
 
 config SCSI_AHA1740
 	tristate "Adaptec AHA1740 support"
@@ -270,7 +273,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aha1740.o.  If you want to compile it as a
+	  The module will be called aha1740.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_AACRAID
@@ -318,7 +321,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called aic7xxx_old.o.
+	  will be called aic7xxx_old.
 
 source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
 
@@ -335,7 +338,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  dpt_i2o.o.
+	  dpt_i2o.
 
 config SCSI_ADVANSYS
 	tristate "AdvanSys SCSI support"
@@ -349,7 +352,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  advansys.o.
+	  advansys.
 
 config SCSI_IN2000
 	tristate "Always IN2000 SCSI support"
@@ -363,7 +366,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called in2000.o.
+	  will be called in2000.
 
 # does not use pci dma and seems to be isa/onboard only for old machines
 config SCSI_AM53C974
@@ -382,7 +385,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called AM53C974.o.
+	  will be called AM53C974.
 
 config SCSI_MEGARAID
 	tristate "AMI MegaRAID support"
@@ -394,7 +397,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called megaraid.o.
+	  will be called megaraid.
 
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
@@ -412,7 +415,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  but only a single instance may be loaded. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
-	  The module will be called BusLogic.o.
+	  The module will be called BusLogic.
 
 config SCSI_OMIT_FLASHPOINT
 	bool "Omit FlashPoint support"
@@ -438,7 +441,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dmx3191d.o.  If you want to compile it as
+	  The module will be called dmx3191d.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_DTC3280
@@ -452,7 +455,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dtc.o.  If you want to compile it as a
+	  The module will be called dtc.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_EATA
@@ -475,7 +478,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called eata.o.
+	  will be called eata.
 
 config SCSI_EATA_TAGGED_QUEUE
 	bool "enable tagged command queueing"
@@ -524,7 +527,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called eata_dma.o.  If you want to compile it as
+	  The module will be called eata_dma.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_EATA_PIO
@@ -541,7 +544,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called eata_pio.o.
+	  will be called eata_pio.
 
 config SCSI_FUTURE_DOMAIN
 	tristate "Future Domain 16xx SCSI/AHA-2920A support"
@@ -561,7 +564,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called fdomain.o. If you want to compile it as a
+	  The module will be called fdomain. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_FD_MCS
@@ -576,7 +579,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called fd_mcs.o. If you want to compile it as a
+	  The module will be called fd_mcs. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_GDTH
@@ -613,7 +616,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called g_NCR5380.o.  If you want to compile it as
+	  The module will be called g_NCR5380.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_GENERIC_NCR5380_MMIO
@@ -629,7 +632,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called g_NCR5380.o.  If you want to compile it as
+	  The module will be called g_NCR5380.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_GENERIC_NCR53C400
@@ -665,7 +668,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ibmmca.o.
+	  will be called ibmmca.
 
 config IBMMCA_SCSI_ORDER_STANDARD
 	bool "Standard SCSI-order"
@@ -729,7 +732,7 @@
 	  inserted in and removed from the running kernel whenever you want),
 	  but only a single instance may be loaded. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
-	  The module will be called ips.o.
+	  The module will be called ips.
 
 config SCSI_INITIO
 	tristate "Initio 9100U(W) support"
@@ -742,7 +745,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called initio.o.
+	  will be called initio.
 
 config SCSI_INIA100
 	tristate "Initio INI-A100U2W support"
@@ -755,7 +758,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called a100u2w.o.
+	  will be called a100u2w.
 
 config SCSI_PPA
 	tristate "IOMEGA parallel port (ppa - older drives)"
@@ -784,7 +787,7 @@
 	  This driver is also available as a module which can be inserted in
 	  and removed from the running kernel whenever you want.  To compile
 	  this driver as a module, say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called ppa.o.
+	  <file:Documentation/modules.txt>.  The module will be called ppa.
 
 config SCSI_IMM
 	tristate "IOMEGA parallel port (imm - newer drives)"
@@ -813,7 +816,7 @@
 	  This driver is also available as a module which can be inserted in
 	  and removed from the running kernel whenever you want.  To compile
 	  this driver as a module, say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called imm.o.
+	  <file:Documentation/modules.txt>.  The module will be called imm.
 
 config SCSI_IZIP_EPP16
 	bool "ppa/imm option - Use slow (but safe) EPP-16"
@@ -856,7 +859,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called NCR53c406.o.
+	  will be called NCR53c406.
 
 config SCSI_NCR_D700
 	tristate "NCR Dual 700 MCA SCSI support"
@@ -915,7 +918,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 53c7,8xx.o.  If you want to compile it as
+	  The module will be called 53c7,8xx.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_NCR53C7xx_sync
@@ -1230,7 +1233,7 @@
 	  If you want to compile this as a module (= code which can be
 	  inserted and removed from the running kernel whenever you want), say
 	  M here and read <file:Documentation/modules.txt>.  The module will
-	  be called mca_53c9x.o.
+	  be called mca_53c9x.
 
 config SCSI_PAS16
 	tristate "PAS16 SCSI support"
@@ -1244,7 +1247,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pas16.o.  If you want to compile it as a
+	  The module will be called pas16.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_PCI2000
@@ -1255,7 +1258,7 @@
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
-	  This driver is also available as a module called pci2000.o ( = code
+	  This driver is also available as a module called pci2000 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1268,7 +1271,7 @@
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
-	  This driver is also available as a module called pci2220i.o ( = code
+	  This driver is also available as a module called pci2220i ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1281,7 +1284,7 @@
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
-	  This driver is also available as a module called psi240i.o ( = code
+	  This driver is also available as a module called psi240i ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1305,7 +1308,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicfas.o. If you want to compile it as
+	  The module will be called qlogicfas. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_QLOGIC_ISP
@@ -1325,7 +1328,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicisp.o.  If you want to compile it as
+	  The module will be called qlogicisp.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_QLOGIC_FC
@@ -1336,12 +1339,16 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicfc.o.  If you want to compile it as
+	  The module will be called qlogicfc.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_QLOGIC_FC_FIRMWARE
 	bool "Include loadable firmware in driver"
 	depends on SCSI_QLOGIC_FC
+  	help
+	  Say Y to include ISP2100 Fabric Initiator/Target Firmware, with
+	  expanded LUN addressing and FcTape (FCP-2) support, in the
+	  Qlogic QLA 1280 driver. This is required on some platforms.
 
 config SCSI_QLOGIC_1280
 	tristate "Qlogic QLA 1280 SCSI support"
@@ -1351,7 +1358,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qla1280.o. If you want to compile it as
+	  The module will be called qla1280. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_SEAGATE
@@ -1366,30 +1373,22 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called seagate.o.  If you want to compile it as a
+	  The module will be called seagate.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 # definitely looks note 64bit safe:
 config SCSI_SIM710
 	tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
-	depends on (ISA || MCA && !X86_64) && SCSI
+	depends on (EISA || MCA && !X86_64) && SCSI
 	---help---
-	  This is a simple driver for NCR53c710 based SCSI host adapters.
+	  This driver for NCR53c710 based SCSI host adapters.
 
-	  More complex drivers for this chip are available ("NCR53c7,8xx SCSI
-	  support", above), but they require that the scsi chip be able to do
-	  DMA block moves between memory and on-chip registers, which can
-	  cause problems under certain conditions.  This driver is designed to
-	  avoid these problems and is intended to work with any Intel machines
-	  using 53c710 chips, including various Compaq and NCR machines.
+	  It currently supports Compaq EISA cards and NCR MCA cards
 
-	  Please read the comments at the top of the file
-	  <file:drivers/scsi/sim710.c> for more information.
-
-	  If you want to compile this driver as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called sim710.o.
+config 53C700_IO_MAPPED
+	bool
+	depends on SCSI_SIM710
+	default y
 
 config SCSI_SYM53C416
 	tristate "Symbios 53c416 SCSI support"
@@ -1410,7 +1409,7 @@
 	  this driver as a module ( = code which can be inserted in and
 	  removed from the running kernel whenever you want), say M here and
 	  read <file:Documentation/modules.txt>. The module will be called
-	  sym53c416.o.
+	  sym53c416.
 
 config SCSI_DC390T
 	tristate "Tekram DC390(T) and Am53/79C974 SCSI support"
@@ -1430,7 +1429,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called tmscsim.o.
+	  will be called tmscsim.
 
 config SCSI_DC390T_NOGENSUPP
 	bool "_omit_ support for non-DC390 adapters"
@@ -1463,7 +1462,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called t128.o.  If you want to compile it as a
+	  The module will be called t128.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_U14_34F
@@ -1482,7 +1481,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called u14-34f.o.  If you want to compile it as a
+	  The module will be called u14-34f.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config SCSI_U14_34F_TAGGED_QUEUE
@@ -1534,7 +1533,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ultrastor.o.
+	  will be called ultrastor.
 
 config SCSI_NSP32
 	tristate "Workbit NinjaSCSI-32Bi/UDE support"
@@ -1547,7 +1546,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called nsp32.o.
+	  will be called nsp32.
 
 config SCSI_DEBUG
 	tristate "SCSI debugging host simulator"
@@ -1569,7 +1568,7 @@
 	  Many Power Macintoshes and clones have a MESH (Macintosh Enhanced
 	  SCSI Hardware) SCSI bus adaptor (the 7200 doesn't, but all of the
 	  other Power Macintoshes do). Say Y to include support for this SCSI
-	  adaptor. This driver is also available as a module called mesh.o
+	  adaptor. This driver is also available as a module called mesh
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want). If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
@@ -1602,7 +1601,7 @@
 	  machines which only have one SCSI bus, such as the 7200, also use
 	  the 53C94. Say Y to include support for the 53C94.
 
-	  This driver is also available as a module called mac53c94.o ( = code
+	  This driver is also available as a module called mac53c94 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -1625,7 +1624,7 @@
 	  built-in SCSI controller, say Y. Otherwise, say N. This driver is
 	  also available as a module ( = code which can be inserted in and
 	  removed from the running kernel whenever you want). The module is
-	  called wd33c93.o. If you want to compile it as a module, say M here
+	  called wd33c93. If you want to compile it as a module, say M here
 	  and read <file:Documentation/modules.txt>.
 
 config A4000T_SCSI
@@ -1641,7 +1640,7 @@
 	  If you have a Commodore A2091 SCSI controller, say Y. Otherwise,
 	  say N. This driver is also available as a module ( = code which can
 	  be inserted in and removed from the running kernel whenever you
-	  want). The module is called wd33c93.o. If you want to compile it as
+	  want). The module is called wd33c93. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config GVP11_SCSI
@@ -1656,7 +1655,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you
-	  want). The module will be called gvp11.o. If you want to compile it
+	  want). The module will be called gvp11. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config CYBERSTORM_SCSI
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	Mon Feb 10 10:39:31 2003
+++ b/drivers/scsi/Makefile	Mon Feb 10 10:39:31 2003
@@ -18,8 +18,6 @@
 CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
 CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
-export-objs	:= scsi_syms.o scsi_proc.o 53c700.o
-
 subdir-$(CONFIG_PCMCIA)		+= pcmcia
 
 obj-$(CONFIG_SCSI)		+= scsi_mod.o
@@ -45,7 +43,7 @@
 obj-$(CONFIG_SUN3_SCSI)		+= sun3_scsi.o  sun3_scsi_vme.o
 obj-$(CONFIG_MVME16x_SCSI)	+= mvme16x.o	53c7xx.o
 obj-$(CONFIG_BVME6000_SCSI)	+= bvme6000.o	53c7xx.o
-obj-$(CONFIG_SCSI_SIM710)	+= sim710.o
+obj-$(CONFIG_SCSI_SIM710)	+= sim710.o	53c700.o
 obj-$(CONFIG_SCSI_ADVANSYS)	+= advansys.o
 obj-$(CONFIG_SCSI_PCI2000)	+= pci2000.o
 obj-$(CONFIG_SCSI_PCI2220I)	+= pci2220i.o
@@ -80,7 +78,6 @@
 obj-$(CONFIG_SCSI_T128)		+= t128.o
 obj-$(CONFIG_SCSI_DMX3191D)	+= dmx3191d.o
 obj-$(CONFIG_SCSI_DTC3280)	+= dtc.o
-obj-$(CONFIG_SCSI_NCR53C7xx)	+= 53c7,8xx.o 
 obj-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2/
 obj-$(CONFIG_SCSI_SYM53C8XX)	+= sym53c8xx.o 
 obj-$(CONFIG_SCSI_NCR53C8XX)	+= ncr53c8xx.o 
@@ -141,12 +138,10 @@
 		   cpqfcTSworker.o cpqfcTStrigger.o
 
 # Files generated that shall be removed upon make clean
-clean-files :=	53c8xx_d.h  53c7xx_d.h sim710_d.h  53c700_d.h	\
-		53c8xx_u.h  53c7xx_u.h sim710_u.h 53c700_u.h
+clean-files :=	53c7xx_d.h 53c700_d.h	\
+		53c7xx_u.h 53c700_u.h
 
-$(obj)/53c7,8xx.o: $(obj)/53c8xx_d.h $(obj)/53c8xx_u.h
 $(obj)/53c7xx.o:   $(obj)/53c7xx_d.h $(obj)/53c7xx_u.h
-$(obj)/sim710.o:   $(obj)/sim710_d.h
 $(obj)/53c700.o $(MODVERDIR)/$(obj)/53c700.ver: $(obj)/53c700_d.h
 
 # If you want to play with the firmware, uncomment
@@ -154,20 +149,10 @@
 
 ifdef GENERATE_FIRMWARE
 
-$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
-	$(CPP) -traditional -DCHIP=810 - < $< | grep -v '^#' | $(PERL) $(src)/script_asm.pl $@ $(@:_d.h=_u.h)
-
-$(obj)/53c8xx_u.h: $(obj)/53c8xx_d.h
-
 $(obj)/53c7xx_d.h: $(src)/53c7xx.scr $(src)/script_asm.pl
 	$(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h)
 
 $(obj)/53c7xx_u.h: $(obj)/53c7xx_d.h
-
-$(obj)/sim710_d.h: $(src)/sim710.scr $(src)/script_asm.pl
-	$(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h)
-
-$(obj)/sim710_u.h: $(obj)/sim710_d.h
 
 $(obj)/53c700_d.h: $(src)/53c700.scr $(src)/script_asm.pl
 	$(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) < $<
diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/NCR5380.c	Mon Feb 10 10:39:24 2003
@@ -929,7 +929,7 @@
 
 static char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length)
 {
-	SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->host->host_no, cmd->target, cmd->lun);
+	SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
 	SPRINTF("        command = ");
 	pos = lprint_command(cmd->cmnd, pos, buffer, length);
 	return (pos);
@@ -1106,7 +1106,7 @@
 
 static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) 
 {
-	struct Scsi_Host *instance = cmd->host;
+	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp;
 
@@ -1126,15 +1126,15 @@
 		case WRITE:
 		case WRITE_6:
 		case WRITE_10:
-			hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
-			hostdata->bytes_write[cmd->target] += cmd->request_bufflen;
+			hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
+			hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;
 			hostdata->pendingw++;
 			break;
 		case READ:
 		case READ_6:
 		case READ_10:
-			hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
-			hostdata->bytes_read[cmd->target] += cmd->request_bufflen;
+			hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
+			hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;
 			hostdata->pendingr++;
 			break;
 	}
@@ -1224,7 +1224,7 @@
 				if (prev != tmp)
 					dprintk(NDEBUG_LISTS, ("MAIN tmp=%p   target=%d   busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun));
 				/*  When we find one, remove it from the issue queue. */
-				if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
+				if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
 					if (prev) {
 						REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
 						prev->host_scribble = tmp->host_scribble;
@@ -1286,7 +1286,7 @@
 				   this is needed for Mustek scanners, that
 				   do not respond to commands immediately
 				   after a scan */
-				printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->target);
+				printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id);
 				LIST(tmp, hostdata->issue_queue);
 				tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
 				hostdata->issue_queue = tmp;
@@ -1421,13 +1421,13 @@
 	case WRITE:
 	case WRITE_6:
 	case WRITE_10:
-		hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
+		hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
 		hostdata->pendingw--;
 		break;
 	case READ:
 	case READ_6:
 	case READ_10:
-		hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
+		hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
 		hostdata->pendingr--;
 		break;
 	}
@@ -1567,7 +1567,7 @@
 	 * the host and target ID's on the SCSI bus.
 	 */
 
-	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target)));
+	NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
 
 	/* 
 	 * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1612,7 +1612,7 @@
 
 	udelay(1);
 
-	dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->target));
+	dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->device->id));
 
 	/* 
 	 * The SCSI specification calls for a 250 ms timeout for the actual 
@@ -1668,7 +1668,7 @@
 
 	if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-		if (hostdata->targets_present & (1 << cmd->target)) {
+		if (hostdata->targets_present & (1 << cmd->device->id)) {
 			printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no);
 			if (hostdata->restart_select)
 				printk(KERN_DEBUG "\trestart select\n");
@@ -1686,7 +1686,7 @@
 		NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 		return 0;
 	}
-	hostdata->targets_present |= (1 << cmd->target);
+	hostdata->targets_present |= (1 << cmd->device->id);
 
 	/*
 	 * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -1713,8 +1713,8 @@
 		goto failed;
 	}
 
-	dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->target));
-	tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
+	dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id));
+	tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->device->lun);
 
 	if(instance->irq != IRQ_NONE)
 		spin_lock_irq(instance->host_lock);
@@ -1729,7 +1729,7 @@
 	dprintk(NDEBUG_SELECTION, ("scsi%d : nexus established.\n", instance->host_no));
 	/* XXX need to handle errors here */
 	hostdata->connected = cmd;
-	hostdata->busy[cmd->target] |= (1 << cmd->lun);
+	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 
 	initialize_SCp(cmd);
 
@@ -2380,7 +2380,7 @@
 						 * If the watchdog timer fires, all future accesses to this
 						 * device will use the polled-IO.
 						 */
-						printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->target, cmd->lun);
+						printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun);
 						cmd->device->borken = 1;
 						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
 						sink = 1;
@@ -2417,14 +2417,14 @@
 				case LINKED_FLG_CMD_COMPLETE:
 					/* Accept message by clearing ACK */
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->target, cmd->lun));
+					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun));
 					/* 
 					 * Sanity check : A linked command should only terminate with
 					 * one of these messages if there are more linked commands
 					 * available.
 					 */
 					if (!cmd->next_link) {
-						printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->target, cmd->lun);
+						printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
 						sink = 1;
 						do_abort(instance);
 						return;
@@ -2433,7 +2433,7 @@
 					/* The next command is still part of this process */
 					cmd->next_link->tag = cmd->tag;
 					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->target, cmd->lun));
+					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun));
 					collect_stats(hostdata, cmd);
 					cmd->scsi_done(cmd);
 					cmd = hostdata->connected;
@@ -2445,8 +2445,8 @@
 					sink = 1;
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 					hostdata->connected = NULL;
-					dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->target, cmd->lun));
-					hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+					dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun));
+					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 
 					/* 
 					 * I'm not sure what the correct thing to do here is : 
@@ -2514,7 +2514,7 @@
 					case ORDERED_QUEUE_TAG:
 					case SIMPLE_QUEUE_TAG:
 						cmd->device->tagged_queue = 0;
-						hostdata->busy[cmd->target] |= (1 << cmd->lun);
+						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 						break;
 					default:
 						break;
@@ -2528,7 +2528,7 @@
 						    hostdata->disconnected_queue;
 						hostdata->connected = NULL;
 						hostdata->disconnected_queue = cmd;
-						dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->target, cmd->lun));
+						dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun));
 						/* 
 						 * Restore phase bits to 0 so an interrupted selection, 
 						 * arbitration can resume.
@@ -2619,9 +2619,9 @@
 						print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
-						printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->target, cmd->lun);
+						printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun);
 					else
-						printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
+						printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun);
 
 					msgout = MESSAGE_REJECT;
 					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -2634,7 +2634,7 @@
 				hostdata->last_message = msgout;
 				NCR5380_transfer_pio(instance, &phase, &len, &data);
 				if (msgout == ABORT) {
-					hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 					hostdata->connected = NULL;
 					cmd->result = DID_ERROR << 16;
 					collect_stats(hostdata, cmd);
@@ -2772,7 +2772,7 @@
 
 
 		for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
-			if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
+			if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
 			    ) {
 				if (prev) {
 					REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
@@ -2872,7 +2872,7 @@
 
 static int NCR5380_abort(Scsi_Cmnd * cmd) {
 	NCR5380_local_declare();
-	struct Scsi_Host *instance = cmd->host;
+	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp, **prev;
 	
@@ -3031,10 +3031,10 @@
 
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
 	NCR5380_local_declare();
-	NCR5380_setup(cmd->host);
+	NCR5380_setup(cmd->device->host);
 
-	NCR5380_print_status(cmd->host);
-	do_reset(cmd->host);
+	NCR5380_print_status(cmd->device->host);
+	do_reset(cmd->device->host);
 	return SUCCESS;
 }
 
diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/scsi/aacraid/aachba.c	Mon Feb 10 10:39:26 2003
@@ -392,8 +392,8 @@
  * Arguments: [1] pointer to void [1] int
  *
  * Purpose: Sets SCSI inquiry data strings for vendor, product
- * and revision level. Allows strings to be set in platform dependant
- * files instead of in OS dependant driver source.
+ * and revision level. Allows strings to be set in platform dependent
+ * files instead of in OS dependent driver source.
  */
 
 static void setinqstr(int devtype, void *data, int tindex)
@@ -463,9 +463,9 @@
 static void aac_io_done(Scsi_Cmnd * scsicmd)
 {
 	unsigned long cpu_flags;
-	spin_lock_irqsave(scsicmd->host->host_lock, cpu_flags);
+	spin_lock_irqsave(scsicmd->device->host->host_lock, cpu_flags);
 	scsicmd->scsi_done(scsicmd);
-	spin_unlock_irqrestore(scsicmd->host->host_lock, cpu_flags);
+	spin_unlock_irqrestore(scsicmd->device->host->host_lock, cpu_flags);
 }
 
 static void __aac_io_done(Scsi_Cmnd * scsicmd)
@@ -546,8 +546,8 @@
 
 	scsicmd = (Scsi_Cmnd *) context;
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
-	cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+	cid =TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
 	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
 	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies));
@@ -591,8 +591,8 @@
 	u32 cid;
 
 	scsicmd = (Scsi_Cmnd *) context;
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
-	cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+	cid = TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
 	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
 	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies));
@@ -637,7 +637,7 @@
 	struct aac_dev *dev;
 	struct fib * cmd_fibcontext;
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	/*
 	 *	Get block address and transfer length
 	 */
@@ -746,7 +746,7 @@
 	struct aac_dev *dev;
 	struct fib * cmd_fibcontext;
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	/*
 	 *	Get block address and transfer length
 	 */
@@ -861,25 +861,25 @@
 	struct fsa_scsi_hba *fsa_dev_ptr;
 	int cardtype;
 	int ret;
-	struct aac_dev *dev = (struct aac_dev *)scsicmd->host->hostdata;
+	struct aac_dev *dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	
 	cardtype = dev->cardtype;
 
-	fsa_dev_ptr = fsa_dev[scsicmd->host->unique_id];
+	fsa_dev_ptr = fsa_dev[scsicmd->device->host->unique_id];
 
 	/*
 	 *	If the bus, target or lun is out of range, return fail
 	 *	Test does not apply to ID 16, the pseudo id for the controller
 	 *	itself.
 	 */
-	if (scsicmd->target != scsicmd->host->this_id) {
-		if ((scsicmd->channel == 0) ){
-			if( (scsicmd->target >= AAC_MAX_TARGET) || (scsicmd->lun != 0)){ 
+	if (scsicmd->device->id != scsicmd->device->host->this_id) {
+		if ((scsicmd->device->channel == 0) ){
+			if( (scsicmd->device->id >= AAC_MAX_TARGET) || (scsicmd->device->lun != 0)){ 
 				scsicmd->result = DID_NO_CONNECT << 16;
 				__aac_io_done(scsicmd);
 				return 0;
 			}
-			cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+			cid = TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
 			/*
 			 *	If the target container doesn't exist, it may have
@@ -890,9 +890,9 @@
 				case SS_INQUIR:
 				case SS_RDCAP:
 				case SS_TEST:
-					spin_unlock_irq(scsicmd->host->host_lock);
+					spin_unlock_irq(scsicmd->device->host->host_lock);
 					probe_container(dev, cid);
-					spin_lock_irq(scsicmd->host->host_lock);
+					spin_lock_irq(scsicmd->device->host->host_lock);
 					if (fsa_dev_ptr->valid[cid] == 0) {
 						scsicmd->result = DID_NO_CONNECT << 16;
 						__aac_io_done(scsicmd);
@@ -944,7 +944,7 @@
 	{
 		struct inquiry_data *inq_data_ptr;
 
-		dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->target));
+		dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
 		inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer;
 		memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
 
@@ -959,7 +959,7 @@
 		 *	see: <vendor>.c i.e. aac.c
 		 */
 		setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]);
-		if (scsicmd->target == scsicmd->host->this_id)
+		if (scsicmd->device->id == scsicmd->device->host->this_id)
 			inq_data_ptr->inqd_pdt = INQD_PDT_PROC;	/* Processor device */
 		else
 			inq_data_ptr->inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
@@ -1053,20 +1053,20 @@
 			 *	containers to /dev/sd device names
 			 */
 			 
-			spin_unlock_irq(scsicmd->host->host_lock);
+			spin_unlock_irq(scsicmd->device->host->host_lock);
 			if  (scsicmd->request->rq_disk)
 				memcpy(fsa_dev_ptr->devname[cid],
 					scsicmd->request->rq_disk->disk_name,
 					8);
 			ret = aac_read(scsicmd, cid);
-			spin_lock_irq(scsicmd->host->host_lock);
+			spin_lock_irq(scsicmd->device->host->host_lock);
 			return ret;
 
 		case SS_WRITE:
 		case SM_WRITE:
-			spin_unlock_irq(scsicmd->host->host_lock);
+			spin_unlock_irq(scsicmd->device->host->host_lock);
 			ret = aac_write(scsicmd, cid);
-			spin_lock_irq(scsicmd->host->host_lock);
+			spin_lock_irq(scsicmd->device->host->host_lock);
 			return ret;
 		default:
 			/*
@@ -1202,7 +1202,7 @@
 	Scsi_Cmnd *scsicmd;
 
 	scsicmd = (Scsi_Cmnd *) context;
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 
 	if (fibptr == NULL)
 		BUG();
@@ -1366,13 +1366,13 @@
 	u16 fibsize;
 	u32 flag;
 
-	if( scsicmd->target > 15 || scsicmd->lun > 7) {
+	if( scsicmd->device->id > 15 || scsicmd->device->lun > 7) {
 		scsicmd->result = DID_NO_CONNECT << 16;
 		__aac_io_done(scsicmd);
 		return 0;
 	}
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	switch(scsicmd->sc_data_direction){
 	case SCSI_DATA_WRITE:
 		flag = SRB_DataOut;
@@ -1402,9 +1402,9 @@
 
 	srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
 	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
-	srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scsicmd->channel));
-	srbcmd->target   = cpu_to_le32(scsicmd->target);
-	srbcmd->lun      = cpu_to_le32(scsicmd->lun);
+	srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scsicmd->device->channel));
+	srbcmd->target   = cpu_to_le32(scsicmd->device->id);
+	srbcmd->lun      = cpu_to_le32(scsicmd->device->lun);
 	srbcmd->flags    = cpu_to_le32(flag);
 	srbcmd->timeout  = cpu_to_le32(0);  // timeout not used
 	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
@@ -1468,7 +1468,7 @@
 	struct aac_dev *dev;
 	unsigned long byte_count = 0;
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	// Get rid of old data
 	psg->count = cpu_to_le32(0);
 	psg->sg[0].addr = cpu_to_le32(NULL);
@@ -1524,7 +1524,7 @@
 	unsigned long byte_count = 0;
 	u64 le_addr;
 
-	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	// Get rid of old data
 	psg->count = cpu_to_le32(0);
 	psg->sg[0].addr[0] = cpu_to_le32(NULL);
diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/aacraid/aacraid.h	Mon Feb 10 10:39:24 2003
@@ -79,7 +79,7 @@
 /*
  *	Host side memory scatter gather list
  *	Used by the adapter for read, write, and readdirplus operations
- *	We have seperate 32 and 64 bit version because even
+ *	We have separate 32 and 64 bit version because even
  *	on 64 bit systems not all cards support the 64 bit version
  */
 struct sgentry {
@@ -443,7 +443,7 @@
 /*
  *	The adapter interface specs all queues to be located in the same
  *	physically contigous block. The host structure that defines the
- *	commuication queues will assume they are each a seperate physically
+ *	commuication queues will assume they are each a separate physically
  *	contigous memory region that will support them all being one big
  *	contigous block. 
  *	There is a command and response queue for each level and direction of
diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/scsi/aacraid/linit.c	Mon Feb 10 10:39:25 2003
@@ -536,7 +536,7 @@
 
 	dprintk((KERN_DEBUG "(scsi%d:%d:%d:%d) Tagged Queue depth %2d, "
 				"%s\n", dev->host->host_no, dev->channel,
-				dev->id, dev->lun, dev->new_queue_depth,
+				dev->id, dev->lun, dev->queue_depth,
 				dev->online ? "OnLine" : "OffLine"));
 	return 0;
 }
diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/advansys.c	Mon Feb 10 10:39:24 2003
@@ -3641,7 +3641,7 @@
 typedef Scsi_Cmnd            REQ, *REQP;
 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
-#define REQPTID(reqp)        ((reqp)->target)
+#define REQPTID(reqp)        ((reqp)->device->id)
 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
 #define REQTIMESTAMP()       (jiffies)
 
@@ -5845,7 +5845,7 @@
     ulong               flags;
     Scsi_Cmnd           *done_scp;
 
-    shp = scp->host;
+    shp = scp->device->host;
     boardp = ASC_BOARDP(shp);
     ASC_STATS(shp, queuecommand);
 
@@ -5941,12 +5941,12 @@
     ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
 
 #ifdef ADVANSYS_STATS
-    if (scp->host != NULL) {
-        ASC_STATS(scp->host, reset);
+    if (scp->device->host != NULL) {
+        ASC_STATS(scp->device->host, reset);
     }
 #endif /* ADVANSYS_STATS */
 
-    if ((shp = scp->host) == NULL) {
+    if ((shp = scp->device->host) == NULL) {
         scp->result = HOST_BYTE(DID_ERROR);
         return FAILED;
     }
@@ -6390,13 +6390,13 @@
         ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
         tscp = REQPNEXT(scp);
         REQPNEXT(scp) = NULL;
-        ASC_STATS(scp->host, done);
+        ASC_STATS(scp->device->host, done);
         ASC_ASSERT(scp->scsi_done != NULL);
 	if (from_isr)
-	    spin_lock_irqsave(scp->host->host_lock, flags);
+	    spin_lock_irqsave(scp->device->host->host_lock, flags);
         scp->scsi_done(scp);
 	if (from_isr)
-	    spin_unlock_irqrestore(scp->host->host_lock, flags);
+	    spin_unlock_irqrestore(scp->device->host->host_lock, flags);
         scp = tscp;
     }
     ASC_DBG(2, "asc_scsi_done_list: done\n");
@@ -6462,8 +6462,8 @@
     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
         (ulong) scp, (ulong) scp->scsi_done);
 
-    boardp = ASC_BOARDP(scp->host);
-    device = boardp->device[scp->target];
+    boardp = ASC_BOARDP(scp->device->host);
+    device = boardp->device[scp->device->id];
 
     if (ASC_NARROW_BOARD(boardp)) {
         /*
@@ -6483,7 +6483,7 @@
          * asc_build_req() can not return ASC_BUSY.
          */
         if (asc_build_req(boardp, scp) == ASC_ERROR) {
-            ASC_STATS(scp->host, build_error);
+            ASC_STATS(scp->device->host, build_error);
             return ASC_ERROR;
         }
 
@@ -6493,12 +6493,12 @@
          */
         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
         case ASC_NOERROR:
-            ASC_STATS(scp->host, exe_noerror);
+            ASC_STATS(scp->device->host, exe_noerror);
             /*
              * Increment monotonically increasing per device successful
              * request counter. Wrapping doesn't matter.
              */
-            boardp->reqcnt[scp->target]++;
+            boardp->reqcnt[scp->device->id]++;
             asc_enqueue(&boardp->active, scp, ASC_BACK);
             ASC_DBG(1,
                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
@@ -6508,13 +6508,13 @@
              * Caller will enqueue request on the target's waiting queue
              * and retry later.
              */
-            ASC_STATS(scp->host, exe_busy);
+            ASC_STATS(scp->device->host, exe_busy);
             break;
         case ASC_ERROR:
             ASC_PRINT2(
 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
                 boardp->id, asc_dvc_varp->err_code);
-            ASC_STATS(scp->host, exe_error);
+            ASC_STATS(scp->device->host, exe_error);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6522,7 +6522,7 @@
             ASC_PRINT2(
 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
                 boardp->id, asc_dvc_varp->err_code);
-            ASC_STATS(scp->host, exe_unknown);
+            ASC_STATS(scp->device->host, exe_unknown);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6563,7 +6563,7 @@
               */
         default:
             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
-            ASC_STATS(scp->host, build_error);
+            ASC_STATS(scp->device->host, build_error);
             return ASC_ERROR;
         }
 
@@ -6573,12 +6573,12 @@
          */
         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
         case ASC_NOERROR:
-            ASC_STATS(scp->host, exe_noerror);
+            ASC_STATS(scp->device->host, exe_noerror);
             /*
              * Increment monotonically increasing per device successful
              * request counter. Wrapping doesn't matter.
              */
-            boardp->reqcnt[scp->target]++;
+            boardp->reqcnt[scp->device->id]++;
             asc_enqueue(&boardp->active, scp, ASC_BACK);
             ASC_DBG(1,
                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
@@ -6588,13 +6588,13 @@
              * Caller will enqueue request on the target's waiting queue
              * and retry later.
              */
-            ASC_STATS(scp->host, exe_busy);
+            ASC_STATS(scp->device->host, exe_busy);
             break;
         case ASC_ERROR:
             ASC_PRINT2(
 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
                 boardp->id, adv_dvc_varp->err_code);
-            ASC_STATS(scp->host, exe_error);
+            ASC_STATS(scp->device->host, exe_error);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6602,7 +6602,7 @@
             ASC_PRINT2(
 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
                 boardp->id, adv_dvc_varp->err_code);
-            ASC_STATS(scp->host, exe_unknown);
+            ASC_STATS(scp->device->host, exe_unknown);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             break;
@@ -6652,9 +6652,9 @@
     }
     asc_scsi_q.cdbptr = &scp->cmnd[0];
     asc_scsi_q.q2.cdb_len = scp->cmd_len;
-    asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
-    asc_scsi_q.q1.target_lun = scp->lun;
-    asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
+    asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
+    asc_scsi_q.q1.target_lun = scp->device->lun;
+    asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
     asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
 
@@ -6669,8 +6669,8 @@
      * started request.
      *
      */
-    if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
-        (boardp->reqcnt[scp->target] % 255) == 0) {
+    if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
+        (boardp->reqcnt[scp->device->id] % 255) == 0) {
         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
     } else {
         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
@@ -6684,11 +6684,11 @@
         /*
          * CDB request of single contiguous buffer.
          */
-        ASC_STATS(scp->host, cont_cnt);
+        ASC_STATS(scp->device->host, cont_cnt);
         asc_scsi_q.q1.data_addr =
             cpu_to_le32(virt_to_bus(scp->request_buffer));
         asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
-        ASC_STATS_ADD(scp->host, cont_xfer,
+        ASC_STATS_ADD(scp->device->host, cont_xfer,
                       ASC_CEILING(scp->request_bufflen, 512));
         asc_scsi_q.q1.sg_queue_cnt = 0;
         asc_scsi_q.sg_head = NULL;
@@ -6699,16 +6699,16 @@
         int                     sgcnt;
         struct scatterlist      *slp;
 
-        if (scp->use_sg > scp->host->sg_tablesize) {
+        if (scp->use_sg > scp->device->host->sg_tablesize) {
             ASC_PRINT3(
 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
-                boardp->id, scp->use_sg, scp->host->sg_tablesize);
+                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             return ASC_ERROR;
         }
 
-        ASC_STATS(scp->host, sg_cnt);
+        ASC_STATS(scp->device->host, sg_cnt);
 
         /*
          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
@@ -6722,7 +6722,7 @@
         asc_scsi_q.q1.data_addr = 0;
         /* This is a byte value, otherwise it would need to be swapped. */
         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
-        ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
+        ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
 
         /*
          * Convert scatter-gather list into ASC_SG_HEAD list.
@@ -6733,7 +6733,7 @@
                 cpu_to_le32(virt_to_bus(
 		(unsigned char *)page_address(slp->page) + slp->offset));
             asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
+            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
         }
     }
 
@@ -6768,7 +6768,7 @@
      */
     if (boardp->adv_reqp == NULL) {
         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
-        ASC_STATS(scp->host, adv_build_noreq);
+        ASC_STATS(scp->device->host, adv_build_noreq);
         return ASC_BUSY;
     } else {
         reqp = boardp->adv_reqp;
@@ -6823,8 +6823,8 @@
         scsiqp->cdb16[i - 12] = scp->cmnd[i];
     }
 
-    scsiqp->target_id = scp->target;
-    scsiqp->target_lun = scp->lun;
+    scsiqp->target_id = scp->device->id;
+    scsiqp->target_lun = scp->device->lun;
 
     scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
     scsiqp->sense_len = sizeof(scp->sense_buffer);
@@ -6844,8 +6844,8 @@
         reqp->sgblkp = NULL;
         scsiqp->sg_list_ptr = NULL;
         scsiqp->sg_real_addr = 0;
-        ASC_STATS(scp->host, cont_cnt);
-        ASC_STATS_ADD(scp->host, cont_xfer,
+        ASC_STATS(scp->device->host, cont_cnt);
+        ASC_STATS_ADD(scp->device->host, cont_xfer,
                       ASC_CEILING(scp->request_bufflen, 512));
     } else {
         /*
@@ -6854,7 +6854,7 @@
         if (scp->use_sg > ADV_MAX_SG_LIST) {
             ASC_PRINT3(
 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
-                boardp->id, scp->use_sg, scp->host->sg_tablesize);
+                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
 
@@ -6879,8 +6879,8 @@
             return ret;
         }
 
-        ASC_STATS(scp->host, sg_cnt);
-        ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
+        ASC_STATS(scp->device->host, sg_cnt);
+        ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
     }
 
     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
@@ -6929,7 +6929,7 @@
          */
         if ((sgblkp = boardp->adv_sgblkp) == NULL) {
             ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
-            ASC_STATS(scp->host, adv_build_nosg);
+            ASC_STATS(scp->device->host, adv_build_nosg);
 
             /*
              * Allocation failed. Free 'adv_sgblk_t' structures already
@@ -6992,7 +6992,7 @@
                 cpu_to_le32(virt_to_bus(
                    (unsigned char *)page_address(slp->page) + slp->offset));
             sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
+            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
 
             if (--sg_elem_cnt == 0)
             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
@@ -7043,7 +7043,7 @@
      * If the request's host pointer is not valid, display a
      * message and return.
      */
-    shp = scp->host;
+    shp = scp->device->host;
     for (i = 0; i < asc_board_count; i++) {
         if (asc_host[i] == shp) {
             break;
@@ -7085,10 +7085,10 @@
          * If an INQUIRY command completed successfully, then call
          * the AscInquiryHandling() function to set-up the device.
          */
-        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
+        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
         {
-            AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
+            AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
         }
 
@@ -7160,10 +7160,10 @@
      * current request finished normally, then set the bit for the target
      * to indicate that a device is present.
      */
-    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
+    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
         qdonep->d3.done_stat == QD_NO_ERROR &&
         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
-        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
+        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
     }
 
     /*
@@ -7232,7 +7232,7 @@
      * If the request's host pointer is not valid, display a message
      * and return.
      */
-    shp = scp->host;
+    shp = scp->device->host;
     for (i = 0; i < asc_board_count; i++) {
         if (asc_host[i] == shp) {
             break;
@@ -7343,10 +7343,10 @@
      * current request finished normally, then set the bit for the target
      * to indicate that a device is present.
      */
-    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
+    if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
         scsiqp->done_status == QD_NO_ERROR &&
         scsiqp->host_status == QHSTA_NO_ERROR) {
-        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
+        boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
     }
 
     /*
@@ -7586,7 +7586,7 @@
         {
             REQP reqp;
             for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
-                REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
+                REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
             }
         }
 #endif /* ADVANSYS_STATS */
@@ -8415,25 +8415,6 @@
         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
     } else {
         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
-    }
-
-    if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
-        len = asc_prt_line(cp, leftlen, " queue_depth:");
-        ASC_PRT_NEXT();
-        for (i = 0; i <= ADV_MAX_TID; i++) {
-            if ((chip_scsi_id == i) ||
-                ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
-                continue;
-            }
-            if (boardp->device[i] == NULL) {
-                continue;
-            }
-            len = asc_prt_line(cp, leftlen, " %X:%d",
-                i, boardp->device[i]->current_queue_depth);
-            ASC_PRT_NEXT();
-        }
-        len = asc_prt_line(cp, leftlen, "\n");
-        ASC_PRT_NEXT();
     }
 
     return totlen;
diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx	Mon Feb 10 10:39:24 2003
@@ -13,7 +13,7 @@
 	If you want to compile the driver as a module ( = code which can be
 	inserted in and removed from the running kernel whenever you want),
 	say M here and read <file:Documentation/modules.txt>.  The module
-	will be called aic7xxx.o.
+	will be called aic7xxx.
 
 config AIC7XXX_CMDS_PER_DEVICE
 	int "Maximum number of TCQ commands per device"
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg
--- a/drivers/scsi/aic7xxx/aic79xx.reg	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.reg	Mon Feb 10 10:39:32 2003
@@ -39,7 +39,7 @@
  *
  * $FreeBSD$
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -173,6 +173,23 @@
 		STATUS_OVERRUN,
 		CFG4OVERRUN,
 		ENTERING_NONPACK,
+		TASKMGMT_FUNC_COMPLETE,		/*
+						 * Task management function
+						 * request completed with
+						 * an expected busfree.
+						 */
+		TASKMGMT_CMD_CMPLT_OKAY,	/*
+						 * A command with a non-zero
+						 * task management function
+						 * has completed via the normal
+						 * command completion method
+						 * for commands with a zero
+						 * task management function.
+						 * This happens when an attempt
+						 * to abort a command loses
+						 * the race for the command to
+						 * complete normally.
+						 */
 		TRACEPOINT0,
 		TRACEPOINT1,
 		TRACEPOINT2,
diff -Nru a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq
--- a/drivers/scsi/aic7xxx/aic79xx.seq	Mon Feb 10 10:39:31 2003
+++ b/drivers/scsi/aic7xxx/aic79xx.seq	Mon Feb 10 10:39:31 2003
@@ -40,7 +40,7 @@
  * $FreeBSD$
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $"
 PATCH_ARG_LIST = "struct ahd_softc *ahd"
 PREFIX = "ahd_"
 
@@ -107,6 +107,16 @@
 good_status_IU_done:
 	bmov	SCBPTR, GSFIFO, 2;
 	clr	SCB_SCSI_STATUS;
+	/*
+	 * If a command completed before an attempted task management
+	 * function completed, notify the host after disabling any
+	 * pending select-outs.
+	 */
+	test	SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally;
+	test	SSTAT0, SELDO|SELINGO jnz . + 2;
+	and	SCSISEQ0, ~ENSELO;
+	SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)
+gsfifo_complete_normally:
 	or	SCB_CONTROL, STATUS_RCVD;
 
 	/*
@@ -471,7 +481,7 @@
 		/*
 		 * This exposes a window whereby a
 		 * busfree just after a selection will
-		 * be missed, but there is not other safe
+		 * be missed, but there is no other safe
 		 * way to enable busfree detection if
 		 * the busfreerev function is broken.
 		 */
@@ -597,7 +607,6 @@
 	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2;
 	mvi	WAITING_TID_TAIL[1], SCB_LIST_NULL;
 	bmov	SCBPTR, CURRSCB, 2;
-END_CRITICAL;
 	mvi	CLRSINT0, CLRSELDO;
 	test	LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase;
 	test	LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase;
@@ -606,17 +615,23 @@
 	 * If this is a packetized connection, return to our
 	 * idle_loop and let our interrupt handler deal with
 	 * any connection setup/teardown issues.  The only
-	 * exception is the case of MK_MESSAGE SCBs.  In the
-	 * A, the LQO manager transitions to LQOSTOP0 even if
-	 * we have selected out with ATN asserted and the target
-	 * REQs in a non-packet phase.
+	 * exceptions are the case of MK_MESSAGE and task management
+	 * SCBs.
 	 */
 	if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) {
+		/*
+		 * In the A, the LQO manager transitions to LQOSTOP0 even if
+		 * we have selected out with ATN asserted and the target
+		 * REQs in a non-packet phase.
+		 */
 		test 	SCB_CONTROL, MK_MESSAGE jz select_out_no_message;
 		test	SCSISIGO, ATNO jnz select_out_non_packetized;
 select_out_no_message:
 	}
-	test	LQOSTAT2, LQOSTOP0 jnz idle_loop;
+	test	LQOSTAT2, LQOSTOP0 jz select_out_non_packetized;
+	test	SCB_TASK_MANAGEMENT, 0xFF jz idle_loop;
+	SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE)
+	jmp	idle_loop;
 
 select_out_non_packetized:
 	/* Non packetized request. */
@@ -625,7 +640,7 @@
 		/*
 		 * This exposes a window whereby a
 		 * busfree just after a selection will
-		 * be missed, but there is not other safe
+		 * be missed, but there is no other safe
 		 * way to enable busfree detection if
 		 * the busfreerev function is broken.
 		 */
@@ -634,6 +649,8 @@
 	}
 	mov	SAVED_SCSIID, SCB_SCSIID;
 	mov	SAVED_LUN, SCB_LUN;
+	mvi	SEQ_FLAGS, NO_CDB_SENT;
+END_CRITICAL;
 	or	SXFRCTL0, SPIOEN;
 
 	/*
@@ -642,7 +659,6 @@
 	 * asserted.
 	 */
 	mvi	MSG_OUT, MSG_IDENTIFYFLAG;
-	mvi	SEQ_FLAGS, NO_CDB_SENT;
 
 	/*
 	 * Main loop for information transfer phases.  Wait for the
@@ -1608,7 +1624,12 @@
 	/*
 	 * Status pkt is transferring to host.
 	 * Wait in idle loop for transfer to complete.
+	 * If a command completed before an attempted
+	 * task management function completed, notify the host.
 	 */
+	test	SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func;
+	SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)
+cfg4istat_no_taskmgmt_func:
 	call	pkt_handle_status;
 	or	SEQINTCTL, IRET ret;
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
--- a/drivers/scsi/aic7xxx/aic79xx_core.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c	Mon Feb 10 10:39:22 2003
@@ -2,7 +2,7 @@
  * Core routines and tables shareable across OS platforms.
  *
  * Copyright (c) 1994-2002 Justin T. Gibbs.
- * Copyright (c) 2000-2002 Adaptec Inc.
+ * Copyright (c) 2000-2003 Adaptec Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#150 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#156 $
  *
  * $FreeBSD$
  */
@@ -171,8 +171,8 @@
 static void		ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
 static void		ahd_handle_devreset(struct ahd_softc *ahd,
 					    struct ahd_devinfo *devinfo,
-					    cam_status status, char *message,
-					    int verbose_level);
+					    u_int lun, cam_status status,
+					    char *message, int verbose_level);
 #if AHD_TARGET_MODE
 static void		ahd_setup_target_msgin(struct ahd_softc *ahd,
 					       struct ahd_devinfo *devinfo,
@@ -438,11 +438,27 @@
 		scbid = next_scbid;
 	}
 	ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
+	ahd_set_scbptr(ahd, saved_scbptr);
+
+	/*
+	 * Flush the good status FIFO for compelted packetized commands.
+	 */
+	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+	while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
+		scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
+		      | ahd_inb(ahd, GSFIFO);
+		scb = ahd_lookup_scb(ahd, scbid);
+		if (scb == NULL) {
+			printf("%s: Warning - GSFIFO SCB %d invalid\n",
+			       ahd_name(ahd), scbid);
+			continue;
+		}
+		ahd_complete_scb(ahd, scb);
+	}
 
 	/*
 	 * Restore state.
 	 */
-	ahd_set_scbptr(ahd, saved_scbptr);
 	ahd_restore_modes(ahd, saved_modes);
 	ahd->flags |= AHD_UPDATE_PEND_CMDS;
 }
@@ -672,8 +688,7 @@
 							&tstate);
 			tinfo = &targ_info->curr;
 			ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-				      AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
-				      /*paused*/TRUE);
+				      AHD_TRANS_ACTIVE, /*paused*/TRUE);
 			ahd_set_syncrate(ahd, &devinfo, /*period*/0,
 					 /*offset*/0, /*ppr_options*/0,
 					 AHD_TRANS_ACTIVE, /*paused*/TRUE);
@@ -988,6 +1003,96 @@
 			 ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE);
 		break;
 	}
+	case TASKMGMT_FUNC_COMPLETE:
+	{
+		u_int	scbid;
+		struct	scb *scb;
+
+		scbid = ahd_get_scbptr(ahd);
+		scb = ahd_lookup_scb(ahd, scbid);
+		if (scb != NULL) {
+			u_int	   lun;
+			u_int	   tag;
+			cam_status error;
+
+			ahd_print_path(ahd, scb);
+			printf("Task Management Func 0x%x Complete\n",
+			       scb->hscb->task_management);
+			lun = CAM_LUN_WILDCARD;
+			tag = SCB_LIST_NULL;
+
+			switch (scb->hscb->task_management) {
+			case SIU_TASKMGMT_ABORT_TASK:
+				tag = scb->hscb->tag;
+			case SIU_TASKMGMT_ABORT_TASK_SET:
+			case SIU_TASKMGMT_CLEAR_TASK_SET:
+				lun = scb->hscb->lun;
+				error = CAM_REQ_ABORTED;
+				ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
+					       'A', lun, tag, ROLE_INITIATOR,
+					       error);
+				break;
+			case SIU_TASKMGMT_LUN_RESET:
+				lun = scb->hscb->lun;
+			case SIU_TASKMGMT_TARGET_RESET:
+			{
+				struct ahd_devinfo devinfo;
+
+				ahd_scb_devinfo(ahd, &devinfo, scb);
+				error = CAM_BDR_SENT;
+				ahd_handle_devreset(ahd, &devinfo, lun,
+						    CAM_BDR_SENT,
+						    lun != CAM_LUN_WILDCARD
+						    ? "Lun Reset"
+						    : "Target Reset",
+						    /*verbose_level*/0);
+				break;
+			}
+			default:
+				panic("Unexpected TaskMgmt Func\n");
+				break;
+			}
+		}
+		break;
+	}
+	case TASKMGMT_CMD_CMPLT_OKAY:
+	{
+		u_int	scbid;
+		struct	scb *scb;
+
+		/*
+		 * An ABORT TASK TMF failed to be delivered before
+		 * the targeted command completed normally.
+		 */
+		scbid = ahd_get_scbptr(ahd);
+		scb = ahd_lookup_scb(ahd, scbid);
+		if (scb != NULL) {
+			/*
+			 * Remove the second instance of this SCB from
+			 * the QINFIFO if it is still there.
+                         */
+			ahd_print_path(ahd, scb);
+			printf("SCB completes before TMF\n");
+			/*
+			 * Handle losing the race.  Wait until any
+			 * current selection completes.  We will then
+			 * set the TMF back to zero in this SCB so that
+			 * the sequencer doesn't bother to issue another
+			 * sequencer interrupt for its completion.
+			 */
+			while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
+			    && (ahd_inb(ahd, SSTAT0) & SELDO) == 0
+			    && (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
+				;
+			ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
+			ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
+					   SCB_GET_CHANNEL(ahd, scb),  
+					   SCB_GET_LUN(scb), scb->hscb->tag, 
+					   ROLE_INITIATOR, /*status*/0,   
+					   SEARCH_REMOVE);
+		}
+		break;
+	}
 	case TRACEPOINT0:
 	case TRACEPOINT1:
 	case TRACEPOINT2:
@@ -1711,8 +1816,8 @@
 					  ROLE_INITIATOR))
 				ahd_set_transaction_status(scb, CAM_REQ_CMP);
 #endif
-			ahd_handle_devreset(ahd, &devinfo, CAM_BDR_SENT,
-					    "Bus Device Reset",
+			ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
+					    CAM_BDR_SENT, "Bus Device Reset",
 					    /*verbose_level*/0);
 			printerror = 0;
 		} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
@@ -2410,8 +2515,9 @@
 		 * occurs the need to renegotiate is
 		 * recorded persistently.
 		 */
+		if ((ahd->features & AHD_WIDE) != 0)
+			tinfo->curr.width = AHD_WIDTH_UNKNOWN;
 		tinfo->curr.period = AHD_PERIOD_UNKNOWN;
-		tinfo->curr.width = AHD_WIDTH_UNKNOWN;
 		tinfo->curr.offset = AHD_OFFSET_UNKNOWN;
 	}
 	if (tinfo->curr.period != tinfo->goal.period
@@ -3618,8 +3724,8 @@
 			if (type == AHDMSG_1B
 			 && ahd->msgout_index > index
 			 && (ahd->msgout_buf[index] == msgval
-			  || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0))
-			   && msgval == MSG_IDENTIFYFLAG)
+			  || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
+			   && msgval == MSG_IDENTIFYFLAG)))
 				found = TRUE;
 			index++;
 		}
@@ -3965,7 +4071,7 @@
 	}
 #ifdef AHD_TARGET_MODE
 	case MSG_BUS_DEV_RESET:
-		ahd_handle_devreset(ahd, devinfo,
+		ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
 				    CAM_BDR_SENT,
 				    "Bus Device Reset Received",
 				    /*verbose_level*/0);
@@ -4121,7 +4227,7 @@
 		 * but rejected our response, we already cleared the
 		 * sync rate before sending our WDTR.
 		 */
-		if (tinfo->goal.period) {
+		if (tinfo->goal.offset != tinfo->curr.offset) {
 
 			/* Start the sync negotiation */
 			ahd->msgout_index = 0;
@@ -4464,16 +4570,16 @@
  */
 static void
 ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
-		    cam_status status, char *message, int verbose_level)
+		    u_int lun, cam_status status, char *message,
+		    int verbose_level)
 {
 #ifdef AHD_TARGET_MODE
 	struct ahd_tmode_tstate* tstate;
-	u_int lun;
 #endif
 	int found;
 
 	found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
-			       CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
+			       lun, SCB_LIST_NULL, devinfo->role,
 			       status);
 
 #ifdef AHD_TARGET_MODE
@@ -4483,10 +4589,20 @@
 	 */
 	tstate = ahd->enabled_targets[devinfo->our_scsiid];
 	if (tstate != NULL) {
-		for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
+		u_int cur_lun;
+		u_int max_lun;
+
+		if (lun != CAM_LUN_WILDCARD) {
+			cur_lun = 0;
+			max_lun = AHD_NUM_LUNS - 1;
+		} else {
+			cur_lun = lun;
+			max_lun = lun;
+		}
+		for (cur_lun <= max_lun; cur_lun++) {
 			struct ahd_tmode_lstate* lstate;
 
-			lstate = tstate->enabled_luns[lun];
+			lstate = tstate->enabled_luns[cur_lun];
 			if (lstate == NULL)
 				continue;
 
@@ -4506,7 +4622,7 @@
 			 /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);
 	
 	ahd_send_async(ahd, devinfo->channel, devinfo->target,
-		       CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+		       lun, AC_SENT_BDR, NULL);
 
 	if (message != NULL
 	 && (verbose_level <= bootverbose))
@@ -8129,8 +8245,11 @@
 	}
 	ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
 
-	if (bootverbose)
+	if (bootverbose) {
 		printf(" %d instructions downloaded\n", downloaded);
+		printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
+		       ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
+	}
 }
 
 static int
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h	Mon Feb 10 10:39:27 2003
@@ -2,7 +2,7 @@
  * Inline routines shareable across OS platforms.
  *
  * Copyright (c) 1994-2001 Justin T. Gibbs.
- * Copyright (c) 2000-2002 Adaptec Inc.
+ * Copyright (c) 2000-2003 Adaptec Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#40 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 $
  *
  * $FreeBSD$
  */
@@ -272,7 +272,6 @@
 	if ((scb->flags & SCB_PACKETIZED) != 0) {
 		/* XXX what about ACA??  It is type 4, but TAG_TYPE == 0x3. */
 		scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE;
-		scb->hscb->task_management = 0;
 		/*
 		 * For Rev A short lun workaround.
 		 */
@@ -770,7 +769,7 @@
 	ahd_setup_scb_common(ahd, scb);
 
 	/*
-	 * Make sure our data is consistant from the
+	 * Make sure our data is consistent from the
 	 * perspective of the adapter.
 	 */
 	ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Mon Feb 10 10:39:23 2003
@@ -1,12 +1,12 @@
 /*
  * Adaptec AIC79xx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#104 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 $
  *
  * --------------------------------------------------------------------------
  * Copyright (c) 1994-2000 Justin T. Gibbs.
  * Copyright (c) 1997-1999 Doug Ledford
- * Copyright (c) 2000-2002 Adaptec Inc.
+ * Copyright (c) 2000-2003 Adaptec Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,12 +42,6 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
-/*
- * This is the only file where module.h should
- * embed module global version info.
- */
-#define AHD_MODVERSION_FILE
-
 #include "aic79xx_osm.h"
 #include "aic79xx_inline.h"
 #include <scsi/scsicam.h>
@@ -482,10 +476,7 @@
 static void ahd_linux_filter_inquiry(struct ahd_softc *ahd,
 				     struct ahd_devinfo *devinfo);
 static void ahd_linux_dev_timed_unfreeze(u_long arg);
-#if NO_YET
 static void ahd_linux_sem_timeout(u_long arg);
-static int  ahd_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
-#endif 
 static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
 static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd);
 static void ahd_linux_start_dv(struct ahd_softc *ahd);
@@ -496,8 +487,6 @@
 				    struct scsi_cmnd *cmd,
 				    struct ahd_devinfo *devinfo,
 				    struct ahd_linux_target *targ);
-static uint32_t aic_error_action(struct scsi_cmnd *cmd,
-				 struct scsi_inquiry_data *inq_data);
 static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd,
 				  struct scsi_cmnd *cmd,
 				  struct ahd_devinfo *devinfo);
@@ -806,6 +795,10 @@
 	return (consumed);
 }
 
+/******************************** Macros **************************************/
+#define BUILD_SCSIID(ahd, cmd)						\
+	((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id)
+
 /************************  Host template entry points *************************/
 static int	   ahd_linux_detect(Scsi_Host_Template *);
 static int	   ahd_linux_release(struct Scsi_Host *);
@@ -971,7 +964,7 @@
 	struct	 ahd_linux_device *dev;
 	u_long	 flags;
 
-	ahd = *(struct ahd_softc **)cmd->host->hostdata;
+	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
 
 	/*
 	 * Save the callback on completion function.
@@ -995,8 +988,9 @@
 		ahd_midlayer_entrypoint_unlock(ahd, &flags);
 		return (0);
 	}
-	dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/TRUE);
+	dev = ahd_linux_get_device(ahd, cmd->device->channel,
+				   cmd->device->id, cmd->device->lun,
+				   /*alloc*/TRUE);
 	if (dev == NULL) {
 		ahd_midlayer_entrypoint_unlock(ahd, &flags);
 		printf("aic79xx_linux_queue: Unable to allocate device!\n");
@@ -1211,31 +1205,303 @@
 ahd_linux_abort(Scsi_Cmnd *cmd)
 {
 	struct ahd_softc *ahd;
-	u_long s;
-#if NOTYET
 	struct ahd_cmd *acmd;
-	int    found;
-#endif
+	struct ahd_cmd *list_acmd;
+	struct ahd_linux_device *dev;
+	struct scb *pending_scb;
+	u_long s;
+	u_int  saved_scbptr;
+	u_int  active_scbptr;
+	u_int  last_phase;
+	int    retval;
+	int    paused;
+	int    wait;
+	int    disconnected;
+	ahd_mode_state saved_modes;
 
-	ahd = *(struct ahd_softc **)cmd->host->hostdata;
-#if NOTYET
-	int error;
-
-	error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT);
-	if (error != 0)
-		printf("aic79xx_abort returns 0x%x\n", error);
-	return (error);
-#else
+	pending_scb = NULL;
+	paused = FALSE;
+	wait = FALSE;
+	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+	acmd = (struct ahd_cmd *)cmd;
+
+	printf("%s:%d:%d:%d: Attempting to abort cmd %p\n",
+	       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+	       cmd->device->lun, cmd);
+
+	/*
+	 * In all versions of Linux, we have to work around
+	 * a major flaw in how the mid-layer is locked down
+	 * if we are to sleep successfully in our error handler
+	 * while allowing our interrupt handler to run.  Since
+	 * the midlayer acquires either the io_request_lock or
+	 * our lock prior to calling us, we must use the
+	 * spin_unlock_irq() method for unlocking our lock.
+	 * This will force interrupts to be enabled on the
+	 * current CPU.  Since the EH thread should not have
+	 * been running with CPU interrupts disabled other than
+	 * by acquiring either the io_request_lock or our own
+	 * lock, this *should* be safe.
+	 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	spin_unlock_irq(&io_request_lock);
+#endif
 	ahd_midlayer_entrypoint_lock(ahd, &s);
-#ifdef AHD_DEBUG
-	if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
-		printf("%s: Abort called for cmd %p\n", ahd_name(ahd), cmd);
-		ahd_dump_card_state(ahd);
+
+	/*
+	 * First determine if we currently own this command.
+	 * Start by searching the device queue.  If not found
+	 * there, check the pending_scb list.  If not found
+	 * at all, and the system wanted us to just abort the
+	 * command return success.
+	 */
+	dev = ahd_linux_get_device(ahd, cmd->device->channel,
+				   cmd->device->id, cmd->device->lun,
+				   /*alloc*/FALSE);
+
+	if (dev == NULL) {
+		/*
+		 * No target device for this command exists,
+		 * so we must not still own the command.
+		 */
+		printf("%s:%d:%d:%d: Is not an active device\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
+		retval = SUCCESS;
+		goto no_cmd;
+	}
+
+	TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
+		if (list_acmd == acmd)
+			break;
+	}
+
+	if (list_acmd != NULL) {
+		printf("%s:%d:%d:%d: Command found on device queue\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
+		TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
+		cmd->result = DID_ABORT << 16;
+		ahd_linux_queue_cmd_complete(ahd, cmd);
+		retval = SUCCESS;
+		goto done;
+	}
+
+	/*
+	 * See if we can find a matching cmd in the pending list.
+	 */
+	LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
+		if (pending_scb->io_ctx == cmd)
+			break;
+	}
+
+	if (pending_scb == NULL) {
+		printf("%s:%d:%d:%d: Command not found\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
+		goto no_cmd;
+	}
+
+	if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
+		/*
+		 * We can't queue two recovery actions using the same SCB
+		 */
+		retval = FAILED;
+		goto  done;
+	}
+
+	/*
+	 * Ensure that the card doesn't do anything
+	 * behind our back.  Also make sure that we
+	 * didn't "just" miss an interrupt that would
+	 * affect this cmd.
+	 */
+	ahd_pause_and_flushwork(ahd);
+	paused = TRUE;
+
+	if ((pending_scb->flags & SCB_ACTIVE) == 0) {
+		printf("%s:%d:%d:%d: Command already completed\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
+		goto no_cmd;
+	}
+
+	ahd_dump_card_state(ahd);
+
+	disconnected = TRUE;
+	if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A',
+			       cmd->device->lun, pending_scb->hscb->tag,
+			       ROLE_INITIATOR, CAM_REQ_ABORTED,
+			       SEARCH_COMPLETE) > 0) {
+		printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+				cmd->device->lun);
+		retval = SUCCESS;
+		goto done;
+	}
+
+	saved_modes = ahd_save_modes(ahd);
+	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+	last_phase = ahd_inb(ahd, LASTPHASE);
+	saved_scbptr = ahd_get_scbptr(ahd);
+	active_scbptr = saved_scbptr;
+	if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
+		struct scb *bus_scb;
+
+		bus_scb = ahd_lookup_scb(ahd, active_scbptr);
+		if (bus_scb == pending_scb)
+			disconnected = FALSE;
+	}
+
+	/*
+	 * At this point, pending_scb is the scb associated with the
+	 * passed in command.  That command is currently active on the
+	 * bus or is in the disconnected state.
+	 */
+	if (last_phase != P_BUSFREE
+	 && pending_scb->hscb->tag == active_scbptr) {
+
+		/*
+		 * We're active on the bus, so assert ATN
+		 * and hope that the target responds.
+		 */
+		pending_scb = ahd_lookup_scb(ahd, active_scbptr);
+		pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
+		ahd_outb(ahd, MSG_OUT, HOST_MSG);
+		ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
+		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
+		       ahd_name(ahd), cmd->device->channel,
+		       cmd->device->id, cmd->device->lun);
+		wait = TRUE;
+	} else if (disconnected) {
+
+		/*
+		 * Actually re-queue this SCB in an attempt
+		 * to select the device before it reconnects.
+		 */
+		pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
+		ahd_set_scbptr(ahd, pending_scb->hscb->tag);
+		pending_scb->hscb->cdb_len = 0;
+		pending_scb->hscb->task_attribute = 0;
+		pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
+
+		if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
+			/*
+			 * Mark the SCB has having an outstanding
+			 * task management function.  Should the command
+			 * complete normally before the task management
+			 * function can be sent, the host will be notified
+			 * to abort our requeued SCB.
+			 */
+			ahd_outb(ahd, SCB_TASK_MANAGEMENT,
+				 pending_scb->hscb->task_management);
+		} else {
+			/*
+			 * If non-packetized, set the MK_MESSAGE control
+			 * bit indicating that we desire to send a message.
+			 * We also set the disconnected flag since there is
+			 * no guarantee that our SCB control byte matches
+			 * the version on the card.  We don't want the
+			 * sequencer to abort the command thinking an
+			 * unsolicited reselection occurred.
+			 */
+			pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
+
+			/*
+			 * The sequencer will never re-reference the
+			 * in-core SCB.  To make sure we are notified
+			 * during reslection, set the MK_MESSAGE flag in
+			 * the card's copy of the SCB.
+			 */
+			ahd_outb(ahd, SCB_CONTROL,
+				 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
+		}
+
+		/*
+		 * Clear out any entries in the QINFIFO first
+		 * so we are the next SCB for this target
+		 * to run.
+		 */
+		ahd_search_qinfifo(ahd, cmd->device->id,
+				   cmd->device->channel + 'A', cmd->device->lun,
+				   SCB_LIST_NULL, ROLE_INITIATOR,
+				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
+		ahd_qinfifo_requeue_tail(ahd, pending_scb);
+		ahd_set_scbptr(ahd, saved_scbptr);
+		ahd_print_path(ahd, pending_scb);
+		printf("Device is disconnected, re-queuing SCB\n");
+		wait = TRUE;
+	} else {
+		printf("%s:%d:%d:%d: Unable to deliver message\n",
+		       ahd_name(ahd), cmd->device->channel,
+		       cmd->device->id, cmd->device->lun);
+		retval = FAILED;
+		goto done;
 	}
+
+no_cmd:
+	/*
+	 * Our assumption is that if we don't have the command, no
+	 * recovery action was required, so we return success.  Again,
+	 * the semantics of the mid-layer recovery engine are not
+	 * well defined, so this may change in time.
+	 */
+	retval = SUCCESS;
+done:
+	if (paused)
+		ahd_unpause(ahd);
+	if (wait) {
+		struct timer_list timer;
+		int ret;
+
+		ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		ahd_unlock(ahd, &s);
+#else
+		spin_unlock_irq(ahd->platform_data->host->host_lock);
+#endif
+		init_timer(&timer);
+		timer.data = (u_long)ahd;
+		timer.expires = jiffies + (5 * HZ);
+		timer.function = ahd_linux_sem_timeout;
+		add_timer(&timer);
+		printf("Recovery code sleeping\n");
+		down(&ahd->platform_data->eh_sem);
+		printf("Recovery code awake\n");
+        	ret = del_timer(&timer);
+		if (ret == 0) {
+			printf("Timer Expired\n");
+			retval = FAILED;
+		}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		ahd_lock(ahd, &s);
+#else
+		spin_lock_irq(ahd->platform_data->host->host_lock);
 #endif
+	}
+	acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
+	TAILQ_INIT(&ahd->platform_data->completeq);
 	ahd_midlayer_entrypoint_unlock(ahd, &s);
-	return (FAILED);
+	if (acmd != NULL) {
+		acmd = ahd_linux_run_complete_queue(ahd, acmd);
+		if (acmd != NULL) {
+			ahd_midlayer_entrypoint_lock(ahd, &s);
+			ahd_schedule_completeq(ahd, acmd);
+			ahd_midlayer_entrypoint_unlock(ahd, &s);
+		}
+	}
+	ahd_schedule_runq(ahd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	spin_lock_irq(&io_request_lock);
 #endif
+	return (retval);
+}
+
+
+static void
+ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd)
+{
+	free(cmd, M_DEVBUF);
 }
 
 /*
@@ -1244,29 +1510,112 @@
 static int
 ahd_linux_dev_reset(Scsi_Cmnd *cmd)
 {
-	struct ahd_softc *ahd;
-#if NOTYET
-	struct ahd_cmd *acmd;
-	u_long s;
-	int    found;
-#endif
+	struct	ahd_softc *ahd;
+	struct	scsi_cmnd *recovery_cmd;
+	struct	ahd_linux_device *dev;
+	struct	ahd_initiator_tinfo *tinfo;
+	struct	ahd_tmode_tstate *tstate;
+	struct	scb *scb;
+	struct	hardware_scb *hscb;
+	struct	ahd_cmd *acmd;
+	u_long	s;
+	struct	timer_list timer;
+	int	retval;
 
-	ahd = *(struct ahd_softc **)cmd->host->hostdata;
-#ifdef AHD_DEBUG
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	spin_unlock_irq(&io_request_lock);
+#endif
+	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+	recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
+	memset(recovery_cmd, 0, sizeof(struct scsi_cmnd));
+	recovery_cmd->device = cmd->device;
+	recovery_cmd->scsi_done = ahd_linux_dev_reset_complete;
+#if AHD_DEBUG
 	if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
-		printf("%s: Dev reset called for cmd %p\n",
-		       ahd_name(ahd), cmd);
+		printf("%s:%d:%d:%d: Device reset called for cmd %p\n",
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun, cmd);
 #endif
-#if NOTYET
-	int error;
+	ahd_midlayer_entrypoint_lock(ahd, &s);
 
-	error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
-	if (error != 0)
-		printf("aic79xx_dev_reset returns 0x%x\n", error);
-	return (error);
+	dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id,
+				   cmd->device->lun, /*alloc*/FALSE);
+	if (dev == NULL) {
+		ahd_midlayer_entrypoint_unlock(ahd, &s);
+		return (FAILED);
+	}
+	if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) {
+		ahd_midlayer_entrypoint_unlock(ahd, &s);
+		return (FAILED);
+	}
+	tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
+				    cmd->device->id, &tstate);
+	recovery_cmd->result = CAM_REQ_INPROG << 16;
+	recovery_cmd->host_scribble = (char *)scb;
+	scb->io_ctx = recovery_cmd;
+	scb->platform_data->dev = dev;
+	scb->sg_count = 0;
+	ahd_set_residual(scb, 0);
+	ahd_set_sense_residual(scb, 0);
+	hscb = scb->hscb;
+	hscb->control = 0;
+	hscb->scsiid = BUILD_SCSIID(ahd, cmd);
+	hscb->lun = cmd->lun;
+	hscb->cdb_len = 0;
+	hscb->task_management = SIU_TASKMGMT_LUN_RESET;
+	scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
+	if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
+		scb->flags |= SCB_PACKETIZED;
+	} else {
+		hscb->control |= MK_MESSAGE;
+	}
+	dev->openings--;
+	dev->active++;
+	dev->commands_issued++;
+	LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
+	ahd_queue_scb(ahd, scb);
+
+	ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	ahd_unlock(ahd, &s);
 #else
-	return (FAILED);
+	spin_unlock_irq(ahd->platform_data->host->host_lock);
+#endif
+	init_timer(&timer);
+	timer.data = (u_long)ahd;
+	timer.expires = jiffies + (5 * HZ);
+	timer.function = ahd_linux_sem_timeout;
+	add_timer(&timer);
+	printf("Recovery code sleeping\n");
+	down(&ahd->platform_data->eh_sem);
+	printf("Recovery code awake\n");
+	retval = SUCCESS;
+	if (del_timer(&timer) == 0) {
+		printf("Timer Expired\n");
+		retval = FAILED;
+	}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	ahd_lock(ahd, &s);
+#else
+	spin_lock_irq(ahd->platform_data->host->host_lock);
+#endif
+	acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
+	TAILQ_INIT(&ahd->platform_data->completeq);
+	ahd_midlayer_entrypoint_unlock(ahd, &s);
+	if (acmd != NULL) {
+		acmd = ahd_linux_run_complete_queue(ahd, acmd);
+		if (acmd != NULL) {
+			ahd_midlayer_entrypoint_lock(ahd, &s);
+			ahd_schedule_completeq(ahd, acmd);
+			ahd_midlayer_entrypoint_unlock(ahd, &s);
+		}
+	}
+	ahd_schedule_runq(ahd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	spin_lock_irq(&io_request_lock);
 #endif
+	printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
+	return (retval);
 }
 
 /*
@@ -1283,14 +1632,14 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	spin_unlock_irq(&io_request_lock);
 #endif
-	ahd = *(struct ahd_softc **)cmd->host->hostdata;
+	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
 #ifdef AHD_DEBUG
 	if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
 		printf("%s: Bus reset called for cmd %p\n",
 		       ahd_name(ahd), cmd);
 #endif
 	ahd_midlayer_entrypoint_lock(ahd, &s);
-	found = ahd_reset_channel(ahd, cmd->channel + 'A',
+	found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
 				  /*initiate reset*/TRUE);
 	acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
 	TAILQ_INIT(&ahd->platform_data->completeq);
@@ -1413,10 +1762,6 @@
 	return (NOTIFY_OK);
 }
 
-/******************************** Macros **************************************/
-#define BUILD_SCSIID(ahd, cmd)						\
-	((((cmd)->target << TID_SHIFT) & TID) | (ahd)->our_id)
-
 /******************************** Bus DMA *************************************/
 int
 ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
@@ -2106,10 +2451,10 @@
 static void
 ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
 {
-	int i;
-	int numtarg;
+	u_int target_id;
+	u_int numtarg;
 
-	i = 0;
+	target_id = 0;
 	numtarg = 0;
 
 	if (aic79xx_no_reset != 0)
@@ -2124,21 +2469,15 @@
 	 * Force negotiation to async for all targets that
 	 * will not see an initial bus reset.
 	 */
-	for (; i < numtarg; i++) {
+	for (; target_id < numtarg; target_id++) {
 		struct ahd_devinfo devinfo;
 		struct ahd_initiator_tinfo *tinfo;
 		struct ahd_tmode_tstate *tstate;
-		u_int our_id;
-		u_int target_id;
-		char channel;
-
-		channel = 'A';
-		our_id = ahd->our_id;
-		target_id = i;
-		tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
+
+		tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
 					    target_id, &tstate);
-		ahd_compile_devinfo(&devinfo, our_id, target_id,
-				    CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
+		ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
+				    CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
 		ahd_update_neg_request(ahd, &devinfo, tstate,
 				       tinfo, AHD_NEG_ALWAYS);
 	}
@@ -2192,7 +2531,10 @@
 void
 ahd_platform_free(struct ahd_softc *ahd)
 {
+	struct ahd_linux_target *targ;
+	struct ahd_linux_device *dev;
 	u_long s;
+	int i, j;
 
 	if (ahd->platform_data != NULL) {
 		/* Kill the DV kthread */
@@ -2214,6 +2556,23 @@
 		ahd_teardown_runq_tasklet(ahd);
 		if (ahd->platform_data->host != NULL)
 			scsi_unregister(ahd->platform_data->host);
+
+		/* destroy all of the device and target objects */
+		for (i = 0; i < AHD_NUM_TARGETS; i++) {
+			targ = ahd->platform_data->targets[i];
+			if (targ != NULL) {
+				for (j = 0; j < AHD_NUM_LUNS; j++) {
+					if (targ->devices[j] != NULL) {
+						dev = targ->devices[j];
+						ahd_linux_free_device(ahd, dev);
+					}
+					if (ahd->platform_data->targets[i] ==
+					    NULL)
+						break;
+				}
+			}
+		}
+
 		if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
 			free_irq(ahd->platform_data->irq, ahd);
 		if (ahd->tags[0] == BUS_SPACE_PIO
@@ -2593,6 +2952,7 @@
 	struct	 ahd_devinfo devinfo;
 	struct	 ahd_linux_target *targ;
 	struct	 scsi_cmnd *cmd;
+	struct	 scsi_device *scsi_dev;
 	struct	 scsi_sense_data *sense;
 	uint8_t *buffer;
 	u_long	 s;
@@ -2620,6 +2980,12 @@
 	ahd_unlock(ahd, &s);
 
 	cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
+	scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK);
+	scsi_dev->host = ahd->platform_data->host;
+	scsi_dev->id = devinfo.target;
+	scsi_dev->lun = devinfo.lun;
+	scsi_dev->channel = devinfo.channel - 'A';
+	ahd->platform_data->dv_scsi_dev = scsi_dev;
 
 	AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC);
 
@@ -2744,6 +3110,11 @@
 	if (cmd != NULL)
 		free(cmd, M_DEVBUF);
 
+	if (ahd->platform_data->dv_scsi_dev != NULL) {
+		free(ahd->platform_data->dv_scsi_dev, M_DEVBUF);
+		ahd->platform_data->dv_scsi_dev = NULL;
+	}
+
 	ahd_lock(ahd, &s);
 	if (targ->dv_buffer != NULL)
 		free(targ->dv_buffer, M_DEVBUF);
@@ -2760,9 +3131,13 @@
 			struct ahd_devinfo *devinfo,
 			struct ahd_linux_target *targ)
 {
+	cam_status cam_status;
 	u_int32_t status;
+	u_int scsi_status;
 
-	status = aic_error_action(cmd, targ->inq_data);
+	scsi_status = ahd_cmd_get_scsi_status(cmd);
+	cam_status = ahd_cmd_get_transaction_status(cmd);
+	status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
 
 	
 #ifdef AHD_DEBUG
@@ -2813,6 +3188,7 @@
 		switch (status & SS_MASK) {
 		case SS_NOP:
 		{
+			u_int xportflags;
 			u_int spi3data;
 
 			if (memcmp(targ->inq_data, targ->dv_buffer,
@@ -2831,6 +3207,10 @@
 			if (ahd_linux_user_dv_setting(ahd) == 0)
 				break;
 
+			xportflags = targ->inq_data->flags;
+			if ((xportflags & (SID_Sync|SID_WBus16)) == 0)
+				break;
+
 			spi3data = targ->inq_data->spi3data;
 			switch (spi3data & SID_SPI_CLOCK_DT_ST) {
 			default:
@@ -3225,104 +3605,13 @@
 	}
 }
 
-static uint32_t
-aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data)
-{
-	aic_sense_action  err_action;
-	cam_status	  status;
-	u_int		  scsi_status;
-	int		  sense;
-
-	status = ahd_cmd_get_transaction_status(cmd);
-	scsi_status = ahd_cmd_get_scsi_status(cmd);
-	sense  = (cmd->result >> 24) == DRIVER_SENSE;
-
-	switch (status) {
-	case CAM_REQ_CMP:
-		err_action = SS_NOP;
-		break;
-	case CAM_AUTOSENSE_FAIL:
-	case CAM_SCSI_STATUS_ERROR:
-
-		switch (scsi_status) {
-		case SCSI_STATUS_OK:
-		case SCSI_STATUS_COND_MET:
-		case SCSI_STATUS_INTERMED:
-		case SCSI_STATUS_INTERMED_COND_MET:
-			err_action = SS_NOP;
-			break;
-		case SCSI_STATUS_CMD_TERMINATED:
-		case SCSI_STATUS_CHECK_COND:
-			if (sense != 0) {
-				struct scsi_sense_data *sense;
-
-				sense = (struct scsi_sense_data *)
-				    &cmd->sense_buffer;
-				err_action =
-				    aic_sense_error_action(sense, inq_data, 0);
-
-			} else {
-				err_action = SS_RETRY|SSQ_FALLBACK
-					   | SSQ_DECREMENT_COUNT|EIO;
-			}
-			break;
-		case SCSI_STATUS_QUEUE_FULL:
-		case SCSI_STATUS_BUSY:
-			err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY
-				   | SSQ_DECREMENT_COUNT|EBUSY;
-			break;
-		case SCSI_STATUS_RESERV_CONFLICT:
-		default:
-			err_action = SS_FAIL|EBUSY;
-			break;
-		}
-		break;
-	case CAM_CMD_TIMEOUT:
-	case CAM_REQ_CMP_ERR:
-	case CAM_UNEXP_BUSFREE:
-	case CAM_UNCOR_PARITY:
-	case CAM_DATA_RUN_ERR:
-		err_action = SS_RETRY|SSQ_FALLBACK|EIO;
-		break;
-	case CAM_UA_ABORT:
-	case CAM_UA_TERMIO:
-	case CAM_MSG_REJECT_REC:
-	case CAM_SEL_TIMEOUT:
-		err_action = SS_FAIL|EIO;
-		break;
-	case CAM_REQ_INVALID:
-	case CAM_PATH_INVALID:
-	case CAM_DEV_NOT_THERE:
-	case CAM_NO_HBA:
-	case CAM_PROVIDE_FAIL:
-	case CAM_REQ_TOO_BIG:		
-	case CAM_RESRC_UNAVAIL:
-	case CAM_BUSY:
-	default:
-		/* panic??  These should never occur in our application. */
-		err_action = SS_FAIL|EIO;
-		break;
-	case CAM_SCSI_BUS_RESET:
-	case CAM_BDR_SENT:		
-	case CAM_REQUEUE_REQ:
-		/* Unconditional requeue */
-		err_action = SS_RETRY;
-		break;
-	}
-
-	return (err_action);
-}
-
 static void
 ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
 		      struct ahd_devinfo *devinfo)
 {
 	memset(cmd, 0, sizeof(struct scsi_cmnd));
-	cmd->host = ahd->platform_data->host;
+	cmd->device = ahd->platform_data->dv_scsi_dev;
 	cmd->scsi_done = ahd_linux_dv_complete;
-	cmd->target = devinfo->target;
-	cmd->lun = devinfo->lun;
-	cmd->channel = devinfo->channel - 'A';
 }
 
 /*
@@ -3475,23 +3764,6 @@
 	cmd->cmnd[4] = le | SSS_START;
 }
 
-/*
- * Return speed in KB/s.
- */
-static u_int
-ahd_linux_calc_speed(u_int width, u_int period, u_int offset)
-{
-	u_int freq;
-
-	if (offset != 0 && period < AHD_SYNCRATE_MIN)
-		freq  = aic_calc_syncsrate(period);
-	else
-		/* Roughly 3.3MB/s for async */
-		freq  = 3300;
-	freq <<= width;
-	return (freq);
-}
-
 static __inline int
 ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
 {
@@ -3549,14 +3821,15 @@
 	if (targ->dv_last_ppr_options == 0)
 		targ->dv_last_ppr_options = ppr_options;
 
-	cur_speed = ahd_linux_calc_speed(width, period, offset);
-	wide_speed = ahd_linux_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
+	cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN);
+	wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
 					  targ->dv_next_wide_period,
-					  MAX_OFFSET);
-	narrow_speed = ahd_linux_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
+					  MAX_OFFSET, AHD_SYNCRATE_MIN);
+	narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
 					    targ->dv_next_narrow_period,
-					    MAX_OFFSET);
-	fallback_speed = ahd_linux_calc_speed(width, period+1, offset);
+					    MAX_OFFSET, AHD_SYNCRATE_MIN);
+	fallback_speed = aic_calc_speed(width, period+1, offset,
+					      AHD_SYNCRATE_MIN);
 #ifdef AHD_DEBUG
 	if (ahd_debug & AHD_SHOW_DV) {
 		printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
@@ -3687,13 +3960,15 @@
 	struct	scb *scb;
 	u_long	flags;
 
-	ahd = *((struct ahd_softc **)cmd->host->hostdata);
+	ahd = *((struct ahd_softc **)cmd->device->host->hostdata);
 	ahd_lock(ahd, &flags);
 
 #ifdef AHD_DEBUG
-	if (ahd_debug & AHD_SHOW_DV)
+	if (ahd_debug & AHD_SHOW_DV) {
 		printf("%s: Timeout while doing DV command %x.\n",
 		       ahd_name(ahd), cmd->cmnd[0]);
+		ahd_dump_card_state(ahd);
+	}
 #endif
 	
 	/*
@@ -3715,7 +3990,7 @@
 		ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
 	else
 		ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
-	ahd_reset_channel(ahd, cmd->channel + 'A', /*initiate*/TRUE);
+	ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate*/TRUE);
 
 	/*
 	 * Add a minimal bus settle delay for devices that are slow to
@@ -3765,7 +4040,7 @@
 {
 	struct ahd_softc *ahd;
 
-	ahd = *((struct ahd_softc **)cmd->host->hostdata);
+	ahd = *((struct ahd_softc **)cmd->device->host->hostdata);
 
 	/* Delete the DV timer before it goes off! */
 	scsi_delete_timer(cmd);
@@ -3773,7 +4048,8 @@
 #ifdef AHD_DEBUG
 	if (ahd_debug & AHD_SHOW_DV)
 		printf("%s:%c:%d: Command completed, status= 0x%x\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->result);
+		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
+		       cmd->result);
 #endif
 
 	/* Wake up the state machine */
@@ -3967,12 +4243,13 @@
 		 * Get an scb to use.
 		 */
 		tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
-					    cmd->target, &tstate);
+					    cmd->device->id, &tstate);
 		if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
 		 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
 			col_idx = AHD_NEVER_COL_IDX;
 		} else {
-			col_idx = AHD_BUILD_COL_IDX(cmd->target, cmd->lun);
+			col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
+						    cmd->device->lun);
 		}
 		if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
 			TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq,
@@ -3992,7 +4269,7 @@
 		 */
 		hscb->control = 0;
 		hscb->scsiid = BUILD_SCSIID(ahd, cmd);
-		hscb->lun = cmd->lun;
+		scb->hscb->task_management = 0;
 		mask = SCB_GET_TARGET_MASK(ahd, scb);
 
 		if ((ahd->user_discenable & mask) != 0)
@@ -4328,7 +4605,34 @@
 		break;
 	}
         case AC_SENT_BDR:
+	{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+		Scsi_Device *scsi_dev;
+
+		/*
+		 * Find the SCSI device associated with this
+		 * request and indicate that a UA is expected.
+		 * XXX This should really be handled by the mid-layer.
+		 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		list_for_each_entry(scsi_dev,
+				    &ahd->platform_data->host->my_devices,
+				    siblings) {
+#else
+		for (scsi_dev = ahd->platform_data->host->host_queue;
+		     scsi_dev != NULL; scsi_dev = scsi_dev->next) {
+#endif
+			if (channel - 'A' == scsi_dev->channel
+			 && target == scsi_dev->id
+			 && (lun == CAM_LUN_WILDCARD
+			  || lun == scsi_dev->lun)) {
+				scsi_dev->was_reset = 1;
+				scsi_dev->expecting_cc_ua = 1;
+			}
+		}
+#endif
 		break;
+	}
         case AC_BUS_RESET:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
 		if (ahd->platform_data->host != NULL) {
@@ -4346,7 +4650,7 @@
  * Calls the higher level scsi done function and frees the scb.
  */
 void
-ahd_done(struct ahd_softc *ahd, struct scb * scb)
+ahd_done(struct ahd_softc *ahd, struct scb *scb)
 {
 	Scsi_Cmnd *cmd;
 	struct	  ahd_linux_device *dev;
@@ -4445,8 +4749,8 @@
 		if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
 		 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
 			ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
-		if ((scb->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) {
-			scb->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE;
+		if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) {
+			ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE;
 			up(&ahd->platform_data->eh_sem);
 		}
 	}
@@ -4459,7 +4763,6 @@
 		ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY;
 		up(&ahd->platform_data->dv_sem);
 	}
-		
 }
 
 static void
@@ -4531,8 +4834,11 @@
 
 				printf("Copied %d bytes of sense data at %d:",
 				       sense_size, sense_offset);
-				for (i = 0; i < sense_size; i++)
-					printf(" 0x%x", cmd->sense_buffer[i]);
+				for (i = 0; i < sense_size; i++) {
+					if ((i & 0xF) == 0)
+						printf("\n");
+					printf("0x%x ", cmd->sense_buffer[i]);
+				}
 				printf("\n");
 			}
 #endif
@@ -4658,10 +4964,13 @@
 		if (status != CAM_REQ_CMP) {
 			struct ahd_linux_device *dev;
 			struct ahd_devinfo devinfo;
+			cam_status cam_status;
 			uint32_t action;
+			u_int scsi_status;
 
-			dev = ahd_linux_get_device(ahd, cmd->channel,
-						   cmd->target, cmd->lun,
+			dev = ahd_linux_get_device(ahd, cmd->device->channel,
+						   cmd->device->id,
+						   cmd->device->lun,
 						   /*alloc*/FALSE);
 
 			if (dev == NULL)
@@ -4672,8 +4981,11 @@
 					    dev->target->target, dev->lun,
 					    dev->target->channel == 0 ? 'A':'B',
 					    ROLE_INITIATOR);
-	
-			action = aic_error_action(cmd, dev->target->inq_data);
+
+			scsi_status = ahd_cmd_get_scsi_status(cmd);
+			cam_status = ahd_cmd_get_transaction_status(cmd);
+			action = aic_error_action(cmd, dev->target->inq_data,
+						  cam_status, scsi_status);
 			if ((action & SSQ_FALLBACK) != 0) {
 
 				/* Update stats */
@@ -4741,7 +5053,8 @@
 			 * evoke a retry even if this command is being sent
 			 * via the eh thread.  Ick!  Ick!  Ick!
 			 */
-			cmd->retries--;
+			if (cmd->retries > 0)
+				cmd->retries--;
 			new_status = DID_OK;
 			ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
 			cmd->result |= (DRIVER_SENSE << 24);
@@ -4936,7 +5249,6 @@
 	ahd_schedule_runq(ahd);
 }
 
-#if NOT_YET
 static void
 ahd_linux_sem_timeout(u_long arg)
 {
@@ -4951,305 +5263,6 @@
 	}
 	ahd_unlock(ahd, &s);
 }
-
-static int
-ahd_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
-{
-	struct ahd_softc *ahd;
-	struct ahd_cmd *acmd;
-	struct ahd_cmd *list_acmd;
-	struct ahd_linux_device *dev;
-	struct scb *pending_scb;
-	u_long s;
-	u_int  saved_scbptr;
-	u_int  active_scb_index;
-	u_int  last_phase;
-	int    retval;
-	int    paused;
-	int    wait;
-	int    disconnected;
-
-	pending_scb = NULL;
-	paused = FALSE;
-	wait = FALSE;
-	ahd = *(struct ahd_softc **)cmd->host->hostdata;
-	acmd = (struct ahd_cmd *)cmd;
-
-	printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
-	       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun,
-	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
-
-	/*
-	 * In all versions of Linux, we have to work around
-	 * a major flaw in how the mid-layer is locked down
-	 * if we are to sleep successfully in our error handler
-	 * while allowing our interrupt handler to run.  Since
-	 * the midlayer acquires either the io_request_lock or
-	 * our lock prior to calling us, we must use the
-	 * spin_unlock_irq() method for unlocking our lock.
-	 * This will force interrupts to be enabled on the
-	 * current CPU.  Since the EH thread should not have
-	 * been running with CPU interrupts disabled other than
-	 * by acquiring either the io_request_lock or our own
-	 * lock, this *should* be safe.
-	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	spin_unlock_irq(&io_request_lock);
-#endif
-	ahd_midlayer_entrypoint_lock(ahd, &s);
-
-	/*
-	 * First determine if we currently own this command.
-	 * Start by searching the device queue.  If not found
-	 * there, check the pending_scb list.  If not found
-	 * at all, and the system wanted us to just abort the
-	 * command return success.
-	 */
-	dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/FALSE);
-
-	if (dev == NULL) {
-		/*
-		 * No target device for this command exists,
-		 * so we must not still own the command.
-		 */
-		printf("%s:%d:%d:%d: Is not an active device\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		retval = SUCCESS;
-		goto no_cmd;
-	}
-
-	TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {
-		if (list_acmd == acmd)
-			break;
-	}
-
-	if (list_acmd != NULL) {
-		printf("%s:%d:%d:%d: Command found on device queue\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		if (flag == SCB_ABORT) {
-			TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
-			cmd->result = DID_ABORT << 16;
-			ahd_linux_queue_cmd_complete(ahd, cmd);
-			retval = SUCCESS;
-			goto done;
-		}
-	}
-
-	/*
-	 * See if we can find a matching cmd in the pending list.
-	 */
-	LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
-		if (pending_scb->io_ctx == cmd)
-			break;
-	}
-
-	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
-
-		/* Any SCB for this device will do for a target reset */
-		LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
-		  	if (ahd_match_scb(ahd, pending_scb, cmd->target,
-					  cmd->channel, CAM_LUN_WILDCARD,
-					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
-				break;
-		}
-	}
-
-	if (pending_scb == NULL) {
-		printf("%s:%d:%d:%d: Command not found\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		goto no_cmd;
-	}
-
-	if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
-		/*
-		 * We can't queue two recovery actions using the same SCB
-		 */
-		retval = FAILED;
-		goto  done;
-	}
-
-	/*
-	 * Ensure that the card doesn't do anything
-	 * behind our back.  Also make sure that we
-	 * didn't "just" miss an interrupt that would
-	 * affect this cmd.
-	 */
-	ahd->flags |= AHD_ALL_INTERRUPTS;
-	do {
-		ahd_intr(ahd);
-		ahd_pause(ahd);
-		ahd_clear_critical_section(ahd);
-	} while (ahd_inb(ahd, INTSTAT) & INT_PEND);
-	ahd->flags &= ~AHD_ALL_INTERRUPTS;
-	paused = TRUE;
-
-	ahd_dump_card_state(ahd);
-
-	if ((pending_scb->flags & SCB_ACTIVE) == 0) {
-		printf("%s:%d:%d:%d: Command already completed\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		goto no_cmd;
-	}
-
-	disconnected = TRUE;
-	if (flag == SCB_ABORT) {
-		if (ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A',
-				       cmd->lun, pending_scb->hscb->tag,
-				       ROLE_INITIATOR, CAM_REQ_ABORTED,
-				       SEARCH_COMPLETE) > 0) {
-			printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
-			       ahd_name(ahd), cmd->channel, cmd->target,
-					cmd->lun);
-			retval = SUCCESS;
-			goto done;
-		}
-	} else if (ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A',
-				      cmd->lun, pending_scb->hscb->tag,
-				      ROLE_INITIATOR, /*status*/0,
-				      SEARCH_COUNT) > 0) {
-		disconnected = FALSE;
-	}
-
-	/*
-	 * At this point, pending_scb is the scb associated with the
-	 * passed in command.  That command is currently active on the
-	 * bus, is in the disconnected state, or we're hoping to find
-	 * a command for the same target active on the bus to abuse to
-	 * send a BDR.  Queue the appropriate message based on which of
-	 * these states we are in.
-	 */
-	last_phase = ahd_inb(ahd, LASTPHASE);
-	saved_scbptr = ahd_inb(ahd, SCBPTR);
-	active_scb_index = ahd_inb(ahd, SCB_TAG);
-	if (last_phase != P_BUSFREE
-	 && (pending_scb->hscb->tag == active_scb_index
-	  || (flag == SCB_DEVICE_RESET
-	   && SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)) == cmd->target))) {
-
-		/*
-		 * We're active on the bus, so assert ATN
-		 * and hope that the target responds.
-		 */
-		pending_scb = ahd_lookup_scb(ahd, active_scb_index);
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
-		ahd_outb(ahd, MSG_OUT, HOST_MSG);
-		ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
-		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		wait = TRUE;
-	} else if (disconnected) {
-
-		/*
-		 * Actually re-queue this SCB in an attempt
-		 * to select the device before it reconnects.
-		 * In either case (selection or reselection),
-		 * we will now issue the approprate message
-		 * to the timed-out device.
-		 *
-		 * Set the MK_MESSAGE control bit indicating
-		 * that we desire to send a message.  We
-		 * also set the disconnected flag since
-		 * in the paging case there is no guarantee
-		 * that our SCB control byte matches the
-		 * version on the card.  We don't want the
-		 * sequencer to abort the command thinking
-		 * an unsolicited reselection occurred.
-		 */
-		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
-
-		/*
-		 * In the non-paging case, the sequencer will
-		 * never re-reference the in-core SCB.
-		 * To make sure we are notified during
-		 * reslection, set the MK_MESSAGE flag in
-		 * the card's copy of the SCB.
-		 */
-		ahd_outb(ahd, SCBPTR, pending_scb->hscb->tag);
-		ahd_outb(ahd, SCB_CONTROL,
-			 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
-
-		/*
-		 * Clear out any entries in the QINFIFO first
-		 * so we are the next SCB for this target
-		 * to run.
-		 */
-		ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A',
-				   cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR,
-				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
-		ahd_print_path(ahd, pending_scb);
-		printf("Queuing a recovery SCB\n");
-		ahd_qinfifo_requeue_tail(ahd, pending_scb);
-		ahd_outb(ahd, SCBPTR, saved_scbptr);
-		printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		wait = TRUE;
-	} else {
-		printf("%s:%d:%d:%d: Unable to deliver message\n",
-		       ahd_name(ahd), cmd->channel, cmd->target, cmd->lun);
-		retval = FAILED;
-		goto done;
-	}
-
-no_cmd:
-	/*
-	 * Our assumption is that if we don't have the command, no
-	 * recovery action was required, so we return success.  Again,
-	 * the semantics of the mid-layer recovery engine are not
-	 * well defined, so this may change in time.
-	 */
-	retval = SUCCESS;
-done:
-	if (paused)
-		ahd_unpause(ahd);
-	if (wait) {
-		struct timer_list timer;
-		int ret;
-
-		pending_scb->platform_data->flags |= AHD_UP_EH_SEMAPHORE;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		ahd_unlock(ahd, &s);
-#else
-		spin_unlock_irq(ahd->platform_data->host->host_lock);
-#endif
-		init_timer(&timer);
-		timer.data = (u_long)ahd;
-		timer.expires = jiffies + (5 * HZ);
-		timer.function = ahd_linux_sem_timeout;
-		add_timer(&timer);
-		printf("Recovery code sleeping\n");
-		down(&ahd->platform_data->eh_sem);
-		printf("Recovery code awake\n");
-        	ret = del_timer(&timer);
-		if (ret == 0) {
-			printf("Timer Expired\n");
-			retval = FAILED;
-		}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		ahd_lock(ahd, &s);
-#else
-		spin_lock_irq(ahd->platform_data->host->host_lock);
-#endif
-	}
-	acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
-	TAILQ_INIT(&ahd->platform_data->completeq);
-	ahd_midlayer_entry_unlock(ahd, &s);
-	if (acmd != NULL) {
-		acmd = ahd_linux_run_complete_queue(ahd, acmd);
-		if (acmd != NULL) {
-			ahd_midlayer_entrypoint_lock(ahd, &s);
-			ahd_schedule_completeq(ahd, acmd);
-			ahd_midlayer_entrypoint_unlock(ahd, &s);
-		}
-	}
-	ahd_schedule_runq(ahd);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	spin_lock_irq(&io_request_lock);
-#endif
-	return (retval);
-}
-#endif
 
 static void
 ahd_linux_dev_timed_unfreeze(u_long arg)
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h	Mon Feb 10 10:39:29 2003
@@ -36,7 +36,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#102 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 $
  *
  */
 #ifndef _AIC79XX_LINUX_H_
@@ -50,11 +50,9 @@
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
 #include <linux/version.h>
-#ifndef AHD_MODVERSION_FILE
-#define __NO_VERSION__
-#endif
 #include <linux/module.h>
 #include <asm/byteorder.h>
+#include <asm/io.h>
 
 #ifndef KERNEL_VERSION
 #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
@@ -72,7 +70,6 @@
 #define AIC_LIB_PREFIX ahd
 #include "scsi.h"
 #include "hosts.h"
-#include "aiclib.h"
 
 /* Name space conflict with BSD queue macros */
 #ifdef LIST_HEAD
@@ -83,6 +80,7 @@
 #include "queue.h"
 #include "scsi_message.h"
 #include "scsi_iu.h"
+#include "aiclib.h"
 
 /*********************************** Debugging ********************************/
 #ifdef CONFIG_AIC79XX_DEBUG_ENABLE
@@ -288,7 +286,7 @@
 #include <linux/smp.h>
 #endif
 
-#define AIC79XX_DRIVER_VERSION "1.3.0.BETA2"
+#define AIC79XX_DRIVER_VERSION "1.3.0"
 
 /**************************** Front End Queues ********************************/
 /*
@@ -323,7 +321,7 @@
 /*
  * A per probed device structure used to deal with some error recovery
  * scenarios that the Linux mid-layer code just doesn't know how to
- * handle.  The structure allocated for a device only becomes persistant
+ * handle.  The structure allocated for a device only becomes persistent
  * after a successfully completed inquiry command to the target when
  * that inquiry data indicates a lun is present.
  */
@@ -489,7 +487,7 @@
  * Per-SCB OSM storage.
  */
 typedef enum {
-	AHD_UP_EH_SEMAPHORE
+	AHD_UP_EH_SEMAPHORE = 0x1
 } ahd_linux_scb_flags;
 
 struct scb_platform_data {
@@ -543,6 +541,7 @@
 	struct semaphore	 dv_cmd_sem;	/* XXX This needs to be in
 						 * the target struct
 						 */
+	struct scsi_device	*dv_scsi_dev;
 	struct Scsi_Host        *host;		/* pointer to scsi host */
 #define AHD_LINUX_NOIRQ	((uint32_t)~0)
 	uint32_t		 irq;		/* IRQ for this adapter */
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
  */
 typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
 typedef struct ahd_reg_parse_entry {
@@ -2367,11 +2367,13 @@
 #define		SPLTINT         	0x01
 
 #define	SEQINTCODE      		0x02
-#define		SAW_HWERR       	0x17
-#define		TRACEPOINT3     	0x16
-#define		TRACEPOINT2     	0x15
-#define		TRACEPOINT1     	0x14
-#define		TRACEPOINT0     	0x13
+#define		SAW_HWERR       	0x19
+#define		TRACEPOINT3     	0x18
+#define		TRACEPOINT2     	0x17
+#define		TRACEPOINT1     	0x16
+#define		TRACEPOINT0     	0x15
+#define		TASKMGMT_CMD_CMPLT_OKAY	0x14
+#define		TASKMGMT_FUNC_COMPLETE	0x13
 #define		ENTERING_NONPACK	0x12
 #define		CFG4OVERRUN     	0x11
 #define		STATUS_OVERRUN  	0x10
@@ -3772,5 +3774,5 @@
 
 
 /* Exported Labels */
-#define	LABEL_seq_isr 	0x25a
-#define	LABEL_timer_isr	0x256
+#define	LABEL_seq_isr 	0x263
+#define	LABEL_timer_isr	0x25f
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
  */
 
 #include "aic79xx_osm.h"
@@ -59,17 +59,19 @@
 	{ "STATUS_OVERRUN",	0x10, 0xff },
 	{ "CFG4OVERRUN",	0x11, 0xff },
 	{ "ENTERING_NONPACK",	0x12, 0xff },
-	{ "TRACEPOINT0",	0x13, 0xff },
-	{ "TRACEPOINT1",	0x14, 0xff },
-	{ "TRACEPOINT2",	0x15, 0xff },
-	{ "TRACEPOINT3",	0x16, 0xff },
-	{ "SAW_HWERR",		0x17, 0xff }
+	{ "TASKMGMT_FUNC_COMPLETE",0x13, 0xff },
+	{ "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff },
+	{ "TRACEPOINT0",	0x15, 0xff },
+	{ "TRACEPOINT1",	0x16, 0xff },
+	{ "TRACEPOINT2",	0x17, 0xff },
+	{ "TRACEPOINT3",	0x18, 0xff },
+	{ "SAW_HWERR",		0x19, 0xff }
 };
 
 int
 ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap)
 {
-	return (ahd_print_register(SEQINTCODE_parse_table, 24, "SEQINTCODE",
+	return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE",
 	    0x02, regvalue, cur_col, wrap));
 }
 
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped
--- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped	Mon Feb 10 10:39:33 2003
@@ -2,92 +2,97 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $
- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $
  */
 static uint8_t seqprog[] = {
 	0xff, 0x02, 0x06, 0x78,
-	0x00, 0xea, 0x3c, 0x59,
+	0x00, 0xea, 0x46, 0x59,
 	0x01, 0xea, 0x04, 0x30,
 	0xff, 0x04, 0x0c, 0x78,
-	0x17, 0xea, 0x3c, 0x59,
-	0x17, 0xea, 0x04, 0x00,
-	0x33, 0xea, 0x30, 0x59,
+	0x19, 0xea, 0x46, 0x59,
+	0x19, 0xea, 0x04, 0x00,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x60, 0x3a, 0x1a, 0x68,
 	0x04, 0x47, 0x1b, 0x68,
 	0xff, 0x21, 0x1b, 0x70,
-	0x40, 0x4b, 0x7e, 0x69,
-	0x00, 0xe2, 0x40, 0x59,
-	0x40, 0x4b, 0x7e, 0x69,
-	0x20, 0x4b, 0x6e, 0x69,
+	0x40, 0x4b, 0x88, 0x69,
+	0x00, 0xe2, 0x4a, 0x59,
+	0x40, 0x4b, 0x88, 0x69,
+	0x20, 0x4b, 0x78, 0x69,
 	0xfc, 0x42, 0x24, 0x78,
 	0x10, 0x40, 0x24, 0x78,
-	0x00, 0xe2, 0x8c, 0x5d,
+	0x00, 0xe2, 0xa4, 0x5d,
 	0x20, 0x4d, 0x28, 0x78,
-	0x00, 0xe2, 0x8c, 0x5d,
+	0x00, 0xe2, 0xa4, 0x5d,
 	0x00, 0xe2, 0x34, 0x58,
-	0x00, 0xe2, 0x5c, 0x58,
-	0x00, 0xe2, 0x6c, 0x58,
+	0x00, 0xe2, 0x66, 0x58,
+	0x00, 0xe2, 0x76, 0x58,
 	0x00, 0xe2, 0x06, 0x40,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
-	0x01, 0x52, 0x4e, 0x7d,
+	0x01, 0x52, 0x66, 0x7d,
 	0x02, 0x58, 0x50, 0x31,
 	0xff, 0xea, 0x10, 0x0b,
+	0xff, 0x93, 0x45, 0x78,
+	0x50, 0x4b, 0x40, 0x68,
+	0xbf, 0x3a, 0x74, 0x08,
+	0x14, 0xea, 0x46, 0x59,
+	0x14, 0xea, 0x04, 0x00,
 	0x08, 0xa8, 0x51, 0x03,
-	0x01, 0xa4, 0x43, 0x78,
-	0x00, 0xe2, 0x32, 0x5b,
+	0x01, 0xa4, 0x4d, 0x78,
+	0x00, 0xe2, 0x44, 0x5b,
 	0x00, 0xe2, 0x34, 0x40,
 	0xff, 0xea, 0xd4, 0x19,
 	0x02, 0xa8, 0x84, 0x32,
-	0x00, 0xea, 0x30, 0x59,
+	0x00, 0xea, 0x3a, 0x59,
 	0x01, 0xea, 0x00, 0x30,
-	0x00, 0xe2, 0x80, 0x5d,
-	0x00, 0xe2, 0x4e, 0x4d,
-	0x11, 0xea, 0x30, 0x59,
+	0x00, 0xe2, 0x98, 0x5d,
+	0x00, 0xe2, 0x66, 0x4d,
+	0x11, 0xea, 0x3a, 0x59,
 	0x11, 0xea, 0x00, 0x00,
-	0x00, 0xe2, 0x80, 0x5d,
-	0x00, 0xe2, 0x4e, 0x4d,
-	0x33, 0xea, 0x30, 0x59,
+	0x00, 0xe2, 0x98, 0x5d,
+	0x00, 0xe2, 0x66, 0x4d,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
-	0x00, 0xe2, 0x28, 0x43,
-	0x00, 0xea, 0x30, 0x59,
+	0x00, 0xe2, 0x3a, 0x43,
+	0x00, 0xea, 0x3a, 0x59,
 	0x01, 0xea, 0x00, 0x30,
-	0x80, 0xf9, 0x64, 0x68,
-	0x00, 0xe2, 0x2e, 0x59,
-	0x11, 0xea, 0x30, 0x59,
+	0x80, 0xf9, 0x6e, 0x68,
+	0x00, 0xe2, 0x38, 0x59,
+	0x11, 0xea, 0x3a, 0x59,
 	0x11, 0xea, 0x00, 0x00,
-	0x80, 0xf9, 0x2e, 0x79,
+	0x80, 0xf9, 0x38, 0x79,
 	0xff, 0xea, 0xd4, 0x0d,
-	0x22, 0xea, 0x30, 0x59,
+	0x22, 0xea, 0x3a, 0x59,
 	0x22, 0xea, 0x00, 0x00,
-	0x10, 0x16, 0x76, 0x78,
+	0x10, 0x16, 0x80, 0x78,
 	0x01, 0x0b, 0xa2, 0x32,
 	0x10, 0x16, 0x2c, 0x00,
-	0x18, 0xad, 0xe4, 0x78,
-	0x04, 0xad, 0xb2, 0x68,
-	0x80, 0xad, 0x4e, 0x7d,
-	0x10, 0xad, 0x80, 0x78,
+	0x18, 0xad, 0xee, 0x78,
+	0x04, 0xad, 0xbc, 0x68,
+	0x80, 0xad, 0x66, 0x7d,
+	0x10, 0xad, 0x8a, 0x78,
 	0xe7, 0xad, 0x5a, 0x0d,
 	0xe7, 0xad, 0x5a, 0x09,
-	0x00, 0xe2, 0x8e, 0x58,
+	0x00, 0xe2, 0x98, 0x58,
 	0xff, 0xea, 0x56, 0x02,
 	0x04, 0x7c, 0x78, 0x32,
-	0x20, 0x16, 0x4e, 0x7d,
+	0x20, 0x16, 0x66, 0x7d,
 	0x04, 0x38, 0x79, 0x32,
 	0x80, 0x37, 0x6f, 0x16,
-	0xff, 0x2d, 0x9d, 0x60,
-	0xff, 0x29, 0x9d, 0x60,
-	0x40, 0x51, 0xad, 0x78,
-	0xff, 0x4f, 0x9d, 0x68,
+	0xff, 0x2d, 0xa7, 0x60,
+	0xff, 0x29, 0xa7, 0x60,
+	0x40, 0x51, 0xb7, 0x78,
+	0xff, 0x4f, 0xa7, 0x68,
 	0xff, 0x4d, 0xc1, 0x19,
 	0x00, 0x4e, 0xd5, 0x19,
-	0x00, 0xe2, 0xac, 0x50,
+	0x00, 0xe2, 0xb6, 0x50,
 	0x01, 0x4c, 0xc1, 0x31,
 	0x00, 0x50, 0xd5, 0x19,
-	0x00, 0xe2, 0xac, 0x48,
-	0x80, 0x18, 0x4e, 0x7d,
+	0x00, 0xe2, 0xb6, 0x48,
+	0x80, 0x18, 0x66, 0x7d,
 	0x02, 0x4a, 0x1d, 0x30,
 	0x10, 0xea, 0x18, 0x00,
 	0x60, 0x18, 0x30, 0x00,
@@ -95,7 +100,7 @@
 	0x02, 0xea, 0x02, 0x00,
 	0xff, 0xea, 0xa0, 0x0a,
 	0x80, 0x18, 0x30, 0x04,
-	0x40, 0xad, 0x4e, 0x7d,
+	0x40, 0xad, 0x66, 0x7d,
 	0xe7, 0xad, 0x5a, 0x09,
 	0x02, 0xa8, 0x40, 0x31,
 	0xff, 0xea, 0xc0, 0x09,
@@ -105,25 +110,25 @@
 	0xff, 0xea, 0x2a, 0x03,
 	0xff, 0xea, 0x2e, 0x03,
 	0x01, 0x10, 0xd4, 0x31,
-	0x10, 0xa8, 0xd9, 0x68,
+	0x10, 0xa8, 0xe3, 0x68,
 	0x3d, 0xa9, 0xc5, 0x29,
 	0xfe, 0xe2, 0xc4, 0x09,
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x50, 0x31,
 	0x02, 0xa0, 0xda, 0x31,
-	0xff, 0xa9, 0xd8, 0x70,
+	0xff, 0xa9, 0xe2, 0x70,
 	0x02, 0xa0, 0x28, 0x37,
-	0xff, 0x21, 0xe1, 0x70,
+	0xff, 0x21, 0xeb, 0x70,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x2c, 0x33,
 	0x02, 0xa0, 0x44, 0x36,
 	0x02, 0xa0, 0x40, 0x32,
 	0x02, 0xa0, 0x44, 0x36,
-	0x04, 0x47, 0xe9, 0x68,
-	0x40, 0x16, 0x14, 0x69,
-	0xff, 0x2d, 0x19, 0x61,
-	0xff, 0x29, 0x4f, 0x75,
+	0x04, 0x47, 0xf3, 0x68,
+	0x40, 0x16, 0x1e, 0x69,
+	0xff, 0x2d, 0x23, 0x61,
+	0xff, 0x29, 0x67, 0x75,
 	0x01, 0x37, 0xc1, 0x31,
 	0x02, 0x28, 0x55, 0x32,
 	0x01, 0xea, 0x5a, 0x01,
@@ -135,20 +140,20 @@
 	0x01, 0x50, 0xa1, 0x1a,
 	0xff, 0x4e, 0x9d, 0x1a,
 	0xff, 0x4f, 0x9f, 0x22,
-	0xff, 0x8d, 0x0d, 0x71,
-	0x80, 0xac, 0x0c, 0x71,
-	0x20, 0x16, 0x0c, 0x69,
+	0xff, 0x8d, 0x17, 0x71,
+	0x80, 0xac, 0x16, 0x71,
+	0x20, 0x16, 0x16, 0x69,
 	0x02, 0x8c, 0x51, 0x31,
-	0x00, 0xe2, 0xf6, 0x40,
+	0x00, 0xe2, 0x00, 0x41,
 	0x01, 0xac, 0x08, 0x31,
 	0x09, 0xea, 0x5a, 0x01,
 	0x02, 0x8c, 0x51, 0x32,
 	0xff, 0xea, 0x1a, 0x07,
 	0x04, 0x24, 0xf9, 0x30,
-	0x1d, 0xea, 0x24, 0x41,
+	0x1d, 0xea, 0x2e, 0x41,
 	0x02, 0x2c, 0x51, 0x31,
 	0x04, 0xac, 0xf9, 0x30,
-	0x19, 0xea, 0x24, 0x59,
+	0x19, 0xea, 0x2e, 0x59,
 	0x02, 0x8c, 0x59, 0x32,
 	0x02, 0x28, 0x19, 0x33,
 	0x02, 0xa8, 0x50, 0x36,
@@ -170,23 +175,23 @@
 	0x02, 0x20, 0xb9, 0x30,
 	0x02, 0x20, 0x51, 0x31,
 	0x4c, 0xa9, 0xd7, 0x28,
-	0x10, 0xa8, 0x4f, 0x79,
+	0x10, 0xa8, 0x59, 0x79,
 	0x01, 0x6b, 0xc0, 0x30,
 	0x02, 0x64, 0xc8, 0x00,
 	0x40, 0x3a, 0x74, 0x04,
-	0x00, 0xe2, 0x5c, 0x58,
-	0x33, 0xea, 0x30, 0x59,
+	0x00, 0xe2, 0x66, 0x58,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x30, 0x3f, 0xc0, 0x09,
-	0x30, 0xe0, 0x50, 0x61,
-	0x20, 0x3f, 0x66, 0x69,
-	0x10, 0x3f, 0x50, 0x79,
+	0x30, 0xe0, 0x5a, 0x61,
+	0x20, 0x3f, 0x70, 0x69,
+	0x10, 0x3f, 0x5a, 0x79,
 	0x02, 0xea, 0x7e, 0x00,
-	0x00, 0xea, 0x30, 0x59,
+	0x00, 0xea, 0x3a, 0x59,
 	0x01, 0xea, 0x00, 0x30,
 	0x02, 0x48, 0x51, 0x35,
 	0x01, 0xea, 0x7e, 0x00,
-	0x11, 0xea, 0x30, 0x59,
+	0x11, 0xea, 0x3a, 0x59,
 	0x11, 0xea, 0x00, 0x00,
 	0x02, 0x48, 0x51, 0x35,
 	0x08, 0xea, 0x98, 0x00,
@@ -196,11 +201,11 @@
 	0x0f, 0x67, 0xc0, 0x09,
 	0x00, 0x34, 0x69, 0x02,
 	0x20, 0xea, 0x96, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x40, 0x3a, 0x9a, 0x69,
+	0x00, 0xe2, 0xee, 0x41,
+	0x40, 0x3a, 0xa4, 0x69,
 	0x02, 0x55, 0x06, 0x68,
-	0x02, 0x56, 0x9a, 0x69,
-	0xff, 0x5b, 0x9a, 0x61,
+	0x02, 0x56, 0xa4, 0x69,
+	0xff, 0x5b, 0xa4, 0x61,
 	0x02, 0x20, 0x51, 0x31,
 	0x80, 0xea, 0xb2, 0x01,
 	0x44, 0xea, 0x00, 0x00,
@@ -208,140 +213,144 @@
 	0x33, 0xea, 0x00, 0x00,
 	0xff, 0xea, 0xb2, 0x09,
 	0xff, 0xe0, 0xc0, 0x19,
-	0xff, 0xe0, 0x9c, 0x79,
+	0xff, 0xe0, 0xa6, 0x79,
 	0x02, 0x94, 0x51, 0x31,
-	0x00, 0xe2, 0x92, 0x41,
+	0x00, 0xe2, 0x9c, 0x41,
 	0x02, 0x5e, 0x50, 0x31,
 	0x02, 0xa8, 0xb8, 0x30,
 	0x02, 0x5c, 0x50, 0x31,
-	0xff, 0x95, 0xad, 0x71,
+	0xff, 0x95, 0xb7, 0x71,
 	0x02, 0x94, 0x41, 0x31,
 	0x02, 0x22, 0x51, 0x31,
 	0x02, 0xa0, 0x2c, 0x33,
 	0x02, 0xa0, 0x44, 0x32,
-	0x00, 0xe2, 0xb6, 0x41,
-	0x10, 0xa8, 0xb7, 0x69,
+	0x00, 0xe2, 0xc0, 0x41,
+	0x10, 0xa8, 0xc1, 0x69,
 	0x3d, 0xa9, 0xc9, 0x29,
 	0x01, 0xe4, 0xc8, 0x01,
 	0x01, 0xea, 0xca, 0x01,
 	0xff, 0xea, 0xda, 0x01,
 	0x02, 0x20, 0x51, 0x31,
 	0x02, 0x96, 0x41, 0x32,
-	0xff, 0x21, 0xbf, 0x61,
+	0xff, 0x21, 0xc9, 0x61,
 	0xff, 0xea, 0x46, 0x02,
 	0x02, 0x5c, 0x50, 0x31,
 	0x40, 0xea, 0x96, 0x00,
-	0x02, 0x56, 0x94, 0x6d,
-	0x01, 0x55, 0x94, 0x6d,
-	0x10, 0xa8, 0xcb, 0x79,
-	0x10, 0x40, 0xcc, 0x69,
-	0x01, 0x56, 0x06, 0x68,
+	0x02, 0x56, 0xac, 0x6d,
+	0x01, 0x55, 0xac, 0x6d,
+	0x10, 0xa8, 0xd5, 0x79,
+	0x10, 0x40, 0xde, 0x69,
+	0x01, 0x56, 0xde, 0x79,
+	0xff, 0x93, 0x07, 0x78,
+	0x13, 0xea, 0x46, 0x59,
+	0x13, 0xea, 0x04, 0x00,
+	0x00, 0xe2, 0x06, 0x40,
 	0xbf, 0x3a, 0x74, 0x08,
 	0x08, 0xea, 0x98, 0x00,
 	0x08, 0x57, 0xae, 0x00,
 	0x01, 0xa9, 0x69, 0x32,
 	0x01, 0xaa, 0x6b, 0x32,
+	0x40, 0xea, 0x66, 0x02,
 	0x08, 0x3c, 0x78, 0x00,
 	0x80, 0xea, 0x62, 0x02,
-	0x40, 0xea, 0x66, 0x02,
-	0x00, 0xe2, 0x92, 0x5b,
+	0x00, 0xe2, 0xa4, 0x5b,
 	0x01, 0x36, 0xc1, 0x31,
-	0x9f, 0xe0, 0x26, 0x7c,
-	0x80, 0xe0, 0xf0, 0x71,
-	0xa0, 0xe0, 0x28, 0x72,
-	0xc0, 0xe0, 0x1e, 0x72,
-	0xe0, 0xe0, 0x58, 0x72,
-	0x01, 0xea, 0x3c, 0x59,
+	0x9f, 0xe0, 0x38, 0x7c,
+	0x80, 0xe0, 0x02, 0x72,
+	0xa0, 0xe0, 0x3a, 0x72,
+	0xc0, 0xe0, 0x30, 0x72,
+	0xe0, 0xe0, 0x6a, 0x72,
+	0x01, 0xea, 0x46, 0x59,
 	0x01, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x80, 0x33, 0xf7, 0x79,
-	0x03, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xee, 0x41,
+	0x80, 0x33, 0x09, 0x7a,
+	0x03, 0xea, 0x46, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0xee, 0x00, 0xfe, 0x69,
+	0xee, 0x00, 0x10, 0x6a,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0xa8, 0x90, 0x32,
-	0x00, 0xe2, 0x56, 0x59,
+	0x00, 0xe2, 0x60, 0x59,
 	0xef, 0x92, 0xd5, 0x19,
-	0x00, 0xe2, 0x0e, 0x52,
+	0x00, 0xe2, 0x20, 0x52,
 	0x0b, 0x84, 0xe1, 0x30,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x14, 0x42,
+	0x00, 0xe2, 0x26, 0x42,
 	0x01, 0x92, 0xd1, 0x30,
 	0x10, 0x80, 0x89, 0x31,
 	0x20, 0xea, 0x32, 0x00,
 	0xbf, 0x33, 0x67, 0x0a,
-	0x20, 0x19, 0x16, 0x6a,
-	0x02, 0x4d, 0xdc, 0x69,
+	0x20, 0x19, 0x28, 0x6a,
+	0x02, 0x4d, 0xee, 0x69,
 	0x40, 0x33, 0x67, 0x02,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x80, 0x33, 0x95, 0x6a,
+	0x00, 0xe2, 0xee, 0x41,
+	0x80, 0x33, 0xa7, 0x6a,
 	0x01, 0x44, 0x10, 0x33,
 	0x08, 0xa8, 0x51, 0x03,
-	0x00, 0xe2, 0xdc, 0x41,
+	0x00, 0xe2, 0xee, 0x41,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0x31, 0xc5, 0x31,
-	0x80, 0xe2, 0x44, 0x62,
-	0x10, 0xa8, 0x69, 0x6a,
+	0x80, 0xe2, 0x56, 0x62,
+	0x10, 0xa8, 0x7b, 0x6a,
 	0xc0, 0xaa, 0xc5, 0x01,
-	0x40, 0xa8, 0x35, 0x6a,
+	0x40, 0xa8, 0x47, 0x6a,
 	0xbf, 0xe2, 0xc4, 0x09,
-	0x20, 0xa8, 0x49, 0x7a,
+	0x20, 0xa8, 0x5b, 0x7a,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0x92, 0x5b,
-	0xa0, 0x36, 0x51, 0x62,
+	0x00, 0xe2, 0xa4, 0x5b,
+	0xa0, 0x36, 0x63, 0x62,
 	0x23, 0xa8, 0x89, 0x08,
-	0x00, 0xe2, 0x92, 0x5b,
-	0xa0, 0x36, 0x51, 0x62,
-	0x00, 0xa8, 0x48, 0x42,
-	0xff, 0xe2, 0x48, 0x62,
-	0x00, 0xe2, 0x68, 0x42,
+	0x00, 0xe2, 0xa4, 0x5b,
+	0xa0, 0x36, 0x63, 0x62,
+	0x00, 0xa8, 0x5a, 0x42,
+	0xff, 0xe2, 0x5a, 0x62,
+	0x00, 0xe2, 0x7a, 0x42,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0xe2, 0x88, 0x30,
-	0x00, 0xe2, 0x92, 0x5b,
-	0xa0, 0x36, 0x27, 0x72,
+	0x00, 0xe2, 0xa4, 0x5b,
+	0xa0, 0x36, 0x39, 0x72,
 	0x40, 0xea, 0x98, 0x00,
 	0x01, 0x31, 0x89, 0x32,
 	0x08, 0xea, 0x62, 0x02,
-	0x00, 0xe2, 0xdc, 0x41,
-	0xe0, 0xea, 0xa2, 0x5b,
-	0x80, 0xe0, 0xa0, 0x6a,
-	0x04, 0xe0, 0x40, 0x73,
-	0x02, 0xe0, 0x70, 0x73,
-	0x00, 0xea, 0xfe, 0x72,
-	0x03, 0xe0, 0x80, 0x73,
-	0x23, 0xe0, 0x7a, 0x72,
-	0x08, 0xe0, 0x9c, 0x72,
-	0x00, 0xe2, 0x92, 0x5b,
-	0x07, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xee, 0x41,
+	0xe0, 0xea, 0xb4, 0x5b,
+	0x80, 0xe0, 0xb2, 0x6a,
+	0x04, 0xe0, 0x52, 0x73,
+	0x02, 0xe0, 0x82, 0x73,
+	0x00, 0xea, 0x10, 0x73,
+	0x03, 0xe0, 0x92, 0x73,
+	0x23, 0xe0, 0x8c, 0x72,
+	0x08, 0xe0, 0xae, 0x72,
+	0x00, 0xe2, 0xa4, 0x5b,
+	0x07, 0xea, 0x46, 0x59,
 	0x07, 0xea, 0x04, 0x00,
-	0x08, 0x42, 0xdd, 0x71,
-	0x04, 0x42, 0x77, 0x62,
+	0x08, 0x42, 0xef, 0x71,
+	0x04, 0x42, 0x89, 0x62,
 	0x01, 0x43, 0x89, 0x30,
-	0x00, 0xe2, 0x68, 0x42,
+	0x00, 0xe2, 0x7a, 0x42,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0x68, 0x42,
+	0x00, 0xe2, 0x7a, 0x42,
 	0x01, 0x00, 0x60, 0x32,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x4c, 0x34, 0xc1, 0x28,
 	0x01, 0x64, 0xc0, 0x31,
-	0x00, 0x30, 0x31, 0x59,
+	0x00, 0x30, 0x3b, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x01, 0xe0, 0x9a, 0x7a,
-	0xa0, 0xea, 0x98, 0x5b,
-	0x01, 0xa0, 0x9a, 0x62,
-	0x01, 0x84, 0x93, 0x7a,
-	0x01, 0xa7, 0x9c, 0x7a,
-	0x00, 0xe2, 0x9c, 0x42,
-	0x03, 0xea, 0x3c, 0x59,
+	0x01, 0xe0, 0xac, 0x7a,
+	0xa0, 0xea, 0xaa, 0x5b,
+	0x01, 0xa0, 0xac, 0x62,
+	0x01, 0x84, 0xa5, 0x7a,
+	0x01, 0xa7, 0xae, 0x7a,
+	0x00, 0xe2, 0xae, 0x42,
+	0x03, 0xea, 0x46, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x9c, 0x42,
-	0x07, 0xea, 0xaa, 0x5b,
+	0x00, 0xe2, 0xae, 0x42,
+	0x07, 0xea, 0xbc, 0x5b,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0xdc, 0x41,
+	0x00, 0xe2, 0xee, 0x41,
 	0x3f, 0xe0, 0x6a, 0x0a,
 	0xc0, 0x34, 0xc1, 0x09,
 	0x00, 0x35, 0x51, 0x01,
@@ -352,54 +361,54 @@
 	0x01, 0xea, 0xc6, 0x01,
 	0x02, 0xe2, 0xc8, 0x31,
 	0x02, 0xec, 0x40, 0x31,
-	0xff, 0xa1, 0xbc, 0x72,
+	0xff, 0xa1, 0xce, 0x72,
 	0x02, 0xe8, 0xda, 0x31,
 	0x02, 0xa0, 0x50, 0x31,
-	0x00, 0xe2, 0xde, 0x42,
+	0x00, 0xe2, 0xf0, 0x42,
 	0x80, 0x33, 0x67, 0x02,
 	0x01, 0x44, 0xd4, 0x31,
-	0x00, 0xe2, 0x92, 0x5b,
+	0x00, 0xe2, 0xa4, 0x5b,
 	0x01, 0x33, 0x67, 0x02,
-	0xe0, 0x36, 0xf9, 0x62,
+	0xe0, 0x36, 0x0b, 0x63,
 	0x02, 0x33, 0x67, 0x02,
-	0x20, 0x46, 0xf2, 0x62,
+	0x20, 0x46, 0x04, 0x63,
 	0xff, 0xea, 0x52, 0x09,
-	0xa8, 0xea, 0x98, 0x5b,
-	0x04, 0xa8, 0xd9, 0x7a,
+	0xa8, 0xea, 0xaa, 0x5b,
+	0x04, 0xa8, 0xeb, 0x7a,
 	0x01, 0x34, 0xc1, 0x31,
-	0x00, 0xa9, 0xd9, 0x62,
+	0x00, 0xa9, 0xeb, 0x62,
 	0x01, 0x35, 0xc1, 0x31,
-	0x00, 0xaa, 0xe3, 0x72,
+	0x00, 0xaa, 0xf5, 0x72,
 	0x01, 0xa9, 0x52, 0x11,
-	0xff, 0xa9, 0xce, 0x6a,
-	0x00, 0xe2, 0xf2, 0x42,
+	0xff, 0xa9, 0xe0, 0x6a,
+	0x00, 0xe2, 0x04, 0x43,
 	0x10, 0x33, 0x67, 0x02,
-	0x04, 0xa8, 0xf3, 0x7a,
+	0x04, 0xa8, 0x05, 0x7b,
 	0xfb, 0xa8, 0x51, 0x0b,
 	0xff, 0xea, 0x66, 0x0a,
-	0x01, 0xa4, 0xed, 0x6a,
+	0x01, 0xa4, 0xff, 0x6a,
 	0x02, 0xa8, 0x90, 0x32,
-	0x00, 0xe2, 0x56, 0x59,
-	0x10, 0xa8, 0x9d, 0x7a,
-	0xff, 0xea, 0xaa, 0x5b,
-	0x00, 0xe2, 0x9c, 0x42,
-	0x04, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0x60, 0x59,
+	0x10, 0xa8, 0xaf, 0x7a,
+	0xff, 0xea, 0xbc, 0x5b,
+	0x00, 0xe2, 0xae, 0x42,
+	0x04, 0xea, 0x46, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x9c, 0x42,
-	0x04, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xae, 0x42,
+	0x04, 0xea, 0x46, 0x59,
 	0x04, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x08, 0xa8, 0x95, 0x7a,
-	0xc0, 0x33, 0x09, 0x7b,
-	0x80, 0x33, 0x95, 0x6a,
-	0xff, 0x88, 0x09, 0x6b,
-	0x40, 0x33, 0x95, 0x6a,
-	0x10, 0xa8, 0x0f, 0x7b,
-	0x0a, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xee, 0x41,
+	0x08, 0xa8, 0xa7, 0x7a,
+	0xc0, 0x33, 0x1b, 0x7b,
+	0x80, 0x33, 0xa7, 0x6a,
+	0xff, 0x88, 0x1b, 0x6b,
+	0x40, 0x33, 0xa7, 0x6a,
+	0x10, 0xa8, 0x21, 0x7b,
+	0x0a, 0xea, 0x46, 0x59,
 	0x0a, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x28, 0x5b,
-	0x00, 0xe2, 0x5c, 0x43,
-	0x50, 0x4b, 0x16, 0x6b,
+	0x00, 0xe2, 0x3a, 0x5b,
+	0x00, 0xe2, 0x6e, 0x43,
+	0x50, 0x4b, 0x28, 0x6b,
 	0xbf, 0x3a, 0x74, 0x08,
 	0x01, 0xe0, 0xf8, 0x31,
 	0xff, 0xea, 0xc0, 0x09,
@@ -407,24 +416,24 @@
 	0x00, 0x2f, 0x5f, 0x22,
 	0x04, 0x47, 0x8f, 0x02,
 	0x01, 0xfc, 0xc0, 0x35,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x02, 0x42, 0x51, 0x31,
 	0x10, 0xa8, 0x51, 0x03,
-	0xff, 0x88, 0x37, 0x6b,
-	0x01, 0xa4, 0x33, 0x6b,
-	0x02, 0xa4, 0x3b, 0x6b,
-	0x01, 0x84, 0x3b, 0x7b,
+	0xff, 0x88, 0x49, 0x6b,
+	0x01, 0xa4, 0x45, 0x6b,
+	0x02, 0xa4, 0x4d, 0x6b,
+	0x01, 0x84, 0x4d, 0x7b,
 	0x02, 0x28, 0x19, 0x33,
 	0x02, 0xa8, 0x50, 0x36,
-	0xff, 0x88, 0x3b, 0x73,
-	0x00, 0xe2, 0x12, 0x5b,
+	0xff, 0x88, 0x4d, 0x73,
+	0x00, 0xe2, 0x24, 0x5b,
 	0x02, 0x2c, 0x19, 0x33,
 	0x02, 0xa8, 0x58, 0x32,
 	0x04, 0xa4, 0x49, 0x07,
-	0xc0, 0x33, 0x95, 0x6a,
+	0xc0, 0x33, 0xa7, 0x6a,
 	0x04, 0xa8, 0x51, 0x03,
-	0x20, 0xa8, 0x5d, 0x6b,
+	0x20, 0xa8, 0x6f, 0x6b,
 	0x02, 0xa8, 0x40, 0x31,
 	0xc0, 0x34, 0xc1, 0x09,
 	0x00, 0x35, 0x51, 0x01,
@@ -439,66 +448,66 @@
 	0xf7, 0x57, 0xae, 0x08,
 	0x08, 0xea, 0x98, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0xee, 0x00, 0x66, 0x6b,
+	0xee, 0x00, 0x78, 0x6b,
 	0x02, 0xea, 0xb4, 0x00,
-	0x00, 0xe2, 0x8e, 0x5b,
-	0x09, 0x4c, 0x68, 0x7b,
+	0x00, 0xe2, 0xa0, 0x5b,
+	0x09, 0x4c, 0x7a, 0x7b,
 	0x08, 0x4c, 0x06, 0x68,
-	0x0b, 0xea, 0x3c, 0x59,
+	0x0b, 0xea, 0x46, 0x59,
 	0x0b, 0xea, 0x04, 0x00,
 	0x01, 0x44, 0xd4, 0x31,
-	0x20, 0x33, 0xdd, 0x79,
-	0x00, 0xe2, 0x78, 0x5b,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x01, 0x84, 0x7d, 0x7b,
+	0x20, 0x33, 0xef, 0x79,
+	0x00, 0xe2, 0x8a, 0x5b,
+	0x00, 0xe2, 0xee, 0x41,
+	0x01, 0x84, 0x8f, 0x7b,
 	0x01, 0xa4, 0x49, 0x07,
 	0x08, 0x60, 0x30, 0x33,
 	0x08, 0x80, 0x41, 0x37,
 	0xdf, 0x33, 0x67, 0x0a,
-	0xee, 0x00, 0x8a, 0x6b,
+	0xee, 0x00, 0x9c, 0x6b,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
-	0x00, 0xe2, 0x56, 0x59,
-	0x00, 0xe2, 0x9c, 0x42,
+	0x00, 0xe2, 0x60, 0x59,
+	0x00, 0xe2, 0xae, 0x42,
 	0x01, 0xea, 0x6c, 0x02,
 	0xc0, 0xea, 0x66, 0x06,
-	0xff, 0x42, 0x92, 0x7b,
-	0x04, 0x4c, 0x92, 0x6b,
+	0xff, 0x42, 0xa4, 0x7b,
+	0x04, 0x4c, 0xa4, 0x6b,
 	0xe0, 0x41, 0x6c, 0x0e,
 	0x01, 0x44, 0xd4, 0x31,
-	0xff, 0x42, 0x9a, 0x7b,
-	0x04, 0x4c, 0x9a, 0x6b,
+	0xff, 0x42, 0xac, 0x7b,
+	0x04, 0x4c, 0xac, 0x6b,
 	0xe0, 0x41, 0x6c, 0x0a,
-	0xe0, 0x36, 0xdd, 0x61,
+	0xe0, 0x36, 0xef, 0x61,
 	0xff, 0xea, 0xca, 0x09,
 	0x01, 0xe2, 0xc8, 0x31,
 	0x01, 0x46, 0xda, 0x35,
 	0x01, 0x44, 0xd4, 0x35,
 	0x10, 0xea, 0x80, 0x00,
 	0x01, 0xe2, 0x62, 0x36,
-	0x04, 0xa6, 0xb2, 0x7b,
+	0x04, 0xa6, 0xc4, 0x7b,
 	0xff, 0xea, 0x5a, 0x09,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x01, 0xa6, 0xd0, 0x6b,
-	0x10, 0xad, 0x4e, 0x7d,
-	0x80, 0xad, 0xc8, 0x6b,
-	0x08, 0xad, 0x4e, 0x6d,
+	0x01, 0xa6, 0xe2, 0x6b,
+	0x10, 0xad, 0x66, 0x7d,
+	0x80, 0xad, 0xda, 0x6b,
+	0x08, 0xad, 0x66, 0x6d,
 	0x04, 0x84, 0xf9, 0x30,
 	0x00, 0xea, 0x08, 0x81,
 	0xff, 0xea, 0xd4, 0x09,
 	0x02, 0x84, 0xf9, 0x88,
 	0x1d, 0xea, 0x5a, 0x01,
 	0x04, 0xa6, 0x4c, 0x05,
-	0x04, 0xa6, 0x4e, 0x7d,
+	0x04, 0xa6, 0x66, 0x7d,
 	0xff, 0xea, 0x5a, 0x09,
 	0x03, 0x84, 0x59, 0x89,
 	0x03, 0xea, 0x4c, 0x01,
-	0x80, 0x1a, 0x4e, 0x7d,
+	0x80, 0x1a, 0x66, 0x7d,
 	0x08, 0xb0, 0xe0, 0x30,
 	0x04, 0xb0, 0xe0, 0x30,
 	0x03, 0xb0, 0xf0, 0x30,
-	0x01, 0x78, 0xdc, 0x7b,
+	0x01, 0x78, 0xee, 0x7b,
 	0x01, 0xa7, 0x4e, 0x11,
 	0x01, 0xb0, 0x06, 0x33,
 	0x7f, 0x83, 0xe9, 0x08,
@@ -509,244 +518,247 @@
 	0x00, 0x86, 0x0d, 0x23,
 	0x00, 0x87, 0x0f, 0x23,
 	0x01, 0x84, 0xc5, 0x31,
-	0x01, 0xa7, 0xf2, 0x7b,
+	0x01, 0xa7, 0x04, 0x7c,
 	0x04, 0xe2, 0xc4, 0x01,
-	0x80, 0x83, 0xf9, 0x7b,
+	0x80, 0x83, 0x0b, 0x7c,
 	0x02, 0xe2, 0xc4, 0x01,
 	0xff, 0xea, 0x4c, 0x09,
 	0x01, 0xe2, 0x36, 0x30,
 	0xc8, 0x19, 0x32, 0x00,
 	0x88, 0x19, 0x32, 0x00,
 	0x01, 0xac, 0xd4, 0x99,
-	0x00, 0xe2, 0x4e, 0x55,
+	0x00, 0xe2, 0x66, 0x55,
 	0xfe, 0xa6, 0x4c, 0x0d,
 	0x0b, 0x98, 0xe1, 0x30,
 	0x01, 0xa0, 0x4f, 0x09,
 	0xfd, 0xa4, 0x49, 0x09,
-	0x80, 0xa3, 0x0f, 0x7c,
+	0x80, 0xa3, 0x21, 0x7c,
 	0x02, 0xa4, 0x48, 0x01,
-	0x01, 0xa7, 0x12, 0x7c,
+	0x01, 0xa7, 0x24, 0x7c,
 	0x04, 0xa4, 0x48, 0x01,
 	0x01, 0xa4, 0x36, 0x30,
 	0xa8, 0xea, 0x32, 0x00,
 	0xfd, 0xa4, 0x49, 0x0b,
 	0x05, 0xa3, 0x07, 0x33,
-	0x80, 0x83, 0x1f, 0x6c,
+	0x80, 0x83, 0x31, 0x6c,
 	0x02, 0xea, 0x4c, 0x05,
 	0xff, 0xea, 0x4c, 0x0d,
-	0x00, 0xe2, 0x28, 0x59,
-	0x02, 0xa6, 0xb4, 0x6b,
+	0x00, 0xe2, 0x32, 0x59,
+	0x02, 0xa6, 0xc6, 0x6b,
 	0x80, 0xf9, 0xf2, 0x05,
-	0xc0, 0x33, 0x2d, 0x7c,
-	0x03, 0xea, 0x3c, 0x59,
+	0xc0, 0x33, 0x3f, 0x7c,
+	0x03, 0xea, 0x46, 0x59,
 	0x03, 0xea, 0x04, 0x00,
-	0x20, 0x33, 0x51, 0x7c,
-	0x01, 0x84, 0x37, 0x6c,
-	0x06, 0xea, 0x3c, 0x59,
+	0x20, 0x33, 0x63, 0x7c,
+	0x01, 0x84, 0x49, 0x6c,
+	0x06, 0xea, 0x46, 0x59,
 	0x06, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x54, 0x44,
+	0x00, 0xe2, 0x66, 0x44,
 	0x01, 0x00, 0x60, 0x32,
-	0xee, 0x00, 0x40, 0x6c,
+	0xee, 0x00, 0x52, 0x6c,
 	0x05, 0xea, 0xb4, 0x00,
-	0x33, 0xea, 0x30, 0x59,
+	0x33, 0xea, 0x3a, 0x59,
 	0x33, 0xea, 0x00, 0x00,
 	0x80, 0x3d, 0x7a, 0x00,
-	0xfc, 0x42, 0x42, 0x7c,
+	0xfc, 0x42, 0x54, 0x7c,
 	0x7f, 0x3d, 0x7a, 0x08,
-	0x00, 0x30, 0x31, 0x59,
+	0x00, 0x30, 0x3b, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x09, 0xea, 0x3c, 0x59,
+	0x09, 0xea, 0x46, 0x59,
 	0x09, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x01, 0xa4, 0x37, 0x6c,
-	0x00, 0xe2, 0x04, 0x5c,
+	0x00, 0xe2, 0xee, 0x41,
+	0x01, 0xa4, 0x49, 0x6c,
+	0x00, 0xe2, 0x16, 0x5c,
 	0x20, 0x33, 0x67, 0x02,
 	0x01, 0x00, 0x60, 0x32,
-	0x02, 0xa6, 0x5c, 0x7c,
-	0x00, 0xe2, 0x20, 0x5c,
-	0x00, 0xe2, 0x5c, 0x58,
-	0x00, 0xe2, 0x6c, 0x58,
+	0x02, 0xa6, 0x6e, 0x7c,
+	0x00, 0xe2, 0x32, 0x5c,
+	0x00, 0xe2, 0x66, 0x58,
+	0x00, 0xe2, 0x76, 0x58,
 	0x00, 0xe2, 0x30, 0x58,
-	0x00, 0x30, 0x31, 0x59,
+	0x00, 0x30, 0x3b, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x20, 0x19, 0x5c, 0x6c,
-	0x00, 0xe2, 0x84, 0x5c,
-	0x04, 0x19, 0x76, 0x6c,
+	0x20, 0x19, 0x6e, 0x6c,
+	0x00, 0xe2, 0x96, 0x5c,
+	0x04, 0x19, 0x88, 0x6c,
 	0x02, 0x19, 0x32, 0x00,
-	0x01, 0x84, 0x77, 0x7c,
-	0x01, 0x1b, 0x70, 0x7c,
-	0x01, 0x1a, 0x76, 0x6c,
-	0x00, 0xe2, 0x26, 0x44,
-	0x80, 0x4b, 0x7c, 0x6c,
-	0x01, 0x4c, 0x78, 0x7c,
-	0x03, 0x42, 0x26, 0x6c,
-	0x00, 0xe2, 0xae, 0x5b,
+	0x01, 0x84, 0x89, 0x7c,
+	0x01, 0x1b, 0x82, 0x7c,
+	0x01, 0x1a, 0x88, 0x6c,
+	0x00, 0xe2, 0x38, 0x44,
+	0x80, 0x4b, 0x8e, 0x6c,
+	0x01, 0x4c, 0x8a, 0x7c,
+	0x03, 0x42, 0x38, 0x6c,
+	0x00, 0xe2, 0xc0, 0x5b,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x04, 0x33, 0xdd, 0x79,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x02, 0x1b, 0x8c, 0x7c,
-	0x08, 0x5d, 0x8a, 0x7c,
+	0x04, 0x33, 0xef, 0x79,
+	0x00, 0xe2, 0xee, 0x41,
+	0x02, 0x1b, 0x9e, 0x7c,
+	0x08, 0x5d, 0x9c, 0x7c,
 	0x03, 0x68, 0x00, 0x37,
 	0x01, 0x84, 0x09, 0x07,
-	0x08, 0x5d, 0x96, 0x6c,
-	0x00, 0xe2, 0x5c, 0x58,
-	0x00, 0x30, 0x31, 0x59,
+	0x08, 0x5d, 0xa8, 0x6c,
+	0x00, 0xe2, 0x66, 0x58,
+	0x00, 0x30, 0x3b, 0x59,
 	0x01, 0x30, 0x01, 0x30,
-	0x00, 0xe2, 0x84, 0x44,
-	0x80, 0x1b, 0xa0, 0x7c,
-	0x80, 0x84, 0xa1, 0x6c,
+	0x00, 0xe2, 0x96, 0x44,
+	0x80, 0x1b, 0xb2, 0x7c,
+	0x80, 0x84, 0xb3, 0x6c,
 	0xff, 0x85, 0x0b, 0x1b,
 	0xff, 0x86, 0x0d, 0x23,
 	0xff, 0x87, 0x0f, 0x23,
 	0xf8, 0x1b, 0x08, 0x0b,
 	0xff, 0xea, 0x4e, 0x09,
-	0x04, 0x1b, 0xa8, 0x7c,
+	0x04, 0x1b, 0xba, 0x7c,
 	0x01, 0xa7, 0x4e, 0x01,
 	0xff, 0xea, 0x06, 0x0b,
 	0x03, 0x68, 0x00, 0x37,
-	0x00, 0xe2, 0xac, 0x58,
+	0x00, 0xe2, 0xb6, 0x58,
 	0x10, 0xea, 0x18, 0x00,
 	0xf9, 0xd9, 0xb2, 0x0d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0xff, 0xea, 0xd4, 0x09,
-	0x10, 0x5b, 0xcc, 0x6c,
-	0x08, 0x5b, 0xd4, 0x6c,
-	0x20, 0x5b, 0xc2, 0x6c,
-	0x02, 0x5b, 0xe2, 0x6d,
-	0x0e, 0xea, 0x3c, 0x59,
+	0x10, 0x5b, 0xde, 0x6c,
+	0x08, 0x5b, 0xe6, 0x6c,
+	0x20, 0x5b, 0xd4, 0x6c,
+	0x02, 0x5b, 0xfa, 0x6d,
+	0x0e, 0xea, 0x46, 0x59,
 	0x0e, 0xea, 0x04, 0x00,
-	0x08, 0x19, 0xc8, 0x7c,
+	0x08, 0x19, 0xda, 0x7c,
 	0xdf, 0x5c, 0xb8, 0x08,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x02, 0xea, 0xb4, 0x00,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x01, 0xa4, 0xab, 0x6d,
-	0x00, 0xe2, 0x04, 0x5c,
-	0x00, 0xe2, 0xee, 0x5c,
+	0x01, 0xa4, 0xc3, 0x6d,
+	0x00, 0xe2, 0x16, 0x5c,
+	0x00, 0xe2, 0x06, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
-	0x00, 0xe2, 0x12, 0x5b,
+	0x00, 0xe2, 0x24, 0x5b,
 	0xf3, 0x92, 0xd5, 0x19,
-	0x00, 0xe2, 0xe2, 0x54,
-	0x80, 0x92, 0xe3, 0x6c,
-	0x0f, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xf4, 0x54,
+	0x80, 0x92, 0xf5, 0x6c,
+	0x0f, 0xea, 0x46, 0x59,
 	0x0f, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xea, 0x44,
+	0x00, 0xe2, 0xfc, 0x44,
 	0x04, 0x8c, 0xe1, 0x30,
 	0x01, 0xea, 0xf2, 0x00,
 	0x02, 0xea, 0x36, 0x00,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x70, 0x5d,
+	0xff, 0x93, 0x03, 0x7d,
+	0x14, 0xea, 0x46, 0x59,
+	0x14, 0xea, 0x04, 0x00,
+	0x00, 0xe2, 0x88, 0x5d,
 	0x01, 0xd9, 0xb2, 0x05,
 	0x02, 0xa8, 0xf4, 0x31,
-	0x02, 0xa6, 0x00, 0x7d,
-	0x00, 0xe2, 0x2a, 0x59,
-	0x20, 0x5b, 0x0e, 0x6d,
-	0xfc, 0x42, 0xfa, 0x7c,
-	0x10, 0x40, 0xfc, 0x6c,
-	0x20, 0x4d, 0xfe, 0x7c,
-	0x08, 0x5d, 0x0e, 0x6d,
-	0x02, 0xa6, 0xb4, 0x6b,
-	0x00, 0xe2, 0x2a, 0x59,
-	0x20, 0x5b, 0x0e, 0x6d,
-	0x01, 0x1b, 0x2e, 0x6d,
-	0xfc, 0x42, 0x0a, 0x7d,
-	0x10, 0x40, 0x0c, 0x6d,
-	0x20, 0x4d, 0x4e, 0x7d,
-	0x08, 0x5d, 0x4e, 0x7d,
+	0x02, 0xa6, 0x18, 0x7d,
+	0x00, 0xe2, 0x34, 0x59,
+	0x20, 0x5b, 0x26, 0x6d,
+	0xfc, 0x42, 0x12, 0x7d,
+	0x10, 0x40, 0x14, 0x6d,
+	0x20, 0x4d, 0x16, 0x7d,
+	0x08, 0x5d, 0x26, 0x6d,
+	0x02, 0xa6, 0xc6, 0x6b,
+	0x00, 0xe2, 0x34, 0x59,
+	0x20, 0x5b, 0x26, 0x6d,
+	0x01, 0x1b, 0x46, 0x6d,
+	0xfc, 0x42, 0x22, 0x7d,
+	0x10, 0x40, 0x24, 0x6d,
+	0x20, 0x4d, 0x66, 0x7d,
+	0x08, 0x5d, 0x66, 0x7d,
 	0x02, 0x19, 0x32, 0x00,
 	0x01, 0x5b, 0x40, 0x31,
-	0x00, 0xe2, 0x84, 0x5c,
-	0x00, 0xe2, 0x78, 0x5b,
+	0x00, 0xe2, 0x96, 0x5c,
+	0x00, 0xe2, 0x8a, 0x5b,
 	0x20, 0xea, 0xb6, 0x00,
-	0x00, 0xe2, 0xae, 0x5b,
+	0x00, 0xe2, 0xc0, 0x5b,
 	0x20, 0x5c, 0xb8, 0x00,
-	0x04, 0x19, 0x24, 0x6d,
-	0x01, 0x1a, 0x24, 0x6d,
-	0x00, 0xe2, 0x2a, 0x59,
-	0x01, 0x1a, 0x4e, 0x7d,
+	0x04, 0x19, 0x3c, 0x6d,
+	0x01, 0x1a, 0x3c, 0x6d,
+	0x00, 0xe2, 0x34, 0x59,
+	0x01, 0x1a, 0x66, 0x7d,
 	0x80, 0xf9, 0xf2, 0x01,
-	0x20, 0xa0, 0x94, 0x7d,
-	0x08, 0xa8, 0x2d, 0x7d,
-	0x00, 0xe2, 0x40, 0x45,
+	0x20, 0xa0, 0xac, 0x7d,
+	0x08, 0xa8, 0x45, 0x7d,
+	0x00, 0xe2, 0x58, 0x45,
 	0x02, 0xea, 0xb4, 0x04,
 	0x02, 0x19, 0x32, 0x00,
-	0x08, 0xa8, 0x51, 0x7d,
-	0x04, 0x5d, 0xaa, 0x7d,
-	0x01, 0x1a, 0xaa, 0x7d,
+	0x08, 0xa8, 0x69, 0x7d,
+	0x04, 0x5d, 0xc2, 0x7d,
+	0x01, 0x1a, 0xc2, 0x7d,
 	0x01, 0xa4, 0x49, 0x03,
 	0x80, 0xf9, 0xf2, 0x01,
 	0x02, 0xa8, 0x84, 0x32,
 	0x02, 0xea, 0xb4, 0x00,
-	0x00, 0xe2, 0x22, 0x43,
+	0x00, 0xe2, 0x34, 0x43,
 	0x02, 0xa8, 0x84, 0x32,
 	0x02, 0xea, 0xb4, 0x00,
 	0xff, 0xea, 0xd4, 0x19,
-	0x00, 0xe2, 0x36, 0x59,
+	0x00, 0xe2, 0x40, 0x59,
 	0x11, 0x00, 0x00, 0x10,
-	0x00, 0xe2, 0x80, 0x5d,
-	0x00, 0xe2, 0x22, 0x53,
+	0x00, 0xe2, 0x98, 0x5d,
+	0x00, 0xe2, 0x34, 0x53,
 	0xff, 0xea, 0xd4, 0x0d,
-	0x00, 0xe2, 0x2a, 0x59,
-	0x40, 0x5b, 0x5c, 0x6d,
-	0x04, 0x5d, 0xaa, 0x7d,
-	0x01, 0x1a, 0xaa, 0x7d,
-	0x20, 0x4d, 0x4e, 0x7d,
-	0x40, 0x5b, 0x94, 0x7d,
-	0x04, 0x5d, 0xaa, 0x7d,
-	0x01, 0x1a, 0xaa, 0x7d,
+	0x00, 0xe2, 0x34, 0x59,
+	0x40, 0x5b, 0x74, 0x6d,
+	0x04, 0x5d, 0xc2, 0x7d,
+	0x01, 0x1a, 0xc2, 0x7d,
+	0x20, 0x4d, 0x66, 0x7d,
+	0x40, 0x5b, 0xac, 0x7d,
+	0x04, 0x5d, 0xc2, 0x7d,
+	0x01, 0x1a, 0xc2, 0x7d,
 	0x80, 0xf9, 0xf2, 0x01,
 	0x01, 0xa4, 0x49, 0x03,
-	0x08, 0xa8, 0x41, 0x6d,
+	0x08, 0xa8, 0x59, 0x6d,
 	0x02, 0xea, 0xb4, 0x04,
-	0xff, 0x6a, 0x76, 0x7d,
-	0x10, 0xea, 0x3c, 0x59,
+	0xff, 0x6a, 0x8e, 0x7d,
+	0x10, 0xea, 0x46, 0x59,
 	0x10, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x76, 0x45,
-	0x00, 0xe2, 0x28, 0x59,
-	0x10, 0x5d, 0x68, 0x6d,
-	0x40, 0x5b, 0x4e, 0x7d,
+	0x00, 0xe2, 0x8e, 0x45,
+	0x00, 0xe2, 0x32, 0x59,
+	0x10, 0x5d, 0x80, 0x6d,
+	0x40, 0x5b, 0x66, 0x7d,
 	0x02, 0x19, 0x32, 0x00,
 	0x80, 0xf9, 0xf2, 0x01,
 	0xff, 0xea, 0x10, 0x03,
 	0x08, 0xa8, 0x51, 0x03,
-	0x00, 0xe2, 0x40, 0x45,
-	0x80, 0xf9, 0x4e, 0x6d,
+	0x00, 0xe2, 0x58, 0x45,
+	0x80, 0xf9, 0x66, 0x6d,
 	0x01, 0x43, 0xc1, 0x31,
-	0x00, 0xfb, 0x4e, 0x65,
+	0x00, 0xfb, 0x66, 0x65,
 	0x01, 0x42, 0xc1, 0x31,
-	0x00, 0xfa, 0x4e, 0x65,
+	0x00, 0xfa, 0x66, 0x65,
 	0x01, 0xe8, 0xd4, 0x1d,
 	0x30, 0x3f, 0xc0, 0x09,
-	0x30, 0xe0, 0x4e, 0x65,
-	0x40, 0x4b, 0x4e, 0x6d,
+	0x30, 0xe0, 0x66, 0x65,
+	0x40, 0x4b, 0x66, 0x6d,
 	0xff, 0xea, 0x52, 0x01,
-	0xee, 0x00, 0x9a, 0x6d,
+	0xee, 0x00, 0xb2, 0x6d,
 	0x80, 0xf9, 0xf2, 0x01,
 	0x02, 0xea, 0xb4, 0x00,
 	0x20, 0xea, 0x9a, 0x00,
-	0xf3, 0x42, 0xa4, 0x6d,
-	0x12, 0xea, 0x3c, 0x59,
+	0xf3, 0x42, 0xbc, 0x6d,
+	0x12, 0xea, 0x46, 0x59,
 	0x12, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x0d, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xee, 0x41,
+	0x0d, 0xea, 0x46, 0x59,
 	0x0d, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0xdc, 0x41,
-	0x11, 0xea, 0x3c, 0x59,
+	0x00, 0xe2, 0xee, 0x41,
+	0x11, 0xea, 0x46, 0x59,
 	0x11, 0xea, 0x04, 0x00,
-	0x00, 0xe2, 0x12, 0x5b,
+	0x00, 0xe2, 0x24, 0x5b,
 	0x08, 0x5a, 0xb4, 0x00,
-	0x00, 0xe2, 0xcc, 0x5d,
+	0x00, 0xe2, 0xe4, 0x5d,
 	0xa8, 0xea, 0x32, 0x00,
-	0x00, 0xe2, 0x2a, 0x59,
-	0x80, 0x1a, 0xbe, 0x7d,
-	0x00, 0xe2, 0xcc, 0x5d,
+	0x00, 0xe2, 0x34, 0x59,
+	0x80, 0x1a, 0xd6, 0x7d,
+	0x00, 0xe2, 0xe4, 0x5d,
 	0x80, 0x19, 0x32, 0x00,
-	0x40, 0x5b, 0xc4, 0x6d,
-	0x08, 0x5a, 0xc4, 0x7d,
-	0x20, 0x4d, 0x4e, 0x7d,
+	0x40, 0x5b, 0xdc, 0x6d,
+	0x08, 0x5a, 0xdc, 0x7d,
+	0x20, 0x4d, 0x66, 0x7d,
 	0x02, 0x84, 0x09, 0x03,
-	0x40, 0x5b, 0x94, 0x7d,
-	0x08, 0xa8, 0x39, 0x6d,
+	0x40, 0x5b, 0xac, 0x7d,
+	0x08, 0xa8, 0x51, 0x6d,
 	0x02, 0xea, 0xb4, 0x04,
 	0x01, 0x38, 0xe1, 0x30,
 	0x05, 0x39, 0xe3, 0x98,
@@ -930,116 +942,122 @@
 	{ ahd_patch0_func, 7, 1, 1 },
 	{ ahd_patch2_func, 24, 1, 2 },
 	{ ahd_patch0_func, 25, 1, 1 },
-	{ ahd_patch2_func, 35, 1, 2 },
-	{ ahd_patch0_func, 36, 1, 1 },
-	{ ahd_patch2_func, 39, 1, 2 },
-	{ ahd_patch0_func, 40, 1, 1 },
-	{ ahd_patch2_func, 43, 1, 2 },
-	{ ahd_patch0_func, 44, 1, 1 },
-	{ ahd_patch2_func, 46, 1, 2 },
-	{ ahd_patch0_func, 47, 1, 1 },
-	{ ahd_patch2_func, 50, 1, 2 },
-	{ ahd_patch0_func, 51, 1, 1 },
-	{ ahd_patch2_func, 54, 1, 2 },
-	{ ahd_patch0_func, 55, 1, 1 },
-	{ ahd_patch2_func, 152, 6, 1 },
-	{ ahd_patch1_func, 158, 2, 1 },
-	{ ahd_patch3_func, 160, 1, 1 },
-	{ ahd_patch2_func, 169, 1, 2 },
-	{ ahd_patch0_func, 170, 1, 1 },
-	{ ahd_patch4_func, 171, 2, 2 },
-	{ ahd_patch0_func, 173, 6, 3 },
-	{ ahd_patch2_func, 176, 1, 2 },
-	{ ahd_patch0_func, 177, 1, 1 },
-	{ ahd_patch2_func, 180, 1, 2 },
-	{ ahd_patch0_func, 181, 1, 1 },
-	{ ahd_patch5_func, 183, 2, 1 },
-	{ ahd_patch3_func, 191, 16, 2 },
-	{ ahd_patch0_func, 207, 1, 1 },
-	{ ahd_patch6_func, 227, 2, 1 },
-	{ ahd_patch5_func, 231, 2, 1 },
-	{ ahd_patch1_func, 245, 1, 2 },
-	{ ahd_patch0_func, 246, 1, 1 },
-	{ ahd_patch1_func, 249, 1, 2 },
-	{ ahd_patch0_func, 250, 1, 1 },
-	{ ahd_patch2_func, 253, 1, 2 },
-	{ ahd_patch0_func, 254, 1, 1 },
-	{ ahd_patch1_func, 309, 1, 2 },
-	{ ahd_patch0_func, 310, 1, 1 },
-	{ ahd_patch2_func, 318, 1, 2 },
+	{ ahd_patch1_func, 32, 1, 2 },
+	{ ahd_patch0_func, 33, 1, 1 },
+	{ ahd_patch2_func, 40, 1, 2 },
+	{ ahd_patch0_func, 41, 1, 1 },
+	{ ahd_patch2_func, 44, 1, 2 },
+	{ ahd_patch0_func, 45, 1, 1 },
+	{ ahd_patch2_func, 48, 1, 2 },
+	{ ahd_patch0_func, 49, 1, 1 },
+	{ ahd_patch2_func, 51, 1, 2 },
+	{ ahd_patch0_func, 52, 1, 1 },
+	{ ahd_patch2_func, 55, 1, 2 },
+	{ ahd_patch0_func, 56, 1, 1 },
+	{ ahd_patch2_func, 59, 1, 2 },
+	{ ahd_patch0_func, 60, 1, 1 },
+	{ ahd_patch2_func, 157, 6, 1 },
+	{ ahd_patch1_func, 163, 2, 1 },
+	{ ahd_patch3_func, 165, 1, 1 },
+	{ ahd_patch2_func, 174, 1, 2 },
+	{ ahd_patch0_func, 175, 1, 1 },
+	{ ahd_patch4_func, 176, 2, 2 },
+	{ ahd_patch0_func, 178, 6, 3 },
+	{ ahd_patch2_func, 181, 1, 2 },
+	{ ahd_patch0_func, 182, 1, 1 },
+	{ ahd_patch2_func, 185, 1, 2 },
+	{ ahd_patch0_func, 186, 1, 1 },
+	{ ahd_patch5_func, 188, 2, 1 },
+	{ ahd_patch3_func, 196, 16, 2 },
+	{ ahd_patch0_func, 212, 1, 1 },
+	{ ahd_patch6_func, 232, 2, 1 },
+	{ ahd_patch1_func, 236, 1, 2 },
+	{ ahd_patch0_func, 237, 1, 1 },
+	{ ahd_patch5_func, 240, 2, 1 },
+	{ ahd_patch1_func, 254, 1, 2 },
+	{ ahd_patch0_func, 255, 1, 1 },
+	{ ahd_patch1_func, 258, 1, 2 },
+	{ ahd_patch0_func, 259, 1, 1 },
+	{ ahd_patch2_func, 262, 1, 2 },
+	{ ahd_patch0_func, 263, 1, 1 },
+	{ ahd_patch1_func, 318, 1, 2 },
 	{ ahd_patch0_func, 319, 1, 1 },
-	{ ahd_patch2_func, 322, 1, 2 },
-	{ ahd_patch0_func, 323, 1, 1 },
-	{ ahd_patch1_func, 330, 1, 2 },
-	{ ahd_patch0_func, 331, 1, 1 },
-	{ ahd_patch7_func, 350, 1, 1 },
-	{ ahd_patch7_func, 353, 1, 1 },
-	{ ahd_patch7_func, 355, 1, 1 },
-	{ ahd_patch7_func, 367, 1, 1 },
-	{ ahd_patch1_func, 377, 1, 2 },
-	{ ahd_patch0_func, 378, 1, 1 },
-	{ ahd_patch1_func, 380, 1, 2 },
-	{ ahd_patch0_func, 381, 1, 1 },
+	{ ahd_patch2_func, 327, 1, 2 },
+	{ ahd_patch0_func, 328, 1, 1 },
+	{ ahd_patch2_func, 331, 1, 2 },
+	{ ahd_patch0_func, 332, 1, 1 },
+	{ ahd_patch1_func, 339, 1, 2 },
+	{ ahd_patch0_func, 340, 1, 1 },
+	{ ahd_patch7_func, 359, 1, 1 },
+	{ ahd_patch7_func, 362, 1, 1 },
+	{ ahd_patch7_func, 364, 1, 1 },
+	{ ahd_patch7_func, 376, 1, 1 },
+	{ ahd_patch1_func, 386, 1, 2 },
+	{ ahd_patch0_func, 387, 1, 1 },
 	{ ahd_patch1_func, 389, 1, 2 },
 	{ ahd_patch0_func, 390, 1, 1 },
-	{ ahd_patch2_func, 401, 1, 2 },
-	{ ahd_patch0_func, 402, 1, 1 },
-	{ ahd_patch8_func, 404, 1, 1 },
-	{ ahd_patch9_func, 431, 1, 1 },
-	{ ahd_patch1_func, 438, 1, 2 },
-	{ ahd_patch0_func, 439, 1, 1 },
-	{ ahd_patch2_func, 451, 1, 2 },
-	{ ahd_patch0_func, 452, 1, 1 },
-	{ ahd_patch10_func, 480, 1, 1 },
-	{ ahd_patch11_func, 489, 1, 2 },
-	{ ahd_patch0_func, 490, 1, 1 },
-	{ ahd_patch12_func, 495, 1, 1 },
-	{ ahd_patch11_func, 496, 1, 1 },
-	{ ahd_patch13_func, 509, 1, 2 },
-	{ ahd_patch0_func, 510, 1, 1 },
-	{ ahd_patch1_func, 532, 1, 2 },
-	{ ahd_patch0_func, 533, 1, 1 },
-	{ ahd_patch1_func, 536, 1, 2 },
-	{ ahd_patch0_func, 537, 1, 1 },
-	{ ahd_patch2_func, 542, 1, 2 },
-	{ ahd_patch0_func, 543, 1, 1 },
-	{ ahd_patch2_func, 547, 1, 2 },
-	{ ahd_patch0_func, 548, 1, 1 },
-	{ ahd_patch1_func, 549, 1, 2 },
-	{ ahd_patch0_func, 550, 1, 1 },
-	{ ahd_patch2_func, 561, 1, 2 },
-	{ ahd_patch0_func, 562, 1, 1 },
-	{ ahd_patch14_func, 566, 1, 1 },
-	{ ahd_patch15_func, 571, 1, 1 },
-	{ ahd_patch16_func, 572, 2, 1 },
-	{ ahd_patch15_func, 576, 1, 2 },
-	{ ahd_patch0_func, 577, 1, 1 },
-	{ ahd_patch2_func, 584, 1, 2 },
-	{ ahd_patch0_func, 585, 1, 1 },
-	{ ahd_patch2_func, 600, 1, 2 },
-	{ ahd_patch0_func, 601, 1, 1 },
-	{ ahd_patch1_func, 607, 1, 2 },
-	{ ahd_patch0_func, 608, 1, 1 },
-	{ ahd_patch1_func, 622, 1, 2 },
-	{ ahd_patch0_func, 623, 1, 1 },
-	{ ahd_patch14_func, 647, 1, 1 },
-	{ ahd_patch14_func, 663, 1, 1 },
-	{ ahd_patch2_func, 675, 1, 2 },
-	{ ahd_patch0_func, 676, 1, 1 },
-	{ ahd_patch1_func, 693, 1, 2 },
-	{ ahd_patch0_func, 694, 1, 1 },
-	{ ahd_patch14_func, 699, 1, 1 },
-	{ ahd_patch1_func, 719, 1, 2 },
-	{ ahd_patch0_func, 720, 1, 1 },
-	{ ahd_patch1_func, 722, 1, 2 },
-	{ ahd_patch0_func, 723, 1, 1 },
-	{ ahd_patch1_func, 725, 1, 2 },
-	{ ahd_patch0_func, 726, 1, 1 },
-	{ ahd_patch17_func, 728, 1, 2 },
-	{ ahd_patch0_func, 729, 2, 1 },
-	{ ahd_patch18_func, 732, 4, 2 },
-	{ ahd_patch0_func, 736, 1, 1 },
-	{ ahd_patch18_func, 742, 11, 1 }
+	{ ahd_patch1_func, 398, 1, 2 },
+	{ ahd_patch0_func, 399, 1, 1 },
+	{ ahd_patch2_func, 410, 1, 2 },
+	{ ahd_patch0_func, 411, 1, 1 },
+	{ ahd_patch8_func, 413, 1, 1 },
+	{ ahd_patch9_func, 440, 1, 1 },
+	{ ahd_patch1_func, 447, 1, 2 },
+	{ ahd_patch0_func, 448, 1, 1 },
+	{ ahd_patch2_func, 460, 1, 2 },
+	{ ahd_patch0_func, 461, 1, 1 },
+	{ ahd_patch10_func, 489, 1, 1 },
+	{ ahd_patch11_func, 498, 1, 2 },
+	{ ahd_patch0_func, 499, 1, 1 },
+	{ ahd_patch12_func, 504, 1, 1 },
+	{ ahd_patch11_func, 505, 1, 1 },
+	{ ahd_patch13_func, 518, 1, 2 },
+	{ ahd_patch0_func, 519, 1, 1 },
+	{ ahd_patch1_func, 541, 1, 2 },
+	{ ahd_patch0_func, 542, 1, 1 },
+	{ ahd_patch1_func, 545, 1, 2 },
+	{ ahd_patch0_func, 546, 1, 1 },
+	{ ahd_patch2_func, 551, 1, 2 },
+	{ ahd_patch0_func, 552, 1, 1 },
+	{ ahd_patch2_func, 556, 1, 2 },
+	{ ahd_patch0_func, 557, 1, 1 },
+	{ ahd_patch1_func, 558, 1, 2 },
+	{ ahd_patch0_func, 559, 1, 1 },
+	{ ahd_patch2_func, 570, 1, 2 },
+	{ ahd_patch0_func, 571, 1, 1 },
+	{ ahd_patch14_func, 575, 1, 1 },
+	{ ahd_patch15_func, 580, 1, 1 },
+	{ ahd_patch16_func, 581, 2, 1 },
+	{ ahd_patch15_func, 585, 1, 2 },
+	{ ahd_patch0_func, 586, 1, 1 },
+	{ ahd_patch2_func, 593, 1, 2 },
+	{ ahd_patch0_func, 594, 1, 1 },
+	{ ahd_patch2_func, 609, 1, 2 },
+	{ ahd_patch0_func, 610, 1, 1 },
+	{ ahd_patch1_func, 616, 1, 2 },
+	{ ahd_patch0_func, 617, 1, 1 },
+	{ ahd_patch1_func, 631, 1, 2 },
+	{ ahd_patch0_func, 632, 1, 1 },
+	{ ahd_patch1_func, 639, 1, 2 },
+	{ ahd_patch0_func, 640, 1, 1 },
+	{ ahd_patch14_func, 659, 1, 1 },
+	{ ahd_patch14_func, 675, 1, 1 },
+	{ ahd_patch2_func, 687, 1, 2 },
+	{ ahd_patch0_func, 688, 1, 1 },
+	{ ahd_patch1_func, 705, 1, 2 },
+	{ ahd_patch0_func, 706, 1, 1 },
+	{ ahd_patch14_func, 711, 1, 1 },
+	{ ahd_patch1_func, 731, 1, 2 },
+	{ ahd_patch0_func, 732, 1, 1 },
+	{ ahd_patch1_func, 734, 1, 2 },
+	{ ahd_patch0_func, 735, 1, 1 },
+	{ ahd_patch1_func, 737, 1, 2 },
+	{ ahd_patch0_func, 738, 1, 1 },
+	{ ahd_patch17_func, 740, 1, 2 },
+	{ ahd_patch0_func, 741, 2, 1 },
+	{ ahd_patch18_func, 744, 4, 2 },
+	{ ahd_patch0_func, 748, 1, 1 },
+	{ ahd_patch18_func, 754, 11, 1 }
 };
 
 static struct cs {
@@ -1048,19 +1066,19 @@
 } critical_sections[] = {
 	{ 11, 12 },
 	{ 13, 14 },
-	{ 24, 32 },
-	{ 33, 46 },
-	{ 59, 62 },
-	{ 89, 114 },
-	{ 115, 146 },
-	{ 148, 152 },
-	{ 160, 168 },
-	{ 191, 224 },
-	{ 647, 663 },
-	{ 663, 681 },
-	{ 686, 692 },
-	{ 699, 704 },
-	{ 704, 710 }
+	{ 24, 37 },
+	{ 38, 51 },
+	{ 64, 67 },
+	{ 94, 119 },
+	{ 120, 151 },
+	{ 153, 157 },
+	{ 165, 173 },
+	{ 196, 245 },
+	{ 659, 675 },
+	{ 675, 693 },
+	{ 698, 704 },
+	{ 711, 716 },
+	{ 716, 722 }
 };
 
 static const int num_critical_sections = sizeof(critical_sections)
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
--- a/drivers/scsi/aic7xxx/aic7xxx.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.h	Mon Feb 10 10:39:27 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#67 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#70 $
  *
  * $FreeBSD$
  */
@@ -318,11 +318,11 @@
  */
 typedef enum {
 	AHC_FNONE	      = 0x000,
-	AHC_PRIMARY_CHANNEL   = 0x003,/*
+	AHC_PRIMARY_CHANNEL   = 0x003,  /*
 					 * The channel that should
 					 * be probed first.
 					 */
-	AHC_USEDEFAULTS	      = 0x004,/*
+	AHC_USEDEFAULTS	      = 0x004,  /*
 					 * For cards without an seeprom
 					 * or a BIOS to initialize the chip's
 					 * SRAM, we use the default target
@@ -330,29 +330,29 @@
 					 */
 	AHC_SEQUENCER_DEBUG   = 0x008,
 	AHC_SHARED_SRAM	      = 0x010,
-	AHC_LARGE_SEEPROM     = 0x020,/* Uses C56_66 not C46 */
+	AHC_LARGE_SEEPROM     = 0x020,  /* Uses C56_66 not C46 */
 	AHC_RESET_BUS_A	      = 0x040,
 	AHC_RESET_BUS_B	      = 0x080,
 	AHC_EXTENDED_TRANS_A  = 0x100,
 	AHC_EXTENDED_TRANS_B  = 0x200,
 	AHC_TERM_ENB_A	      = 0x400,
 	AHC_TERM_ENB_B	      = 0x800,
-	AHC_INITIATORROLE     = 0x1000,/*
+	AHC_INITIATORROLE     = 0x1000,  /*
 					  * Allow initiator operations on
 					  * this controller.
 					  */
-	AHC_TARGETROLE	      = 0x2000,/*
+	AHC_TARGETROLE	      = 0x2000,  /*
 					  * Allow target operations on this
 					  * controller.
 					  */
 	AHC_NEWEEPROM_FMT     = 0x4000,
 	AHC_RESOURCE_SHORTAGE = 0x8000,
-	AHC_TQINFIFO_BLOCKED  = 0x10000,/* Blocked waiting for ATIOs */
-	AHC_INT50_SPEEDFLEX   = 0x20000,/*
+	AHC_TQINFIFO_BLOCKED  = 0x10000,  /* Blocked waiting for ATIOs */
+	AHC_INT50_SPEEDFLEX   = 0x20000,  /*
 					   * Internal 50pin connector
 					   * sits behind an aic3860
 					   */
-	AHC_SCB_BTT	      = 0x40000,/*
+	AHC_SCB_BTT	      = 0x40000,  /*
 					   * The busy targets table is
 					   * stored in SCB space rather
 					   * than SRAM.
@@ -363,7 +363,9 @@
 	AHC_EDGE_INTERRUPT    = 0x800000,  /* Device uses edge triggered ints */
 	AHC_39BIT_ADDRESSING  = 0x1000000, /* Use 39 bit addressing scheme. */
 	AHC_LSCBS_ENABLED     = 0x2000000, /* 64Byte SCBs enabled */
-	AHC_SCB_CONFIG_USED   = 0x4000000  /* No SEEPROM but SCB2 had info. */
+	AHC_SCB_CONFIG_USED   = 0x4000000, /* No SEEPROM but SCB2 had info. */
+	AHC_NO_BIOS_INIT      = 0x8000000, /* No BIOS left over settings. */
+	AHC_DISABLE_PCI_PERR  = 0x10000000
 } ahc_flag;
 
 /************************* Hardware  SCB Definition ***************************/
@@ -758,6 +760,7 @@
 #define AHC_SYNCRATE_ULTRA	3
 #define AHC_SYNCRATE_FAST	6
 #define AHC_SYNCRATE_MAX	AHC_SYNCRATE_DT
+#define	AHC_SYNCRATE_MIN	13
 
 /***************************** Lookup Tables **********************************/
 /*
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq
--- a/drivers/scsi/aic7xxx/aic7xxx.seq	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx.seq	Mon Feb 10 10:39:30 2003
@@ -40,7 +40,7 @@
  * $FreeBSD$
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $"
 PATCH_ARG_LIST = "struct ahc_softc *ahc"
 PREFIX = "ahc_"
 
@@ -193,7 +193,7 @@
 		 * Setup the DMA for sending the identify and
 		 * command information.
 		 */
-		or	SEQ_FLAGS, CMDPHASE_PENDING;
+		mvi	SEQ_FLAGS, CMDPHASE_PENDING;
 
 		mov     A, TQINPOS;
 		if ((ahc->features & AHC_CMD_CHAN) != 0) {
@@ -306,7 +306,7 @@
 		} else {
 			mvi	DFDAT, SCB_LIST_NULL;
 		}
-		mvi	SEQ_FLAGS, TARG_CMD_PENDING;
+		or	SEQ_FLAGS, TARG_CMD_PENDING;
 		test	SEQ_FLAGS2, TARGET_MSG_PENDING
 			jnz target_mesgout_pending;
 		test	SCSISIGI, ATNI jnz target_mesgout_continue;
@@ -512,6 +512,7 @@
 target_mesgout_continue:
 		call	target_inb;
 target_mesgout_pending:
+		and	SEQ_FLAGS2, ~TARGET_MSG_PENDING;
 		/* Local Processing goes here... */
 		jmp	host_target_message_loop;
 		
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c	Mon Feb 10 10:39:26 2003
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#108 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#112 $
  *
  * $FreeBSD$
  */
@@ -1844,8 +1844,9 @@
 		 * occurs the need to renegotiate is
 		 * recorded persistently.
 		 */
+		if ((ahc->features & AHC_WIDE) != 0)
+			tinfo->curr.width = AHC_WIDTH_UNKNOWN;
 		tinfo->curr.period = AHC_PERIOD_UNKNOWN;
-		tinfo->curr.width = AHC_WIDTH_UNKNOWN;
 		tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
 	}
 	if (tinfo->curr.period != tinfo->goal.period
@@ -3443,7 +3444,7 @@
 		 * but rejected our response, we already cleared the
 		 * sync rate before sending our WDTR.
 		 */
-		if (tinfo->goal.offset) {
+		if (tinfo->goal.offset != tinfo->curr.offset) {
 
 			/* Start the sync negotiation */
 			ahc->msgout_index = 0;
@@ -4045,6 +4046,14 @@
 	 * to disturb the integrity of the bus.
 	 */
 	ahc_pause(ahc);
+	if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
+		/*
+		 * The chip has not been initialized since
+		 * PCI/EISA/VLB bus reset.  Don't trust
+		 * "left over BIOS data".
+		 */
+		ahc->flags |= AHC_NO_BIOS_INIT;
+	}
 	sxfrctl1_b = 0;
 	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
 		u_int sblkctl;
@@ -4539,8 +4548,9 @@
 	size_t	 driver_data_size;
 	uint32_t physaddr;
 
-#ifdef AHC_DEBUG_SEQUENCER
-	ahc->flags |= AHC_SEQUENCER_DEBUG;
+#ifdef AHC_DEBUG
+	if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
+		ahc->flags |= AHC_SEQUENCER_DEBUG;
 #endif
 
 #ifdef AHC_PRINT_SRAM
@@ -4875,7 +4885,7 @@
 			tinfo->curr.protocol_version = 2;
 			tinfo->curr.transport_version = 2;
 		}
-		tstate->ultraenb = ultraenb;
+		tstate->ultraenb = 0;
 	}
 	ahc->user_discenable = discenable;
 	ahc->user_tagenable = tagenable;
@@ -6483,8 +6493,11 @@
 	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
 	ahc_restart(ahc);
 
-	if (bootverbose)
+	if (bootverbose) {
 		printf(" %d instructions downloaded\n", downloaded);
+		printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
+		       ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
+	}
 }
 
 static int
@@ -6702,6 +6715,7 @@
 	struct	scb *scb;
 	struct	scb_tailq *untagged_q;
 	u_int	cur_col;
+	int	paused;
 	int	target;
 	int	maxtarget;
 	int	i;
@@ -6712,12 +6726,21 @@
 	uint8_t scb_index;
 	uint8_t saved_scbptr;
 
-	saved_scbptr = ahc_inb(ahc, SCBPTR);
+	if (ahc_is_paused(ahc)) {
+		paused = 1;
+	} else {
+		paused = 0;
+		ahc_pause(ahc);
+	}
 
+	saved_scbptr = ahc_inb(ahc, SCBPTR);
 	last_phase = ahc_inb(ahc, LASTPHASE);
-	printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n",
+	printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
+	       "%s: Dumping Card State %s, at SEQADDR 0x%x\n",
 	       ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
 	       ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
+	if (paused)
+		printf("Card was paused\n");
 	printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
 	       ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
 	       ahc_inb(ahc, ARG_2));
@@ -6725,13 +6748,14 @@
 	       ahc_inb(ahc, SCBPTR));
 	cur_col = 0;
 	if ((ahc->features & AHC_DT) != 0)
-		ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
+		ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
+	ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
 	ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
-	ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
 	ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
 	ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
 	ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
 	ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
+	ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
 	ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
 	ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
 	ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
@@ -6862,7 +6886,10 @@
 	}
 
 	ahc_platform_dump_card_state(ahc);
+	printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
 	ahc_outb(ahc, SCBPTR, saved_scbptr);
+	if (paused == 0)
+		ahc_unpause(ahc);
 }
 
 /************************* Target Mode ****************************************/
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h
--- a/drivers/scsi/aic7xxx/aic7xxx_inline.h	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h	Mon Feb 10 10:39:33 2003
@@ -460,7 +460,7 @@
 	ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
 
 	/*
-	 * Make sure our data is consistant from the
+	 * Make sure our data is consistent from the
 	 * perspective of the adapter.
 	 */
 	ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Mon Feb 10 10:39:23 2003
@@ -1,7 +1,7 @@
 /*
  * Adaptec AIC7xxx device driver for Linux.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#169 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 $
  *
  * Copyright (c) 1994 John Aycock
  *   The University of Calgary Department of Computer Science.
@@ -119,12 +119,6 @@
  *
  */
 
-/*
- * This is the only file where module.h should
- * embed module global version info.
- */
-#define AHC_MODVERSION_FILE
-
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include <scsi/scsicam.h>
@@ -524,8 +518,6 @@
 				    struct scsi_cmnd *cmd,
 				    struct ahc_devinfo *devinfo,
 				    struct ahc_linux_target *targ);
-static uint32_t aic_dv_error_action(struct scsi_cmnd *cmd,
-				    struct scsi_inquiry_data *inq_data);
 static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc,
 				  struct scsi_cmnd *cmd,
 				  struct ahc_devinfo *devinfo);
@@ -976,7 +968,7 @@
 	struct	 ahc_linux_device *dev;
 	u_long	 flags;
 
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 
 	/*
 	 * Save the callback on completion function.
@@ -1000,8 +992,8 @@
 		ahc_midlayer_entrypoint_unlock(ahc, &flags);
 		return (0);
 	}
-	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/TRUE);
+	dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
+				   cmd->device->lun, /*alloc*/TRUE);
 	if (dev == NULL) {
 		ahc_midlayer_entrypoint_unlock(ahc, &flags);
 		printf("aic7xxx_linux_queue: Unable to allocate device!\n");
@@ -1245,12 +1237,12 @@
 	u_long s;
 	int    found;
 
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	spin_unlock_irq(&io_request_lock);
 #endif
 	ahc_midlayer_entrypoint_lock(ahc, &s);
-	found = ahc_reset_channel(ahc, cmd->channel + 'A',
+	found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
 				  /*initiate reset*/TRUE);
 	acmd = TAILQ_FIRST(&ahc->platform_data->completeq);
 	TAILQ_INIT(&ahc->platform_data->completeq);
@@ -1374,10 +1366,10 @@
 }
 
 /******************************** Macros **************************************/
-#define BUILD_SCSIID(ahc, cmd)						\
-	((((cmd)->target << TID_SHIFT) & TID)				\
-	| (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b)	\
-	| (((cmd)->channel == 0) ? 0 : TWIN_CHNLB))
+#define BUILD_SCSIID(ahc, cmd)						    \
+	((((cmd)->device->id << TID_SHIFT) & TID)			    \
+	| (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
+	| (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
 
 /******************************** Bus DMA *************************************/
 int
@@ -2045,6 +2037,9 @@
 #endif
 	ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
 	ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
+	if (aic7xxx_pci_parity == 0)
+		ahc->flags |= AHC_DISABLE_PCI_PERR;
+
 	if (TAILQ_EMPTY(&ahc_tailq))
 		register_reboot_notifier(&ahc_linux_notifier);
 	return (0);
@@ -2053,7 +2048,10 @@
 void
 ahc_platform_free(struct ahc_softc *ahc)
 {
+	struct ahc_linux_target *targ;
+	struct ahc_linux_device *dev;
 	u_long s;
+	int i, j;
 
 	if (ahc->platform_data != NULL) {
 		/* Kill the DV kthread */
@@ -2077,6 +2075,23 @@
 #endif
 		if (ahc->platform_data->host != NULL)
 			scsi_unregister(ahc->platform_data->host);
+
+		/* destroy all of the device and target objects */
+		for (i = 0; i < AHC_NUM_TARGETS; i++) {
+			targ = ahc->platform_data->targets[i];
+			if (targ != NULL) {
+				for (j = 0; j < AHC_NUM_LUNS; j++) {
+					if (targ->devices[j] != NULL) {
+						dev = targ->devices[j];
+						ahc_linux_free_device(ahc, dev);
+					}
+					if (ahc->platform_data->targets[i] ==
+					    NULL)
+						break;
+				}
+			}
+		}
+
 		if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
 			free_irq(ahc->platform_data->irq, ahc);
 		if (ahc->tag == BUS_SPACE_PIO
@@ -2446,6 +2461,7 @@
 	struct	 ahc_devinfo devinfo;
 	struct	 ahc_linux_target *targ;
 	struct	 scsi_cmnd *cmd;
+	struct	 scsi_device *scsi_dev;
 	struct	 scsi_sense_data *sense;
 	uint8_t *buffer;
 	u_long	 s;
@@ -2473,6 +2489,12 @@
 	ahc_unlock(ahc, &s);
 
 	cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
+	scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK);
+	scsi_dev->host = ahc->platform_data->host;
+	scsi_dev->id = devinfo.target;
+	scsi_dev->lun = devinfo.lun;
+	scsi_dev->channel = devinfo.channel - 'A';
+	ahc->platform_data->dv_scsi_dev = scsi_dev;
 
 	AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC);
 
@@ -2597,6 +2619,11 @@
 	if (cmd != NULL)
 		free(cmd, M_DEVBUF);
 
+	if (ahc->platform_data->dv_scsi_dev != NULL) {
+		free(ahc->platform_data->dv_scsi_dev, M_DEVBUF);
+		ahc->platform_data->dv_scsi_dev = NULL;
+	}
+
 	ahc_lock(ahc, &s);
 	if (targ->dv_buffer != NULL)
 		free(targ->dv_buffer, M_DEVBUF);
@@ -2613,9 +2640,13 @@
 			struct ahc_devinfo *devinfo,
 			struct ahc_linux_target *targ)
 {
+	cam_status cam_status;
 	u_int32_t status;
+	u_int scsi_status;
 
-	status = aic_dv_error_action(cmd, targ->inq_data);
+	scsi_status = ahc_cmd_get_scsi_status(cmd);
+	cam_status = ahc_cmd_get_transaction_status(cmd);
+	status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status);
 
 	
 #ifdef AHC_DEBUG
@@ -2666,6 +2697,7 @@
 		switch (status & SS_MASK) {
 		case SS_NOP:
 		{
+			u_int xportflags;
 			u_int spi3data;
 
 			if (memcmp(targ->inq_data, targ->dv_buffer,
@@ -2684,6 +2716,10 @@
 			if (ahc_linux_user_dv_setting(ahc) == 0)
 				break;
 
+			xportflags = targ->inq_data->flags;
+			if ((xportflags & (SID_Sync|SID_WBus16)) == 0)
+				break;
+
 			spi3data = targ->inq_data->spi3data;
 			switch (spi3data & SID_SPI_CLOCK_DT_ST) {
 			default:
@@ -3077,104 +3113,13 @@
 	}
 }
 
-static uint32_t
-aic_dv_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data)
-{
-	aic_sense_action  err_action;
-	cam_status	  status;
-	u_int		  scsi_status;
-	int		  sense;
-
-	status = ahc_cmd_get_transaction_status(cmd);
-	scsi_status = ahc_cmd_get_scsi_status(cmd);
-	sense  = (cmd->result >> 24) == DRIVER_SENSE;
-
-	switch (status) {
-	case CAM_REQ_CMP:
-		err_action = SS_NOP;
-		break;
-	case CAM_AUTOSENSE_FAIL:
-	case CAM_SCSI_STATUS_ERROR:
-
-		switch (scsi_status) {
-		case SCSI_STATUS_OK:
-		case SCSI_STATUS_COND_MET:
-		case SCSI_STATUS_INTERMED:
-		case SCSI_STATUS_INTERMED_COND_MET:
-			err_action = SS_NOP;
-			break;
-		case SCSI_STATUS_CMD_TERMINATED:
-		case SCSI_STATUS_CHECK_COND:
-			if (sense != 0) {
-				struct scsi_sense_data *sense;
-
-				sense = (struct scsi_sense_data *)
-				    &cmd->sense_buffer;
-				err_action =
-				    aic_sense_error_action(sense, inq_data, 0);
-
-			} else {
-				err_action = SS_RETRY|SSQ_FALLBACK
-					   | SSQ_DECREMENT_COUNT|EIO;
-			}
-			break;
-		case SCSI_STATUS_QUEUE_FULL:
-		case SCSI_STATUS_BUSY:
-			err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY
-				   | SSQ_DECREMENT_COUNT|EBUSY;
-			break;
-		case SCSI_STATUS_RESERV_CONFLICT:
-		default:
-			err_action = SS_FAIL|EBUSY;
-			break;
-		}
-		break;
-	case CAM_REQ_CMP_ERR:
-	case CAM_CMD_TIMEOUT:
-	case CAM_UNEXP_BUSFREE:
-	case CAM_UNCOR_PARITY:
-	case CAM_DATA_RUN_ERR:
-		err_action = SS_RETRY|SSQ_FALLBACK|EIO;
-		break;
-	case CAM_UA_ABORT:
-	case CAM_UA_TERMIO:
-	case CAM_MSG_REJECT_REC:
-	case CAM_SEL_TIMEOUT:
-		err_action = SS_FAIL|EIO;
-		break;
-	case CAM_REQ_INVALID:
-	case CAM_PATH_INVALID:
-	case CAM_DEV_NOT_THERE:
-	case CAM_NO_HBA:
-	case CAM_PROVIDE_FAIL:
-	case CAM_REQ_TOO_BIG:		
-	case CAM_RESRC_UNAVAIL:
-	case CAM_BUSY:
-	default:
-		/* panic??  These should never occur in our application. */
-		err_action = SS_FAIL|EIO;
-		break;
-	case CAM_SCSI_BUS_RESET:
-	case CAM_BDR_SENT:		
-	case CAM_REQUEUE_REQ:
-		/* Unconditional requeue */
-		err_action = SS_RETRY;
-		break;
-	}
-
-	return (err_action);
-}
-
 static void
 ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
 		      struct ahc_devinfo *devinfo)
 {
 	memset(cmd, 0, sizeof(struct scsi_cmnd));
-	cmd->host = ahc->platform_data->host;
+	cmd->device = ahc->platform_data->dv_scsi_dev;
 	cmd->scsi_done = ahc_linux_dv_complete;
-	cmd->target = devinfo->target;
-	cmd->lun = devinfo->lun;
-	cmd->channel = devinfo->channel - 'A';
 }
 
 /*
@@ -3327,23 +3272,6 @@
 	cmd->cmnd[4] = le | SSS_START;
 }
 
-/*
- * Return speed in KB/s.
- */
-static u_int
-ahc_linux_calc_speed(u_int width, u_int period, u_int offset)
-{
-	u_int freq;
-
-	if (offset != 0)
-		freq  = aic_calc_syncsrate(period);
-	else
-		/* Roughly 3.3MB/s for async */
-		freq  = 3300;
-	freq <<= width;
-	return (freq);
-}
-
 static int
 ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
 {
@@ -3391,14 +3319,17 @@
 	if (targ->dv_last_ppr_options == 0)
 		targ->dv_last_ppr_options = ppr_options;
 
-	cur_speed = ahc_linux_calc_speed(width, period, offset);
-	wide_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
+	cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN);
+	wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT,
 					  targ->dv_next_wide_period,
-					  MAX_OFFSET);
-	narrow_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
+					  MAX_OFFSET,
+					  AHC_SYNCRATE_MIN);
+	narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT,
 					    targ->dv_next_narrow_period,
-					    MAX_OFFSET);
-	fallback_speed = ahc_linux_calc_speed(width, period+1, offset);
+					    MAX_OFFSET,
+					    AHC_SYNCRATE_MIN);
+	fallback_speed = aic_calc_speed(width, period+1, offset,
+					AHC_SYNCRATE_MIN);
 #ifdef AHC_DEBUG
 	if (ahc_debug & AHC_SHOW_DV) {
 		printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, "
@@ -3532,13 +3463,15 @@
 	struct	scb *scb;
 	u_long	flags;
 
-	ahc = *((struct ahc_softc **)cmd->host->hostdata);
+	ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
 	ahc_lock(ahc, &flags);
 
 #ifdef AHC_DEBUG
-	if (ahc_debug & AHC_SHOW_DV)
+	if (ahc_debug & AHC_SHOW_DV) {
 		printf("%s: Timeout while doing DV command %x.\n",
 		       ahc_name(ahc), cmd->cmnd[0]);
+		ahc_dump_card_state(ahc);
+	}
 #endif
 	
 	/*
@@ -3560,7 +3493,7 @@
 		ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
 	else
 		ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
-	ahc_reset_channel(ahc, cmd->channel + 'A', /*initiate*/TRUE);
+	ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE);
 
 	/*
 	 * Add a minimal bus settle delay for devices that are slow to
@@ -3610,7 +3543,7 @@
 {
 	struct ahc_softc *ahc;
 
-	ahc = *((struct ahc_softc **)cmd->host->hostdata);
+	ahc = *((struct ahc_softc **)cmd->device->host->hostdata);
 
 	/* Delete the DV timer before it goes off! */
 	scsi_delete_timer(cmd);
@@ -3618,7 +3551,8 @@
 #ifdef AHC_DEBUG
 	if (ahc_debug & AHC_SHOW_DV)
 		printf("%s:%d:%d: Command completed, status= 0x%x\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->result);
+		       ahc_name(ahc), cmd->device->channel,
+		       cmd->device->id, cmd->result);
 #endif
 
 	/* Wake up the state machine */
@@ -3834,7 +3768,7 @@
 		 */
 		hscb->control = 0;
 		hscb->scsiid = BUILD_SCSIID(ahc, cmd);
-		hscb->lun = cmd->lun;
+		hscb->lun = cmd->device->lun;
 		mask = SCB_GET_TARGET_MASK(ahc, scb);
 		tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
 					    SCB_GET_OUR_ID(scb),
@@ -4245,7 +4179,34 @@
 		break;
 	}
         case AC_SENT_BDR:
+	{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+		Scsi_Device *scsi_dev;
+
+		/*
+		 * Find the SCSI device associated with this
+		 * request and indicate that a UA is expected.
+		 * XXX This should really be handled by the mid-layer.
+		 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		list_for_each_entry(scsi_dev,
+				    &ahc->platform_data->host->my_devices,
+				    siblings) {
+#else
+		for (scsi_dev = ahc->platform_data->host->host_queue;
+		     scsi_dev != NULL; scsi_dev = scsi_dev->next) {
+#endif
+			if (channel - 'A' == scsi_dev->channel
+			 && target == scsi_dev->id
+			 && (lun == CAM_LUN_WILDCARD
+			  || lun == scsi_dev->lun)) {
+				scsi_dev->was_reset = 1;
+				scsi_dev->expecting_cc_ua = 1;
+			}
+		}
+#endif
 		break;
+	}
         case AC_BUS_RESET:
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
 		if (ahc->platform_data->host != NULL) {
@@ -4371,8 +4332,8 @@
 		if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
 		 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
 			ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
-		if ((scb->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
-			scb->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
+		if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
+			ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
 			up(&ahc->platform_data->eh_sem);
 		}
 	}
@@ -4441,8 +4402,11 @@
 
 				printf("Copied %d bytes of sense data:",
 				       sense_size);
-				for (i = 0; i < sense_size; i++)
-					printf(" 0x%x", cmd->sense_buffer[i]);
+				for (i = 0; i < sense_size; i++) {
+					if ((i & 0xF) == 0)
+						printf("\n");
+					printf("0x%x ", cmd->sense_buffer[i]);
+				}
 				printf("\n");
 			}
 #endif
@@ -4616,7 +4580,8 @@
 			 * evoke a retry even if this command is being sent
 			 * via the eh thread.  Ick!  Ick!  Ick!
 			 */
-			cmd->retries--;
+			if (cmd->retries > 0)
+				cmd->retries--;
 			new_status = DID_OK;
 			ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
 			cmd->result |= (DRIVER_SENSE << 24);
@@ -4851,6 +4816,7 @@
 	u_int  saved_scbptr;
 	u_int  active_scb_index;
 	u_int  last_phase;
+	u_int  saved_scsiid;
 	int    retval;
 	int    paused;
 	int    wait;
@@ -4859,11 +4825,12 @@
 	pending_scb = NULL;
 	paused = FALSE;
 	wait = FALSE;
-	ahc = *(struct ahc_softc **)cmd->host->hostdata;
+	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 	acmd = (struct ahc_cmd *)cmd;
 
 	printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
-	       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun,
+	       ahc_name(ahc), cmd->device->channel,
+	       cmd->device->id, cmd->device->lun,
 	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
 
 	/*
@@ -4892,8 +4859,8 @@
 	 * at all, and the system wanted us to just abort the
 	 * command return success.
 	 */
-	dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target,
-				   cmd->lun, /*alloc*/FALSE);
+	dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
+				   cmd->device->lun, /*alloc*/FALSE);
 
 	if (dev == NULL) {
 		/*
@@ -4901,7 +4868,8 @@
 		 * so we must not still own the command.
 		 */
 		printf("%s:%d:%d:%d: Is not an active device\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		retval = SUCCESS;
 		goto no_cmd;
 	}
@@ -4913,7 +4881,8 @@
 
 	if (list_acmd != NULL) {
 		printf("%s:%d:%d:%d: Command found on device queue\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		if (flag == SCB_ABORT) {
 			TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
 			cmd->result = DID_ABORT << 16;
@@ -4924,11 +4893,13 @@
 	}
 
 	if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
-	 && ahc_search_untagged_queues(ahc, cmd, cmd->target,
-				       cmd->channel + 'A', cmd->lun,
+	 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
+				       cmd->device->channel + 'A',
+				       cmd->device->lun,
 				       CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
 		printf("%s:%d:%d:%d: Command found on untagged queue\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		retval = SUCCESS;
 		goto done;
 	}
@@ -4945,8 +4916,9 @@
 
 		/* Any SCB for this device will do for a target reset */
 		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		  	if (ahc_match_scb(ahc, pending_scb, cmd->target,
-					  cmd->channel + 'A', CAM_LUN_WILDCARD,
+		  	if (ahc_match_scb(ahc, pending_scb, cmd->device->id,
+					  cmd->device->channel + 'A',
+					  CAM_LUN_WILDCARD,
 					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
 				break;
 		}
@@ -4954,7 +4926,8 @@
 
 	if (pending_scb == NULL) {
 		printf("%s:%d:%d:%d: Command not found\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		goto no_cmd;
 	}
 
@@ -4978,24 +4951,28 @@
 
 	if ((pending_scb->flags & SCB_ACTIVE) == 0) {
 		printf("%s:%d:%d:%d: Command already completed\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		goto no_cmd;
 	}
 
 	disconnected = TRUE;
 	if (flag == SCB_ABORT) {
-		if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				       cmd->lun, pending_scb->hscb->tag,
+		if (ahc_search_qinfifo(ahc, cmd->device->id,
+				       cmd->device->channel + 'A',
+				       cmd->device->lun,
+				       pending_scb->hscb->tag,
 				       ROLE_INITIATOR, CAM_REQ_ABORTED,
 				       SEARCH_COMPLETE) > 0) {
 			printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
-			       ahc_name(ahc), cmd->channel, cmd->target,
-					cmd->lun);
+			       ahc_name(ahc), cmd->device->channel,
+					cmd->device->id, cmd->device->lun);
 			retval = SUCCESS;
 			goto done;
 		}
-	} else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				      cmd->lun, pending_scb->hscb->tag,
+	} else if (ahc_search_qinfifo(ahc, cmd->device->id,
+				      cmd->device->channel + 'A',
+				      cmd->device->lun, pending_scb->hscb->tag,
 				      ROLE_INITIATOR, /*status*/0,
 				      SEARCH_COUNT) > 0) {
 		disconnected = FALSE;
@@ -5024,10 +5001,11 @@
 	last_phase = ahc_inb(ahc, LASTPHASE);
 	saved_scbptr = ahc_inb(ahc, SCBPTR);
 	active_scb_index = ahc_inb(ahc, SCB_TAG);
+	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
 	if (last_phase != P_BUSFREE
 	 && (pending_scb->hscb->tag == active_scb_index
 	  || (flag == SCB_DEVICE_RESET
-	   && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) {
+	   && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) {
 
 		/*
 		 * We're active on the bus, so assert ATN
@@ -5038,7 +5016,8 @@
 		ahc_outb(ahc, MSG_OUT, HOST_MSG);
 		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
 		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		wait = TRUE;
 	} else if (disconnected) {
 
@@ -5068,8 +5047,9 @@
 		 * same element in the SCB, SCB_NEXT, for
 		 * both the qinfifo and the disconnected list.
 		 */
-		ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A',
-				     cmd->lun, pending_scb->hscb->tag,
+		ahc_search_disc_list(ahc, cmd->device->id,
+				     cmd->device->channel + 'A',
+				     cmd->device->lun, pending_scb->hscb->tag,
 				     /*stop_on_first*/TRUE,
 				     /*remove*/TRUE,
 				     /*save_state*/FALSE);
@@ -5092,19 +5072,20 @@
 		 * so we are the next SCB for this target
 		 * to run.
 		 */
-		ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A',
-				   cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR,
-				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);
-		ahc_print_path(ahc, pending_scb);
-		printf("Queuing a recovery SCB\n");
+		ahc_search_qinfifo(ahc, cmd->device->id,
+				   cmd->device->channel + 'A',
+				   cmd->device->lun, SCB_LIST_NULL,
+				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
+				   SEARCH_COMPLETE);
 		ahc_qinfifo_requeue_tail(ahc, pending_scb);
 		ahc_outb(ahc, SCBPTR, saved_scbptr);
-		printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		ahc_print_path(ahc, pending_scb);
+		printf("Device is disconnected, re-queuing SCB\n");
 		wait = TRUE;
 	} else {
 		printf("%s:%d:%d:%d: Unable to deliver message\n",
-		       ahc_name(ahc), cmd->channel, cmd->target, cmd->lun);
+		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
+		       cmd->device->lun);
 		retval = FAILED;
 		goto done;
 	}
@@ -5124,7 +5105,7 @@
 		struct timer_list timer;
 		int ret;
 
-		pending_scb->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
+		ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		ahc_unlock(ahc, &s);
 #else
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h	Mon Feb 10 10:39:25 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h	Mon Feb 10 10:39:25 2003
@@ -18,7 +18,7 @@
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  * 
- * Copyright (c) 2000-2001 Adaptec Inc.
+ * Copyright (c) 2000-2003 Adaptec Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#118 $
+ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#123 $
  *
  */
 #ifndef _AIC7XXX_LINUX_H_
@@ -67,9 +67,6 @@
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
 #include <linux/version.h>
-#ifndef AHC_MODVERSION_FILE
-#define __NO_VERSION__
-#endif
 #include <linux/module.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -90,7 +87,6 @@
 #define AIC_LIB_PREFIX ahc
 #include "scsi.h"
 #include "hosts.h"
-#include "aiclib.h"
 
 /* Name space conflict with BSD queue macros */
 #ifdef LIST_HEAD
@@ -100,6 +96,7 @@
 #include "cam.h"
 #include "queue.h"
 #include "scsi_message.h"
+#include "aiclib.h"
 
 /*********************************** Debugging ********************************/
 #ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
@@ -302,7 +299,7 @@
 #include <linux/smp.h>
 #endif
 
-#define AIC7XXX_DRIVER_VERSION "6.2.26"
+#define AIC7XXX_DRIVER_VERSION "6.2.28"
 
 /**************************** Front End Queues ********************************/
 /*
@@ -337,7 +334,7 @@
 /*
  * A per probed device structure used to deal with some error recovery
  * scenarios that the Linux mid-layer code just doesn't know how to
- * handle.  The structure allocated for a device only becomes persistant
+ * handle.  The structure allocated for a device only becomes persistent
  * after a successfully completed inquiry command to the target when
  * that inquiry data indicates a lun is present.
  */
@@ -497,7 +494,7 @@
  * Per-SCB OSM storage.
  */
 typedef enum {
-	AHC_UP_EH_SEMAPHORE
+	AHC_UP_EH_SEMAPHORE = 0x1
 } ahc_linux_scb_flags;
 
 struct scb_platform_data {
@@ -550,6 +547,7 @@
 	struct semaphore	 dv_cmd_sem;	/* XXX This needs to be in
 						 * the target struct
 						 */
+	struct scsi_device	*dv_scsi_dev;
 	struct Scsi_Host        *host;		/* pointer to scsi host */
 #define AHC_LINUX_NOIRQ	((uint32_t)~0)
 	uint32_t		 irq;		/* IRQ for this adapter */
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c	Mon Feb 10 10:39:23 2003
@@ -39,7 +39,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#55 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $
  *
  * $FreeBSD$
  */
@@ -641,6 +641,7 @@
 #define AHC_494X_SLOT_CHANNEL_D	7
 
 #define	DEVCONFIG		0x40
+#define		PCIERRGENDIS	0x80000000ul
 #define		SCBSIZE32	0x00010000ul	/* aic789X only */
 #define		REXTVALID	0x00001000ul	/* ultra cards only */
 #define		MPORTMODE	0x00000400ul	/* aic7870+ only */
@@ -785,6 +786,7 @@
 	u_int	 sxfrctl1;
 	u_int	 scsiseq;
 	u_int	 dscommand0;
+	uint32_t devconfig;
 	int	 error;
 	uint8_t	 sblkctl;
 
@@ -809,6 +811,8 @@
 	 */
 	ahc_intr_enable(ahc, FALSE);
 
+	devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
+
 	/*
 	 * If we need to support high memory, enable dual
 	 * address cycles.  This bit must be set to enable
@@ -816,21 +820,30 @@
 	 * 64bit bus (PCI64BIT set in devconfig).
 	 */
 	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
-		uint32_t devconfig;
 
 		if (bootverbose)
 			printf("%s: Enabling 39Bit Addressing\n",
 			       ahc_name(ahc));
-		devconfig = ahc_pci_read_config(ahc->dev_softc,
-						DEVCONFIG, /*bytes*/4);
 		devconfig |= DACEN;
-		ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
-				     devconfig, /*bytes*/4);
 	}
 	
+	/* Ensure that pci error generation, a test feature, is disabled. */
+	devconfig |= PCIERRGENDIS;
+
+	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
+
 	/* Ensure busmastering is enabled */
 	command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
 	command |= PCIM_CMD_BUSMASTEREN;
+
+	/*
+	 * Disable PCI parity error reporting.  Users typically
+	 * do this to work around broken PCI chipsets that get
+	 * the parity timing wrong and thus generate lots of spurious
+	 * errors.
+	 */
+	if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0)
+		command &= ~PCIM_CMD_PERRESPEN;
 	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1);
 
 	/* On all PCI adapters, we allow SCB paging */
@@ -947,7 +960,8 @@
 		 * a SEEPROM.
 		 */
 		/* See if someone else set us up already */
-		if (scsiseq != 0) {
+		if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
+		 && scsiseq != 0) {
 			printf("%s: Using left over BIOS settings\n",
 				ahc_name(ahc));
 			ahc->flags &= ~AHC_USEDEFAULTS;
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped
--- a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped	Mon Feb 10 10:39:29 2003
@@ -2,7 +2,7 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $
  */
 typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped
--- a/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped	Mon Feb 10 10:39:27 2003
@@ -2,7 +2,7 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $
  */
 
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped
--- a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped	Mon Feb 10 10:39:33 2003
@@ -2,13 +2,13 @@
  * DO NOT EDIT - This file is automatically generated
  *		 from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
  * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $
  */
 static uint8_t seqprog[] = {
 	0xb2, 0x00, 0x00, 0x08,
 	0xf7, 0x11, 0x22, 0x08,
-	0x00, 0x65, 0xea, 0x59,
+	0x00, 0x65, 0xec, 0x59,
 	0xf7, 0x01, 0x02, 0x08,
 	0xff, 0x6a, 0x24, 0x08,
 	0x40, 0x00, 0x40, 0x68,
@@ -21,15 +21,15 @@
 	0x01, 0x4d, 0xc8, 0x30,
 	0x00, 0x4c, 0x12, 0x70,
 	0x01, 0x39, 0xa2, 0x30,
-	0x00, 0x6a, 0xd2, 0x5e,
+	0x00, 0x6a, 0xd4, 0x5e,
 	0x01, 0x51, 0x20, 0x31,
 	0x01, 0x57, 0xae, 0x00,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x24, 0x5e,
+	0x00, 0x51, 0x26, 0x5e,
 	0x01, 0x51, 0xc8, 0x30,
 	0x00, 0x39, 0xc8, 0x60,
 	0x00, 0xbb, 0x30, 0x70,
-	0xc1, 0x6a, 0xea, 0x5e,
+	0xc1, 0x6a, 0xec, 0x5e,
 	0x01, 0xbf, 0x72, 0x30,
 	0x01, 0x40, 0x7e, 0x31,
 	0x01, 0x90, 0x80, 0x30,
@@ -46,13 +46,13 @@
 	0x80, 0x0b, 0xb6, 0x78,
 	0x20, 0x6a, 0x16, 0x00,
 	0xa4, 0x6a, 0x06, 0x00,
-	0x08, 0x3c, 0x78, 0x00,
+	0x08, 0x6a, 0x78, 0x00,
 	0x01, 0x50, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x0e, 0x5e,
+	0x48, 0x6a, 0x10, 0x5e,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x0e, 0x5e,
+	0x48, 0x6a, 0x10, 0x5e,
 	0x01, 0x6a, 0x26, 0x01,
 	0xf0, 0x19, 0x7a, 0x08,
 	0x0f, 0x18, 0xc8, 0x08,
@@ -63,7 +63,7 @@
 	0x80, 0x3d, 0x7a, 0x00,
 	0x01, 0x3d, 0xd8, 0x31,
 	0x01, 0x3d, 0x32, 0x31,
-	0x10, 0x03, 0x4c, 0x79,
+	0x10, 0x03, 0x4e, 0x79,
 	0x00, 0x65, 0xf2, 0x58,
 	0x80, 0x66, 0xae, 0x78,
 	0x01, 0x66, 0xd8, 0x31,
@@ -79,7 +79,7 @@
 	0x00, 0x65, 0xaa, 0x48,
 	0x01, 0x66, 0xd8, 0x31,
 	0x01, 0x66, 0x32, 0x31,
-	0x10, 0x03, 0x4c, 0x79,
+	0x10, 0x03, 0x4e, 0x79,
 	0x00, 0x65, 0xf2, 0x58,
 	0x01, 0x66, 0xd8, 0x31,
 	0x01, 0x66, 0x32, 0x31,
@@ -87,13 +87,13 @@
 	0x40, 0x3c, 0x78, 0x00,
 	0xff, 0x6a, 0xd8, 0x01,
 	0xff, 0x6a, 0x32, 0x01,
-	0x10, 0x6a, 0x78, 0x00,
+	0x10, 0x3c, 0x78, 0x00,
 	0x02, 0x57, 0x40, 0x69,
 	0x10, 0x03, 0x3e, 0x69,
 	0x00, 0x65, 0x20, 0x41,
 	0x02, 0x57, 0xae, 0x00,
 	0x00, 0x65, 0x9e, 0x40,
-	0x61, 0x6a, 0xea, 0x5e,
+	0x61, 0x6a, 0xec, 0x5e,
 	0x08, 0x51, 0x20, 0x71,
 	0x02, 0x0b, 0xb2, 0x78,
 	0x00, 0x65, 0xae, 0x40,
@@ -105,8 +105,8 @@
 	0x08, 0x1f, 0xc4, 0x78,
 	0x80, 0x3d, 0x7a, 0x00,
 	0x20, 0x6a, 0x16, 0x00,
-	0x00, 0x65, 0xca, 0x41,
-	0x00, 0x65, 0xc4, 0x5e,
+	0x00, 0x65, 0xcc, 0x41,
+	0x00, 0x65, 0xc6, 0x5e,
 	0x00, 0x65, 0x12, 0x40,
 	0x20, 0x11, 0xd2, 0x68,
 	0x20, 0x6a, 0x18, 0x00,
@@ -137,57 +137,58 @@
 	0x01, 0xb9, 0x7a, 0x30,
 	0x01, 0xba, 0x7c, 0x30,
 	0x00, 0x65, 0xea, 0x58,
-	0x80, 0x0b, 0xc2, 0x79,
+	0x80, 0x0b, 0xc4, 0x79,
 	0x12, 0x01, 0x02, 0x00,
 	0x01, 0xab, 0xac, 0x30,
-	0xe4, 0x6a, 0x80, 0x5d,
+	0xe4, 0x6a, 0x82, 0x5d,
 	0x40, 0x6a, 0x16, 0x00,
-	0x80, 0xba, 0x96, 0x5d,
+	0x80, 0xba, 0x98, 0x5d,
 	0x20, 0xb8, 0x18, 0x79,
-	0x20, 0x6a, 0x96, 0x5d,
-	0x00, 0xab, 0x96, 0x5d,
+	0x20, 0x6a, 0x98, 0x5d,
+	0x00, 0xab, 0x98, 0x5d,
 	0x01, 0xa9, 0x78, 0x30,
 	0x10, 0xb8, 0x20, 0x79,
-	0xe4, 0x6a, 0x80, 0x5d,
+	0xe4, 0x6a, 0x82, 0x5d,
 	0x00, 0x65, 0xae, 0x40,
 	0x10, 0x03, 0x3c, 0x69,
-	0x08, 0x3c, 0x58, 0x69,
-	0x04, 0x3c, 0x90, 0x69,
-	0x02, 0x3c, 0x96, 0x69,
-	0x01, 0x3c, 0x42, 0x79,
+	0x08, 0x3c, 0x5a, 0x69,
+	0x04, 0x3c, 0x92, 0x69,
+	0x02, 0x3c, 0x98, 0x69,
+	0x01, 0x3c, 0x44, 0x79,
 	0xff, 0x6a, 0x70, 0x00,
-	0x00, 0x65, 0xa2, 0x59,
-	0x00, 0x6a, 0xd2, 0x5e,
+	0x00, 0x65, 0xa4, 0x59,
+	0x00, 0x6a, 0xd4, 0x5e,
 	0xff, 0x38, 0x30, 0x71,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x38, 0x24, 0x5e,
+	0x00, 0x38, 0x26, 0x5e,
 	0x00, 0x65, 0xea, 0x58,
 	0x12, 0x01, 0x02, 0x00,
 	0x00, 0x65, 0x18, 0x41,
 	0xa4, 0x6a, 0x06, 0x00,
 	0x00, 0x65, 0xf2, 0x58,
+	0xfd, 0x57, 0xae, 0x08,
 	0x00, 0x65, 0xae, 0x40,
-	0xe4, 0x6a, 0x80, 0x5d,
-	0x20, 0x3c, 0x48, 0x79,
-	0x02, 0x6a, 0x96, 0x5d,
-	0x04, 0x6a, 0x96, 0x5d,
-	0x01, 0x03, 0x4a, 0x69,
+	0xe4, 0x6a, 0x82, 0x5d,
+	0x20, 0x3c, 0x4a, 0x79,
+	0x02, 0x6a, 0x98, 0x5d,
+	0x04, 0x6a, 0x98, 0x5d,
+	0x01, 0x03, 0x4c, 0x69,
 	0xf7, 0x11, 0x22, 0x08,
 	0xff, 0x6a, 0x24, 0x08,
 	0xff, 0x6a, 0x06, 0x08,
 	0x01, 0x6a, 0x7e, 0x00,
-	0x00, 0x65, 0xa2, 0x59,
+	0x00, 0x65, 0xa4, 0x59,
 	0x00, 0x65, 0x04, 0x40,
 	0x80, 0x86, 0xc8, 0x08,
 	0x01, 0x4f, 0xc8, 0x30,
-	0x00, 0x50, 0x6a, 0x61,
-	0xc4, 0x6a, 0x80, 0x5d,
-	0x40, 0x3c, 0x66, 0x79,
-	0x28, 0x6a, 0x96, 0x5d,
-	0x00, 0x65, 0x4a, 0x41,
-	0x08, 0x6a, 0x96, 0x5d,
-	0x00, 0x65, 0x4a, 0x41,
-	0x84, 0x6a, 0x80, 0x5d,
+	0x00, 0x50, 0x6c, 0x61,
+	0xc4, 0x6a, 0x82, 0x5d,
+	0x40, 0x3c, 0x68, 0x79,
+	0x28, 0x6a, 0x98, 0x5d,
+	0x00, 0x65, 0x4c, 0x41,
+	0x08, 0x6a, 0x98, 0x5d,
+	0x00, 0x65, 0x4c, 0x41,
+	0x84, 0x6a, 0x82, 0x5d,
 	0x00, 0x65, 0xf2, 0x58,
 	0x01, 0x66, 0xc8, 0x30,
 	0x01, 0x64, 0xd8, 0x31,
@@ -195,62 +196,62 @@
 	0x5b, 0x64, 0xc8, 0x28,
 	0x30, 0x64, 0xca, 0x18,
 	0x01, 0x6c, 0xc8, 0x30,
-	0xff, 0x64, 0x8c, 0x79,
+	0xff, 0x64, 0x8e, 0x79,
 	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x7e, 0x79,
-	0x01, 0x64, 0x84, 0x61,
+	0x02, 0x0b, 0x80, 0x79,
+	0x01, 0x64, 0x86, 0x61,
 	0xf7, 0x01, 0x02, 0x08,
 	0x01, 0x06, 0xd8, 0x31,
 	0x01, 0x06, 0x32, 0x31,
 	0xff, 0x64, 0xc8, 0x18,
-	0xff, 0x64, 0x7e, 0x69,
+	0xff, 0x64, 0x80, 0x69,
 	0xf7, 0x3c, 0x78, 0x08,
 	0x00, 0x65, 0x20, 0x41,
 	0x40, 0xaa, 0x7e, 0x10,
-	0x04, 0xaa, 0x80, 0x5d,
-	0x00, 0x65, 0x5c, 0x42,
-	0xc4, 0x6a, 0x80, 0x5d,
+	0x04, 0xaa, 0x82, 0x5d,
+	0x00, 0x65, 0x5e, 0x42,
+	0xc4, 0x6a, 0x82, 0x5d,
 	0xc0, 0x6a, 0x7e, 0x00,
-	0x00, 0xa8, 0x96, 0x5d,
+	0x00, 0xa8, 0x98, 0x5d,
 	0xe4, 0x6a, 0x06, 0x00,
-	0x00, 0x6a, 0x96, 0x5d,
-	0x00, 0x65, 0x4a, 0x41,
-	0x10, 0x3c, 0xa6, 0x69,
-	0x00, 0xbb, 0x9c, 0x44,
+	0x00, 0x6a, 0x98, 0x5d,
+	0x00, 0x65, 0x4c, 0x41,
+	0x10, 0x3c, 0xa8, 0x69,
+	0x00, 0xbb, 0x9e, 0x44,
 	0x18, 0x6a, 0xda, 0x01,
 	0x01, 0x69, 0xd8, 0x31,
 	0x1c, 0x6a, 0xd0, 0x01,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0xae, 0x79,
+	0x80, 0xee, 0xb0, 0x79,
 	0xff, 0x6a, 0xdc, 0x09,
 	0x01, 0x93, 0x26, 0x01,
 	0x03, 0x6a, 0x2a, 0x01,
 	0x01, 0x69, 0x32, 0x31,
-	0x1c, 0x6a, 0xf2, 0x5d,
+	0x1c, 0x6a, 0xf4, 0x5d,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xba, 0x5e,
+	0x00, 0x65, 0xbc, 0x5e,
 	0x01, 0x50, 0xa0, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
 	0x1a, 0x01, 0x02, 0x00,
 	0x80, 0x6a, 0x74, 0x00,
 	0x40, 0x6a, 0x78, 0x00,
 	0x40, 0x6a, 0x16, 0x00,
-	0x00, 0x65, 0xea, 0x5d,
+	0x00, 0x65, 0xec, 0x5d,
 	0x01, 0x3f, 0xc8, 0x30,
-	0xbf, 0x64, 0x5c, 0x7a,
-	0x80, 0x64, 0xb0, 0x73,
-	0xa0, 0x64, 0x12, 0x74,
-	0xc0, 0x64, 0x06, 0x74,
-	0xe0, 0x64, 0x42, 0x74,
-	0x01, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0xca, 0x41,
+	0xbf, 0x64, 0x5e, 0x7a,
+	0x80, 0x64, 0xb2, 0x73,
+	0xa0, 0x64, 0x14, 0x74,
+	0xc0, 0x64, 0x08, 0x74,
+	0xe0, 0x64, 0x44, 0x74,
+	0x01, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0xcc, 0x41,
 	0xf7, 0x11, 0x22, 0x08,
 	0x01, 0x06, 0xd4, 0x30,
 	0xff, 0x6a, 0x24, 0x08,
 	0xf7, 0x01, 0x02, 0x08,
-	0x09, 0x0c, 0xe4, 0x79,
+	0x09, 0x0c, 0xe6, 0x79,
 	0x08, 0x0c, 0x04, 0x68,
-	0xb1, 0x6a, 0xea, 0x5e,
+	0xb1, 0x6a, 0xec, 0x5e,
 	0xff, 0x6a, 0x26, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0x02, 0x6a, 0x08, 0x30,
@@ -263,33 +264,33 @@
 	0x00, 0xa5, 0x4a, 0x21,
 	0x00, 0xa6, 0x4c, 0x21,
 	0x00, 0xa7, 0x4e, 0x25,
-	0x08, 0xeb, 0xee, 0x7e,
-	0x80, 0xeb, 0x04, 0x7a,
+	0x08, 0xeb, 0xf0, 0x7e,
+	0x80, 0xeb, 0x06, 0x7a,
 	0xff, 0x6a, 0xd6, 0x09,
-	0x08, 0xeb, 0x08, 0x6a,
+	0x08, 0xeb, 0x0a, 0x6a,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x80, 0xa3, 0xee, 0x6e,
-	0x88, 0xeb, 0x1e, 0x72,
-	0x08, 0xeb, 0xee, 0x6e,
-	0x04, 0xea, 0x22, 0xe2,
-	0x08, 0xee, 0xee, 0x6e,
+	0x80, 0xa3, 0xf0, 0x6e,
+	0x88, 0xeb, 0x20, 0x72,
+	0x08, 0xeb, 0xf0, 0x6e,
+	0x04, 0xea, 0x24, 0xe2,
+	0x08, 0xee, 0xf0, 0x6e,
 	0x04, 0x6a, 0xd0, 0x81,
 	0x05, 0xa4, 0xc0, 0x89,
 	0x03, 0xa5, 0xc2, 0x31,
 	0x09, 0x6a, 0xd6, 0x05,
-	0x00, 0x65, 0x06, 0x5a,
+	0x00, 0x65, 0x08, 0x5a,
 	0x06, 0xa4, 0xd4, 0x89,
-	0x80, 0x94, 0xee, 0x7e,
+	0x80, 0x94, 0xf0, 0x7e,
 	0x07, 0xe9, 0x10, 0x31,
-	0x01, 0x8c, 0x2a, 0x7a,
+	0x01, 0x8c, 0x2c, 0x7a,
 	0x01, 0x55, 0xaa, 0x10,
 	0x01, 0xe9, 0x46, 0x31,
-	0x00, 0xa3, 0xcc, 0x5e,
-	0x00, 0x65, 0xf8, 0x59,
+	0x00, 0xa3, 0xce, 0x5e,
+	0x00, 0x65, 0xfa, 0x59,
 	0x01, 0xa4, 0xca, 0x30,
-	0x01, 0x55, 0x36, 0x7a,
+	0x01, 0x55, 0x38, 0x7a,
 	0x04, 0x65, 0xca, 0x00,
-	0x80, 0xa3, 0x3a, 0x7a,
+	0x80, 0xa3, 0x3c, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x80, 0x93, 0x26, 0x01,
@@ -297,168 +298,168 @@
 	0x01, 0x8c, 0xc8, 0x30,
 	0x00, 0x88, 0xc8, 0x18,
 	0x02, 0x64, 0xc8, 0x88,
-	0xff, 0x64, 0xee, 0x7e,
-	0xff, 0x8d, 0x50, 0x6a,
-	0xff, 0x8e, 0x50, 0x6a,
+	0xff, 0x64, 0xf0, 0x7e,
+	0xff, 0x8d, 0x52, 0x6a,
+	0xff, 0x8e, 0x52, 0x6a,
 	0x03, 0x8c, 0xd4, 0x98,
-	0x00, 0x65, 0xee, 0x56,
+	0x00, 0x65, 0xf0, 0x56,
 	0x01, 0x64, 0x70, 0x30,
 	0xff, 0x64, 0xc8, 0x10,
 	0x01, 0x64, 0xc8, 0x18,
 	0x00, 0x8c, 0x18, 0x19,
 	0xff, 0x8d, 0x1a, 0x21,
 	0xff, 0x8e, 0x1c, 0x25,
-	0xc0, 0x3c, 0x60, 0x7a,
-	0x21, 0x6a, 0xea, 0x5e,
+	0xc0, 0x3c, 0x62, 0x7a,
+	0x21, 0x6a, 0xec, 0x5e,
 	0xa8, 0x6a, 0x76, 0x00,
 	0x79, 0x6a, 0x76, 0x00,
-	0x40, 0x3f, 0x68, 0x6a,
+	0x40, 0x3f, 0x6a, 0x6a,
 	0x04, 0x3b, 0x76, 0x00,
 	0x04, 0x6a, 0xd4, 0x81,
-	0x20, 0x3c, 0x70, 0x7a,
-	0x51, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0x8a, 0x42,
+	0x20, 0x3c, 0x72, 0x7a,
+	0x51, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0x8c, 0x42,
 	0x20, 0x3c, 0x78, 0x00,
-	0x00, 0xb3, 0xcc, 0x5e,
+	0x00, 0xb3, 0xce, 0x5e,
 	0x07, 0xac, 0x10, 0x31,
 	0x05, 0xb3, 0x46, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xac, 0x6a, 0x00, 0x5e,
+	0xac, 0x6a, 0x02, 0x5e,
 	0xa3, 0x6a, 0xcc, 0x00,
-	0xb3, 0x6a, 0x04, 0x5e,
-	0x00, 0x65, 0x40, 0x5a,
+	0xb3, 0x6a, 0x06, 0x5e,
+	0x00, 0x65, 0x42, 0x5a,
 	0xfd, 0xa4, 0x48, 0x09,
 	0x01, 0x8c, 0xaa, 0x08,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xf8, 0x5d,
-	0x01, 0xa4, 0x9c, 0x7a,
+	0x00, 0x65, 0xfa, 0x5d,
+	0x01, 0xa4, 0x9e, 0x7a,
 	0x04, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
 	0x80, 0x02, 0x04, 0x00,
-	0x10, 0x0c, 0x92, 0x7a,
-	0x03, 0x9e, 0x94, 0x6a,
+	0x10, 0x0c, 0x94, 0x7a,
+	0x03, 0x9e, 0x96, 0x6a,
 	0x7f, 0x02, 0x04, 0x08,
-	0x91, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0xca, 0x41,
+	0x91, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0xcc, 0x41,
 	0x01, 0xa4, 0xca, 0x30,
-	0x80, 0xa3, 0xa2, 0x7a,
+	0x80, 0xa3, 0xa4, 0x7a,
 	0x02, 0x65, 0xca, 0x00,
-	0x01, 0x55, 0xa6, 0x7a,
+	0x01, 0x55, 0xa8, 0x7a,
 	0x04, 0x65, 0xca, 0x00,
 	0x01, 0x65, 0xf8, 0x31,
 	0x01, 0x3b, 0x26, 0x31,
-	0x00, 0x65, 0x0c, 0x5a,
-	0x01, 0xfc, 0xb4, 0x6a,
-	0x80, 0x0b, 0xaa, 0x6a,
-	0x10, 0x0c, 0xaa, 0x7a,
-	0x20, 0x93, 0xaa, 0x6a,
+	0x00, 0x65, 0x0e, 0x5a,
+	0x01, 0xfc, 0xb6, 0x6a,
+	0x80, 0x0b, 0xac, 0x6a,
+	0x10, 0x0c, 0xac, 0x7a,
+	0x20, 0x93, 0xac, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x02, 0xfc, 0xbe, 0x7a,
-	0x40, 0x0d, 0xd8, 0x6a,
+	0x02, 0xfc, 0xc0, 0x7a,
+	0x40, 0x0d, 0xda, 0x6a,
 	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0xd8, 0x42,
-	0x40, 0x0d, 0xc4, 0x6a,
-	0x00, 0x65, 0x0c, 0x5a,
-	0x00, 0x65, 0xb6, 0x42,
-	0x80, 0xfc, 0xce, 0x7a,
-	0x80, 0xa4, 0xce, 0x6a,
+	0x00, 0x65, 0xda, 0x42,
+	0x40, 0x0d, 0xc6, 0x6a,
+	0x00, 0x65, 0x0e, 0x5a,
+	0x00, 0x65, 0xb8, 0x42,
+	0x80, 0xfc, 0xd0, 0x7a,
+	0x80, 0xa4, 0xd0, 0x6a,
 	0xff, 0xa5, 0x4a, 0x19,
 	0xff, 0xa6, 0x4c, 0x21,
 	0xff, 0xa7, 0x4e, 0x21,
 	0xf8, 0xfc, 0x48, 0x09,
 	0xff, 0x6a, 0xaa, 0x08,
-	0x04, 0xfc, 0xd6, 0x7a,
+	0x04, 0xfc, 0xd8, 0x7a,
 	0x01, 0x55, 0xaa, 0x00,
 	0xff, 0x6a, 0x46, 0x09,
-	0x04, 0x3b, 0xf0, 0x6a,
+	0x04, 0x3b, 0xf2, 0x6a,
 	0x02, 0x93, 0x26, 0x01,
-	0x01, 0x94, 0xda, 0x7a,
-	0x01, 0x94, 0xda, 0x7a,
-	0x01, 0x94, 0xda, 0x7a,
-	0x01, 0x94, 0xda, 0x7a,
-	0x01, 0x94, 0xda, 0x7a,
-	0x01, 0xa4, 0xee, 0x7a,
-	0x01, 0xfc, 0xe8, 0x7a,
-	0x01, 0x94, 0xf0, 0x6a,
-	0x00, 0x65, 0x8a, 0x42,
-	0x01, 0x94, 0xee, 0x7a,
-	0x10, 0x94, 0xf0, 0x6a,
+	0x01, 0x94, 0xdc, 0x7a,
+	0x01, 0x94, 0xdc, 0x7a,
+	0x01, 0x94, 0xdc, 0x7a,
+	0x01, 0x94, 0xdc, 0x7a,
+	0x01, 0x94, 0xdc, 0x7a,
+	0x01, 0xa4, 0xf0, 0x7a,
+	0x01, 0xfc, 0xea, 0x7a,
+	0x01, 0x94, 0xf2, 0x6a,
+	0x00, 0x65, 0x8c, 0x42,
+	0x01, 0x94, 0xf0, 0x7a,
+	0x10, 0x94, 0xf2, 0x6a,
 	0xd7, 0x93, 0x26, 0x09,
-	0x28, 0x93, 0xf4, 0x6a,
+	0x28, 0x93, 0xf6, 0x6a,
 	0x01, 0x85, 0x0a, 0x01,
-	0x02, 0xfc, 0xfc, 0x6a,
+	0x02, 0xfc, 0xfe, 0x6a,
 	0x01, 0x14, 0x46, 0x31,
 	0xff, 0x6a, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x09,
-	0xff, 0x38, 0x0a, 0x6b,
-	0x80, 0xa3, 0x0a, 0x7b,
-	0x80, 0x0b, 0x08, 0x7b,
-	0x04, 0x3b, 0x0a, 0x7b,
+	0xff, 0x38, 0x0c, 0x6b,
+	0x80, 0xa3, 0x0c, 0x7b,
+	0x80, 0x0b, 0x0a, 0x7b,
+	0x04, 0x3b, 0x0c, 0x7b,
 	0xbf, 0x3b, 0x76, 0x08,
 	0x01, 0x3b, 0x26, 0x31,
-	0x00, 0x65, 0x0c, 0x5a,
-	0x01, 0x0b, 0x18, 0x6b,
-	0x10, 0x0c, 0x0c, 0x7b,
-	0x04, 0x93, 0x16, 0x6b,
-	0x01, 0x94, 0x14, 0x7b,
-	0x10, 0x94, 0x16, 0x6b,
+	0x00, 0x65, 0x0e, 0x5a,
+	0x01, 0x0b, 0x1a, 0x6b,
+	0x10, 0x0c, 0x0e, 0x7b,
+	0x04, 0x93, 0x18, 0x6b,
+	0x01, 0x94, 0x16, 0x7b,
+	0x10, 0x94, 0x18, 0x6b,
 	0xc7, 0x93, 0x26, 0x09,
 	0x01, 0x99, 0xd4, 0x30,
-	0x38, 0x93, 0x1a, 0x6b,
-	0xff, 0x08, 0x6c, 0x6b,
-	0xff, 0x09, 0x6c, 0x6b,
-	0xff, 0x0a, 0x6c, 0x6b,
-	0xff, 0x38, 0x36, 0x7b,
+	0x38, 0x93, 0x1c, 0x6b,
+	0xff, 0x08, 0x6e, 0x6b,
+	0xff, 0x09, 0x6e, 0x6b,
+	0xff, 0x0a, 0x6e, 0x6b,
+	0xff, 0x38, 0x38, 0x7b,
 	0x04, 0x14, 0x10, 0x31,
 	0x01, 0x38, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0x06, 0x5e,
-	0x00, 0x38, 0xf2, 0x5d,
+	0x14, 0x6a, 0x08, 0x5e,
+	0x00, 0x38, 0xf4, 0x5d,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x62, 0x43,
-	0x80, 0xa3, 0x3c, 0x7b,
+	0x00, 0x65, 0x64, 0x43,
+	0x80, 0xa3, 0x3e, 0x7b,
 	0x01, 0xa4, 0x48, 0x01,
-	0x00, 0x65, 0x6c, 0x43,
-	0x08, 0xeb, 0x42, 0x7b,
-	0x00, 0x65, 0x0c, 0x5a,
-	0x08, 0xeb, 0x3e, 0x6b,
+	0x00, 0x65, 0x6e, 0x43,
+	0x08, 0xeb, 0x44, 0x7b,
+	0x00, 0x65, 0x0e, 0x5a,
+	0x08, 0xeb, 0x40, 0x6b,
 	0x07, 0xe9, 0x10, 0x31,
 	0x01, 0xe9, 0xca, 0x30,
 	0x01, 0x65, 0x46, 0x31,
-	0x00, 0x6a, 0xcc, 0x5e,
+	0x00, 0x6a, 0xce, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa4, 0x6a, 0x06, 0x5e,
-	0x08, 0x6a, 0xf2, 0x5d,
+	0xa4, 0x6a, 0x08, 0x5e,
+	0x08, 0x6a, 0xf4, 0x5d,
 	0x0d, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xba, 0x5e,
+	0x00, 0x65, 0xbc, 0x5e,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x00, 0x65, 0x9c, 0x5e,
+	0x00, 0x65, 0x9e, 0x5e,
 	0x01, 0x99, 0x46, 0x31,
-	0x00, 0xa3, 0xcc, 0x5e,
+	0x00, 0xa3, 0xce, 0x5e,
 	0x01, 0x88, 0x10, 0x31,
-	0x00, 0x65, 0x40, 0x5a,
-	0x00, 0x65, 0xf8, 0x59,
+	0x00, 0x65, 0x42, 0x5a,
+	0x00, 0x65, 0xfa, 0x59,
 	0x03, 0x8c, 0x10, 0x30,
-	0x00, 0x65, 0xf8, 0x5d,
-	0x01, 0x8c, 0x6a, 0x7b,
+	0x00, 0x65, 0xfa, 0x5d,
+	0x01, 0x8c, 0x6c, 0x7b,
 	0x01, 0x55, 0xaa, 0x10,
-	0x80, 0x0b, 0x8a, 0x6a,
-	0x80, 0x0b, 0x74, 0x6b,
-	0x01, 0x0c, 0x6e, 0x7b,
-	0x10, 0x0c, 0x8a, 0x7a,
-	0x03, 0x9e, 0x8a, 0x6a,
-	0x00, 0x65, 0x02, 0x5a,
-	0x00, 0x6a, 0xcc, 0x5e,
-	0x01, 0xa4, 0x94, 0x6b,
-	0xff, 0x38, 0x8a, 0x7b,
+	0x80, 0x0b, 0x8c, 0x6a,
+	0x80, 0x0b, 0x76, 0x6b,
+	0x01, 0x0c, 0x70, 0x7b,
+	0x10, 0x0c, 0x8c, 0x7a,
+	0x03, 0x9e, 0x8c, 0x6a,
+	0x00, 0x65, 0x04, 0x5a,
+	0x00, 0x6a, 0xce, 0x5e,
+	0x01, 0xa4, 0x96, 0x6b,
+	0xff, 0x38, 0x8c, 0x7b,
 	0x01, 0x38, 0xc8, 0x30,
 	0x00, 0x08, 0x40, 0x19,
 	0xff, 0x6a, 0xc8, 0x08,
 	0x00, 0x09, 0x42, 0x21,
 	0x00, 0x0a, 0x44, 0x21,
 	0xff, 0x6a, 0x70, 0x08,
-	0x00, 0x65, 0x8c, 0x43,
+	0x00, 0x65, 0x8e, 0x43,
 	0x03, 0x08, 0x40, 0x31,
 	0x03, 0x08, 0x40, 0x31,
 	0x01, 0x08, 0x40, 0x31,
@@ -467,19 +468,19 @@
 	0xfd, 0xb4, 0x68, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0x12, 0x01, 0x02, 0x00,
-	0x04, 0x3c, 0xca, 0x79,
+	0x04, 0x3c, 0xcc, 0x79,
 	0xfb, 0x3c, 0x78, 0x08,
 	0x04, 0x93, 0x20, 0x79,
-	0x01, 0x0c, 0xa0, 0x6b,
+	0x01, 0x0c, 0xa2, 0x6b,
 	0x01, 0x55, 0x20, 0x79,
 	0x80, 0x04, 0x20, 0x79,
-	0xe4, 0x6a, 0x80, 0x5d,
-	0x23, 0x6a, 0x96, 0x5d,
-	0x01, 0x6a, 0x96, 0x5d,
+	0xe4, 0x6a, 0x82, 0x5d,
+	0x23, 0x6a, 0x98, 0x5d,
+	0x01, 0x6a, 0x98, 0x5d,
 	0x00, 0x65, 0x20, 0x41,
-	0x00, 0x65, 0xca, 0x41,
-	0x80, 0x3c, 0xb4, 0x7b,
-	0x21, 0x6a, 0xea, 0x5e,
+	0x00, 0x65, 0xcc, 0x41,
+	0x80, 0x3c, 0xb6, 0x7b,
+	0x21, 0x6a, 0xec, 0x5e,
 	0x01, 0xbc, 0x18, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x02, 0x6a, 0xf8, 0x01,
@@ -489,16 +490,16 @@
 	0xff, 0x6a, 0x12, 0x08,
 	0xff, 0x6a, 0x14, 0x08,
 	0xf3, 0xbc, 0xd4, 0x18,
-	0xa0, 0x6a, 0xda, 0x53,
+	0xa0, 0x6a, 0xdc, 0x53,
 	0x04, 0xa0, 0x10, 0x31,
 	0xac, 0x6a, 0x26, 0x01,
 	0x04, 0xa0, 0x10, 0x31,
 	0x03, 0x08, 0x18, 0x31,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xa0, 0x6a, 0x06, 0x5e,
-	0x00, 0xbc, 0xf2, 0x5d,
+	0xa0, 0x6a, 0x08, 0x5e,
+	0x00, 0xbc, 0xf4, 0x5d,
 	0x3d, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xf2, 0x43,
+	0x00, 0x65, 0xf4, 0x43,
 	0xff, 0x6a, 0x10, 0x09,
 	0xa4, 0x6a, 0x26, 0x01,
 	0x0c, 0xa0, 0x32, 0x31,
@@ -508,128 +509,128 @@
 	0x36, 0x6a, 0x26, 0x01,
 	0x02, 0x93, 0x26, 0x01,
 	0x35, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xae, 0x5e,
-	0x00, 0x65, 0xae, 0x5e,
+	0x00, 0x65, 0xb0, 0x5e,
+	0x00, 0x65, 0xb0, 0x5e,
 	0x02, 0x93, 0x26, 0x01,
 	0xbf, 0x3c, 0x78, 0x08,
-	0x04, 0x0b, 0xf8, 0x6b,
-	0x10, 0x0c, 0xf4, 0x7b,
-	0x01, 0x03, 0xf8, 0x6b,
-	0x20, 0x93, 0xfa, 0x6b,
-	0x04, 0x0b, 0x00, 0x6c,
+	0x04, 0x0b, 0xfa, 0x6b,
+	0x10, 0x0c, 0xf6, 0x7b,
+	0x01, 0x03, 0xfa, 0x6b,
+	0x20, 0x93, 0xfc, 0x6b,
+	0x04, 0x0b, 0x02, 0x6c,
 	0x40, 0x3c, 0x78, 0x00,
 	0xc7, 0x93, 0x26, 0x09,
-	0x38, 0x93, 0x02, 0x6c,
-	0x00, 0x65, 0xca, 0x41,
-	0x80, 0x3c, 0x68, 0x6c,
+	0x38, 0x93, 0x04, 0x6c,
+	0x00, 0x65, 0xcc, 0x41,
+	0x80, 0x3c, 0x6a, 0x6c,
 	0x01, 0x06, 0x50, 0x31,
 	0x80, 0xb8, 0x70, 0x01,
-	0x00, 0x65, 0xca, 0x41,
+	0x00, 0x65, 0xcc, 0x41,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x3a, 0xca, 0x30,
-	0x80, 0x65, 0x2e, 0x64,
-	0x10, 0xb8, 0x52, 0x6c,
+	0x80, 0x65, 0x30, 0x64,
+	0x10, 0xb8, 0x54, 0x6c,
 	0xc0, 0xba, 0xca, 0x00,
-	0x40, 0xb8, 0x1e, 0x6c,
+	0x40, 0xb8, 0x20, 0x6c,
 	0xbf, 0x65, 0xca, 0x08,
-	0x20, 0xb8, 0x32, 0x7c,
+	0x20, 0xb8, 0x34, 0x7c,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xea, 0x5d,
-	0xa0, 0x3f, 0x3a, 0x64,
+	0x00, 0x65, 0xec, 0x5d,
+	0xa0, 0x3f, 0x3c, 0x64,
 	0x23, 0xb8, 0x0c, 0x08,
-	0x00, 0x65, 0xea, 0x5d,
-	0xa0, 0x3f, 0x3a, 0x64,
-	0x00, 0xbb, 0x32, 0x44,
-	0xff, 0x65, 0x32, 0x64,
-	0x00, 0x65, 0x52, 0x44,
+	0x00, 0x65, 0xec, 0x5d,
+	0xa0, 0x3f, 0x3c, 0x64,
+	0x00, 0xbb, 0x34, 0x44,
+	0xff, 0x65, 0x34, 0x64,
+	0x00, 0x65, 0x54, 0x44,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x65, 0x0c, 0x30,
-	0x00, 0x65, 0xea, 0x5d,
-	0xa0, 0x3f, 0x0e, 0x74,
+	0x00, 0x65, 0xec, 0x5d,
+	0xa0, 0x3f, 0x10, 0x74,
 	0x40, 0x6a, 0x18, 0x00,
 	0x01, 0x3a, 0xa6, 0x30,
 	0x08, 0x6a, 0x74, 0x00,
-	0x00, 0x65, 0xca, 0x41,
-	0x64, 0x6a, 0x7a, 0x5d,
-	0x80, 0x64, 0xea, 0x6c,
-	0x04, 0x64, 0xac, 0x74,
-	0x02, 0x64, 0xbc, 0x74,
-	0x00, 0x6a, 0x72, 0x74,
-	0x03, 0x64, 0xda, 0x74,
-	0x23, 0x64, 0x5a, 0x74,
-	0x08, 0x64, 0x6e, 0x74,
-	0x61, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0xea, 0x5d,
-	0x08, 0x51, 0xcc, 0x71,
-	0x00, 0x65, 0x52, 0x44,
-	0x80, 0x04, 0x6c, 0x7c,
-	0x51, 0x6a, 0x70, 0x5d,
-	0x01, 0x51, 0x6c, 0x64,
-	0x01, 0xa4, 0x64, 0x7c,
-	0x01, 0x55, 0x6e, 0x7c,
-	0x41, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0x6e, 0x44,
-	0x21, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0x6e, 0x44,
-	0x07, 0x6a, 0x66, 0x5d,
+	0x00, 0x65, 0xcc, 0x41,
+	0x64, 0x6a, 0x7c, 0x5d,
+	0x80, 0x64, 0xec, 0x6c,
+	0x04, 0x64, 0xae, 0x74,
+	0x02, 0x64, 0xbe, 0x74,
+	0x00, 0x6a, 0x74, 0x74,
+	0x03, 0x64, 0xdc, 0x74,
+	0x23, 0x64, 0x5c, 0x74,
+	0x08, 0x64, 0x70, 0x74,
+	0x61, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0xec, 0x5d,
+	0x08, 0x51, 0xce, 0x71,
+	0x00, 0x65, 0x54, 0x44,
+	0x80, 0x04, 0x6e, 0x7c,
+	0x51, 0x6a, 0x72, 0x5d,
+	0x01, 0x51, 0x6e, 0x64,
+	0x01, 0xa4, 0x66, 0x7c,
+	0x01, 0x55, 0x70, 0x7c,
+	0x41, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0x70, 0x44,
+	0x21, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0x70, 0x44,
+	0x07, 0x6a, 0x68, 0x5d,
 	0x01, 0x06, 0xd4, 0x30,
-	0x00, 0x65, 0xca, 0x41,
-	0x80, 0xb8, 0x68, 0x7c,
-	0xc0, 0x3c, 0x7c, 0x7c,
-	0x80, 0x3c, 0x68, 0x6c,
-	0xff, 0xa8, 0x7c, 0x6c,
-	0x40, 0x3c, 0x68, 0x6c,
-	0x10, 0xb8, 0x80, 0x7c,
-	0xa1, 0x6a, 0xea, 0x5e,
-	0x01, 0xb4, 0x86, 0x6c,
-	0x02, 0xb4, 0x88, 0x6c,
-	0x01, 0xa4, 0x88, 0x7c,
-	0xff, 0xa8, 0x98, 0x7c,
+	0x00, 0x65, 0xcc, 0x41,
+	0x80, 0xb8, 0x6a, 0x7c,
+	0xc0, 0x3c, 0x7e, 0x7c,
+	0x80, 0x3c, 0x6a, 0x6c,
+	0xff, 0xa8, 0x7e, 0x6c,
+	0x40, 0x3c, 0x6a, 0x6c,
+	0x10, 0xb8, 0x82, 0x7c,
+	0xa1, 0x6a, 0xec, 0x5e,
+	0x01, 0xb4, 0x88, 0x6c,
+	0x02, 0xb4, 0x8a, 0x6c,
+	0x01, 0xa4, 0x8a, 0x7c,
+	0xff, 0xa8, 0x9a, 0x7c,
 	0x04, 0xb4, 0x68, 0x01,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x24, 0x5e,
-	0xff, 0xa8, 0x98, 0x7c,
-	0x71, 0x6a, 0xea, 0x5e,
-	0x40, 0x51, 0x98, 0x64,
-	0x00, 0x65, 0xc4, 0x5e,
-	0x00, 0x65, 0xdc, 0x41,
-	0x00, 0xbb, 0x9c, 0x5c,
-	0x00, 0x65, 0xdc, 0x41,
-	0x00, 0x65, 0xc4, 0x5e,
+	0x00, 0xbb, 0x26, 0x5e,
+	0xff, 0xa8, 0x9a, 0x7c,
+	0x71, 0x6a, 0xec, 0x5e,
+	0x40, 0x51, 0x9a, 0x64,
+	0x00, 0x65, 0xc6, 0x5e,
+	0x00, 0x65, 0xde, 0x41,
+	0x00, 0xbb, 0x9e, 0x5c,
+	0x00, 0x65, 0xde, 0x41,
+	0x00, 0x65, 0xc6, 0x5e,
 	0x01, 0x65, 0xa2, 0x30,
 	0x01, 0xf8, 0xc8, 0x30,
 	0x01, 0x4e, 0xc8, 0x30,
-	0x00, 0x6a, 0xc8, 0xdd,
-	0x00, 0x51, 0xda, 0x5d,
+	0x00, 0x6a, 0xca, 0xdd,
+	0x00, 0x51, 0xdc, 0x5d,
 	0x01, 0x4e, 0x9c, 0x18,
 	0x02, 0x6a, 0x22, 0x05,
-	0xc0, 0x3c, 0x68, 0x6c,
+	0xc0, 0x3c, 0x6a, 0x6c,
 	0x04, 0xb8, 0x70, 0x01,
-	0x00, 0x65, 0xe6, 0x5e,
-	0x20, 0xb8, 0xdc, 0x69,
+	0x00, 0x65, 0xe8, 0x5e,
+	0x20, 0xb8, 0xde, 0x69,
 	0x01, 0xbb, 0xa2, 0x30,
 	0x01, 0xba, 0x7c, 0x30,
-	0x00, 0xb9, 0xe0, 0x5c,
-	0x00, 0x65, 0xdc, 0x41,
+	0x00, 0xb9, 0xe2, 0x5c,
+	0x00, 0x65, 0xde, 0x41,
 	0x01, 0x06, 0xd4, 0x30,
-	0x20, 0x3c, 0xca, 0x79,
-	0x20, 0x3c, 0x6e, 0x7c,
-	0x01, 0xa4, 0xca, 0x7c,
+	0x20, 0x3c, 0xcc, 0x79,
+	0x20, 0x3c, 0x70, 0x7c,
+	0x01, 0xa4, 0xcc, 0x7c,
 	0x01, 0xb4, 0x68, 0x01,
-	0x00, 0x65, 0xca, 0x41,
-	0x00, 0x65, 0x6e, 0x44,
+	0x00, 0x65, 0xcc, 0x41,
+	0x00, 0x65, 0x70, 0x44,
 	0x04, 0x14, 0x58, 0x31,
 	0x01, 0x06, 0xd4, 0x30,
 	0x08, 0xa0, 0x60, 0x31,
 	0xac, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0x06, 0x5e,
+	0x14, 0x6a, 0x08, 0x5e,
 	0x01, 0x06, 0xd4, 0x30,
-	0xa0, 0x6a, 0xfe, 0x5d,
-	0x00, 0x65, 0xca, 0x41,
+	0xa0, 0x6a, 0x00, 0x5e,
+	0x00, 0x65, 0xcc, 0x41,
 	0xdf, 0x3c, 0x78, 0x08,
 	0x12, 0x01, 0x02, 0x00,
-	0x00, 0x65, 0x6e, 0x44,
+	0x00, 0x65, 0x70, 0x44,
 	0x4c, 0x65, 0xcc, 0x28,
 	0x01, 0x3e, 0x20, 0x31,
 	0xd0, 0x66, 0xcc, 0x18,
@@ -640,102 +641,102 @@
 	0xd0, 0x65, 0xca, 0x18,
 	0x01, 0x3e, 0x20, 0x31,
 	0x30, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0xf8, 0x4c,
+	0x00, 0x65, 0xfa, 0x4c,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x00, 0x55,
+	0x00, 0x65, 0x02, 0x55,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x20, 0x65, 0xca, 0x18,
 	0xe0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x0a, 0x4d,
+	0x00, 0x65, 0x0c, 0x4d,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xd0, 0x65, 0xd4, 0x18,
-	0x00, 0x65, 0x12, 0x55,
+	0x00, 0x65, 0x14, 0x55,
 	0xe1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
 	0x01, 0x6c, 0xa2, 0x30,
-	0xff, 0x51, 0x24, 0x75,
-	0x00, 0x51, 0xa0, 0x5d,
+	0xff, 0x51, 0x26, 0x75,
+	0x00, 0x51, 0xa2, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
-	0x00, 0x65, 0x46, 0x45,
+	0x00, 0x65, 0x48, 0x45,
 	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x46, 0x75,
-	0x00, 0x65, 0xc2, 0x5e,
+	0x00, 0x3e, 0x48, 0x75,
+	0x00, 0x65, 0xc4, 0x5e,
 	0x80, 0x3c, 0x78, 0x00,
 	0x01, 0x06, 0xd4, 0x30,
-	0x00, 0x65, 0xea, 0x5d,
+	0x00, 0x65, 0xec, 0x5d,
 	0x01, 0x3c, 0x78, 0x00,
-	0xe0, 0x3f, 0x62, 0x65,
+	0xe0, 0x3f, 0x64, 0x65,
 	0x02, 0x3c, 0x78, 0x00,
-	0x20, 0x12, 0x62, 0x65,
-	0x51, 0x6a, 0x70, 0x5d,
-	0x00, 0x51, 0xa0, 0x5d,
-	0x51, 0x6a, 0x70, 0x5d,
+	0x20, 0x12, 0x64, 0x65,
+	0x51, 0x6a, 0x72, 0x5d,
+	0x00, 0x51, 0xa2, 0x5d,
+	0x51, 0x6a, 0x72, 0x5d,
 	0x01, 0x51, 0x20, 0x31,
 	0x04, 0x3c, 0x78, 0x00,
 	0x01, 0xb9, 0xc8, 0x30,
-	0x00, 0x3d, 0x60, 0x65,
+	0x00, 0x3d, 0x62, 0x65,
 	0x08, 0x3c, 0x78, 0x00,
 	0x01, 0xba, 0xc8, 0x30,
-	0x00, 0x3e, 0x60, 0x65,
+	0x00, 0x3e, 0x62, 0x65,
 	0x10, 0x3c, 0x78, 0x00,
-	0x04, 0xb8, 0x60, 0x7d,
+	0x04, 0xb8, 0x62, 0x7d,
 	0xfb, 0xb8, 0x70, 0x09,
-	0x20, 0xb8, 0x56, 0x6d,
+	0x20, 0xb8, 0x58, 0x6d,
 	0x01, 0x90, 0xc8, 0x30,
 	0xff, 0x6a, 0xa2, 0x00,
-	0x00, 0x3d, 0xe0, 0x5c,
+	0x00, 0x3d, 0xe2, 0x5c,
 	0x01, 0x64, 0x20, 0x31,
 	0xff, 0x6a, 0x78, 0x08,
 	0x00, 0x65, 0xea, 0x58,
-	0x10, 0xb8, 0x6e, 0x7c,
-	0xff, 0x6a, 0x66, 0x5d,
-	0x00, 0x65, 0x6e, 0x44,
-	0x00, 0x65, 0xc2, 0x5e,
-	0x31, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0x6e, 0x44,
+	0x10, 0xb8, 0x70, 0x7c,
+	0xff, 0x6a, 0x68, 0x5d,
+	0x00, 0x65, 0x70, 0x44,
+	0x00, 0x65, 0xc4, 0x5e,
+	0x31, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0x70, 0x44,
 	0x10, 0x3f, 0x06, 0x00,
 	0x10, 0x6a, 0x06, 0x00,
 	0x01, 0x65, 0x74, 0x34,
-	0x81, 0x6a, 0xea, 0x5e,
-	0x00, 0x65, 0x72, 0x45,
+	0x81, 0x6a, 0xec, 0x5e,
+	0x00, 0x65, 0x74, 0x45,
 	0x01, 0x06, 0xd4, 0x30,
-	0x01, 0x0c, 0x72, 0x7d,
-	0x04, 0x0c, 0x6c, 0x6d,
+	0x01, 0x0c, 0x74, 0x7d,
+	0x04, 0x0c, 0x6e, 0x6d,
 	0xe0, 0x03, 0x7e, 0x08,
-	0xe0, 0x3f, 0xca, 0x61,
+	0xe0, 0x3f, 0xcc, 0x61,
 	0x01, 0x65, 0xcc, 0x30,
 	0x01, 0x12, 0xda, 0x34,
 	0x01, 0x06, 0xd4, 0x34,
-	0x01, 0x03, 0x80, 0x6d,
+	0x01, 0x03, 0x82, 0x6d,
 	0x40, 0x03, 0xcc, 0x08,
 	0x01, 0x65, 0x06, 0x30,
 	0x40, 0x65, 0xc8, 0x08,
-	0x00, 0x66, 0x8e, 0x75,
-	0x40, 0x65, 0x8e, 0x7d,
-	0x00, 0x65, 0x8e, 0x5d,
+	0x00, 0x66, 0x90, 0x75,
+	0x40, 0x65, 0x90, 0x7d,
+	0x00, 0x65, 0x90, 0x5d,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x08,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x98, 0x7d,
+	0x02, 0x0b, 0x9a, 0x7d,
 	0x01, 0x65, 0x0c, 0x30,
-	0x02, 0x0b, 0x9c, 0x7d,
+	0x02, 0x0b, 0x9e, 0x7d,
 	0xf7, 0x01, 0x02, 0x0c,
 	0x01, 0x65, 0xc8, 0x30,
-	0xff, 0x41, 0xc0, 0x75,
+	0xff, 0x41, 0xc2, 0x75,
 	0x01, 0x41, 0x20, 0x31,
 	0xff, 0x6a, 0xa4, 0x00,
-	0x00, 0x65, 0xb0, 0x45,
-	0xff, 0xbf, 0xc0, 0x75,
+	0x00, 0x65, 0xb2, 0x45,
+	0xff, 0xbf, 0xc2, 0x75,
 	0x01, 0x90, 0xa4, 0x30,
 	0x01, 0xbf, 0x20, 0x31,
-	0x00, 0xbb, 0xaa, 0x65,
-	0xff, 0x52, 0xbe, 0x75,
+	0x00, 0xbb, 0xac, 0x65,
+	0xff, 0x52, 0xc0, 0x75,
 	0x01, 0xbf, 0xcc, 0x30,
 	0x01, 0x90, 0xca, 0x30,
 	0x01, 0x52, 0x20, 0x31,
@@ -743,28 +744,28 @@
 	0x01, 0x65, 0x20, 0x35,
 	0x01, 0xbf, 0x82, 0x34,
 	0x01, 0x64, 0xa2, 0x30,
-	0x00, 0x6a, 0xd2, 0x5e,
+	0x00, 0x6a, 0xd4, 0x5e,
 	0x0d, 0x6a, 0x76, 0x00,
-	0x00, 0x51, 0x24, 0x46,
+	0x00, 0x51, 0x26, 0x46,
 	0x01, 0x65, 0xa4, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x18, 0x5e,
+	0x48, 0x6a, 0x1a, 0x5e,
 	0x01, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x05,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x48, 0x6a, 0x18, 0x5e,
-	0x01, 0x6a, 0xf2, 0x5d,
+	0x48, 0x6a, 0x1a, 0x5e,
+	0x01, 0x6a, 0xf4, 0x5d,
 	0x01, 0x6a, 0x26, 0x05,
 	0x01, 0x65, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0xde, 0x7d,
+	0x80, 0xee, 0xe0, 0x7d,
 	0xff, 0x6a, 0xdc, 0x0d,
 	0x01, 0x65, 0x32, 0x31,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xba, 0x46,
-	0x81, 0x6a, 0xea, 0x5e,
-	0x01, 0x0c, 0xea, 0x7d,
-	0x04, 0x0c, 0xe8, 0x6d,
+	0x00, 0x65, 0xbc, 0x46,
+	0x81, 0x6a, 0xec, 0x5e,
+	0x01, 0x0c, 0xec, 0x7d,
+	0x04, 0x0c, 0xea, 0x6d,
 	0xe0, 0x03, 0x06, 0x08,
 	0xe0, 0x03, 0x7e, 0x0c,
 	0x01, 0x65, 0x18, 0x31,
@@ -783,7 +784,7 @@
 	0x01, 0x6c, 0xda, 0x34,
 	0x3d, 0x64, 0xa4, 0x28,
 	0x55, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0x18, 0x46,
+	0x00, 0x65, 0x1a, 0x46,
 	0x2e, 0x64, 0xa4, 0x28,
 	0x66, 0x64, 0xc8, 0x28,
 	0x00, 0x6c, 0xda, 0x18,
@@ -794,63 +795,63 @@
 	0x00, 0x6c, 0xda, 0x24,
 	0x01, 0x65, 0xc8, 0x30,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0x14, 0x5e,
+	0x44, 0x6a, 0x16, 0x5e,
 	0x01, 0x90, 0xe2, 0x31,
-	0x04, 0x3b, 0x38, 0x7e,
+	0x04, 0x3b, 0x3a, 0x7e,
 	0x30, 0x6a, 0xd0, 0x01,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x1d, 0x6a, 0xdc, 0x01,
-	0xdc, 0xee, 0x34, 0x66,
-	0x00, 0x65, 0x50, 0x46,
+	0xdc, 0xee, 0x36, 0x66,
+	0x00, 0x65, 0x52, 0x46,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x20, 0xa0, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0x40, 0x7e,
+	0x80, 0xee, 0x42, 0x7e,
 	0x11, 0x6a, 0xdc, 0x01,
-	0x50, 0xee, 0x44, 0x66,
+	0x50, 0xee, 0x46, 0x66,
 	0x20, 0x6a, 0xd0, 0x01,
 	0x09, 0x6a, 0xdc, 0x01,
-	0x88, 0xee, 0x4a, 0x66,
+	0x88, 0xee, 0x4c, 0x66,
 	0x19, 0x6a, 0xdc, 0x01,
-	0xd8, 0xee, 0x4e, 0x66,
+	0xd8, 0xee, 0x50, 0x66,
 	0xff, 0x6a, 0xdc, 0x09,
-	0x18, 0xee, 0x52, 0x6e,
+	0x18, 0xee, 0x54, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x44, 0x6a, 0x14, 0x5e,
-	0x20, 0x6a, 0xf2, 0x5d,
+	0x44, 0x6a, 0x16, 0x5e,
+	0x20, 0x6a, 0xf4, 0x5d,
 	0x01, 0x3b, 0x26, 0x31,
-	0x04, 0x3b, 0x6c, 0x6e,
+	0x04, 0x3b, 0x6e, 0x6e,
 	0xa0, 0x6a, 0xca, 0x00,
 	0x20, 0x65, 0xc8, 0x18,
-	0x00, 0x65, 0xaa, 0x5e,
-	0x00, 0x65, 0x64, 0x66,
+	0x00, 0x65, 0xac, 0x5e,
+	0x00, 0x65, 0x66, 0x66,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xba, 0x46,
+	0x00, 0x65, 0xbc, 0x46,
 	0xa0, 0x6a, 0xcc, 0x00,
 	0xff, 0x6a, 0xc8, 0x08,
-	0x20, 0x94, 0x70, 0x6e,
-	0x10, 0x94, 0x72, 0x6e,
-	0x08, 0x94, 0x8c, 0x6e,
-	0x08, 0x94, 0x8c, 0x6e,
-	0x08, 0x94, 0x8c, 0x6e,
+	0x20, 0x94, 0x72, 0x6e,
+	0x10, 0x94, 0x74, 0x6e,
+	0x08, 0x94, 0x8e, 0x6e,
+	0x08, 0x94, 0x8e, 0x6e,
+	0x08, 0x94, 0x8e, 0x6e,
 	0xff, 0x8c, 0xc8, 0x10,
 	0xc1, 0x64, 0xc8, 0x18,
 	0xf8, 0x64, 0xc8, 0x08,
 	0x01, 0x99, 0xda, 0x30,
-	0x00, 0x66, 0x80, 0x66,
-	0xc0, 0x66, 0xbc, 0x76,
+	0x00, 0x66, 0x82, 0x66,
+	0xc0, 0x66, 0xbe, 0x76,
 	0x60, 0x66, 0xc8, 0x18,
 	0x3d, 0x64, 0xc8, 0x28,
-	0x00, 0x65, 0x70, 0x46,
+	0x00, 0x65, 0x72, 0x46,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x8e, 0x6e,
+	0x08, 0x93, 0x90, 0x6e,
 	0x00, 0x62, 0xc4, 0x18,
-	0x00, 0x65, 0xba, 0x5e,
-	0x00, 0x65, 0x9a, 0x5e,
-	0x00, 0x65, 0x9a, 0x5e,
-	0x00, 0x65, 0x9a, 0x5e,
+	0x00, 0x65, 0xbc, 0x5e,
+	0x00, 0x65, 0x9c, 0x5e,
+	0x00, 0x65, 0x9c, 0x5e,
+	0x00, 0x65, 0x9c, 0x5e,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
 	0x01, 0x99, 0xda, 0x30,
@@ -867,11 +868,11 @@
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x31,
 	0x01, 0x6c, 0x32, 0x35,
-	0x08, 0x94, 0xba, 0x7e,
+	0x08, 0x94, 0xbc, 0x7e,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0xbe, 0x6e,
+	0x08, 0x93, 0xc0, 0x6e,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x04, 0xb8, 0xe6, 0x6e,
+	0x04, 0xb8, 0xe8, 0x6e,
 	0x01, 0x42, 0x7e, 0x31,
 	0xff, 0x6a, 0x76, 0x01,
 	0x01, 0x90, 0x84, 0x34,
@@ -879,14 +880,14 @@
 	0x01, 0x85, 0x0a, 0x01,
 	0x7f, 0x65, 0x10, 0x09,
 	0xfe, 0x85, 0x0a, 0x0d,
-	0xff, 0x42, 0xe2, 0x66,
-	0xff, 0x41, 0xda, 0x66,
-	0xd1, 0x6a, 0xea, 0x5e,
+	0xff, 0x42, 0xe4, 0x66,
+	0xff, 0x41, 0xdc, 0x66,
+	0xd1, 0x6a, 0xec, 0x5e,
 	0xff, 0x6a, 0xca, 0x04,
 	0x01, 0x41, 0x20, 0x31,
 	0x01, 0xbf, 0x82, 0x30,
 	0x01, 0x6a, 0x76, 0x00,
-	0x00, 0xbb, 0x24, 0x46,
+	0x00, 0xbb, 0x26, 0x46,
 	0x01, 0x42, 0x20, 0x31,
 	0x01, 0xbf, 0x84, 0x34,
 	0x01, 0x41, 0x7e, 0x31,
@@ -1140,163 +1141,163 @@
 	{ ahc_patch1_func, 119, 1, 2 },
 	{ ahc_patch0_func, 120, 1, 1 },
 	{ ahc_patch7_func, 121, 4, 1 },
-	{ ahc_patch7_func, 131, 94, 11 },
+	{ ahc_patch7_func, 131, 95, 11 },
 	{ ahc_patch4_func, 151, 1, 1 },
-	{ ahc_patch1_func, 167, 1, 1 },
-	{ ahc_patch12_func, 172, 1, 2 },
-	{ ahc_patch0_func, 173, 1, 1 },
-	{ ahc_patch9_func, 184, 1, 2 },
-	{ ahc_patch0_func, 185, 1, 1 },
-	{ ahc_patch9_func, 194, 1, 2 },
-	{ ahc_patch0_func, 195, 1, 1 },
-	{ ahc_patch9_func, 211, 6, 2 },
-	{ ahc_patch0_func, 217, 6, 1 },
-	{ ahc_patch8_func, 225, 20, 2 },
-	{ ahc_patch1_func, 240, 1, 1 },
-	{ ahc_patch1_func, 247, 1, 2 },
-	{ ahc_patch0_func, 248, 2, 2 },
-	{ ahc_patch11_func, 249, 1, 1 },
-	{ ahc_patch9_func, 257, 31, 3 },
-	{ ahc_patch1_func, 273, 14, 2 },
-	{ ahc_patch13_func, 278, 1, 1 },
-	{ ahc_patch14_func, 288, 14, 1 },
-	{ ahc_patch1_func, 304, 1, 2 },
-	{ ahc_patch0_func, 305, 1, 1 },
-	{ ahc_patch9_func, 308, 1, 1 },
-	{ ahc_patch13_func, 313, 1, 1 },
-	{ ahc_patch9_func, 314, 2, 2 },
-	{ ahc_patch0_func, 316, 4, 1 },
-	{ ahc_patch14_func, 320, 1, 1 },
-	{ ahc_patch15_func, 323, 2, 3 },
-	{ ahc_patch9_func, 323, 1, 2 },
-	{ ahc_patch0_func, 324, 1, 1 },
-	{ ahc_patch6_func, 329, 1, 2 },
-	{ ahc_patch0_func, 330, 1, 1 },
-	{ ahc_patch1_func, 334, 50, 11 },
-	{ ahc_patch6_func, 343, 2, 4 },
-	{ ahc_patch7_func, 343, 1, 1 },
-	{ ahc_patch8_func, 344, 1, 1 },
-	{ ahc_patch0_func, 345, 1, 1 },
-	{ ahc_patch16_func, 346, 1, 1 },
-	{ ahc_patch6_func, 365, 6, 3 },
-	{ ahc_patch16_func, 365, 5, 1 },
-	{ ahc_patch0_func, 371, 5, 1 },
-	{ ahc_patch13_func, 379, 5, 1 },
-	{ ahc_patch0_func, 384, 54, 17 },
-	{ ahc_patch14_func, 384, 1, 1 },
-	{ ahc_patch7_func, 386, 2, 2 },
-	{ ahc_patch17_func, 387, 1, 1 },
-	{ ahc_patch9_func, 390, 1, 1 },
-	{ ahc_patch18_func, 397, 1, 1 },
-	{ ahc_patch14_func, 402, 9, 3 },
-	{ ahc_patch9_func, 403, 3, 2 },
-	{ ahc_patch0_func, 406, 3, 1 },
-	{ ahc_patch9_func, 414, 6, 2 },
-	{ ahc_patch0_func, 420, 9, 2 },
-	{ ahc_patch13_func, 420, 1, 1 },
-	{ ahc_patch13_func, 429, 2, 1 },
-	{ ahc_patch14_func, 431, 1, 1 },
-	{ ahc_patch9_func, 433, 1, 2 },
-	{ ahc_patch0_func, 434, 1, 1 },
-	{ ahc_patch7_func, 437, 1, 1 },
+	{ ahc_patch1_func, 168, 1, 1 },
+	{ ahc_patch12_func, 173, 1, 2 },
+	{ ahc_patch0_func, 174, 1, 1 },
+	{ ahc_patch9_func, 185, 1, 2 },
+	{ ahc_patch0_func, 186, 1, 1 },
+	{ ahc_patch9_func, 195, 1, 2 },
+	{ ahc_patch0_func, 196, 1, 1 },
+	{ ahc_patch9_func, 212, 6, 2 },
+	{ ahc_patch0_func, 218, 6, 1 },
+	{ ahc_patch8_func, 226, 20, 2 },
+	{ ahc_patch1_func, 241, 1, 1 },
+	{ ahc_patch1_func, 248, 1, 2 },
+	{ ahc_patch0_func, 249, 2, 2 },
+	{ ahc_patch11_func, 250, 1, 1 },
+	{ ahc_patch9_func, 258, 31, 3 },
+	{ ahc_patch1_func, 274, 14, 2 },
+	{ ahc_patch13_func, 279, 1, 1 },
+	{ ahc_patch14_func, 289, 14, 1 },
+	{ ahc_patch1_func, 305, 1, 2 },
+	{ ahc_patch0_func, 306, 1, 1 },
+	{ ahc_patch9_func, 309, 1, 1 },
+	{ ahc_patch13_func, 314, 1, 1 },
+	{ ahc_patch9_func, 315, 2, 2 },
+	{ ahc_patch0_func, 317, 4, 1 },
+	{ ahc_patch14_func, 321, 1, 1 },
+	{ ahc_patch15_func, 324, 2, 3 },
+	{ ahc_patch9_func, 324, 1, 2 },
+	{ ahc_patch0_func, 325, 1, 1 },
+	{ ahc_patch6_func, 330, 1, 2 },
+	{ ahc_patch0_func, 331, 1, 1 },
+	{ ahc_patch1_func, 335, 50, 11 },
+	{ ahc_patch6_func, 344, 2, 4 },
+	{ ahc_patch7_func, 344, 1, 1 },
+	{ ahc_patch8_func, 345, 1, 1 },
+	{ ahc_patch0_func, 346, 1, 1 },
+	{ ahc_patch16_func, 347, 1, 1 },
+	{ ahc_patch6_func, 366, 6, 3 },
+	{ ahc_patch16_func, 366, 5, 1 },
+	{ ahc_patch0_func, 372, 5, 1 },
+	{ ahc_patch13_func, 380, 5, 1 },
+	{ ahc_patch0_func, 385, 54, 17 },
+	{ ahc_patch14_func, 385, 1, 1 },
+	{ ahc_patch7_func, 387, 2, 2 },
+	{ ahc_patch17_func, 388, 1, 1 },
+	{ ahc_patch9_func, 391, 1, 1 },
+	{ ahc_patch18_func, 398, 1, 1 },
+	{ ahc_patch14_func, 403, 9, 3 },
+	{ ahc_patch9_func, 404, 3, 2 },
+	{ ahc_patch0_func, 407, 3, 1 },
+	{ ahc_patch9_func, 415, 6, 2 },
+	{ ahc_patch0_func, 421, 9, 2 },
+	{ ahc_patch13_func, 421, 1, 1 },
+	{ ahc_patch13_func, 430, 2, 1 },
+	{ ahc_patch14_func, 432, 1, 1 },
+	{ ahc_patch9_func, 434, 1, 2 },
+	{ ahc_patch0_func, 435, 1, 1 },
 	{ ahc_patch7_func, 438, 1, 1 },
-	{ ahc_patch8_func, 439, 3, 3 },
-	{ ahc_patch6_func, 440, 1, 2 },
-	{ ahc_patch0_func, 441, 1, 1 },
-	{ ahc_patch9_func, 442, 1, 1 },
-	{ ahc_patch15_func, 443, 1, 2 },
-	{ ahc_patch13_func, 443, 1, 1 },
-	{ ahc_patch14_func, 445, 9, 4 },
-	{ ahc_patch9_func, 445, 1, 1 },
-	{ ahc_patch9_func, 452, 2, 1 },
-	{ ahc_patch0_func, 454, 4, 3 },
-	{ ahc_patch9_func, 454, 1, 2 },
-	{ ahc_patch0_func, 455, 3, 1 },
-	{ ahc_patch1_func, 459, 2, 1 },
-	{ ahc_patch7_func, 461, 10, 2 },
-	{ ahc_patch0_func, 471, 1, 1 },
-	{ ahc_patch8_func, 472, 118, 22 },
-	{ ahc_patch1_func, 474, 3, 2 },
-	{ ahc_patch0_func, 477, 5, 3 },
-	{ ahc_patch9_func, 477, 2, 2 },
-	{ ahc_patch0_func, 479, 3, 1 },
-	{ ahc_patch1_func, 484, 2, 2 },
-	{ ahc_patch0_func, 486, 6, 3 },
-	{ ahc_patch9_func, 486, 2, 2 },
-	{ ahc_patch0_func, 488, 3, 1 },
-	{ ahc_patch1_func, 494, 2, 2 },
-	{ ahc_patch0_func, 496, 9, 7 },
-	{ ahc_patch9_func, 496, 5, 6 },
-	{ ahc_patch19_func, 496, 1, 2 },
-	{ ahc_patch0_func, 497, 1, 1 },
-	{ ahc_patch19_func, 499, 1, 2 },
-	{ ahc_patch0_func, 500, 1, 1 },
-	{ ahc_patch0_func, 501, 4, 1 },
-	{ ahc_patch6_func, 506, 3, 2 },
-	{ ahc_patch0_func, 509, 1, 1 },
-	{ ahc_patch6_func, 519, 1, 2 },
-	{ ahc_patch0_func, 520, 1, 1 },
-	{ ahc_patch20_func, 557, 7, 1 },
-	{ ahc_patch3_func, 592, 1, 2 },
-	{ ahc_patch0_func, 593, 1, 1 },
-	{ ahc_patch21_func, 596, 1, 1 },
-	{ ahc_patch8_func, 598, 106, 33 },
-	{ ahc_patch4_func, 600, 1, 1 },
-	{ ahc_patch1_func, 606, 2, 2 },
-	{ ahc_patch0_func, 608, 1, 1 },
-	{ ahc_patch1_func, 611, 1, 2 },
-	{ ahc_patch0_func, 612, 1, 1 },
-	{ ahc_patch9_func, 613, 3, 3 },
-	{ ahc_patch15_func, 614, 1, 1 },
-	{ ahc_patch0_func, 616, 4, 1 },
-	{ ahc_patch19_func, 625, 2, 2 },
-	{ ahc_patch0_func, 627, 1, 1 },
-	{ ahc_patch19_func, 631, 10, 3 },
-	{ ahc_patch5_func, 633, 8, 1 },
-	{ ahc_patch0_func, 641, 9, 2 },
-	{ ahc_patch5_func, 642, 8, 1 },
-	{ ahc_patch4_func, 652, 1, 2 },
-	{ ahc_patch0_func, 653, 1, 1 },
-	{ ahc_patch19_func, 654, 1, 2 },
-	{ ahc_patch0_func, 655, 3, 2 },
-	{ ahc_patch4_func, 657, 1, 1 },
-	{ ahc_patch5_func, 658, 1, 1 },
-	{ ahc_patch5_func, 661, 1, 1 },
-	{ ahc_patch5_func, 663, 1, 1 },
-	{ ahc_patch4_func, 665, 2, 2 },
-	{ ahc_patch0_func, 667, 2, 1 },
-	{ ahc_patch5_func, 669, 1, 1 },
-	{ ahc_patch5_func, 672, 1, 1 },
-	{ ahc_patch5_func, 675, 1, 1 },
-	{ ahc_patch19_func, 679, 1, 1 },
-	{ ahc_patch19_func, 682, 1, 1 },
-	{ ahc_patch4_func, 688, 1, 1 },
-	{ ahc_patch6_func, 691, 1, 2 },
-	{ ahc_patch0_func, 692, 1, 1 },
-	{ ahc_patch7_func, 704, 16, 1 },
-	{ ahc_patch4_func, 720, 20, 1 },
-	{ ahc_patch9_func, 741, 4, 2 },
-	{ ahc_patch0_func, 745, 4, 1 },
-	{ ahc_patch9_func, 749, 4, 2 },
-	{ ahc_patch0_func, 753, 3, 1 },
-	{ ahc_patch6_func, 759, 1, 1 },
-	{ ahc_patch22_func, 761, 14, 1 },
-	{ ahc_patch7_func, 775, 3, 1 },
-	{ ahc_patch9_func, 787, 24, 8 },
-	{ ahc_patch19_func, 791, 1, 2 },
-	{ ahc_patch0_func, 792, 1, 1 },
-	{ ahc_patch15_func, 797, 4, 2 },
-	{ ahc_patch0_func, 801, 7, 3 },
-	{ ahc_patch23_func, 801, 5, 2 },
-	{ ahc_patch0_func, 806, 2, 1 },
-	{ ahc_patch0_func, 811, 42, 3 },
-	{ ahc_patch18_func, 823, 18, 2 },
-	{ ahc_patch0_func, 841, 1, 1 },
-	{ ahc_patch4_func, 865, 1, 1 },
-	{ ahc_patch4_func, 866, 3, 2 },
-	{ ahc_patch0_func, 869, 1, 1 },
-	{ ahc_patch13_func, 870, 3, 1 },
-	{ ahc_patch4_func, 873, 12, 1 }
+	{ ahc_patch7_func, 439, 1, 1 },
+	{ ahc_patch8_func, 440, 3, 3 },
+	{ ahc_patch6_func, 441, 1, 2 },
+	{ ahc_patch0_func, 442, 1, 1 },
+	{ ahc_patch9_func, 443, 1, 1 },
+	{ ahc_patch15_func, 444, 1, 2 },
+	{ ahc_patch13_func, 444, 1, 1 },
+	{ ahc_patch14_func, 446, 9, 4 },
+	{ ahc_patch9_func, 446, 1, 1 },
+	{ ahc_patch9_func, 453, 2, 1 },
+	{ ahc_patch0_func, 455, 4, 3 },
+	{ ahc_patch9_func, 455, 1, 2 },
+	{ ahc_patch0_func, 456, 3, 1 },
+	{ ahc_patch1_func, 460, 2, 1 },
+	{ ahc_patch7_func, 462, 10, 2 },
+	{ ahc_patch0_func, 472, 1, 1 },
+	{ ahc_patch8_func, 473, 118, 22 },
+	{ ahc_patch1_func, 475, 3, 2 },
+	{ ahc_patch0_func, 478, 5, 3 },
+	{ ahc_patch9_func, 478, 2, 2 },
+	{ ahc_patch0_func, 480, 3, 1 },
+	{ ahc_patch1_func, 485, 2, 2 },
+	{ ahc_patch0_func, 487, 6, 3 },
+	{ ahc_patch9_func, 487, 2, 2 },
+	{ ahc_patch0_func, 489, 3, 1 },
+	{ ahc_patch1_func, 495, 2, 2 },
+	{ ahc_patch0_func, 497, 9, 7 },
+	{ ahc_patch9_func, 497, 5, 6 },
+	{ ahc_patch19_func, 497, 1, 2 },
+	{ ahc_patch0_func, 498, 1, 1 },
+	{ ahc_patch19_func, 500, 1, 2 },
+	{ ahc_patch0_func, 501, 1, 1 },
+	{ ahc_patch0_func, 502, 4, 1 },
+	{ ahc_patch6_func, 507, 3, 2 },
+	{ ahc_patch0_func, 510, 1, 1 },
+	{ ahc_patch6_func, 520, 1, 2 },
+	{ ahc_patch0_func, 521, 1, 1 },
+	{ ahc_patch20_func, 558, 7, 1 },
+	{ ahc_patch3_func, 593, 1, 2 },
+	{ ahc_patch0_func, 594, 1, 1 },
+	{ ahc_patch21_func, 597, 1, 1 },
+	{ ahc_patch8_func, 599, 106, 33 },
+	{ ahc_patch4_func, 601, 1, 1 },
+	{ ahc_patch1_func, 607, 2, 2 },
+	{ ahc_patch0_func, 609, 1, 1 },
+	{ ahc_patch1_func, 612, 1, 2 },
+	{ ahc_patch0_func, 613, 1, 1 },
+	{ ahc_patch9_func, 614, 3, 3 },
+	{ ahc_patch15_func, 615, 1, 1 },
+	{ ahc_patch0_func, 617, 4, 1 },
+	{ ahc_patch19_func, 626, 2, 2 },
+	{ ahc_patch0_func, 628, 1, 1 },
+	{ ahc_patch19_func, 632, 10, 3 },
+	{ ahc_patch5_func, 634, 8, 1 },
+	{ ahc_patch0_func, 642, 9, 2 },
+	{ ahc_patch5_func, 643, 8, 1 },
+	{ ahc_patch4_func, 653, 1, 2 },
+	{ ahc_patch0_func, 654, 1, 1 },
+	{ ahc_patch19_func, 655, 1, 2 },
+	{ ahc_patch0_func, 656, 3, 2 },
+	{ ahc_patch4_func, 658, 1, 1 },
+	{ ahc_patch5_func, 659, 1, 1 },
+	{ ahc_patch5_func, 662, 1, 1 },
+	{ ahc_patch5_func, 664, 1, 1 },
+	{ ahc_patch4_func, 666, 2, 2 },
+	{ ahc_patch0_func, 668, 2, 1 },
+	{ ahc_patch5_func, 670, 1, 1 },
+	{ ahc_patch5_func, 673, 1, 1 },
+	{ ahc_patch5_func, 676, 1, 1 },
+	{ ahc_patch19_func, 680, 1, 1 },
+	{ ahc_patch19_func, 683, 1, 1 },
+	{ ahc_patch4_func, 689, 1, 1 },
+	{ ahc_patch6_func, 692, 1, 2 },
+	{ ahc_patch0_func, 693, 1, 1 },
+	{ ahc_patch7_func, 705, 16, 1 },
+	{ ahc_patch4_func, 721, 20, 1 },
+	{ ahc_patch9_func, 742, 4, 2 },
+	{ ahc_patch0_func, 746, 4, 1 },
+	{ ahc_patch9_func, 750, 4, 2 },
+	{ ahc_patch0_func, 754, 3, 1 },
+	{ ahc_patch6_func, 760, 1, 1 },
+	{ ahc_patch22_func, 762, 14, 1 },
+	{ ahc_patch7_func, 776, 3, 1 },
+	{ ahc_patch9_func, 788, 24, 8 },
+	{ ahc_patch19_func, 792, 1, 2 },
+	{ ahc_patch0_func, 793, 1, 1 },
+	{ ahc_patch15_func, 798, 4, 2 },
+	{ ahc_patch0_func, 802, 7, 3 },
+	{ ahc_patch23_func, 802, 5, 2 },
+	{ ahc_patch0_func, 807, 2, 1 },
+	{ ahc_patch0_func, 812, 42, 3 },
+	{ ahc_patch18_func, 824, 18, 2 },
+	{ ahc_patch0_func, 842, 1, 1 },
+	{ ahc_patch4_func, 866, 1, 1 },
+	{ ahc_patch4_func, 867, 3, 2 },
+	{ ahc_patch0_func, 870, 1, 1 },
+	{ ahc_patch13_func, 871, 3, 1 },
+	{ ahc_patch4_func, 874, 12, 1 }
 };
 
 static struct cs {
@@ -1305,11 +1306,11 @@
 } critical_sections[] = {
 	{ 11, 18 },
 	{ 21, 30 },
-	{ 720, 736 },
-	{ 866, 869 },
-	{ 873, 879 },
-	{ 881, 883 },
-	{ 883, 885 }
+	{ 721, 737 },
+	{ 867, 870 },
+	{ 874, 880 },
+	{ 882, 884 },
+	{ 884, 886 }
 };
 
 static const int num_critical_sections = sizeof(critical_sections)
diff -Nru a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c
--- a/drivers/scsi/aic7xxx/aiclib.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/aic7xxx/aiclib.c	Mon Feb 10 10:39:27 2003
@@ -1230,3 +1230,106 @@
 	 */
 	return (10000000 / (period_factor * 4 * 10));
 }
+
+/*
+ * Return speed in KB/s.
+ */
+u_int
+aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate)
+{
+	u_int freq;
+
+	if (offset != 0 && period < min_rate)
+		freq  = aic_calc_syncsrate(period);
+	else
+		/* Roughly 3.3MB/s for async */
+		freq  = 3300;
+	freq <<= width;
+	return (freq);
+}
+
+uint32_t
+aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data,
+		 cam_status status, u_int scsi_status)
+{
+	aic_sense_action  err_action;
+	int		  sense;
+
+	sense  = (cmd->result >> 24) == DRIVER_SENSE;
+
+	switch (status) {
+	case CAM_REQ_CMP:
+		err_action = SS_NOP;
+		break;
+	case CAM_AUTOSENSE_FAIL:
+	case CAM_SCSI_STATUS_ERROR:
+
+		switch (scsi_status) {
+		case SCSI_STATUS_OK:
+		case SCSI_STATUS_COND_MET:
+		case SCSI_STATUS_INTERMED:
+		case SCSI_STATUS_INTERMED_COND_MET:
+			err_action = SS_NOP;
+			break;
+		case SCSI_STATUS_CMD_TERMINATED:
+		case SCSI_STATUS_CHECK_COND:
+			if (sense != 0) {
+				struct scsi_sense_data *sense;
+
+				sense = (struct scsi_sense_data *)
+				    &cmd->sense_buffer;
+				err_action =
+				    aic_sense_error_action(sense, inq_data, 0);
+
+			} else {
+				err_action = SS_RETRY|SSQ_FALLBACK
+					   | SSQ_DECREMENT_COUNT|EIO;
+			}
+			break;
+		case SCSI_STATUS_QUEUE_FULL:
+		case SCSI_STATUS_BUSY:
+			err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY
+				   | SSQ_DECREMENT_COUNT|EBUSY;
+			break;
+		case SCSI_STATUS_RESERV_CONFLICT:
+		default:
+			err_action = SS_FAIL|EBUSY;
+			break;
+		}
+		break;
+	case CAM_CMD_TIMEOUT:
+	case CAM_REQ_CMP_ERR:
+	case CAM_UNEXP_BUSFREE:
+	case CAM_UNCOR_PARITY:
+	case CAM_DATA_RUN_ERR:
+		err_action = SS_RETRY|SSQ_FALLBACK|EIO;
+		break;
+	case CAM_UA_ABORT:
+	case CAM_UA_TERMIO:
+	case CAM_MSG_REJECT_REC:
+	case CAM_SEL_TIMEOUT:
+		err_action = SS_FAIL|EIO;
+		break;
+	case CAM_REQ_INVALID:
+	case CAM_PATH_INVALID:
+	case CAM_DEV_NOT_THERE:
+	case CAM_NO_HBA:
+	case CAM_PROVIDE_FAIL:
+	case CAM_REQ_TOO_BIG:		
+	case CAM_RESRC_UNAVAIL:
+	case CAM_BUSY:
+	default:
+		/* panic??  These should never occur in our application. */
+		err_action = SS_FAIL|EIO;
+		break;
+	case CAM_SCSI_BUS_RESET:
+	case CAM_BDR_SENT:		
+	case CAM_REQUEUE_REQ:
+		/* Unconditional requeue */
+		err_action = SS_RETRY;
+		break;
+	}
+
+	return (err_action);
+}
+
diff -Nru a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
--- a/drivers/scsi/aic7xxx/aiclib.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/aic7xxx/aiclib.h	Mon Feb 10 10:39:23 2003
@@ -861,11 +861,13 @@
 
 #define	aic_sense_desc			AIC_LIB_ENTRY(_sense_desc)
 #define	aic_sense_error_action		AIC_LIB_ENTRY(_sense_error_action)
+#define	aic_error_action		AIC_LIB_ENTRY(_error_action)
 #define	aic_op_desc			AIC_LIB_ENTRY(_op_desc)
 #define	aic_cdb_string			AIC_LIB_ENTRY(_cdb_string)
 #define aic_print_inquiry		AIC_LIB_ENTRY(_print_inquiry)
 #define aic_calc_syncsrate		AIC_LIB_ENTRY(_calc_syncrate)
 #define	aic_calc_syncparam		AIC_LIB_ENTRY(_calc_syncparam)
+#define	aic_calc_speed			AIC_LIB_ENTRY(_calc_speed)
 #define	aic_inquiry_match		AIC_LIB_ENTRY(_inquiry_match)
 #define	aic_static_inquiry_match	AIC_LIB_ENTRY(_static_inquiry_match)
 
@@ -878,6 +880,9 @@
 aic_sense_action	aic_sense_error_action(struct scsi_sense_data*,
 					       struct scsi_inquiry_data*,
 					       uint32_t /*sense_flags*/);
+uint32_t		aic_error_action(struct scsi_cmnd *,
+					 struct scsi_inquiry_data *,
+					 cam_status, u_int);
 
 #define	SF_RETRY_UA	0x01
 #define SF_NO_PRINT	0x02
@@ -892,6 +897,8 @@
 
 u_int		aic_calc_syncsrate(u_int /*period_factor*/);
 u_int		aic_calc_syncparam(u_int /*period*/);
+u_int		aic_calc_speed(u_int width, u_int period, u_int offset,
+			       u_int min_rate);
 	
 int		aic_inquiry_match(caddr_t /*inqbuffer*/,
 				  caddr_t /*table_entry*/);
diff -Nru a/drivers/scsi/aic7xxx/scsi_iu.h b/drivers/scsi/aic7xxx/scsi_iu.h
--- a/drivers/scsi/aic7xxx/scsi_iu.h	Mon Feb 10 10:39:26 2003
+++ b/drivers/scsi/aic7xxx/scsi_iu.h	Mon Feb 10 10:39:26 2003
@@ -28,4 +28,12 @@
     (12 + (((siu)->flags & SIU_RSPVALID)		\
 	? scsi_4btoul((siu)->pkt_failures_length)	\
 	: 0))
+
+#define	SIU_TASKMGMT_NONE		0x00
+#define	SIU_TASKMGMT_ABORT_TASK		0x01
+#define	SIU_TASKMGMT_ABORT_TASK_SET	0x02
+#define	SIU_TASKMGMT_CLEAR_TASK_SET	0x04
+#define	SIU_TASKMGMT_LUN_RESET		0x08
+#define	SIU_TASKMGMT_TARGET_RESET	0x20
+#define	SIU_TASKMGMT_CLEAR_ACA		0x40
 #endif /*_SCSI_SCSI_IU_H*/
diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	Mon Feb 10 10:39:32 2003
@@ -313,7 +313,7 @@
                     p->user[tindex].options);
     if(sdptr->simple_tags)
     {
-      size += sprintf(BLS, "  Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->new_queue_depth, aic_dev->max_q_depth);
+      size += sprintf(BLS, "  Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth);
     }
     if(aic_dev->barrier_total)
       size += sprintf(BLS, "  Total transfers %ld:\n    (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n",
diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/scsi/aic7xxx_old.c	Mon Feb 10 10:39:26 2003
@@ -1040,11 +1040,11 @@
                         (((scb->hscb)->target_channel_lun >> 4) & 0xf), \
                         ((scb->hscb)->target_channel_lun & 0x07)
 
-#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01),  \
-                        ((cmd->target) & 0x0f), \
-                        ((cmd->lun) & 0x07)
+#define CTL_OF_CMD(cmd) ((cmd->device->channel) & 0x01),  \
+                        ((cmd->device->id) & 0x0f), \
+                        ((cmd->device->lun) & 0x07)
 
-#define TARGET_INDEX(cmd)  ((cmd)->target | ((cmd)->channel << 3))
+#define TARGET_INDEX(cmd)  ((cmd)->device->id | ((cmd)->device->channel << 3))
 
 /*
  * A nice little define to make doing our printks a little easier
@@ -2557,7 +2557,7 @@
      * than the right hand side.  If the number of SG array elements
      * is changed, this function may not be near so efficient any more.
      *
-     * Since the DMA'able buffers are now allocated in a seperate
+     * Since the DMA'able buffers are now allocated in a separate
      * chunk this algorithm has been modified to match.  The '12'
      * and '6' factors in scb_size are for the DMA'able command byte
      * and sensebuffers respectively.  -DaveM
@@ -4068,7 +4068,7 @@
              * normal.
              */
 	    scsi_adjust_queue_depth(scb->cmd->device, MSG_SIMPLE_TAG,
-			    scb->cmd->device->new_queue_depth);
+			    scb->cmd->device->queue_depth);
             scb->tag_action = MSG_SIMPLE_Q_TAG;
             scb->hscb->control &= ~SCB_TAG_TYPE;
             scb->hscb->control |= MSG_SIMPLE_Q_TAG;
@@ -4284,7 +4284,7 @@
                 memcpy(scb->sense_cmd, &generic_sense[0],
                        sizeof(generic_sense));
 
-                scb->sense_cmd[1] = (cmd->lun << 5);
+                scb->sense_cmd[1] = (cmd->device->lun << 5);
                 scb->sense_cmd[4] = sizeof(cmd->sense_buffer);
 
                 scb->sg_list[0].length = 
@@ -4935,9 +4935,9 @@
   struct aic7xxx_syncrate *syncrate;
   struct aic_dev_data *aic_dev;
 
-  target = scb->cmd->target;
-  channel = scb->cmd->channel;
-  lun = scb->cmd->lun;
+  target = scb->cmd->device->id;
+  channel = scb->cmd->device->channel;
+  lun = scb->cmd->device->lun;
   reply = reject = done = FALSE;
   tindex = TARGET_INDEX(scb->cmd);
   aic_dev = AIC_DEV(scb->cmd);
@@ -6026,11 +6026,11 @@
        */
       aic_dev = AIC_DEV(scb->cmd);
       aic_dev->needppr = aic_dev->needppr_copy = 0;
-      aic7xxx_set_width(p, scb->cmd->target, scb->cmd->channel, scb->cmd->lun,
+      aic7xxx_set_width(p, scb->cmd->device->id, scb->cmd->device->channel, scb->cmd->device->lun,
                         MSG_EXT_WDTR_BUS_8_BIT,
                         (AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE),
 			aic_dev);
-      aic7xxx_set_syncrate(p, NULL, scb->cmd->target, scb->cmd->channel, 0, 0,
+      aic7xxx_set_syncrate(p, NULL, scb->cmd->device->id, scb->cmd->device->channel, 0, 0,
                            0, AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE,
 			   aic_dev);
       aic_dev->goal.options = 0;
@@ -6307,8 +6307,8 @@
         unpause_sequencer(p, FALSE);
         continue;
       }
-      aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
-        scb->cmd->lun, scb->hscb->tag);
+      aic7xxx_reset_device(p, scb->cmd->device->id, scb->cmd->device->channel,
+        scb->cmd->device->lun, scb->hscb->tag);
       scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
         SCB_QUEUED_ABORT);
       unpause_sequencer(p, FALSE);
@@ -10201,8 +10201,8 @@
     }
     scb->flags |= SCB_DTR_SCB;
   }
-  hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
-        ((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07);
+  hscb->target_channel_lun = ((cmd->device->id << 4) & 0xF0) |
+        ((cmd->device->channel & 0x01) << 3) | (cmd->device->lun & 0x07);
 
   /*
    * The interpretation of request_buffer and request_bufflen
@@ -10298,7 +10298,7 @@
   struct aic7xxx_scb *scb;
   struct aic_dev_data *aic_dev;
 
-  p = (struct aic7xxx_host *) cmd->host->hostdata;
+  p = (struct aic7xxx_host *) cmd->device->host->hostdata;
 
   aic_dev = cmd->device->hostdata;  
 #ifdef AIC7XXX_VERBOSE_DEBUGGING
@@ -10379,7 +10379,7 @@
     printk(KERN_ERR "aic7xxx_bus_device_reset: called with NULL cmd!\n");
     return FAILED;
   }
-  p = (struct aic7xxx_host *)cmd->host->hostdata;
+  p = (struct aic7xxx_host *)cmd->device->host->hostdata;
   aic_dev = AIC_DEV(cmd);
   if(aic7xxx_position(cmd) < p->scb_data->numscbs)
     scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
@@ -10441,7 +10441,7 @@
          aic_inb(p, STCNT));
   }
 
-  channel = cmd->channel;
+  channel = cmd->device->channel;
 
     /*
      * Send a Device Reset Message:
@@ -10508,7 +10508,7 @@
    * Check to see if the command is on the qinfifo.  If it is, then we will
    * not need to queue the command again since the card should start it soon
    */
-  if (aic7xxx_search_qinfifo(p, cmd->channel, cmd->target, cmd->lun, hscb->tag,
+  if (aic7xxx_search_qinfifo(p, cmd->device->channel, cmd->device->id, cmd->device->lun, hscb->tag,
 			  0, TRUE, NULL) == 0)
   {
     disconnected = TRUE;
@@ -10604,7 +10604,7 @@
     printk(KERN_ERR "aic7xxx_abort: called with NULL cmd!\n");
     return FAILED;
   }
-  p = (struct aic7xxx_host *)cmd->host->hostdata;
+  p = (struct aic7xxx_host *)cmd->device->host->hostdata;
   aic_dev = AIC_DEV(cmd);
   if(aic7xxx_position(cmd) < p->scb_data->numscbs)
     scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
@@ -10664,8 +10664,8 @@
 /*
  *  We just checked the waiting_q, now for the QINFIFO
  */
-  if ( ((found = aic7xxx_search_qinfifo(p, cmd->target, cmd->channel,
-                     cmd->lun, scb->hscb->tag, SCB_ABORT | SCB_QUEUED_FOR_DONE,
+  if ( ((found = aic7xxx_search_qinfifo(p, cmd->device->id, cmd->device->channel,
+                     cmd->device->lun, scb->hscb->tag, SCB_ABORT | SCB_QUEUED_FOR_DONE,
                      FALSE, NULL)) != 0) &&
                     (aic7xxx_verbose & VERBOSE_ABORT_PROCESS))
   {
@@ -10825,7 +10825,7 @@
   struct aic7xxx_host *p;
   struct aic_dev_data *aic_dev;
 
-  p = (struct aic7xxx_host *) cmd->host->hostdata;
+  p = (struct aic7xxx_host *) cmd->device->host->hostdata;
   aic_dev = AIC_DEV(cmd);
   if(aic7xxx_position(cmd) < p->scb_data->numscbs)
   {
@@ -10872,10 +10872,10 @@
  *  By this point, we want to already know what we are going to do and
  *  only have the following code implement our course of action.
  */
-  aic7xxx_reset_channel(p, cmd->channel, TRUE);
+  aic7xxx_reset_channel(p, cmd->device->channel, TRUE);
   if (p->features & AHC_TWIN)
   {
-    aic7xxx_reset_channel(p, cmd->channel ^ 0x01, TRUE);
+    aic7xxx_reset_channel(p, cmd->device->channel ^ 0x01, TRUE);
     restart_sequencer(p);
   }
   aic_outb(p,  aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE), SIMODE1);
diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/scsi/atp870u.c	Mon Feb 10 10:39:25 2003
@@ -492,17 +492,17 @@
 	struct Scsi_Host *host;
 	struct atp_unit *dev;
 
-	if (req_p->channel != 0) {
+	if (req_p->device->channel != 0) {
 		req_p->result = 0x00040000;
 		done(req_p);
 		return 0;
 	};
 
-	host = req_p->host;
+	host = req_p->device->host;
 	dev = (struct atp_unit *)&host->hostdata;
 	
 	m = 1;
-	m = m << req_p->target;
+	m = m << req_p->device->id;
 
 	/*
 	 *      Fake a timeout for missing targets
@@ -600,9 +600,9 @@
 		dev->quhdu = 0;
 	}
 	workrequ = dev->querequ[dev->quhdu];
-	if (dev->id[workrequ->target].curr_req == 0) {
-		dev->id[workrequ->target].curr_req = workrequ;
-		dev->last_cmd = workrequ->target;
+	if (dev->id[workrequ->device->id].curr_req == 0) {
+		dev->id[workrequ->device->id].curr_req = workrequ;
+		dev->last_cmd = workrequ->device->id;
 		goto cmd_subp;
 	}
 	dev->quhdu = j;
@@ -638,7 +638,7 @@
 
 	tmport = workportu + 0x1b;
 	j = 0;
-	target_id = workrequ->target;
+	target_id = workrequ->device->id;
 
 	/*
 	 *      Wide ?
@@ -665,7 +665,7 @@
 		outb(dev->ata_cdbu[i], tmport++);
 	}
 	tmport = workportu + 0x0f;
-	outb(workrequ->lun, tmport);
+	outb(workrequ->device->lun, tmport);
 	tmport += 0x02;
 	/*
 	 *      Write the target
@@ -2606,7 +2606,7 @@
 	unsigned char j, k;
 	Scsi_Cmnd *workrequ;
 	unsigned int tmport;
-	struct atp_unit *dev = (struct atp_unit *)&SCpnt->host->hostdata;
+	struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata;
 
 	printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
 	printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/constants.c	Mon Feb 10 10:39:30 2003
@@ -1118,9 +1118,9 @@
 
 void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
     printk("scsi%d : destination target %d, lun %d\n", 
-	   cmd->host->host_no, 
-	   cmd->target, 
-	   cmd->lun);
+	   cmd->device->host->host_no, 
+	   cmd->device->id, 
+	   cmd->device->lun);
     printk("        command = ");
     print_command (cmd->cmnd);
 }
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/cpqfcTSinit.c	Mon Feb 10 10:39:23 2003
@@ -730,9 +730,12 @@
 
       case CPQFC_IOCTL_FC_TARGET_ADDRESS:
 	// can we find an FC device mapping to this SCSI target?
-	DumCmnd.channel = ScsiDev->channel;		// For searching
-	DumCmnd.target  = ScsiDev->id;
-	DumCmnd.lun     = ScsiDev->lun;
+/* 	DumCmnd.channel = ScsiDev->channel; */		// For searching
+/* 	DumCmnd.target  = ScsiDev->id; */
+/* 	DumCmnd.lun     = ScsiDev->lun; */
+
+        DumCmnd.device = ScsiDev;
+	
 	pLoggedInPort = fcFindLoggedInPort( fcChip,
 		&DumCmnd, // search Scsi Nexus
 		0,        // DON'T search linked list for FC port id
@@ -1297,7 +1300,7 @@
 
 int cpqfcTS_queuecommand(Scsi_Cmnd *Cmnd, void (* done)(Scsi_Cmnd *))
 {
-  struct Scsi_Host *HostAdapter = Cmnd->host;
+  struct Scsi_Host *HostAdapter = Cmnd->device->host;
   CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
   PTACHYON fcChip = &cpqfcHBAdata->fcChip;
   TachFCHDR_GCMND fchs;  // only use for FC destination id field  
@@ -1353,9 +1356,9 @@
 //    printk(" @Q bad targ cmnd %p@ ", Cmnd);
       QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
     }
-    else if (Cmnd->lun >= CPQFCTS_MAX_LUN)
+    else if (Cmnd->device->lun >= CPQFCTS_MAX_LUN)
     {
-      printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->lun);
+      printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->device->lun);
       QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
     } 
 
@@ -1475,7 +1478,7 @@
 int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd)
 {
 
-  struct Scsi_Host *HostAdapter = Cmnd->host;
+  struct Scsi_Host *HostAdapter = Cmnd->device->host;
   // get the pointer to our Scsi layer HBA buffer  
   CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
   PTACHYON fcChip = &cpqfcHBAdata->fcChip;
@@ -1601,8 +1604,7 @@
 
   scsi_cdb[0] = RELEASE;
 
-  // allocate with wait = true, interruptible = false 
-  SCpnt = scsi_allocate_device(ScsiDev, 1);
+  SCpnt = scsi_get_command(ScsiDev, GFP_KERNEL);
   {
     CPQFC_DECLARE_COMPLETION(wait);
     
@@ -1651,7 +1653,7 @@
   result = SCpnt->result;
 
   SDpnt = SCpnt->device;
-  scsi_release_command(SCpnt);
+  scsi_put_command(SCpnt);
   SCpnt = NULL;
 
   // if (!SDpnt->was_reset && SDpnt->scsi_request_fn)
@@ -1668,9 +1670,9 @@
   int retval;
   Scsi_Device *SDpnt = Cmnd->device;
   // printk("   ENTERING cpqfcTS_eh_device_reset() \n");
-  spin_unlock_irq(Cmnd->host->host_lock);
+  spin_unlock_irq(Cmnd->device->host->host_lock);
   retval = cpqfcTS_TargetDeviceReset( SDpnt, 0);
-  spin_lock_irq(Cmnd->host->host_lock);
+  spin_lock_irq(Cmnd->device->host->host_lock);
   return retval;
 }
 
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/scsi/dpt_i2o.c	Mon Feb 10 10:39:31 2003
@@ -391,7 +391,7 @@
 		return 0;
 	}
 
-	pHba = (adpt_hba*)cmd->host->hostdata[0];
+	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
 	if (!pHba) {
 		return FAILED;
 	}
@@ -424,7 +424,7 @@
 		 * to the device structure.  This should be a TEST_UNIT_READY
 		 * command from scan_scsis_single.
 		 */
-		if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) {
+		if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun)) == NULL) {
 			// TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response 
 			// with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
 			cmd->result = (DID_NO_CONNECT << 16);
@@ -647,7 +647,7 @@
 	if(cmd->serial_number == 0){
 		return FAILED;
 	}
-	pHba = (adpt_hba*) cmd->host->hostdata[0];
+	pHba = (adpt_hba*) cmd->device->host->hostdata[0];
 	printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
 	if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
 		printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
@@ -685,7 +685,7 @@
 	int old_state;
 	struct adpt_device* d = (void*) cmd->device->hostdata;
 
-	pHba = (void*) cmd->host->hostdata[0];
+	pHba = (void*) cmd->device->host->hostdata[0];
 	printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
 	if (!d) {
 		printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
@@ -722,11 +722,11 @@
 	adpt_hba* pHba;
 	u32 msg[4];
 
-	pHba = (adpt_hba*)cmd->host->hostdata[0];
+	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
 	memset(msg, 0, sizeof(msg));
-	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid );
+	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid );
 	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);
+	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, (void*)msg,sizeof(msg), FOREVER) ){
@@ -743,8 +743,8 @@
 {
 	adpt_hba* pHba;
 	int rcode;
-	pHba = (adpt_hba*)cmd->host->hostdata[0];
-	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid );
+	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
+	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid );
 	rcode =  adpt_hba_reset(pHba);
 	if(rcode == 0){
 		printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
@@ -2216,7 +2216,7 @@
 	// calculate resid for sg 
 	cmd->resid = cmd->request_bufflen - readl(reply+5);
 
-	pHba = (adpt_hba*) cmd->host->hostdata[0];
+	pHba = (adpt_hba*) cmd->device->host->hostdata[0];
 
 	cmd->sense_buffer[0] = '\0';  // initialize sense valid flag to false
 
@@ -2240,7 +2240,7 @@
 		case I2O_SCSI_DSC_NO_ADAPTER:
 		case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
 			printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
-				pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, hba_status, dev_status, cmd->cmnd[0]);
+				pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]);
 			cmd->result = (DID_TIME_OUT << 16);
 			break;
 		case I2O_SCSI_DSC_ADAPTER_BUSY:
@@ -2280,7 +2280,7 @@
 		case I2O_SCSI_DSC_REQUEST_INVALID:
 		default:
 			printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
-				pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+				pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
 			       hba_status, dev_status, cmd->cmnd[0]);
 			cmd->result = (DID_ERROR << 16);
 			break;
@@ -2298,7 +2298,7 @@
 				/* This is to handle an array failed */
 				cmd->result = (DID_TIME_OUT << 16);
 				printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
-					pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, 
+					pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, 
 					hba_status, dev_status, cmd->cmnd[0]);
 
 			}
@@ -2310,7 +2310,7 @@
 		 */
 		cmd->result = (DID_TIME_OUT << 16);
 		printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
-			pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+			pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
 			((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
 	}
 
@@ -2510,13 +2510,16 @@
 	Scsi_Device* 	d = NULL;
 
 	list_for_each_entry(d, &pHba->host->my_devices, siblings) {
-		for(cmd = d->device_queue; cmd ; cmd = cmd->next){
+		unsigned long flags;
+		spin_lock_irqsave(&d->list_lock, flags);
+		list_for_each_entry(cmd, &d->cmd_list, list) {
 			if(cmd->serial_number == 0){
 				continue;
 			}
 			cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
 			cmd->scsi_done(cmd);
 		}
+		spin_unlock_irqrestore(&d->list_lock, flags);
 	}
 }
 
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/scsi/eata.c	Mon Feb 10 10:39:31 2003
@@ -895,7 +895,7 @@
       tag_suffix = "";
       }
 
-   if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2)
+   if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
       link_suffix = ", sorted";
    else if (TLDEV(dev->type))
       link_suffix = ", unsorted";
@@ -904,7 +904,7 @@
 
    printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
           BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-          dev->new_queue_depth, link_suffix, tag_suffix);
+          dev->queue_depth, link_suffix, tag_suffix);
 
    return FALSE;
 }
@@ -1640,7 +1640,7 @@
    struct mscp *cpp;
 
    /* j is the board number */
-   j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
 
    if (SCpnt->host_scribble)
       panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
@@ -1678,8 +1678,8 @@
    SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
 
    if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
-                        BN(j), i, SCpnt->channel, SCpnt->target,
-                        SCpnt->lun, SCpnt->pid);
+                        BN(j), i, SCpnt->device->channel, SCpnt->device->id,
+                        SCpnt->device->lun, SCpnt->pid);
 
    cpp->reqsen = TRUE;
    cpp->dispri = TRUE;
@@ -1687,9 +1687,9 @@
    if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = TRUE;
 #endif
    cpp->one = TRUE;
-   cpp->channel = SCpnt->channel;
-   cpp->target = SCpnt->target;
-   cpp->lun = SCpnt->lun;
+   cpp->channel = SCpnt->device->channel;
+   cpp->target = SCpnt->device->id;
+   cpp->lun = SCpnt->device->lun;
    cpp->SCpnt = SCpnt;
    memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
@@ -1699,7 +1699,7 @@
    /* Map DMA buffers and SG list */
    map_dma(i, j);
 
-   if (linked_comm && SCpnt->device->new_queue_depth > 2
+   if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
       flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
@@ -1711,7 +1711,7 @@
       unmap_dma(i, j);
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
-             BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);
+             BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid);
       return 1;
       }
 
@@ -1722,17 +1722,17 @@
 static int eata2x_eh_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
       printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+             BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
       return SUCCESS;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
    printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+          BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -1798,9 +1798,9 @@
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
    printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+          BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -2056,8 +2056,8 @@
          k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
          printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\
                 " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
-                (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
-                SCpnt->lun, SCpnt->pid, k, flushcount, n_ready,
+                (ihdlr ? "ihdlr" : "qcomm"), SCpnt->device->channel, SCpnt->device->id,
+                SCpnt->device->lun, SCpnt->pid, k, flushcount, n_ready,
                 SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
                 YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
                 YESNO(overlap), cpp->din);
@@ -2093,7 +2093,7 @@
       if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
          printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
                 " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
-                SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k);
+                SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k);
          HD(j)->cp_stat[k] = ABORTING;
          continue;
          }
@@ -2207,7 +2207,7 @@
 
    sync_dma(i, j);
 
-   if (linked_comm && SCpnt->device->new_queue_depth > 2
+   if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type))
       flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
 
@@ -2227,7 +2227,7 @@
 
          /* If there was a bus reset, redo operation on each target */
          else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
-                  && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
+                  && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel])
             status = DID_BUS_BUSY << 16;
 
          /* Works around a flaw in scsi.c */
@@ -2240,18 +2240,18 @@
             status = DID_OK << 16;
 
          if (tstatus == GOOD)
-            HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
+            HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE;
 
          if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
              (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
                (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
             printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
                    "target_status 0x%x, sense key 0x%x.\n", BN(j),
-                   SCpnt->channel, SCpnt->target, SCpnt->lun,
+                   SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
                    SCpnt->pid, spp->target_status,
                    SCpnt->sense_buffer[2]);
 
-         HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
+         HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
 
          if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
@@ -2259,11 +2259,11 @@
       case ASST:     /* Selection Time Out */
       case 0x02:     /* Command Time Out   */
 
-         if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
+         if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
             status = DID_ERROR << 16;
          else {
             status = DID_TIME_OUT << 16;
-            HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
+            HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++;
             }
 
          break;
@@ -2318,7 +2318,7 @@
       printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
              " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
              BN(j), i, spp->adapter_status, spp->target_status,
-             SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+             SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid,
              reg, HD(j)->iocount);
 
    unmap_dma(i, j);
diff -Nru a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c
--- a/drivers/scsi/eata_dma.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/eata_dma.c	Mon Feb 10 10:39:23 2003
@@ -270,7 +270,7 @@
 	    }
 
 	    cmd = ccb->cmd;
-	    base = (uint) cmd->host->base;
+	    base = (uint) cmd->device->host->base;
        	    hba_stat = sp->hba_stat;
 	    
 	    scsi_stat = (sp->scsi_stat >> 1) & 0x1f; 
@@ -299,8 +299,8 @@
 	    eata_stat = inb(base + HA_RSTATUS); 
 	    DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, "
 				 "target: %x, lun: %x, ea_s: %#.2x, hba_s: "
-				 "%#.2x \n", irq, base, cmd->pid, cmd->target,
-				 cmd->lun, eata_stat, hba_stat));
+				 "%#.2x \n", irq, base, cmd->pid, cmd->device->id,
+				 cmd->device->lun, eata_stat, hba_stat));
 	    
 	    switch (hba_stat) {
 	    case HA_NO_ERROR:	/* NO Error */
@@ -337,7 +337,7 @@
  		break;
 	    case HA_CP_RESET_NA:
 	    case HA_CP_RESET:
-	        HD(cmd)->resetlevel[cmd->channel] = 0; 
+	        HD(cmd)->resetlevel[cmd->device->channel] = 0; 
 		result = DID_RESET << 16;
 		DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: reseted cmd "
 				       "pid %ldreturned\n", 
@@ -478,7 +478,7 @@
     queue_counter++;
 
     hd = HD(cmd);
-    sh = cmd->host;
+    sh = cmd->device->host;
     
     if (cmd->cmnd[0] == REQUEST_SENSE && cmd->sense_buffer[0] != 0) {
         DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n"));
@@ -517,7 +517,7 @@
     restore_flags(flags);
     
     DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n",
-			  cmd->pid, cmd->target, cmd->lun, y));
+			  cmd->pid, cmd->device->id, cmd->device->lun, y));
     DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
     
     if(hd->do_latency == TRUE) 
@@ -547,7 +547,7 @@
     /* FIXME: This will will have to be changed once the midlevel driver 
      *        allows different HBA IDs on every channel.
      */
-    if (cmd->target == sh->this_id) 
+    if (cmd->device->id == sh->this_id) 
 	ccb->Interpret = TRUE;	/* Interpret command */
 
     if (cmd->use_sg) {
@@ -586,9 +586,9 @@
     ccb->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
     ccb->reqlen = sizeof(cmd->sense_buffer);
     
-    ccb->cp_id = cmd->target;
-    ccb->cp_channel = cmd->channel;
-    ccb->cp_lun = cmd->lun;
+    ccb->cp_id = cmd->device->id;
+    ccb->cp_channel = cmd->device->channel;
+    ccb->cp_lun = cmd->device->lun;
     ccb->cp_dispri = TRUE;
     ccb->cp_identify = TRUE;
     memcpy(ccb->cp_cdb, cmd->cmnd, cmd->cmd_len);
@@ -604,14 +604,14 @@
 	cmd->result = DID_BUS_BUSY << 16;
 	DBG(DBG_QUEUE && DBG_ABNORM, 
 	    printk("eata_queue target %d, pid %ld, HBA busy, "
-		   "returning DID_BUS_BUSY\n",cmd->target, cmd->pid));
+		   "returning DID_BUS_BUSY\n",cmd->device->id, cmd->pid));
 	ccb->status = FREE;    
 	done(cmd);
 	return(0);
     }
     DBG(DBG_QUEUE, printk("Queued base %#.4x pid: %ld target: %x lun: %x "
 			 "slot %d irq %d\n", (s32)sh->base, cmd->pid, 
-			 cmd->target, cmd->lun, y, sh->irq));
+			 cmd->device->id, cmd->device->lun, y, sh->irq));
     DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
 
     return(0);
@@ -629,7 +629,7 @@
     cli();
 
     DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x"
-			   " reason %x\n", cmd->pid, cmd->target, cmd->lun, 
+			   " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, 
 			   cmd->abort_reason));
     DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
 
@@ -642,7 +642,7 @@
 	}
     }
 
-    while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) {
+    while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY) {
 	if (--loop == 0) {
 	    printk("eata_dma: abort, timeout error.\n");
 	    DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
@@ -690,7 +690,7 @@
     cli();
     
     DBG(DBG_ABNORM, printk("eata_reset called pid:%ld target: %x lun: %x"
-			   " reason %x\n", cmd->pid, cmd->target, cmd->lun, 
+			   " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, 
 			   cmd->abort_reason));
 	
     for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) {
@@ -708,7 +708,7 @@
 	return (SCSI_RESET_ERROR);
     }
     
-    while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
+    while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY)
 	if (--loop == 0) {
 	    printk("eata_reset: exit, timeout error.\n");
 	    restore_flags(flags);
@@ -716,7 +716,7 @@
 	    return (SCSI_RESET_ERROR);
 	}
  
-    for (x = 0; x < cmd->host->can_queue; x++) {
+    for (x = 0; x < cmd->device->host->can_queue; x++) {
 	if (HD(cmd)->ccb[x].status == FREE)
 	    continue;
 
@@ -743,8 +743,8 @@
     }
     
     /* hard reset the HBA  */
-    inb((u32) (cmd->host->base) + HA_RSTATUS);	/* This might cause trouble */
-    eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET);
+    inb((u32) (cmd->device->host->base) + HA_RSTATUS);	/* This might cause trouble */
+    eata_send_command(0, (u32) cmd->device->host->base, EATA_CMD_RESET);
     
     HD(cmd)->state = RESET;
 
@@ -757,7 +757,7 @@
     DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled again.\n"));
     DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
     
-    for (x = 0; x < cmd->host->can_queue; x++) {
+    for (x = 0; x < cmd->device->host->can_queue; x++) {
 	
 	/* Skip slots already set free by interrupt and those that 
          * are still LOCKED from the last reset */
diff -Nru a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h
--- a/drivers/scsi/eata_generic.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/eata_generic.h	Mon Feb 10 10:39:27 2003
@@ -90,7 +90,7 @@
 #define WRITE            1
 #define OTHER            2
 
-#define HD(cmd)	 ((hostdata *)&(cmd->host->hostdata))
+#define HD(cmd)	 ((hostdata *)&(cmd->device->host->hostdata))
 #define CD(cmd)	 ((struct eata_ccb *)(cmd->host_scribble))
 #define SD(host) ((hostdata *)&(host->hostdata))
 
diff -Nru a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
--- a/drivers/scsi/eata_pio.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/eata_pio.c	Mon Feb 10 10:39:29 2003
@@ -157,7 +157,7 @@
 
 		cp = &hd->ccb[0];
 		cmd = cp->cmd;
-		base = (uint) cmd->host->base;
+		base = (uint) cmd->device->host->base;
 
 		do {
 			stat = inb(base + HA_RSTATUS);
@@ -286,7 +286,7 @@
 	queue_counter++;
 
 	hd = HD(cmd);
-	sh = cmd->host;
+	sh = cmd->device->host;
 	base = (uint) sh->base;
 
 	/* use only slot 0, as 2001 can handle only one cmd at a time */
@@ -310,7 +310,7 @@
 
 	cp->status = USED;	/* claim free slot */
 
-	DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y));
+	DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->device->id, cmd->device->lun, y));
 
 	cmd->scsi_done = (void *) done;
 
@@ -319,14 +319,14 @@
 	else
 		cp->DataIn = TRUE;	/* Input mode  */
 
-	cp->Interpret = (cmd->target == hd->hostid);
+	cp->Interpret = (cmd->device->id == hd->hostid);
 	cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen);
 	cp->Auto_Req_Sen = FALSE;
 	cp->cp_reqDMA = htonl(0);
 	cp->reqlen = 0;
 
-	cp->cp_id = cmd->target;
-	cp->cp_lun = cmd->lun;
+	cp->cp_id = cmd->device->id;
+	cp->cp_lun = cmd->device->lun;
 	cp->cp_dispri = FALSE;
 	cp->cp_identify = TRUE;
 	memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
@@ -353,7 +353,7 @@
 
 	if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) {
 		cmd->result = DID_BUS_BUSY << 16;
-		printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
+		printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->device->id, cmd->pid);
 		done(cmd);
 		cp->status = FREE;
 		return (0);
@@ -366,7 +366,7 @@
 	for (x = 0; x < hd->cppadlen; x++)
 		outw(0, base + HA_RDATA);
 
-	DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->target, cmd->lun, y, sh->irq));
+	DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->device->id, cmd->device->lun, y, sh->irq));
 
 	return (0);
 }
@@ -375,10 +375,10 @@
 {
 	uint loop = HZ;
 
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason));
+	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
 
 
-	while (inb(cmd->host->base + HA_RAUXSTAT) & HA_ABUSY)
+	while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
 		if (--loop == 0) {
 			printk(KERN_WARNING "eata_pio: abort, timeout error.\n");
 			return FAILED;
@@ -408,9 +408,9 @@
 	uint x, limit = 0;
 	unsigned char success = FALSE;
 	Scsi_Cmnd *sp;
-	struct Scsi_Host *host = cmd->host;
+	struct Scsi_Host *host = cmd->device->host;
 
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason));
+	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
 
 	if (HD(cmd)->state == RESET) {
 		printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
@@ -419,7 +419,7 @@
 
 	/* force all slots to be free */
 
-	for (x = 0; x < cmd->host->can_queue; x++) {
+	for (x = 0; x < cmd->device->host->can_queue; x++) {
 
 		if (HD(cmd)->ccb[x].status == FREE)
 			continue;
@@ -433,7 +433,7 @@
 	}
 
 	/* hard reset the HBA  */
-	outb(EATA_CMD_RESET, (uint) cmd->host->base + HA_WCOMMAND);
+	outb(EATA_CMD_RESET, (uint) cmd->device->host->base + HA_WCOMMAND);
 
 	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n"));
 	HD(cmd)->state = RESET;
@@ -445,7 +445,7 @@
 
 	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit));
 
-	for (x = 0; x < cmd->host->can_queue; x++) {
+	for (x = 0; x < cmd->device->host->can_queue; x++) {
 
 		/* Skip slots already set free by interrupt */
 		if (HD(cmd)->ccb[x].status != RESET)
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/esp.c	Mon Feb 10 10:39:33 2003
@@ -453,7 +453,7 @@
 	Scsi_Cmnd *ptr, *prev;
 
 	for (ptr = *SC, prev = NULL;
-	     ptr && ((ptr->target != target) || (ptr->lun != lun));
+	     ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
 	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)
 		;
 	if (ptr) {
@@ -1447,7 +1447,7 @@
 
 static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp)
 {
-	struct esp_pointers *ep = &esp->data_pointers[sp->target];
+	struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
 
 	sp->SCp.ptr = ep->saved_ptr;
 	sp->SCp.buffer = ep->saved_buffer;
@@ -1457,7 +1457,7 @@
 
 static void esp_save_pointers(struct esp *esp, Scsi_Cmnd *sp)
 {
-	struct esp_pointers *ep = &esp->data_pointers[sp->target];
+	struct esp_pointers *ep = &esp->data_pointers[sp->device->id];
 
 	ep->saved_ptr = sp->SCp.ptr;
 	ep->saved_buffer = sp->SCp.buffer;
@@ -1559,8 +1559,8 @@
 
 	SDptr = SCptr->device;
 	esp_dev = SDptr->hostdata;
-	lun = SCptr->lun;
-	target = SCptr->target;
+	lun = SCptr->device->lun;
+	target = SCptr->device->id;
 
 	esp->snip = 0;
 	esp->msgout_len = 0;
@@ -1621,7 +1621,7 @@
 		 * disconnect.
 		 */
 		ESPMISC(("esp: Selecting device for first time. target=%d "
-			 "lun=%d\n", target, SCptr->lun));
+			 "lun=%d\n", target, SCptr->device->lun));
 		if (!SDptr->borken && !esp_dev->disconnect)
 			esp_dev->disconnect = 1;
 
@@ -1731,7 +1731,7 @@
 		    SDptr->removable == 0) ||
 		    cdrom_hwbug_wkaround || SDptr->borken) {
 			ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d "
-				 "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun));
+				 "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
 			esp_dev->disconnect = 0;
 			*cmdp++ = IDENTIFY(0, lun);
 		} else {
@@ -1822,10 +1822,10 @@
 	SCpnt->SCp.phase = not_issued;
 
 	/* We use the scratch area. */
-	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->target, SCpnt->lun));
-	ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun));
+	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->device->lun));
+	ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->device->lun));
 
-	esp = (struct esp *) SCpnt->host->hostdata;
+	esp = (struct esp *) SCpnt->device->host->hostdata;
 	esp_get_dmabufs(esp, SCpnt);
 	esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */
 
@@ -1852,7 +1852,7 @@
 /* Only queuing supported in this ESP driver. */
 static int esp_command(Scsi_Cmnd *SCpnt)
 {
-	struct esp *esp = (struct esp *) SCpnt->host->hostdata;
+	struct esp *esp = (struct esp *) SCpnt->device->host->hostdata;
 
 	ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id));
 	return -1;
@@ -1863,7 +1863,7 @@
 {
 	ESPLOG(("[tgt<%02x> lun<%02x> "
 		"pphase<%s> cphase<%s>]",
-		SCptr->target, SCptr->lun,
+		SCptr->device->id, SCptr->device->lun,
 		phase_string(SCptr->SCp.sent_command),
 		phase_string(SCptr->SCp.phase)));
 }
@@ -1917,7 +1917,7 @@
 /* Abort a command.  The host_lock is acquired by caller. */
 static int esp_abort(Scsi_Cmnd *SCptr)
 {
-	struct esp *esp = (struct esp *) SCptr->host->hostdata;
+	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;
 	int don;
 
 	ESPLOG(("esp%d: Aborting command\n", esp->esp_id));
@@ -2049,7 +2049,7 @@
  */
 static int esp_reset(Scsi_Cmnd *SCptr)
 {
-	struct esp *esp = (struct esp *) SCptr->host->hostdata;
+	struct esp *esp = (struct esp *) SCptr->device->host->hostdata;
 
 	(void) esp_do_resetbus(esp);
 
@@ -2474,13 +2474,13 @@
 	if (esp->prev_soff  != esp_dev->sync_max_offset ||
 	    esp->prev_stp   != esp_dev->sync_min_period ||
 	    (esp->erev > esp100a &&
-	     esp->prev_cfg3 != esp->config3[sp->target])) {
+	     esp->prev_cfg3 != esp->config3[sp->device->id])) {
 		esp->prev_soff = esp_dev->sync_max_offset;
 		esp->prev_stp = esp_dev->sync_min_period;
 		sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF);
 		sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP);
 		if (esp->erev > esp100a) {
-			esp->prev_cfg3 = esp->config3[sp->target];
+			esp->prev_cfg3 = esp->config3[sp->device->id];
 			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
 		}
 	}
@@ -2736,7 +2736,7 @@
 			esp->esp_id,
 			SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual));
 		ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, 
-			SCptr->target));
+			SCptr->device->id));
 		SCptr->device->borken = 1;
 		esp_dev->sync = 0;
 		bytes_sent = 0;
@@ -2842,7 +2842,7 @@
 
 		if (SCptr->SCp.Status != GOOD &&
 		    SCptr->SCp.Status != CONDITION_GOOD &&
-		    ((1<<SCptr->target) & esp->targets_present) &&
+		    ((1<<SCptr->device->id) & esp->targets_present) &&
 		    esp_dev->sync &&
 		    esp_dev->sync_max_offset) {
 			/* SCSI standard says that the synchronous capabilities
@@ -2853,7 +2853,7 @@
 			 * state.
 			 */
 			ESPMISC(("esp: Status <%d> for target %d lun %d\n",
-				 SCptr->SCp.Status, SCptr->target, SCptr->lun));
+				 SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun));
 
 			/* But don't do this when spinning up a disk at
 			 * boot time while we poll for completion as it
@@ -2864,14 +2864,14 @@
 			if (esp_should_clear_sync(SCptr) != 0)
 				esp_dev->sync = 0;
 		}
-		ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->lun));
+		ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
 		esp_done(esp, ((SCptr->SCp.Status & 0xff) |
 			       ((SCptr->SCp.Message & 0xff)<<8) |
 			       (DID_OK << 16)));
 	} else if (esp->prevmsgin == DISCONNECT) {
 		/* Normal disconnect. */
 		esp_cmd(esp, ESP_CMD_ESEL);
-		ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun));
+		ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
 		append_SC(&esp->disconnected_SC, SCptr);
 		esp->current_SC = NULL;
 		if (esp->issue_SC)
@@ -2901,21 +2901,21 @@
 	sp = esp->issue_SC;
 	ESPLOG(("esp%d: issue_SC[", esp->esp_id));
 	while (sp) {
-		ESPLOG(("<%02x,%02x>", sp->target, sp->lun));
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
 		sp = (Scsi_Cmnd *) sp->host_scribble;
 	}
 	ESPLOG(("]\n"));
 	sp = esp->current_SC;
 	ESPLOG(("esp%d: current_SC[", esp->esp_id));
 	if (sp)
-		ESPLOG(("<%02x,%02x>", sp->target, sp->lun));
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
 	else
 		ESPLOG(("<NULL>"));
 	ESPLOG(("]\n"));
 	sp = esp->disconnected_SC;
 	ESPLOG(("esp%d: disconnected_SC[", esp->esp_id));
 	while (sp) {
-		ESPLOG(("<%02x,%02x>", sp->target, sp->lun));
+		ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun));
 		sp = (Scsi_Cmnd *) sp->host_scribble;
 	}
 	ESPLOG(("]\n"));
@@ -2959,7 +2959,7 @@
 	esp_cmd(esp, ESP_CMD_MOK);
 
 	if (esp->erev == fashme)
-		sbus_writeb(((SCptr->target & 0xf) |
+		sbus_writeb(((SCptr->device->id & 0xf) |
 			     (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)),
 			    esp->eregs + ESP_BUSID);
 
@@ -3246,7 +3246,7 @@
 	 */
 	if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) {
 		/* target speaks... */
-		esp->targets_present |= (1<<SCptr->target);
+		esp->targets_present |= (1<<SCptr->device->id);
 
 		/* What if the target ignores the sdtr? */
 		if (esp->snip)
@@ -3275,7 +3275,7 @@
 			 * XXX for synchronous transfers.
 			 */
 			ESPLOG(("esp%d: STEP_ASEL for tgt %d\n",
-				esp->esp_id, SCptr->target));
+				esp->esp_id, SCptr->device->id));
 
 		case ESP_STEP_SID:
 			/* Arbitration won, target selected, went
@@ -3395,7 +3395,7 @@
 		if (esp->disconnected_SC)
 			esp_cmd(esp, ESP_CMD_ESEL);
 
-		if (((1<<SCptr->target) & esp->targets_present) &&
+		if (((1<<SCptr->device->id) & esp->targets_present) &&
 		    esp->seqreg != 0 &&
 		    (esp->cur_msgout[0] == EXTENDED_MESSAGE) &&
 		    (SCptr->SCp.phase == in_slct_msg ||
@@ -3403,7 +3403,7 @@
 			/* shit */
 			esp->snip = 0;
 			ESPLOG(("esp%d: Failed synchronous negotiation for target %d "
-				"lun %d\n", esp->esp_id, SCptr->target, SCptr->lun));
+				"lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
 			esp_dev->sync_max_offset = 0;
 			esp_dev->sync_min_period = 0;
 			esp_dev->sync = 1; /* so we don't negotiate again */
@@ -3429,9 +3429,9 @@
 		 * or whenever when we are scanning the bus for targets.
 		 * But first make sure that is really what is happening.
 		 */
-		if (((1<<SCptr->target) & esp->targets_present)) {
+		if (((1<<SCptr->device->id) & esp->targets_present)) {
 			ESPLOG(("esp%d: Warning, live target %d not responding to "
-				"selection.\n", esp->esp_id, SCptr->target));
+				"selection.\n", esp->esp_id, SCptr->device->id));
 
 			/* This _CAN_ happen.  The SCSI standard states that
 			 * the target is to _not_ respond to selection if
@@ -3444,7 +3444,7 @@
 			/* Else, there really isn't anyone there. */
 			ESPMISC(("esp: selection failure, maybe nobody there?\n"));
 			ESPMISC(("esp: target %d lun %d\n",
-				 SCptr->target, SCptr->lun));
+				 SCptr->device->id, SCptr->device->lun));
 			esp_done(esp, (DID_BAD_TARGET << 16));
 		}
 		return do_intr_end;
@@ -3517,7 +3517,7 @@
 
 	case NOP:
 		ESPLOG(("esp%d: target %d sends a nop\n", esp->esp_id,
-			esp->current_SC->target));
+			esp->current_SC->device->id));
 		return 0;
 
 	case RESTORE_POINTERS:
@@ -3600,7 +3600,7 @@
 		int integer = hz / 1000000;
 		int fraction = (hz - (integer * 1000000)) / 10000;
 		if ((esp->erev == fashme) &&
-		    (esp->config3[esp->current_SC->target] & ESP_CONFIG3_EWIDE)) {
+		    (esp->config3[esp->current_SC->device->id] & ESP_CONFIG3_EWIDE)) {
 			type = "FAST-WIDE";
 			integer <<= 1;
 			fraction <<= 1;
@@ -3615,7 +3615,7 @@
 		 * sibling call optimization.  -DaveM
 		 */
 		ESPLOG((KERN_INFO "esp%d: target %d ",
-			esp->esp_id, esp->current_SC->target));
+			esp->esp_id, esp->current_SC->device->id));
 		ESPLOG(("[period %dns offset %d %d.%02dMHz ",
 			(int) msg3 * 4, (int) msg4,
 			integer, fraction));
@@ -3623,7 +3623,7 @@
 			(((msg3 * 4) < 200) ? "-II" : "")));
 	} else {
 		ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n",
-			esp->esp_id, esp->current_SC->target));
+			esp->esp_id, esp->current_SC->device->id));
 	}
 }
 
@@ -3707,11 +3707,11 @@
 					 */
 					if (esp->erev == fashme)
 						esp_dev->sync_max_offset &= ~esp->radelay;
-					esp->config3[SCptr->target] |= bit;
+					esp->config3[SCptr->device->id] |= bit;
 				} else {
-					esp->config3[SCptr->target] &= ~bit;
+					esp->config3[SCptr->device->id] &= ~bit;
 				}
-				esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp->prev_cfg3 = esp->config3[SCptr->device->id];
 				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
 			}
 			esp->prev_soff = esp_dev->sync_max_offset;
@@ -3721,7 +3721,7 @@
 			ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
 				 esp_dev->sync_max_offset,
 				 esp_dev->sync_min_period,
-				 esp->config3[SCptr->target]));
+				 esp->config3[SCptr->device->id]));
 
 			esp->snip = 0;
 		} else if (esp_dev->sync_max_offset) {
@@ -3740,8 +3740,8 @@
 					bit = ESP_CONFIG3_FAST;
 				else
 					bit = ESP_CONFIG3_FSCSI;
-				esp->config3[SCptr->target] &= ~bit;
-				esp->prev_cfg3 = esp->config3[SCptr->target];
+				esp->config3[SCptr->device->id] &= ~bit;
+				esp->prev_cfg3 = esp->config3[SCptr->device->id];
 				sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
 			}
 		}
@@ -3778,7 +3778,7 @@
 			/* Things look good; let's see what we got. */
 			if (size == 16) {
 				/* Set config 3 register for this target. */
-				esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE;
+				esp->config3[SCptr->device->id] |= ESP_CONFIG3_EWIDE;
 			} else {
 				/* Just make sure it was one byte sized. */
 				if (size != 8) {
@@ -3788,9 +3788,9 @@
 					goto finish;
 				}
 				/* Pure paranoia. */
-				esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE);
+				esp->config3[SCptr->device->id] &= ~(ESP_CONFIG3_EWIDE);
 			}
-			esp->prev_cfg3 = esp->config3[SCptr->target];
+			esp->prev_cfg3 = esp->config3[SCptr->device->id];
 			sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3);
 
 			/* Regardless, next try for sync transfers. */
@@ -4258,7 +4258,7 @@
 			 * a nexus is alive on the bus.
 			 */
 			ESPLOG(("esp%d: Forcing async and disabling disconnect for "
-				"target %d\n", esp->esp_id, SCptr->target));
+				"target %d\n", esp->esp_id, SCptr->device->id));
 			SCptr->device->borken = 1; /* foo on you */
 		}
 
diff -Nru a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c
--- a/drivers/scsi/fcal.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/fcal.c	Mon Feb 10 10:39:23 2003
@@ -292,11 +292,12 @@
 	if (SCpnt->cmnd[1] & 0xe0) return -EINVAL;
 	/* FC-PLDA tells us... */
 	memset(addr, 0, 8);
-	f = (struct fcal *)SCpnt->host->hostdata;
-	if (!f->map[SCpnt->target]) return -EINVAL;
+	f = (struct fcal *)SCpnt->device->host->hostdata;
+	if (!f->map[SCpnt->device->id])
+		return -EINVAL;
 	/* Now, determine DID: It will be Native Identifier, so we zero upper
 	   2 bytes of the 3 byte DID, lowest byte will be AL-PA */
-	fcmd->did = target2alpa[SCpnt->target];
+	fcmd->did = target2alpa[SCpnt->device->id];
 	FCALD(("trying DID %06x\n", fcmd->did))
 	return 0;
 }
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/fdomain.c	Mon Feb 10 10:39:30 2003
@@ -1252,9 +1252,9 @@
 #if EVERY_ACCESS
 	 printk( " AFAIL " );
 #endif
-         spin_lock_irqsave(current_SC->host->host_lock, flags);
+         spin_lock_irqsave(current_SC->device->host->host_lock, flags);
 	 my_done( DID_BUS_BUSY << 16 );
-         spin_unlock_irqrestore(current_SC->host->host_lock, flags);
+         spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
 	 return;
       }
       current_SC->SCp.phase = in_selection;
@@ -1262,7 +1262,7 @@
       outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
 
       outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
-      outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
+      outb( adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port );
       
       /* Stop arbitration and enable parity */
       outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
@@ -1274,13 +1274,13 @@
       status = inb( SCSI_Status_port );
       if (!(status & 0x01)) {
 	 /* Try again, for slow devices */
-	 if (fdomain_select( current_SC->target )) {
+	 if (fdomain_select( current_SC->device->id )) {
 #if EVERY_ACCESS
 	    printk( " SFAIL " );
 #endif
-            spin_lock_irqsave(current_SC->host->host_lock, flags);
+            spin_lock_irqsave(current_SC->device->host->host_lock, flags);
 	    my_done( DID_NO_CONNECT << 16 );
-            spin_unlock_irqrestore(current_SC->host->host_lock, flags);
+            spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
 	    return;
 	 } else {
 #if EVERY_ACCESS
@@ -1337,7 +1337,7 @@
 	     && current_SC->SCp.Status != 2
 	     && current_SC->SCp.Status != 8) {
 	    printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n",
-		    current_SC->target,
+		    current_SC->device->id,
 		    current_SC->cmnd[0],
 		    current_SC->SCp.Status );
 	 }
@@ -1476,10 +1476,10 @@
 #if EVERY_ACCESS
       printk( "BEFORE MY_DONE. . ." );
 #endif
-      spin_lock_irqsave(current_SC->host->host_lock, flags);
+      spin_lock_irqsave(current_SC->device->host->host_lock, flags);
       my_done( (current_SC->SCp.Status & 0xff)
 	       | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
-      spin_unlock_irqrestore(current_SC->host->host_lock, flags);
+      spin_unlock_irqrestore(current_SC->device->host->host_lock, flags);
 #if EVERY_ACCESS
       printk( "RETURNING.\n" );
 #endif
@@ -1580,13 +1580,13 @@
    unsigned int irr;
    unsigned int isr;
 
-   if (!SCpnt || !SCpnt->host) {
+   if (!SCpnt || !SCpnt->device || !SCpnt->device->host) {
       printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n");
       return;
    }
    
-   printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->host ) );
-   print_banner(SCpnt->host);
+   printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) );
+   print_banner(SCpnt->device->host);
    switch (SCpnt->SCp.phase) {
    case in_arbitration: printk("arbitration"); break;
    case in_selection:   printk("selection");   break;
@@ -1596,7 +1596,7 @@
 
    printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
 	   SCpnt->SCp.phase,
-	   SCpnt->target,
+	   SCpnt->device->id,
 	   *(unsigned char *)SCpnt->cmnd,
 	   SCpnt->use_sg,
 	   SCpnt->request_bufflen );
diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/g_NCR5380.c	Mon Feb 10 10:39:24 2003
@@ -746,7 +746,7 @@
 static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd)
 {
 	int start = len;
-	PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->host->host_no ANDP cmd->target ANDP cmd->lun);
+	PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun);
 	PRINTP("        command = ");
 	len += sprint_command(buffer, len, cmd->cmnd);
 	return len - start;
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/gdth.c	Mon Feb 10 10:39:29 2003
@@ -2313,8 +2313,8 @@
     GDTH_LOCK_HA(ha, flags);
 
     scp->SCp.this_residual = (int)priority;
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-    t = scp->target;
+    b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+    t = scp->device->id;
 #if LINUX_VERSION_CODE >= 0x010300
     if (priority >= DEFAULT_PRI) {
         if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
@@ -2375,8 +2375,8 @@
     for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
         if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
             pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
-        b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
-        t = nscp->target;
+        b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
+        t = nscp->device->id;
         if (nscp->SCp.this_residual >= DEFAULT_PRI) {
             if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
@@ -2407,13 +2407,13 @@
                         b, t, nscp->lun));
                 /* TEST_UNIT_READY -> set scan mode */
                 if ((ha->scan_mode & 0x0f) == 0) {
-                    if (b == 0 && t == 0 && nscp->lun == 0) {
+                    if (b == 0 && t == 0 && nscp->device->lun == 0) {
                         ha->scan_mode |= 1;
                         TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));
                     }
                 } else if ((ha->scan_mode & 0x0f) == 1) {
-                    if (b == 0 && ((t == 0 && nscp->lun == 1) ||
-                         (t == 1 && nscp->lun == 0))) {
+                    if (b == 0 && ((t == 0 && nscp->device->lun == 1) ||
+                         (t == 1 && nscp->device->lun == 0))) {
                         nscp->SCp.sent_command = GDT_SCAN_START;
                         nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) 
                             | SCSIRAWSERVICE;
@@ -2483,7 +2483,7 @@
                 this_cmd = FALSE;
             else 
                 ha->raw[BUS_L2P(ha,b)].io_cnt[t]++;
-        } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->lun != 0) {
+        } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->device->lun != 0) {
             TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n",
                     nscp->cmnd[0], b, t, nscp->lun));
             nscp->result = DID_BAD_TARGET << 16;
@@ -2682,7 +2682,7 @@
     gdth_modep_data mpd;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    t  = scp->target;
+    t  = scp->device->id;
     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
            scp->cmnd[0],t));
 
@@ -2900,8 +2900,8 @@
     unchar t,l;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    t = scp->target;
-    l = scp->lun;
+    t = scp->device->id;
+    l = scp->device->lun;
     cmdp = ha->pccb;
     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
            scp->cmnd[0],b,t,l));
@@ -3372,7 +3372,7 @@
     if (rval == 2) {
         gdth_putq(hanum,scp,scp->SCp.this_residual);
     } else if (rval == 1) {
-        GDTH_LOCK_SCSI_DONE(scp->host, flags);
+        GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
         scp->scsi_done(scp);
         GDTH_UNLOCK_SCSI_DONE(scp->host,flags);
     }
@@ -3461,9 +3461,9 @@
         printk("\n");
 
     } else {
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+        b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
-            ha->raw[BUS_L2P(ha,b)].io_cnt[scp->target]--;
+            ha->raw[BUS_L2P(ha,b)].io_cnt[scp->device->id]--;
         }
         /* cache or raw service */
         if (ha->status == S_OK) {
@@ -3474,12 +3474,12 @@
                         scp->SCp.sent_command));
                 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
                 if (scp->SCp.sent_command == GDT_CLUST_INFO) {
-                    ha->hdr[scp->target].cluster_type = (unchar)ha->info;
-                    if (!(ha->hdr[scp->target].cluster_type & 
+                    ha->hdr[scp->device->id].cluster_type = (unchar)ha->info;
+                    if (!(ha->hdr[scp->device->id].cluster_type & 
                         CLUSTER_MOUNTED)) {
                         /* NOT MOUNTED -> MOUNT */
                         scp->SCp.sent_command = GDT_MOUNT;
-                        if (ha->hdr[scp->target].cluster_type & 
+                        if (ha->hdr[scp->device->id].cluster_type & 
                             CLUSTER_RESERVED) {
                             /* cluster drive RESERVED (on the other node) */
                             scp->SCp.phase = -2;      /* reservation conflict */
@@ -3489,11 +3489,11 @@
                     }
                 } else {
                     if (scp->SCp.sent_command == GDT_MOUNT) {
-                        ha->hdr[scp->target].cluster_type |= CLUSTER_MOUNTED;
-                        ha->hdr[scp->target].media_changed = TRUE;
+                        ha->hdr[scp->device->id].cluster_type |= CLUSTER_MOUNTED;
+                        ha->hdr[scp->device->id].media_changed = TRUE;
                     } else if (scp->SCp.sent_command == GDT_UNMOUNT) {
-                        ha->hdr[scp->target].cluster_type &= ~CLUSTER_MOUNTED;
-                        ha->hdr[scp->target].media_changed = TRUE;
+                        ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_MOUNTED;
+                        ha->hdr[scp->device->id].media_changed = TRUE;
                     } 
                     scp->SCp.sent_command = -1;
                 }
@@ -3503,9 +3503,9 @@
             } else {
                 /* RESERVE/RELEASE ? */
                 if (scp->cmnd[0] == RESERVE) {
-                    ha->hdr[scp->target].cluster_type |= CLUSTER_RESERVED;
+                    ha->hdr[scp->device->id].cluster_type |= CLUSTER_RESERVED;
                 } else if (scp->cmnd[0] == RELEASE) {
-                    ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED;
+                    ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED;
                 }           
                 scp->result = DID_OK << 16;
                 scp->sense_buffer[0] = 0;
@@ -3538,10 +3538,10 @@
                 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
             } else if (service == CACHESERVICE) {
                 if (ha->status == S_CACHE_UNKNOWN &&
-                    (ha->hdr[scp->target].cluster_type & 
+                    (ha->hdr[scp->device->id].cluster_type & 
                      CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) {
                     /* bus reset -> force GDT_CLUST_INFO */
-                    ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED;
+                    ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED;
                 }
                 memset((char*)scp->sense_buffer,0,16);
                 if (ha->status == (ushort)S_CACHE_RESERV) {
@@ -3560,7 +3560,7 @@
                     ha->dvr.eu.sync.service = service;
                     ha->dvr.eu.sync.status  = ha->status;
                     ha->dvr.eu.sync.info    = ha->info;
-                    ha->dvr.eu.sync.hostdrive = scp->target;
+                    ha->dvr.eu.sync.hostdrive = scp->device->id;
                     if (ha->status >= 0x8000)
                         gdth_store_event(ha, ES_SYNC, 0, &ha->dvr);
                     else
@@ -4507,15 +4507,15 @@
     unchar b;
 
     TRACE2(("gdth_eh_bus_reset()\n"));
-    hanum = NUMDATA(scp->host)->hanum;
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+    hanum = NUMDATA(scp->device->host)->hanum;
+    b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
     ha    = HADATA(gdth_ctr_tab[hanum]);
 
     /* clear command tab */
     GDTH_LOCK_HA(ha, flags);
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         cmnd = ha->cmd_tab[i].cmnd;
-        if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
+        if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
             ha->cmd_tab[i].cmnd = UNUSED_CMND;
     }
     GDTH_UNLOCK_HA(ha, flags);
@@ -4593,13 +4593,13 @@
     int priority;
 
     TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n",
-           scp->cmnd[0],scp->target,scp->lun));
+           scp->cmnd[0],scp->device->id,scp->lun));
     
     scp->scsi_done = (void *)done;
     scp->SCp.have_data_in = 1;
     scp->SCp.phase = -1;
     scp->SCp.sent_command = -1;
-    hanum = NUMDATA(scp->host)->hanum;
+    hanum = NUMDATA(scp->device->host)->hanum;
 #ifdef GDTH_STATISTICS
     ++act_ios;
 #endif
@@ -4637,7 +4637,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-    scp  = scsi_allocate_device(sdev, 1);
+    scp  = scsi_get_command(sdev, GFP_KERNEL);
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -4665,7 +4665,7 @@
         }
     }
 #if LINUX_VERSION_CODE >= 0x020322
-    scsi_release_command(scp);
+    scsi_put_command(scp);
     scsi_free_host_dev(sdev);
 #endif
 }
@@ -4711,7 +4711,7 @@
         memset(cmnd, 0xff, MAX_COMMAND_SIZE);
 #if LINUX_VERSION_CODE >= 0x020322
         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-        scp  = scsi_allocate_device(sdev, 1);
+        scp  = scsi_get_command(sdev, GFP_KERNEL);
         scp->cmd_len = 12;
         scp->use_sg = 0;
 #else
@@ -4728,7 +4728,7 @@
         TRACE2(("gdth_halt(): reset controller %d\n", hanum));
 #if LINUX_VERSION_CODE >= 0x020322
         gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
-        scsi_release_command(scp);
+        scsi_put_command(scp);
         scsi_free_host_dev(sdev);
 #else
         gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
--- a/drivers/scsi/gdth_proc.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/gdth_proc.c	Mon Feb 10 10:39:27 2003
@@ -48,7 +48,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_allocate_device(sdev, 1);
+    scp  = scsi_get_command(sdev, GFP_KERNEL);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
@@ -81,7 +81,7 @@
         ret_val = -EINVAL;
     }
 #if LINUX_VERSION_CODE >= 0x020322
-    scsi_release_command(scp);
+    scsi_put_command(scp);
     scsi_free_host_dev(sdev);
 #endif
     return ret_val;
@@ -447,8 +447,8 @@
         piord->size = sizeof(gdth_iord_str);
         memcpy(cmnd, piowr->iu.scsi.cmd, 12);
 #if LINUX_VERSION_CODE >= 0x020322
-        scp->target = piowr->iu.scsi.target;
-        scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+        scp->device->id = piowr->iu.scsi.target;
+        scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
         scp->cmd_len = piowr->iu.scsi.cmd_len;
         gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout);
         piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
@@ -467,7 +467,7 @@
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
 #if LINUX_VERSION_CODE >= 0x020322
-        scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+        scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
         piord->status = (ulong32)gdth_eh_bus_reset( scp );
         if (piord->status == SUCCESS)
             piord->status = S_OK;
@@ -712,7 +712,7 @@
 
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_allocate_device(sdev, 1);
+    scp  = scsi_get_command(sdev, GFP_KERNEL);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
@@ -1234,7 +1234,7 @@
 
 stop_output:
 #if LINUX_VERSION_CODE >= 0x020322
-    scsi_release_command(scp);
+    scsi_put_command(scp);
     scsi_free_host_dev(sdev);
 #endif
     *start = buffer +(offset-begin);
@@ -1383,8 +1383,8 @@
 
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         scp = ha->cmd_tab[i].cmnd;
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        if (!SPECIAL_SCP(scp) && scp->target == (unchar)id && 
+        b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+        if (!SPECIAL_SCP(scp) && scp->device->id == (unchar)id && 
             b == (unchar)busnum) {
             scp->SCp.have_data_in = 0;
             GDTH_UNLOCK_HA(ha, flags);
@@ -1410,8 +1410,8 @@
     GDTH_LOCK_HA(ha, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        if (scp->target == (unchar)id && b == (unchar)busnum) {
+        b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+        if (scp->device->id == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
             scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
         }
@@ -1430,8 +1430,8 @@
     GDTH_LOCK_HA(ha, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        if (scp->target == (unchar)id && b == (unchar)busnum) {
+        b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+        if (scp->device->id == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_start_timeout(): update_timeout()\n"));
             gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
         }
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/hosts.c	Mon Feb 10 10:39:23 2003
@@ -205,13 +205,15 @@
 {
 	struct Scsi_Host *shost = sdev->host;
 	struct scsi_cmnd *scmd;
+	unsigned long flags;
 
 	/*
 	 * Loop over all of the commands associated with the
 	 * device.  If any of them are busy, then set the state
 	 * back to inactive and bail.
 	 */
-	for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
+	spin_lock_irqsave(&sdev->list_lock, flags);
+	list_for_each_entry(scmd, &sdev->cmd_list, list) {
 		if (scmd->request && scmd->request->rq_status != RQ_INACTIVE)
 			goto active;
 
@@ -223,22 +225,24 @@
 		if (scmd->request)
 			scmd->request->rq_status = RQ_SCSI_DISCONNECTING;
 	}
+	spin_unlock_irqrestore(&sdev->list_lock, flags);
 
 	return 0;
 
 active:
 	printk(KERN_ERR "SCSI device not inactive - rq_status=%d, target=%d, "
 			"pid=%ld, state=%d, owner=%d.\n",
-			scmd->request->rq_status, scmd->target,
+			scmd->request->rq_status, scmd->device->id,
 			scmd->pid, scmd->state, scmd->owner);
 
 	list_for_each_entry(sdev, &shost->my_devices, siblings) {
-		for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
+		list_for_each_entry(scmd, &sdev->cmd_list, list) {
 			if (scmd->request->rq_status == RQ_SCSI_DISCONNECTING)
 				scmd->request->rq_status = RQ_INACTIVE;
 		}
 	}
 
+	spin_unlock_irqrestore(&sdev->list_lock, flags);
 	printk(KERN_ERR "Device busy???\n");
 	return 1;
 }
@@ -285,7 +289,15 @@
 	return 0;
 }
 
-int __scsi_add_host(struct Scsi_Host *shost)
+/**
+ * scsi_add_host - add a scsi host
+ * @shost:	scsi host pointer to add
+ * @dev:	a struct device of type scsi class
+ *
+ * Return value: 
+ * 	0 on success / != 0 for error
+ **/
+int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
 {
 	Scsi_Host_Template *sht = shost->hostt;
 	struct scsi_device *sdev;
@@ -294,6 +306,11 @@
 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
 			sht->info ? sht->info(shost) : sht->name);
 
+	if (dev) {
+		dev->class_data = shost;
+		shost->host_gendev = dev;
+	}
+
 	scsi_scan_host(shost);
 			
 	list_for_each_entry (sdev, &shost->my_devices, siblings) {
@@ -306,23 +323,6 @@
 }
 
 /**
- * scsi_add_host - add a scsi host
- * @shost:	scsi host pointer to add
- * @dev:	a struct device of type scsi class
- *
- * Return value: 
- * 	0 on success / != 0 for error
- **/
-int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
-{
-	if (dev) {
-		dev->class_data = shost;
-		shost->host_gendev = dev;
-	}
-	return __scsi_add_host(shost);
-}
-
-/**
  * scsi_unregister - unregister a scsi host
  * @shost:	scsi host to be unregistered
  **/
@@ -346,10 +346,8 @@
 	}
 
 	shost->hostt->present--;
-
-	/* Cleanup proc */
 	scsi_proc_host_rm(shost);
-
+	scsi_destroy_command_freelist(shost);
 	kfree(shost);
 }
 
@@ -370,7 +368,7 @@
 struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
 {
 	struct Scsi_Host *shost, *shost_scr;
-	int gfp_mask;
+	int gfp_mask, rval;
 	DECLARE_COMPLETION(sem);
 
         /* Check to see if this host has any error handling facilities */
@@ -398,7 +396,6 @@
 
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
-	atomic_set(&shost->host_active,0);
 	INIT_LIST_HEAD(&shost->my_devices);
 
 	init_waitqueue_head(&shost->host_wait);
@@ -437,7 +434,7 @@
 	shost->unchecked_isa_dma = shost_tp->unchecked_isa_dma;
 	shost->use_clustering = shost_tp->use_clustering;
 	if (!blk_nohighio)
-	shost->highmem_io = shost_tp->highmem_io;
+		shost->highmem_io = shost_tp->highmem_io;
 
 	shost->max_sectors = shost_tp->max_sectors;
 	shost->use_blk_tcq = shost_tp->use_blk_tcq;
@@ -459,6 +456,9 @@
 found:
 	spin_unlock(&scsi_host_list_lock);
 
+	rval = scsi_setup_command_freelist(shost);
+	if (rval)
+		goto fail;
 	scsi_proc_host_add(shost);
 
 	shost->eh_notify = &sem;
@@ -469,10 +469,15 @@
 	 */
 	wait_for_completion(&sem);
 	shost->eh_notify = NULL;
-
 	shost->hostt->present++;
-
 	return shost;
+
+fail:
+	spin_lock(&scsi_host_list_lock);
+	list_del(&shost->sh_list);
+	spin_unlock(&scsi_host_list_lock);
+	kfree(shost);
+	return NULL;
 }
 
 /**
@@ -505,7 +510,7 @@
 	 */
 	list_for_each_entry(shost, &scsi_host_list, sh_list)
 		if (shost->hostt == shost_tp)
-			if (__scsi_add_host(shost))
+			if (scsi_add_host(shost, NULL))
 				goto out_of_space;
 
 	return 0;
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/hosts.h	Mon Feb 10 10:39:24 2003
@@ -29,6 +29,9 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 
+struct scsi_host_cmd_pool;
+
+
 /* It is senseless to set SG_ALL any higher than this - the performance
  *  does not get any better, and it wastes memory
  */
@@ -375,6 +378,10 @@
     struct list_head      sh_list;
     struct list_head	  my_devices;
 
+    struct scsi_host_cmd_pool *cmd_pool;
+    spinlock_t            free_list_lock;
+    struct list_head      free_list;   /* backup store of cmd structs */
+
     spinlock_t		  default_lock;
     spinlock_t		  *host_lock;
 
@@ -389,7 +396,6 @@
     unsigned int            eh_kill:1; /* set when killing the eh thread */
     wait_queue_head_t       host_wait;
     Scsi_Host_Template    * hostt;
-    atomic_t                host_active; /* commands checked out */
     volatile unsigned short host_busy;   /* commands actually active on low-level */
     volatile unsigned short host_failed; /* commands that failed. */
     
@@ -605,8 +611,8 @@
 	list_for_each_entry (sdev, &shost->my_devices, siblings)
                 if (sdev->channel == channel && sdev->id == pun
                    && sdev->lun ==lun)
-                        break;
-        return sdev;
+                        return sdev;
+        return NULL;
 }
 
 /*
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/ide-scsi.c	Mon Feb 10 10:39:29 2003
@@ -96,9 +96,18 @@
 	unsigned long flags;			/* Status/Action flags */
 	unsigned long transform;		/* SCSI cmd translation layer */
 	unsigned long log;			/* log flags */
-	int id;
 } idescsi_scsi_t;
 
+static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)
+{
+	return (idescsi_scsi_t*) (&host[1]);
+}
+
+static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
+{
+	return scsihost_to_idescsi(ide_drive->driver_data);
+}
+
 /*
  *	Per ATAPI device status bits.
  */
@@ -262,7 +271,7 @@
 
 static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_command)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	idescsi_pc_t   *pc;
 	struct request *rq;
 	u8             *buf;
@@ -299,7 +308,7 @@
 
 static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	struct request *rq = HWGROUP(drive)->rq;
 	idescsi_pc_t *pc = (idescsi_pc_t *) rq->special;
 	int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
@@ -348,7 +357,7 @@
 			} else printk("\n");
 		}
 	}
-	host = pc->scsi_cmd->host;
+	host = pc->scsi_cmd->device->host;
 	spin_lock_irqsave(host->host_lock, flags);
 	pc->done(pc->scsi_cmd);
 	spin_unlock_irqrestore(host->host_lock, flags);
@@ -369,7 +378,7 @@
  */
 static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	idescsi_pc_t *pc=scsi->pc;
 	struct request *rq = pc->rq;
 	atapi_bcount_t bcount;
@@ -463,7 +472,7 @@
 
 static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	idescsi_pc_t *pc = scsi->pc;
 	atapi_ireason_t ireason;
 	ide_startstop_t startstop;
@@ -493,7 +502,7 @@
  */
 static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	atapi_feature_t feature;
 	atapi_bcount_t bcount;
 	struct request *rq = pc->rq;
@@ -555,11 +564,9 @@
 	return ide_stopped;
 }
 
-static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES];
-
 static void idescsi_add_settings(ide_drive_t *drive)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 
 /*
  *			drive	setting name	read/write	ioctl	ioctl		data type	min	max	mul_factor	div_factor	data pointer		set function
@@ -574,15 +581,10 @@
 /*
  *	Driver initialization.
  */
-static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
+static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
 {
 	DRIVER(drive)->busy++;
-	idescsi_drives[id] = drive;
-	drive->driver_data = scsi;
 	drive->ready_stat = 0;
-	memset (scsi, 0, sizeof (idescsi_scsi_t));
-	scsi->drive = drive;
-	scsi->id = id;
 	if (drive->id && (drive->id->config & 0x0060) == 0x20)
 		set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
 	set_bit(IDESCSI_TRANSFORM, &scsi->transform);
@@ -596,13 +598,17 @@
 
 static int idescsi_cleanup (ide_drive_t *drive)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	struct Scsi_Host *scsihost = drive->driver_data;
 
 	if (ide_unregister_subdriver(drive))
 		return 1;
+	
+	/* FIXME?: Are these two statements necessary? */
 	drive->driver_data = NULL;
 	drive->disk->fops = ide_fops;
-	kfree(scsi);
+
+	scsi_remove_host(scsihost);
+	scsi_unregister(scsihost);
 	return 0;
 }
 
@@ -654,52 +660,23 @@
 	.ioctl		= idescsi_ide_ioctl,
 };
 
-static int idescsi_attach(ide_drive_t *drive)
-{
-	idescsi_scsi_t *scsi;
-	int id;
-
-	if (!strstr("ide-scsi", drive->driver_req))
-		goto failed;
-	if (!drive->present)
-		goto failed;
-	/* we accept everything except ide-disk */
-	if (drive->media == ide_disk)
-		goto failed;
-	if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
-		printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
-		goto failed;
-	}
-	if (ide_register_subdriver (drive, &idescsi_driver, IDE_SUBDRIVER_VERSION)) {
-		printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
-		kfree (scsi);
-		goto failed;
-	}
-	for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
-		;
-	idescsi_setup (drive, scsi, id);
-	drive->disk->fops = &idescsi_ops;
-	return 0;
-failed:
-	return 1;
-}
+static int idescsi_attach(ide_drive_t *drive);
 
-int idescsi_slave_configure(Scsi_Device * sdp)
+static int idescsi_slave_configure(Scsi_Device * sdp)
 {
 	/* Configure detected device */
 	scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);
 	return 0;
 }
 
-const char *idescsi_info (struct Scsi_Host *host)
+static const char *idescsi_info (struct Scsi_Host *host)
 {
 	return "SCSI host adapter emulation for IDE ATAPI devices";
 }
 
-int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
+static int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
 {
-	ide_drive_t *drive = idescsi_drives[dev->id];
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);
 
 	if (cmd == SG_SET_TRANSFORM) {
 		if (arg)
@@ -789,7 +766,7 @@
 
 static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
 {
-	idescsi_scsi_t *scsi = drive->driver_data;
+	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	struct gendisk *disk = cmd->request->rq_disk;
 
 	if (disk) {
@@ -800,18 +777,18 @@
 	return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
 }
 
-int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-	ide_drive_t *drive = idescsi_drives[cmd->target];
-	idescsi_scsi_t *scsi;
+	idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);
+	ide_drive_t *drive = scsi->drive;
 	struct request *rq = NULL;
 	idescsi_pc_t *pc = NULL;
 
 	if (!drive) {
-		printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target);
+		printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->device->id);
 		goto abort;
 	}
-	scsi = drive->driver_data;
+	scsi = drive_to_idescsi(drive);
 	pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
 	rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
 	if (rq == NULL || pc == NULL) {
@@ -853,9 +830,9 @@
 	rq->special = (char *) pc;
 	rq->bio = idescsi_dma_bio (drive, pc);
 	rq->flags = REQ_SPECIAL;
-	spin_unlock_irq(cmd->host->host_lock);
+	spin_unlock_irq(cmd->device->host->host_lock);
 	(void) ide_do_drive_cmd (drive, rq, ide_end);
-	spin_lock_irq(cmd->host->host_lock);
+	spin_lock_irq(cmd->device->host->host_lock);
 	return 0;
 abort:
 	if (pc) kfree (pc);
@@ -865,43 +842,43 @@
 	return 1;
 }
 
-int idescsi_abort (Scsi_Cmnd *cmd)
+static int idescsi_abort (Scsi_Cmnd *cmd)
 {
 	int countdown = 8;
 	unsigned long flags;
-	ide_drive_t *drive = idescsi_drives[cmd->target];
-	idescsi_scsi_t *scsi;
+	idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host);
+	ide_drive_t *drive = scsi->drive;
 
 	printk (KERN_ERR "ide-scsi: abort called for %lu\n", cmd->serial_number);
-	if (drive && (scsi = drive->driver_data))
-		while (countdown--) {
-			/* is cmd active?
-			 *  need to lock so this stuff doesn't change under us */
-			spin_lock_irqsave(&ide_lock, flags);
-			if (scsi->pc && scsi->pc->scsi_cmd && 
-					scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
-				/* yep - let's give it some more time - 
-				 * we can do that, we're in _our_ error kernel thread */
-				spin_unlock_irqrestore(&ide_lock, flags);
-				scsi_sleep(HZ);
-				continue;
-			}
-			/* no, but is it queued in the ide subsystem? */
-			if (elv_queue_empty(&drive->queue)) {
-				spin_unlock_irqrestore(&ide_lock, flags);
-				return SUCCESS;
-			}
+	while (countdown--) {
+		/* is cmd active?
+		 *  need to lock so this stuff doesn't change under us */
+		spin_lock_irqsave(&ide_lock, flags);
+		if (scsi->pc && scsi->pc->scsi_cmd && 
+				scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
+			/* yep - let's give it some more time - 
+			 * we can do that, we're in _our_ error kernel thread */
+			spin_unlock_irqrestore(&ide_lock, flags);
+			scsi_sleep(HZ);
+			continue;
+		}
+		/* no, but is it queued in the ide subsystem? */
+		if (elv_queue_empty(&drive->queue)) {
 			spin_unlock_irqrestore(&ide_lock, flags);
-			schedule_timeout(HZ/10);
+			return SUCCESS;
 		}
+		spin_unlock_irqrestore(&ide_lock, flags);
+		schedule_timeout(HZ/10);
+	}
 	return FAILED;
 }
 
-int idescsi_reset (Scsi_Cmnd *cmd)
+static int idescsi_reset (Scsi_Cmnd *cmd)
 {
 	unsigned long flags;
 	struct request *req;
-	ide_drive_t *drive = idescsi_drives[cmd->target];
+	idescsi_scsi_t *idescsi = scsihost_to_idescsi(cmd->device->host);
+	ide_drive_t *drive = idescsi->drive;
 
 	printk (KERN_ERR "ide-scsi: reset called for %lu\n", cmd->serial_number);
 	/* first null the handler for the drive and let any process
@@ -919,7 +896,8 @@
 	}
 	/* FIXME - this will probably leak memory */
 	HWGROUP(drive)->rq = NULL;
-	if (drive->driver_data) ((idescsi_scsi_t *)drive->driver_data)->pc = NULL;
+	if (drive_to_idescsi(drive))
+		drive_to_idescsi(drive)->pc = NULL;
 	spin_unlock_irqrestore(&ide_lock, flags);
 	/* finally, reset the drive (and its partner on the bus...) */
 	ide_do_reset (drive);	
@@ -929,7 +907,8 @@
 static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,
 		sector_t capacity, int *parm)
 {
-	ide_drive_t *drive = idescsi_drives[sdev->id];
+	idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);
+	ide_drive_t *drive = idescsi->drive;
 
 	if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
 		parm[0] = drive->bios_head;
@@ -956,10 +935,9 @@
 	.max_sectors		= 128,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.emulated		= 1,
+	.proc_name		= "ide-scsi",
 };
 
-static struct Scsi_Host *idescsi_host;
-
 static struct device     idescsi_primary = {
 	.name		= "Ide-scsi Parent",
 	.bus_id		= "ide-scsi",
@@ -968,39 +946,60 @@
 	.name		= "ide-scsi",
 };
 
-static int __init init_idescsi_module(void)
+static int idescsi_attach(ide_drive_t *drive)
 {
-	int id;
-	int last_lun = 0;
+	idescsi_scsi_t *idescsi;
+	struct Scsi_Host *host;
+	int err;
 
-	ide_register_driver(&idescsi_driver);
-	device_register(&idescsi_primary);
-	bus_register   (&idescsi_emu_bus);
-	idescsi_template.proc_name = "ide-scsi";
-	idescsi_host = scsi_register(&idescsi_template, 0);
-	if(idescsi_host == NULL)
+	if (!strstr("ide-scsi", drive->driver_req) ||
+	    !drive->present ||
+	    drive->media == ide_disk ||
+	    !(host = scsi_register(&idescsi_template,sizeof(idescsi_scsi_t))))
 		return 1;
-		
-	for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++)
-		last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun);
-	idescsi_host->max_id = id;
-	idescsi_host->max_lun = last_lun + 1;
-	scsi_add_host(idescsi_host, &idescsi_primary);
-	return 0;
+
+	host->max_id = 1;
+	host->max_lun = 1;
+	drive->driver_data = host;
+	idescsi = scsihost_to_idescsi(host);
+	idescsi->drive = drive;
+	err = ide_register_subdriver (drive, &idescsi_driver,
+				      IDE_SUBDRIVER_VERSION);
+	if (!err) {
+		idescsi_setup (drive, idescsi);
+		drive->disk->fops = &idescsi_ops;
+		err = scsi_add_host(host, &idescsi_primary);
+		if (!err)
+			return 0;
+		/* fall through on error */
+		ide_unregister_subdriver(drive);
+	}
+
+	scsi_unregister(host);
+	return err;
 }
 
-static void __exit exit_idescsi_module(void)
+static int __init init_idescsi_module(void)
 {
-	ide_drive_t *drive;
-	int id;
+	int err;
 
-	scsi_remove_host(idescsi_host);
-	for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
-		drive = idescsi_drives[id];
-		if (drive)
-			DRIVER(drive)->busy = 0;
+	err = bus_register(&idescsi_emu_bus);
+	if (!err) {
+		err = device_register(&idescsi_primary);
+		if (!err) {
+			err = ide_register_driver(&idescsi_driver);
+			if (!err)
+				return 0;
+
+			device_unregister(&idescsi_primary);
+		}
+		bus_unregister(&idescsi_emu_bus);
 	}
-	scsi_unregister   (idescsi_host);
+	return err;
+}
+
+static void __exit exit_idescsi_module(void)
+{
 	device_unregister(&idescsi_primary);
 	bus_unregister   (&idescsi_emu_bus);
 	ide_unregister_driver(&idescsi_driver);
diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/in2000.c	Mon Feb 10 10:39:30 2003
@@ -343,10 +343,10 @@
 	struct IN2000_hostdata *hostdata;
 	Scsi_Cmnd *tmp;
 
-	instance = cmd->host;
+	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
-	DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->target, cmd->cmnd[0], cmd->pid))
+	DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->device->id, cmd->cmnd[0], cmd->pid))
 
 /* Set up a few fields in the Scsi_Cmnd structure for our own use:
  *  - host_scribble is the pointer to the next cmd in the input queue
@@ -428,7 +428,7 @@
  * Go see if any of them are runnable!
  */
 
-	in2000_execute(cmd->host);
+	in2000_execute(cmd->device->host);
 
 	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid))
 	    return 0;
@@ -473,7 +473,7 @@
 	cmd = (Scsi_Cmnd *) hostdata->input_Q;
 	prev = 0;
 	while (cmd) {
-		if (!(hostdata->busy[cmd->target] & (1 << cmd->lun)))
+		if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)))
 			break;
 		prev = cmd;
 		cmd = (Scsi_Cmnd *) cmd->host_scribble;
@@ -496,7 +496,7 @@
 		hostdata->input_Q = (Scsi_Cmnd *) cmd->host_scribble;
 
 #ifdef PROC_STATISTICS
-	hostdata->cmd_cnt[cmd->target]++;
+	hostdata->cmd_cnt[cmd->device->id]++;
 #endif
 
 /*
@@ -504,9 +504,9 @@
  */
 
 	if (is_dir_out(cmd))
-		write_3393(hostdata, WD_DESTINATION_ID, cmd->target);
+		write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id);
 	else
-		write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
+		write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id | DSTID_DPD);
 
 /* Now we need to figure out whether or not this command is a good
  * candidate for disconnect/reselect. We guess to the best of our
@@ -543,7 +543,7 @@
 	if (!(hostdata->input_Q))	/* input_Q empty? */
 		goto no;
 	for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble) {
-		if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) {
+		if ((prev->device->id != cmd->device->id) || (prev->device->lun != cmd->device->lun)) {
 			for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble)
 				prev->SCp.phase = 1;
 			goto yes;
@@ -555,17 +555,17 @@
 	cmd->SCp.phase = 1;
 
 #ifdef PROC_STATISTICS
-	hostdata->disc_allowed_cnt[cmd->target]++;
+	hostdata->disc_allowed_cnt[cmd->device->id]++;
 #endif
 
       no:
 	write_3393(hostdata, WD_SOURCE_ID, ((cmd->SCp.phase) ? SRCID_ER : 0));
 
-	write_3393(hostdata, WD_TARGET_LUN, cmd->lun);
-	write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]);
-	hostdata->busy[cmd->target] |= (1 << cmd->lun);
+	write_3393(hostdata, WD_TARGET_LUN, cmd->device->lun);
+	write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->device->id]);
+	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 
-	if ((hostdata->level2 <= L2_NONE) || (hostdata->sync_stat[cmd->target] == SS_UNSET)) {
+	if ((hostdata->level2 <= L2_NONE) || (hostdata->sync_stat[cmd->device->id] == SS_UNSET)) {
 
 		/*
 		 * Do a 'Select-With-ATN' command. This will end with
@@ -587,11 +587,11 @@
  * unless we don't want to even _try_ synchronous transfers: In this
  * case we set SS_SET to make the defaults final.
  */
-		if (hostdata->sync_stat[cmd->target] == SS_UNSET) {
-			if (hostdata->sync_off & (1 << cmd->target))
-				hostdata->sync_stat[cmd->target] = SS_SET;
+		if (hostdata->sync_stat[cmd->device->id] == SS_UNSET) {
+			if (hostdata->sync_off & (1 << cmd->device->id))
+				hostdata->sync_stat[cmd->device->id] = SS_SET;
 			else
-				hostdata->sync_stat[cmd->target] = SS_FIRST;
+				hostdata->sync_stat[cmd->device->id] = SS_FIRST;
 		}
 		hostdata->state = S_SELECTING;
 		write_3393_count(hostdata, 0);	/* this guarantees a DATA_PHASE interrupt */
@@ -753,7 +753,7 @@
 	unsigned short f;
 	int i;
 
-	hostdata = (struct IN2000_hostdata *) cmd->host->hostdata;
+	hostdata = (struct IN2000_hostdata *) cmd->device->host->hostdata;
 
 /* Normally, you'd expect 'this_residual' to be non-zero here.
  * In a series of scatter-gather transfers, however, this
@@ -772,7 +772,7 @@
 
 /* Set up hardware registers */
 
-	write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]);
+	write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->device->id]);
 	write_3393_count(hostdata, cmd->SCp.this_residual);
 	write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS);
 	write1_io(0, IO_FIFO_WRITE);	/* zero counter, assume write */
@@ -1077,7 +1077,7 @@
 		}
 
 		cmd->result = DID_NO_CONNECT << 16;
-		hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 		hostdata->state = S_UNCONNECTED;
 		cmd->scsi_done(cmd);
 
@@ -1099,16 +1099,16 @@
 
 		/* construct an IDENTIFY message with correct disconnect bit */
 
-		hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->lun);
+		hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->device->lun);
 		if (cmd->SCp.phase)
 			hostdata->outgoing_msg[0] |= 0x40;
 
-		if (hostdata->sync_stat[cmd->target] == SS_FIRST) {
+		if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) {
 #ifdef SYNC_DEBUG
 			printk(" sending SDTR ");
 #endif
 
-			hostdata->sync_stat[cmd->target] = SS_WAITING;
+			hostdata->sync_stat[cmd->device->id] = SS_WAITING;
 
 			/* tack on a 2nd message to ask about synchronous transfers */
 
@@ -1227,8 +1227,8 @@
 #ifdef SYNC_DEBUG
 			    printk("-REJ-");
 #endif
-			if (hostdata->sync_stat[cmd->target] == SS_WAITING)
-				hostdata->sync_stat[cmd->target] = SS_SET;
+			if (hostdata->sync_stat[cmd->device->id] == SS_WAITING)
+				hostdata->sync_stat[cmd->device->id] = SS_SET;
 			write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
 			hostdata->state = S_CONNECTED;
 			break;
@@ -1248,7 +1248,7 @@
 				switch (ucp[2]) {	/* what's the EXTENDED code? */
 				case EXTENDED_SDTR:
 					id = calc_sync_xfer(ucp[3], ucp[4]);
-					if (hostdata->sync_stat[cmd->target] != SS_WAITING) {
+					if (hostdata->sync_stat[cmd->device->id] != SS_WAITING) {
 
 /* A device has sent an unsolicited SDTR message; rather than go
  * through the effort of decoding it and then figuring out what
@@ -1266,14 +1266,14 @@
 						hostdata->outgoing_msg[3] = hostdata->default_sx_per / 4;
 						hostdata->outgoing_msg[4] = 0;
 						hostdata->outgoing_len = 5;
-						hostdata->sync_xfer[cmd->target] = calc_sync_xfer(hostdata->default_sx_per / 4, 0);
+						hostdata->sync_xfer[cmd->device->id] = calc_sync_xfer(hostdata->default_sx_per / 4, 0);
 					} else {
-						hostdata->sync_xfer[cmd->target] = id;
+						hostdata->sync_xfer[cmd->device->id] = id;
 					}
 #ifdef SYNC_DEBUG
-					printk("sync_xfer=%02x", hostdata->sync_xfer[cmd->target]);
+					printk("sync_xfer=%02x", hostdata->sync_xfer[cmd->device->id]);
 #endif
-					hostdata->sync_stat[cmd->target] = SS_SET;
+					hostdata->sync_stat[cmd->device->id] = SS_SET;
 					write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
 					hostdata->state = S_CONNECTED;
 					break;
@@ -1335,7 +1335,7 @@
 			lun = read_3393(hostdata, WD_TARGET_LUN);
 			DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
 			    hostdata->connected = NULL;
-			hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 			hostdata->state = S_UNCONNECTED;
 			if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
 				cmd->SCp.Status = lun;
@@ -1420,7 +1420,7 @@
 		}
 		DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid))
 		    hostdata->connected = NULL;
-		hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 		hostdata->state = S_UNCONNECTED;
 		if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
 			cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
@@ -1451,7 +1451,7 @@
 		switch (hostdata->state) {
 		case S_PRE_CMP_DISC:
 			hostdata->connected = NULL;
-			hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+			hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 			hostdata->state = S_UNCONNECTED;
 			DB(DB_INTR, printk(":%d", cmd->SCp.Status))
 			    if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
@@ -1468,7 +1468,7 @@
 			hostdata->state = S_UNCONNECTED;
 
 #ifdef PROC_STATISTICS
-			hostdata->disc_done_cnt[cmd->target]++;
+			hostdata->disc_done_cnt[cmd->device->id]++;
 #endif
 
 			break;
@@ -1496,7 +1496,7 @@
 			if (hostdata->selecting) {
 				cmd = (Scsi_Cmnd *) hostdata->selecting;
 				hostdata->selecting = NULL;
-				hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+				hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 				cmd->host_scribble = (uchar *) hostdata->input_Q;
 				hostdata->input_Q = cmd;
 			}
@@ -1506,7 +1506,7 @@
 
 			if (cmd) {
 				if (phs == 0x00) {
-					hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 					cmd->host_scribble = (uchar *) hostdata->input_Q;
 					hostdata->input_Q = cmd;
 				} else {
@@ -1538,7 +1538,7 @@
 		cmd = (Scsi_Cmnd *) hostdata->disconnected_Q;
 		patch = NULL;
 		while (cmd) {
-			if (id == cmd->target && lun == cmd->lun)
+			if (id == cmd->device->id && lun == cmd->device->lun)
 				break;
 			patch = cmd;
 			cmd = (Scsi_Cmnd *) cmd->host_scribble;
@@ -1565,9 +1565,9 @@
 		 */
 
 		if (is_dir_out(cmd))
-			write_3393(hostdata, WD_DESTINATION_ID, cmd->target);
+			write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id);
 		else
-			write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
+			write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id | DSTID_DPD);
 		if (hostdata->level2 >= L2_RESELECT) {
 			write_3393_count(hostdata, 0);	/* we want a DATA_PHASE interrupt */
 			write_3393(hostdata, WD_COMMAND_PHASE, 0x45);
@@ -1648,7 +1648,7 @@
 	struct IN2000_hostdata *hostdata;
 	int x;
 
-	instance = cmd->host;
+	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
 	printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
@@ -1693,7 +1693,7 @@
 	uchar sr, asr;
 	unsigned long timeout;
 
-	instance = cmd->host;
+	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
 	printk(KERN_DEBUG "scsi%d: Abort-", instance->host_no);
@@ -1767,7 +1767,7 @@
 		sr = read_3393(hostdata, WD_SCSI_STATUS);
 		printk("asr=%02x, sr=%02x.", asr, sr);
 
-		hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 		hostdata->connected = NULL;
 		hostdata->state = S_UNCONNECTED;
 		cmd->result = DID_ABORT << 16;
@@ -2263,7 +2263,7 @@
 		strcat(bp, "\nconnected:     ");
 		if (hd->connected) {
 			cmd = (Scsi_Cmnd *) hd->connected;
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 		}
 	}
@@ -2271,7 +2271,7 @@
 		strcat(bp, "\ninput_Q:       ");
 		cmd = (Scsi_Cmnd *) hd->input_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (Scsi_Cmnd *) cmd->host_scribble;
 		}
@@ -2280,7 +2280,7 @@
 		strcat(bp, "\ndisconnected_Q:");
 		cmd = (Scsi_Cmnd *) hd->disconnected_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (Scsi_Cmnd *) cmd->host_scribble;
 		}
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/ini9100u.c	Mon Feb 10 10:39:24 2003
@@ -466,9 +466,9 @@
 	pSCB->SCB_Srb = SCpnt;
 	pSCB->SCB_Opcode = ExecSCSI;
 	pSCB->SCB_Flags = SCF_POST;	/* After SCSI done, call post routine */
-	pSCB->SCB_Target = SCpnt->target;
-	pSCB->SCB_Lun = SCpnt->lun;
-	pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW;
+	pSCB->SCB_Target = SCpnt->device->id;
+	pSCB->SCB_Lun = SCpnt->device->lun;
+	pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
 	pSCB->SCB_Flags |= SCF_SENSE;	/* Turn on auto request sense   */
 
 	pSCB->SCB_SensePtr = (U32) VIRT_TO_BUS(SCpnt->sense_buffer);
@@ -522,13 +522,13 @@
 	register SCB *pSCB;
 	HCS *pHCB;		/* Point to Host adapter control block */
 
-	if (SCpnt->lun > 16) {	/* 07/22/98 */
+	if (SCpnt->device->lun > 16) {	/* 07/22/98 */
 
 		SCpnt->result = (DID_TIME_OUT << 16);
 		done(SCpnt);	/* Notify system DONE           */
 		return (0);
 	}
-	pHCB = (HCS *) SCpnt->host->base;
+	pHCB = (HCS *) SCpnt->device->host->base;
 
 	SCpnt->scsi_done = done;
 	/* Get free SCSI control block  */
@@ -558,7 +558,7 @@
 {
 	HCS *pHCB;
 
-	pHCB = (HCS *) SCpnt->host->base;
+	pHCB = (HCS *) SCpnt->device->host->base;
 	return tul_abort_srb(pHCB, SCpnt);
 }
 
@@ -570,12 +570,12 @@
 {				/* I need Host Control Block Information */
 	HCS *pHCB;
 
-	pHCB = (HCS *) SCpnt->host->base;
+	pHCB = (HCS *) SCpnt->device->host->base;
 
 	if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
 		return tul_reset_scsi_bus(pHCB);
 	else
-		return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags);
+		return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->device->id, reset_flags);
 }
 
 /*
diff -Nru a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
--- a/drivers/scsi/inia100.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/inia100.c	Mon Feb 10 10:39:24 2003
@@ -459,8 +459,8 @@
 
 	pSCB->SCB_Opcode = ORC_EXECSCSI;
 	pSCB->SCB_Flags = SCF_NO_DCHK;	/* Clear done bit               */
-	pSCB->SCB_Target = SCpnt->target;
-	pSCB->SCB_Lun = SCpnt->lun;
+	pSCB->SCB_Target = SCpnt->device->id;
+	pSCB->SCB_Lun = SCpnt->device->lun;
 	pSCB->SCB_Reserved0 = 0;
 	pSCB->SCB_Reserved1 = 0;
 	pSCB->SCB_SGLen = 0;
@@ -501,7 +501,7 @@
 		printk("max cdb length= %x\b", SCpnt->cmd_len);
 		pSCB->SCB_CDBLen = IMAX_CDB;
 	}
-	pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW;
+	pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
 	if (SCpnt->device->tagged_supported) {	/* Tag Support                  */
 		pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;	/* Do simple tag only   */
 	} else {
@@ -523,7 +523,7 @@
 	register ORC_SCB *pSCB;
 	ORC_HCS *pHCB;		/* Point to Host adapter control block */
 
-	pHCB = (ORC_HCS *) SCpnt->host->hostdata;
+	pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
 	SCpnt->scsi_done = done;
 	/* Get free SCSI control block  */
 	if ((pSCB = orc_alloc_scb(pHCB)) == NULL) {
@@ -549,7 +549,7 @@
 {
 	ORC_HCS *hcsp;
 
-	hcsp = (ORC_HCS *) SCpnt->host->hostdata;
+	hcsp = (ORC_HCS *) SCpnt->device->host->hostdata;
 	return orc_abort_srb(hcsp, SCpnt);
 }
 
@@ -564,7 +564,7 @@
 static int inia100_bus_reset(Scsi_Cmnd * SCpnt)
 {				/* I need Host Control Block Information */
 	ORC_HCS *pHCB;
-	pHCB = (ORC_HCS *) SCpnt->host->hostdata;
+	pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
 	return orc_reset_scsi_bus(pHCB);
 }
 
@@ -578,8 +578,8 @@
 static int inia100_device_reset(Scsi_Cmnd * SCpnt)
 {				/* I need Host Control Block Information */
 	ORC_HCS *pHCB;
-	pHCB = (ORC_HCS *) SCpnt->host->hostdata;
-	return orc_device_reset(pHCB, SCpnt, SCpnt->target);
+	pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
+	return orc_device_reset(pHCB, SCpnt, SCpnt->device->id);
 
 }
 
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/ips.c	Mon Feb 10 10:39:23 2003
@@ -6,7 +6,7 @@
 /*             David Jeffery, Adaptec, Inc.                                  */
 /*                                                                           */
 /* Copyright (C) 2000 IBM Corporation                                        */ 
-/* Copyright (C) 2002 Adaptec, Inc.                                          */ 
+/* Copyright (C) 2002,2003 Adaptec, 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      */
@@ -127,6 +127,9 @@
 /*          - Get rid on IOCTL_NEW_COMMAND code                              */
 /*          - Add Extended DCDB Commands for Tape Support in 5I              */
 /* 5.10.12  - use pci_dma interfaces, update for 2.5 kernel changes          */
+/* 5.10.15  - remove unused code (sem, macros, etc.)                         */
+/* 5.30.00  - use __devexit_p()                                              */
+/* 6.00.00  - Add 6x Adapters and Battery Flash                              */
 /*****************************************************************************/
 
 /*
@@ -191,14 +194,16 @@
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "5.10"
-#define IPS_VERSION_LOW         ".13-BETA "
+#define IPS_VERSION_HIGH        "5.99"
+#define IPS_VERSION_LOW         ".00-BETA"
+
 
 #if !defined(__i386__) && !defined(__ia64__)
    #error "This driver has only been tested on the x86/ia64 platforms"
 #endif
 
 #if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0)
+    #include "sd.h"
     #define IPS_SG_ADDRESS(sg)       ((sg)->address)
     #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
     #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
@@ -241,34 +246,23 @@
 static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */
 static int          ips_force_i2o = 1;               /* Always use I2O command delivery */
 static int          ips_ioctlsize = IPS_IOCTL_SIZE;  /* Size of the ioctl buffer        */
-static int          ips_cd_boot = 0;                 /* Booting from ServeRAID Manager CD */
+static int          ips_cd_boot = 0;                 /* Booting from Manager CD         */
 static char        *ips_FlashData = NULL;            /* CD Boot - Flash Data Buffer      */
-static long          ips_FlashDataInUse = 0;          /* CD Boot - Flash Data In Use Flag */
+static long         ips_FlashDataInUse = 0;          /* CD Boot - Flash Data In Use Flag */
 static uint32_t     MaxLiteCmds = 32;                /* Max Active Cmds for a Lite Adapter */  
+static Scsi_Host_Template ips_driver_template = IPS;
 
 IPS_DEFINE_COMPAT_TABLE( Compatable );               /* Version Compatability Table      */
 
 
-   /* This table describes any / all ServeRAID Adapters */
+   /* This table describes all ServeRAID Adapters */
    static struct  pci_device_id  ips_pci_table[]  __devinitdata = {
            { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
            { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+           { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
            { 0, }
    };
 
-   /* This table describes only Sarasota ( ServeRAID 5i ) Adapters */
-   static struct  pci_device_id  ips_pci_table_5i[]  __devinitdata = {
-                   { 0x1014, 0x01BD, PCI_ANY_ID, 0x259, 0, 0 },
-                   { 0x1014, 0x01BD, PCI_ANY_ID, 0x258, 0, 0 },
-                   { 0, }
-                   };   
-    
-   /* This table describes all i960 Adapters */
-   static struct  pci_device_id  ips_pci_table_i960[]  __devinitdata = {
-                   { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-                   { 0, }
-                   };   
-
    MODULE_DEVICE_TABLE( pci, ips_pci_table );
 
    static char ips_hot_plug_name[] = "ips";
@@ -283,27 +277,13 @@
        .remove		= __devexit_p(ips_remove_device),
    }; 
            
-   struct pci_driver ips_pci_driver_5i = {
-       .name		= ips_hot_plug_name,
-       .id_table	= ips_pci_table_5i,
-       .probe		= ips_insert_device,
-       .remove		= __devexit_p(ips_remove_device),
-   };
-
-   struct pci_driver ips_pci_driver_i960 = {
-       .name		= ips_hot_plug_name,
-       .id_table	= ips_pci_table_i960,
-       .probe		= ips_insert_device,
-       .remove		= __devexit_p(ips_remove_device),
-   };
-
 
 /*
  * Necessary forward function protoypes
  */
 static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
 
-#define MAX_ADAPTER_NAME 11
+#define MAX_ADAPTER_NAME 15
 
 static char ips_adapter_name[][30] = {
    "ServeRAID",
@@ -318,9 +298,12 @@
    "ServeRAID 4Mx",
    "ServeRAID 4Lx",
    "ServeRAID 5i",
-   "ServeRAID 5i"
+   "ServeRAID 5i",
+   "ServeRAID 00",
+   "ServeRAID 00"
 };
 
+
 static struct notifier_block ips_notifier = {
    ips_halt, NULL, 0
 };
@@ -390,9 +373,6 @@
 int ips_eh_abort(Scsi_Cmnd *);
 int ips_eh_reset(Scsi_Cmnd *);
 int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
-int ips_biosparam(struct scsi_device *, struct block_device *,
-		sector_t, int *);
-int ips_slave_configure(Scsi_Device *);
 const char * ips_info(struct Scsi_Host *);
 void do_ipsintr(int, void *, struct pt_regs *);
 static int ips_hainit(ips_ha_t *);
@@ -441,7 +421,6 @@
 static void ips_free_flash_copperhead(ips_ha_t *ha);
 static void ips_get_bios_version(ips_ha_t *, int);
 static void ips_identify_controller(ips_ha_t *);
-//static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
 static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
 static void ips_enable_int_copperhead(ips_ha_t *);
 static void ips_enable_int_copperhead_memio(ips_ha_t *);
@@ -482,6 +461,8 @@
 static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
+static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned int count);
+static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned int count);
 
 int  ips_proc_info(char *, char **, off_t, int, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
@@ -489,11 +470,11 @@
 static int copy_info(IPS_INFOSTR *, char *, ...);
 static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr );
 static void ips_version_check(ips_ha_t *ha, int intr);
-static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index);
+static int ips_abort_init(ips_ha_t *ha, int index);
 static int ips_init_phase2( int index );
 
 static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
-
+static int ips_register_scsi(int index);
 /*--------------------------------------------------------------------------*/
 /* Exported Functions                                                       */
 /*--------------------------------------------------------------------------*/
@@ -562,6 +543,7 @@
 /****************************************************************************/
 int
 ips_detect(Scsi_Host_Template *SHT) {
+   int  i;
 
    METHOD_TRACE("ips_detect", 1);
 
@@ -570,36 +552,26 @@
       ips_setup(ips);
 #endif
 
-   /* If Booting from the ServeRAID Manager CD, Allocate a large Flash  */
-   /* Buffer ( so we won't need to allocate one for each adapter ).     */
+   /* If Booting from the Manager CD, Allocate a large Flash        */
+   /* Buffer ( so we won't need to allocate one for each adapter ). */
     if ( ips_cd_boot ) {            
-      ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 );   
+      ips_FlashData = ( char * ) __get_free_pages( IPS_INIT_GFP, 7 );   
       if (ips_FlashData == NULL) {
          /* The validity of this pointer is checked in ips_make_passthru() before it is used */
          printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" );
       }
    }                                                                               
+   if (!pci_present())
+      return (0);
 
    SHT->proc_info = ips_proc_info;
    SHT->proc_name = "ips";
 
- #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
-   spin_unlock_irq(&io_request_lock);
- #endif
-   /* By definition, a Sarasota ( 5i ) Adapter MUST be enumerated first or the */
-   /* server may not boot properly. The adapters must be enumerated in exactly */
-   /* the same order as ServeRAID BIOS for the machine to come up properly.    */
-
-   pci_module_init(&ips_pci_driver_5i);          /* Ask for 5i Adapters First  */
-   if (ips_num_controllers)                      /* If there is a 5i Adapter   */
-      pci_module_init(&ips_pci_driver_i960);     /*    Get all i960's next     */
-   pci_module_init(&ips_pci_driver);             /* Get all remaining Adapters */
-                                                 /*  ( in normal BUS order )   */
- #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
-   spin_lock_irq(&io_request_lock);
- #endif
-   if (ips_num_controllers > 0) 
-      register_reboot_notifier(&ips_notifier);
+   for(i = 0; i < ips_num_controllers; i++){
+      if ( ips_register_scsi(i) )
+         ips_free(ips_ha[i]);
+         ips_released_controllers++;
+   } 
 
    return (ips_num_controllers);
 }
@@ -614,7 +586,7 @@
    /*                                
     * Setup Functions
     */
-   if (IPS_IS_MORPHEUS(ha)) {
+   if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
       /* morpheus / marco / sebring */
       ha->func.isintr = ips_isintr_morpheus;
       ha->func.isinit = ips_isinit_morpheus;
@@ -734,10 +706,6 @@
 
    ips_released_controllers++;
 
-   if (ips_num_controllers == ips_released_controllers){
-      unregister_reboot_notifier(&ips_notifier);
-      pci_unregister_driver(&ips_pci_driver);
-   }
    return (FALSE);
 }
 
@@ -817,7 +785,7 @@
    if (!SC)
       return (FAILED);
 
-   ha = (ips_ha_t *) SC->host->hostdata;
+   ha = (ips_ha_t *) SC->device->host->hostdata;
 
    if (!ha)
       return (FAILED);
@@ -884,7 +852,7 @@
       return (FAILED);
    }
 
-   ha = (ips_ha_t *) SC->host->hostdata;
+   ha = (ips_ha_t *) SC->device->host->hostdata;
 
    if (!ha) {
       DEBUG(1, "Reset called with NULL ha struct");
@@ -1072,7 +1040,7 @@
 
    METHOD_TRACE("ips_queue", 1);
 
-   ha = (ips_ha_t *) SC->host->hostdata;
+   ha = (ips_ha_t *) SC->device->host->hostdata;
 
    if (!ha)
       return (1);
@@ -1100,12 +1068,12 @@
              ips_name,
              ha->host_num,
              SC->cmnd[0],
-             SC->channel,
-             SC->target,
-             SC->lun);
+             SC->device->channel,
+             SC->device->id,
+             SC->device->lun);
 
    /* Check for command to initiator IDs */
-   if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) {
+   if ((SC->device->channel > 0) && (SC->device->id == ha->ha_id[SC->device->channel])) {
       SC->result = DID_NO_CONNECT << 16;
       done(SC);
 
@@ -1155,13 +1123,6 @@
 
    ips_next(ha, IPS_INTR_IORL);
    
-   /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
-   if ( ips_FlashData == ha->ioctl_data ) {                               
-      ha->ioctl_data = ha->flash_data;                           
-      ha->ioctl_order = ha->flash_order;                          
-      ha->ioctl_datasize = ha->flash_datasize;                       
-      ips_FlashDataInUse = 0;                                             
-   }
    return (0);
 }
 
@@ -1174,7 +1135,7 @@
 /*   Set bios geometry for the controller                                   */
 /*                                                                          */
 /****************************************************************************/
-int
+static int
 ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 		sector_t capacity, int geom[]) {
    ips_ha_t         *ha;
@@ -1308,6 +1269,12 @@
    if (!ha) 
       return;
    host = ips_sh[ha->host_num];
+   /* interrupt during initialization */
+   if(!host){
+      (*ha->func.intr)(ha);
+      return;
+   }
+
    IPS_LOCK_SAVE(host->host_lock, cpu_flags);
 
    if (!ha->active) {
@@ -1478,7 +1445,8 @@
    bp = &buffer[0];
    memset(bp, 0, sizeof(buffer));
 
-   sprintf(bp, "%s%s%s", "IBM PCI ServeRAID ", IPS_VERSION_HIGH, IPS_VERSION_LOW );
+   sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
+               IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT );
 
    if (ha->ad_type > 0 &&
        ha->ad_type <= MAX_ADAPTER_NAME) {
@@ -1556,9 +1524,9 @@
       return (0);
 
    if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
-       (SC->channel == 0) &&
-       (SC->target == IPS_ADAPTER_ID) &&
-       (SC->lun == 0) &&
+       (SC->device->channel == 0) &&
+       (SC->device->id == IPS_ADAPTER_ID) &&
+       (SC->device->lun == 0) &&
         SC->request_buffer){
       if((!SC->use_sg) && SC->request_bufflen &&
          (((char *) SC->request_buffer)[0] == 'C') &&
@@ -1579,6 +1547,39 @@
 
 /****************************************************************************/
 /*                                                                          */
+/* Routine Name: ips_alloc_passthru_buffer                                  */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   allocate a buffer large enough for the ioctl data if the ioctl buffer  */
+/*   is too small or doesn't exist                                          */
+/****************************************************************************/
+static int
+ips_alloc_passthru_buffer(ips_ha_t *ha, int length){
+	void *bigger_buf;
+	int count;
+	int order;
+
+	if(ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order))
+		return 0;
+	/* there is no buffer or it's not big enough, allocate a new one */
+	for (count = PAGE_SIZE, order = 0;
+	     count < length;
+	     order++, count <<= 1);
+	bigger_buf = (void *) __get_free_pages(IPS_ATOMIC_GFP, order);
+	if (bigger_buf) {
+		/* free the old memory */
+		free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
+		/* use the new memory */
+		ha->ioctl_data = (char *) bigger_buf;
+		ha->ioctl_order = order;
+	} else {
+		return -1;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/*                                                                          */
 /* Routine Name: ips_make_passthru                                          */
 /*                                                                          */
 /* Routine Description:                                                     */
@@ -1589,73 +1590,42 @@
 static int
 ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
    ips_passthru_t *pt;
-   char *buffer;
    int length = 0;
+   int ret;
 
    METHOD_TRACE("ips_make_passthru", 1);
 
    if(!SC->use_sg){
-      buffer = SC->request_buffer;
       length = SC->request_bufflen;
    }else{
       struct scatterlist *sg = SC->request_buffer;
       int i;
       for(i = 0; i < SC->use_sg; i++)
          length += sg[i].length;
-
-      if (length < sizeof(ips_passthru_t)) {
-         /* wrong size */
-         DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
-             ips_name, ha->host_num);
-         return (IPS_FAILURE);
-      }else if(!ha->ioctl_data || length > (PAGE_SIZE << ha->ioctl_order)){
-         void *bigger_buf;
-         int count;
-         int order;
-         /* try to allocate a bigger buffer */
-         for (count = PAGE_SIZE, order = 0;
-              count < length;
-              order++, count <<= 1);
-         bigger_buf = (void *) __get_free_pages(GFP_ATOMIC, order);
-         if (bigger_buf) {
-            /* free the old memory */
-            free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
-            /* use the new memory */
-            ha->ioctl_data = (char *) bigger_buf;
-            ha->ioctl_order = order;
-            ha->ioctl_datasize = count;
-         } else {
-             pt = (ips_passthru_t*)IPS_SG_ADDRESS(sg);
-             pt->BasicStatus = 0x0B;
-             pt->ExtendedStatus = 0x00;
-             SC->result = DID_ERROR << 16;
-             return (IPS_FAILURE);
-         }
-      }
-      ha->ioctl_datasize = length;
-      length = 0;
-      for(i = 0; i < SC->use_sg; i++){
-         memcpy(&ha->ioctl_data[length], IPS_SG_ADDRESS(&sg[i]), sg[i].length);
-         length += sg[i].length;
-      }
-      pt = (ips_passthru_t *)ha->ioctl_data;
-      buffer = ha->ioctl_data;
-   }
-   if (!length || !buffer) {
-      /* no data */
-      DEBUG_VAR(1, "(%s%d) No passthru structure",
-                ips_name, ha->host_num);
-
-      return (IPS_FAILURE);
    }
    if (length < sizeof(ips_passthru_t)) {
       /* wrong size */
       DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
-             ips_name, ha->host_num);
-
+          ips_name, ha->host_num);
       return (IPS_FAILURE);
    }
-   pt = (ips_passthru_t*) buffer;
+   if(ips_alloc_passthru_buffer(ha, length)){
+      /* allocation failure!  If ha->ioctl_data exists, use it to return
+         some error codes.  Return a failed command to the scsi layer. */
+      if(ha->ioctl_data){
+         pt = (ips_passthru_t *)ha->ioctl_data;
+         ips_scmd_buf_read(SC, pt, sizeof(ips_passthru_t));
+         pt->BasicStatus = 0x0B;
+         pt->ExtendedStatus = 0x00;
+         ips_scmd_buf_write(SC, pt, sizeof(ips_passthru_t));
+      }
+      return IPS_FAILURE;
+   }
+   ha->ioctl_datasize = length;
+
+   ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);      
+   pt = (ips_passthru_t *)ha->ioctl_data;
+
    /*
     * Some notes about the passthru interface used
     *
@@ -1664,26 +1634,14 @@
     * packet we received from the sg driver. In this
     * case the CmdBSize field of the pt structure is
     * used for the size of the buffer.
-    *
-    * IF the scsi op_code == 0x81 then we assume that
-    * we will need our own buffer and we will copy the
-    * data to/from the user buffer passed in the scsi
-    * command.  The data address resides at offset 4
-    * in the scsi command.  The length of the data resides
-    * at offset 8 in the scsi command.
     */
 
    switch (pt->CoppCmd) {
    case IPS_NUMCTRLS:
-      memcpy(buffer + sizeof(ips_passthru_t),
+      memcpy(ha->ioctl_data + sizeof(ips_passthru_t),
              &ips_num_controllers, sizeof(int));
-      SC->result = DID_OK << 16;
-
-      return (IPS_SUCCESS_IMM);
-
-   case IPS_CTRLINFO:
-      memcpy(buffer + sizeof(ips_passthru_t),
-             ha, sizeof(ips_ha_t));
+      ips_scmd_buf_write(SC, ha->ioctl_data,
+                         sizeof(ips_passthru_t) + sizeof(int));
       SC->result = DID_OK << 16;
 
       return (IPS_SUCCESS_IMM);
@@ -1700,9 +1658,11 @@
          }
 
          if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
-            pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)
-            return ips_flash_copperhead(ha, pt, scb);
-
+            pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) {
+            ret = ips_flash_copperhead(ha, pt, scb);
+            ips_scmd_buf_write(SC, ha->ioctl_data, sizeof(ips_passthru_t));
+            return ret;
+         }
          if (ips_usrcmd(ha, pt, scb))
             return (IPS_SUCCESS);
          else
@@ -1713,8 +1673,8 @@
 
    } /* end switch */
 
-         return (IPS_FAILURE);
-      }
+   return (IPS_FAILURE);
+}
 
 /****************************************************************************/
 /* Routine Name: ips_flash_copperhead                                       */
@@ -1752,7 +1712,7 @@
                     pt->CoppCP.cmd.flashfw.count;
          for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize;
               ha->flash_order++, count <<= 1);
-         ha->flash_data = (char *)__get_free_pages(GFP_ATOMIC, ha->flash_order);
+         ha->flash_data = (char *)__get_free_pages(IPS_ATOMIC_GFP, ha->flash_order);
          ha->flash_datasize = 0;
       }else
          return IPS_FAILURE;
@@ -1829,13 +1789,55 @@
 }
 
 /****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_fill_scb_sg_single                                     */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   Fill in a single scb sg_list element from an address                   */
+/*   return a -1 if a breakup occured                                       */
+/****************************************************************************/
+static inline int ips_fill_scb_sg_single(ips_ha_t *ha, dma_addr_t busaddr,
+                            ips_scb_t *scb, int indx, unsigned int e_len)
+{
+
+   int      ret_val = 0;
+
+   if ( (scb->data_len + e_len) > ha->max_xfer) {
+      e_len = ha->max_xfer - scb->data_len;
+      scb->breakup = indx;
+      ++scb->sg_break;
+      ret_val = -1;
+   } else {
+      scb->breakup = 0;
+      scb->sg_break = 0;
+   }
+   if (IPS_USE_ENH_SGLIST(ha)) {
+      scb->sg_list.enh_list[indx].address_lo =
+         cpu_to_le32(pci_dma_lo32(busaddr));
+      scb->sg_list.enh_list[indx].address_hi =
+         cpu_to_le32(pci_dma_hi32(busaddr));
+      scb->sg_list.enh_list[indx].length =
+         cpu_to_le32(e_len);
+   } else {
+      scb->sg_list.std_list[indx].address =
+         cpu_to_le32(pci_dma_lo32(busaddr));
+      scb->sg_list.std_list[indx].length =
+         cpu_to_le32(e_len);
+   }
+
+   ++scb->sg_len;
+   scb->data_len += e_len;
+   return ret_val;
+}
+
+/****************************************************************************/
 /* Routine Name: ips_flash_firmware                                         */
 /* Routine Description:                                                     */
 /*   flashes the firmware of a copperhead adapter                           */
 /****************************************************************************/
 static int
 ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
-   IPS_SG_LIST *sg_list;
+   IPS_SG_LIST sg_list;
    uint32_t cmd_busaddr;
 
    if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
@@ -1850,16 +1852,16 @@
       return IPS_FAILURE;
    }
    /* Save the S/G list pointer so it doesn't get clobbered */
-   sg_list = scb->sg_list;
+   sg_list.list = scb->sg_list.list;
    cmd_busaddr = scb->scb_busaddr;
    /* copy in the CP */
    memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
    /* FIX stuff that might be wrong */
-   scb->sg_list = sg_list;
+   scb->sg_list.list = sg_list.list;
    scb->scb_busaddr = cmd_busaddr;
-   scb->bus = scb->scsi_cmd->channel;
-   scb->target_id = scb->scsi_cmd->target;
-   scb->lun = scb->scsi_cmd->lun;
+   scb->bus = scb->scsi_cmd->device->channel;
+   scb->target_id = scb->scsi_cmd->device->id;
+   scb->lun = scb->scsi_cmd->device->lun;
    scb->sg_len = 0;
    scb->data_len = 0;
    scb->flags = 0;
@@ -1872,7 +1874,7 @@
                                       IPS_DMA_DIR(scb));
    scb->flags |= IPS_SCB_MAP_SINGLE;
    scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
-   scb->cmd.flashfw.buffer_addr = scb->data_busaddr;
+   scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
    if (pt->TimeOut)
       scb->timeout = pt->TimeOut;
    scb->scsi_cmd->result = DID_OK <<16;
@@ -1904,7 +1906,7 @@
 /****************************************************************************/
 static int
 ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
-   IPS_SG_LIST *sg_list;
+   IPS_SG_LIST sg_list;
    uint32_t cmd_busaddr;
 
    METHOD_TRACE("ips_usrcmd", 1);
@@ -1913,18 +1915,18 @@
       return (0);
 
    /* Save the S/G list pointer so it doesn't get clobbered */
-   sg_list = scb->sg_list;
+   sg_list.list = scb->sg_list.list;
    cmd_busaddr = scb->scb_busaddr;
    /* copy in the CP */
    memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
    memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
 
    /* FIX stuff that might be wrong */
-   scb->sg_list = sg_list;
+   scb->sg_list.list = sg_list.list;
    scb->scb_busaddr = cmd_busaddr;
-   scb->bus = scb->scsi_cmd->channel;
-   scb->target_id = scb->scsi_cmd->target;
-   scb->lun = scb->scsi_cmd->lun;
+   scb->bus = scb->scsi_cmd->device->channel;
+   scb->target_id = scb->scsi_cmd->device->id;
+   scb->lun = scb->scsi_cmd->device->lun;
    scb->sg_len = 0;
    scb->data_len = 0;
    scb->flags = 0;
@@ -1940,23 +1942,13 @@
       return (0);
 
    if (pt->CmdBSize) {
-      if(!scb->scsi_cmd->use_sg){
-         scb->data_len = pt->CmdBSize;
-         scb->data_busaddr = pci_map_single(ha->pcidev,
-                                            scb->scsi_cmd->request_buffer +
-                                            sizeof(ips_passthru_t),
-                                            pt->CmdBSize,
-                                            IPS_DMA_DIR(scb));
-         scb->flags |= IPS_SCB_MAP_SINGLE;
-      } else {
-         scb->data_len = pt->CmdBSize;
-         scb->data_busaddr = pci_map_single(ha->pcidev,
-                                            ha->ioctl_data +
-                                            sizeof(ips_passthru_t),
-                                            pt->CmdBSize,
-                                            IPS_DMA_DIR(scb));
-         scb->flags |= IPS_SCB_MAP_SINGLE;
-      }
+      scb->data_len = pt->CmdBSize;
+      scb->data_busaddr = pci_map_single(ha->pcidev,
+                                         ha->ioctl_data +
+                                         sizeof(ips_passthru_t),
+                                         pt->CmdBSize,
+                                         IPS_DMA_DIR(scb));
+      scb->flags |= IPS_SCB_MAP_SINGLE;
    } else {
       scb->data_busaddr = 0L;
    }
@@ -2013,10 +2005,7 @@
 
       return ;
    }
-   if(!scb->scsi_cmd->use_sg)
-      pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
-   else
-      pt = (ips_passthru_t *) ha->ioctl_data;
+   pt = (ips_passthru_t *) ha->ioctl_data;
 
    /* Copy data back to the user */
    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)        /* Copy DCDB Back to Caller's Area */
@@ -2031,14 +2020,7 @@
      scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
       ips_free_flash_copperhead(ha);
 
-   if(scb->scsi_cmd->use_sg){
-      int i, length = 0;
-      struct scatterlist *sg = scb->scsi_cmd->request_buffer;
-      for(i = 0; i < scb->scsi_cmd->use_sg; i++){
-         memcpy(IPS_SG_ADDRESS(&sg[i]), &ha->ioctl_data[length], sg[i].length);
-         length += sg[i].length;
-      }
-   }
+   ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
 }
 
 /****************************************************************************/
@@ -2104,6 +2086,9 @@
    copy_info(&info, "\tDriver Version                    : %s%s\n",
              IPS_VERSION_HIGH, IPS_VERSION_LOW);
 
+   copy_info(&info, "\tDriver Build                      : %d\n",
+             IPS_BUILD_IDENT);
+
    copy_info(&info, "\tMax Physical Devices              : %d\n",
              ha->enq->ucMaxPhysicalDevices);
    copy_info(&info, "\tMax Active Commands               : %d\n",
@@ -2245,6 +2230,17 @@
       }
 
       break;
+
+   case IPS_DEVICEID_MARCO:
+      switch (ha->subdevice_id) {
+      case IPS_SUBDEVICEID_6M:
+          ha->ad_type = IPS_ADTYPE_SERVERAID6M;
+          break;
+      case IPS_SUBDEVICEID_6I:
+          ha->ad_type = IPS_ADTYPE_SERVERAID6I;
+          break;
+      }
+      break;
    }
 }
 
@@ -2355,7 +2351,7 @@
    } else {
       /* Morpheus Family - Send Command to the card */
 
-      buffer = kmalloc(0x1000, GFP_ATOMIC);
+      buffer = kmalloc(0x1000, IPS_ATOMIC_GFP);
       if (!buffer)
          return;
 
@@ -2477,6 +2473,10 @@
       return (0);
    }
 
+   /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
+   if ( (ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1) ) 
+      ips_clear_adapter(ha, IPS_INTR_IORL);
+   
    /* set limits on SID, LUN, BUS */
    ha->ntargets = IPS_MAX_TARGETS + 1;
    ha->nlun = 1;
@@ -2666,7 +2666,7 @@
     
    p = ha->scb_waitlist.head;
    while ((p) && (scb = ips_getscb(ha))) {
-      if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) {
+      if ((p->device->channel > 0) && (ha->dcdb_active[p->device->channel-1] & (1 << p->device->id))) {
          ips_freescb(ha, scb);
          p = (Scsi_Cmnd *) p->host_scribble;
          continue;
@@ -2683,9 +2683,9 @@
 
       memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer));
 
-      scb->target_id = SC->target;
-      scb->lun = SC->lun;
-      scb->bus = SC->channel;
+      scb->target_id = SC->device->id;
+      scb->lun = SC->device->lun;
+      scb->bus = SC->device->channel;
       scb->scsi_cmd = SC;
       scb->breakup = 0;
       scb->data_len = 0;
@@ -2705,68 +2705,20 @@
          scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
                                     scsi_to_pci_dma_dir(SC->sc_data_direction));
          scb->flags |= IPS_SCB_MAP_SG;
-         if (scb->sg_count == 1) {
-            if (sg_dma_len(sg) > ha->max_xfer) {
-     	       scb->breakup = 1;
-               scb->data_len = ha->max_xfer;
-            } else
-               scb->data_len = sg_dma_len(sg);
-
-            scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = sg_dma_address(sg);
-            scb->sg_len = 0;
-         } else {
-            /* Check for the first Element being bigger than MAX_XFER */
-            if (sg_dma_len(&sg[0]) > ha->max_xfer) {
-               scb->sg_list[0].address = cpu_to_le32(sg_dma_address(&sg[0]));
-               scb->sg_list[0].length = ha->max_xfer;
-               scb->data_len = ha->max_xfer;
-               scb->breakup = 0; 
-               scb->sg_break=1;  
-               scb->sg_len = 1;
-            } else {
-               for (i = 0; i < scb->sg_count; i++) {
-                  scb->sg_list[i].address = cpu_to_le32(sg_dma_address(&sg[i]));
-                  scb->sg_list[i].length = cpu_to_le32(sg_dma_len(&sg[i]));
-            
-                  if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
-                     /*
-                      * Data Breakup required
-                      */
-                     scb->breakup = i;
-                     break;
-                  }
-               
-                  scb->data_len += sg_dma_len(&sg[i]);
-               }
-
-               if (!scb->breakup)
-                  scb->sg_len = scb->sg_count;
-               else
-                  scb->sg_len = scb->breakup;
-            }
-
-            scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = scb->sg_busaddr;
+         for (i = 0; i < scb->sg_count; i++) {
+            if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[i]),
+                                        scb, i, sg_dma_len(&sg[i])) < 0)
+               break;
          }
+         scb->dcdb.transfer_length = scb->data_len;
       } else {
          if (SC->request_bufflen) {
-            if (SC->request_bufflen > ha->max_xfer) {
-               /*
-                * Data breakup required
-                */
-               scb->breakup = 1;
-               scb->data_len = ha->max_xfer;
-            } else {
-               scb->data_len = SC->request_bufflen;
-            }
-
-            scb->dcdb.transfer_length = scb->data_len;
             scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer,
-                                               scb->data_len,
+                                               SC->request_bufflen,
                                                scsi_to_pci_dma_dir(SC->sc_data_direction));
             scb->flags |= IPS_SCB_MAP_SINGLE;
-            scb->sg_len = 0;
+            ips_fill_scb_sg_single(ha, scb->data_busaddr, scb, 0, SC->request_bufflen);
+            scb->dcdb.transfer_length = scb->data_len;
          } else {
             scb->data_busaddr = 0L;
             scb->sg_len = 0;
@@ -3319,118 +3271,41 @@
        */
       if ((scb->breakup) || (scb->sg_break)) {
          /* we had a data breakup */
-         uint8_t bk_save;
-
-         bk_save = scb->breakup;
-         scb->breakup = 0;
-         mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ);
+         scb->data_len = 0;
 
          if (scb->sg_count) {
             /* S/G request */
             struct scatterlist *sg;
-            int                 i;
+            int ips_sg_index = 0;
+            int sg_dma_index;
 
             sg = scb->scsi_cmd->request_buffer;
 
-            if (scb->sg_count == 1) {
-               if (sg_dma_len(sg) - (bk_save * ha->max_xfer) > ha->max_xfer) {
-                  /* Further breakup required */
-                  scb->data_len = ha->max_xfer;
-                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
-                  scb->breakup = bk_save + 1;
-               } else {
-                  scb->data_len = sg_dma_len(sg) - (bk_save * ha->max_xfer);
-                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
-               }
+            /* Spin forward to last dma chunk */
+            sg_dma_index = scb->breakup;
 
-               scb->dcdb.transfer_length = scb->data_len;
-               scb->sg_len = 0;
-            } else {
-               /* We're here because there was MORE than one s/g unit. */
-	            /* bk_save points to which sg unit to look at           */
-	            /* sg_break points to how far through this unit we are  */
-	            /* NOTE: We will not move from one sg to another here,  */
-               /*    just finish the one we are in.  Not the most      */
-               /*    efficient, but it keeps it from getting too hacky */
-
-		         /* IF sg_break is non-zero, then just work on this current sg piece, */
-               /* pointed to by bk_save                                             */
-               if (scb->sg_break) {
-                  scb->sg_len = 1;
-                  scb->sg_list[0].address = sg_dma_address(&sg[bk_save])
-                                            + ha->max_xfer*scb->sg_break;
-                  if (ha->max_xfer > sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break) 
-                     scb->sg_list[0].length = sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break;
-                  else 
-                     scb->sg_list[0].length = ha->max_xfer;
-                  scb->sg_break++;              /* MUST GO HERE for math below to work */
-                  scb->data_len = scb->sg_list[0].length;;
-
-                  if (sg_dma_len(&sg[bk_save]) <= ha->max_xfer * scb->sg_break ) {
-                     scb->sg_break = 0;         /* No more work in this unit */
-                     if (( bk_save + 1 ) >= scb->sg_count) 
-                        scb->breakup = 0;
-                     else
-                        scb->breakup = bk_save + 1;
-                  }
-               } else {
-			         /* ( sg_break == 0 ), so this is our first look at a new sg piece */
-                  if (sg_dma_len(&sg[bk_save]) > ha->max_xfer) {
-                     scb->sg_list[0].address = sg_dma_address(&sg[bk_save]);
-                     scb->sg_list[0].length = ha->max_xfer;
-                     scb->breakup = bk_save;
-                     scb->sg_break = 1;
-                     scb->data_len = ha->max_xfer;
-                     scb->sg_len = 1;
- 	          } else {
-	         /* OK, the next sg is a short one, so loop until full */
-                     scb->data_len = 0;
-                     scb->sg_len = 0;
-                     scb->sg_break = 0;
-                     /*   We're only doing full units here */
-                     for (i = bk_save; i < scb->sg_count; i++) {
-                        scb->sg_list[i - bk_save].address = sg_dma_address(&sg[i]);
-                        scb->sg_list[i - bk_save].length = cpu_to_le32(sg_dma_len(&sg[i]));
-                        if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
-                           scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
-                           break;
-                        }
-                        scb->data_len += sg_dma_len(&sg[i]);
-                        scb->sg_len++;           /* only if we didn't get too big */
-		  		         }
-			         }
-		         }
-
-               /* Also, we need to be sure we don't queue work ( breakup != 0 )
-                  if no more sg units for next time */
-               scb->dcdb.transfer_length = scb->data_len;
-               scb->data_busaddr = scb->sg_busaddr;
-            }
-                                              
-         } else {
-            /* Non S/G Request */
-            pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
-                             IPS_DMA_DIR(scb));
-            if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
-               /* Further breakup required */
-               scb->data_len = ha->max_xfer;
-               scb->data_busaddr = pci_map_single(ha->pcidev,
-                                           scb->scsi_cmd->request_buffer +
-                                           (bk_save * ha->max_xfer),
-                                           scb->data_len, IPS_DMA_DIR(scb));
-               scb->breakup = bk_save + 1;
-            } else {
-               scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer);
-               scb->data_busaddr = pci_map_single(ha->pcidev,
-                                           scb->scsi_cmd->request_buffer +
-                                           (bk_save * ha->max_xfer),
-                                           scb->data_len, IPS_DMA_DIR(scb));
-	    }
+            /* Take care of possible partial on last chunk*/
+            ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]),
+                                   scb, ips_sg_index++,
+                                   sg_dma_len(&sg[sg_dma_index]));
+
+            for (; sg_dma_index < scb->sg_count; sg_dma_index++) {
+                 if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]),
+                                             scb, ips_sg_index++, 
+                                             sg_dma_len(&sg[sg_dma_index])) < 0)
+                    break;
 
-            scb->dcdb.transfer_length = scb->data_len;
-            scb->sg_len = 0;
-         }
+            }
 
+         } else {
+	 /* Non S/G Request */
+            (void) ips_fill_scb_sg_single(ha,
+                                          scb->data_busaddr + (scb->sg_break * ha->max_xfer),
+                                          scb, 0,
+                                          scb->scsi_cmd->request_bufflen - (scb->sg_break * ha->max_xfer));
+          }
+ 
+         scb->dcdb.transfer_length = scb->data_len;
          scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]];
 
          if (!scb->dcdb.cmd_attribute & 0x3)
@@ -3499,9 +3374,9 @@
       DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
                 ips_name,
                 ha->host_num,
-                scb->scsi_cmd->channel,
-                scb->scsi_cmd->target,
-                scb->scsi_cmd->lun,
+                scb->scsi_cmd->device->channel,
+                scb->scsi_cmd->channel->id,
+                scb->scsi_cmd->channel->lun,
                 scb->basic_status,
                 scb->extended_status,
                 scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
@@ -3636,6 +3511,68 @@
 
 /****************************************************************************/
 /*                                                                          */
+/* Routine Name: ips_scmd_buf_write                                         */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*  Write data to Scsi_Cmnd request_buffer at proper offsets                */
+/****************************************************************************/
+static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned
+				   int count)
+{
+	if (scmd->use_sg) {
+		int i;
+		unsigned int min_cnt, xfer_cnt;
+		char *cdata = (char *)data;
+		struct scatterlist *sg = scmd->request_buffer;
+		for (i = 0, xfer_cnt = 0;
+		     (i < scmd->use_sg) && (xfer_cnt < count); i++){
+			if(!IPS_SG_ADDRESS(&sg[i]))
+				return;
+			min_cnt = min( count - xfer_cnt, sg[i].length);
+			memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt],
+			       min_cnt);
+			xfer_cnt += min_cnt;
+		}
+
+	} else {
+		unsigned int min_cnt = min(count, scmd->request_bufflen);
+		memcpy(scmd->request_buffer, data, min_cnt);
+	}
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_scmd_buf_read                                          */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*  Copy data from a Scsi_Cmnd to a new, linear buffer                      */
+/****************************************************************************/
+static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned
+				   int count)
+{
+	if (scmd->use_sg) {
+		int i;
+		unsigned int min_cnt, xfer_cnt;
+		char *cdata = (char *)data;
+		struct scatterlist *sg = scmd->request_buffer;
+		for (i = 0, xfer_cnt = 0;
+		     (i < scmd->use_sg) && (xfer_cnt < count); i++){
+			if(!IPS_SG_ADDRESS(&sg[i]))
+				return;
+			min_cnt = min( count - xfer_cnt, sg[i].length);
+			memcpy(&cdata[xfer_cnt],IPS_SG_ADDRESS(&sg[i]),
+			       min_cnt);
+			xfer_cnt += min_cnt;
+		}
+
+	} else {
+		unsigned int min_cnt = min(count, scmd->request_bufflen);
+		memcpy(data, scmd->request_buffer, min_cnt);
+	}
+}
+
+/****************************************************************************/
+/*                                                                          */
 /* Routine Name: ips_send_cmd                                               */
 /*                                                                          */
 /* Routine Description:                                                     */
@@ -3710,7 +3647,7 @@
                strncpy(inquiry.ProductId, "SERVERAID       ", 16);
                strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
 
-               memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen);
+	       ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry));
 
                scb->scsi_cmd->result = DID_OK << 16;
             }
@@ -3740,15 +3677,19 @@
          if (!scb->sg_len) {
             scb->cmd.basic_io.op_code =
             (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
+            scb->cmd.basic_io.enhanced_sg = 0;
+            scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
          } else {
             scb->cmd.basic_io.op_code =
             (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
+            scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+            scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr);
          }
 
+         scb->cmd.basic_io.segment_4G = 0;
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.basic_io.log_drv = scb->target_id;
          scb->cmd.basic_io.sg_count = scb->sg_len;
-         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
 
          if (scb->cmd.basic_io.lba)
             scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
@@ -3763,7 +3704,6 @@
          if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
             scb->cmd.basic_io.sector_count = cpu_to_le16(256);
 
-         scb->cmd.basic_io.reserved = 0;
          ret = IPS_SUCCESS;
          break;
 
@@ -3772,15 +3712,19 @@
          if (!scb->sg_len) {
             scb->cmd.basic_io.op_code =
             (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
+            scb->cmd.basic_io.enhanced_sg = 0;
+            scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
          } else {
             scb->cmd.basic_io.op_code =
             (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
+            scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+            scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr);
          }
 
+         scb->cmd.basic_io.segment_4G = 0;
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
          scb->cmd.basic_io.log_drv = scb->target_id;
          scb->cmd.basic_io.sg_count = scb->sg_len;
-         scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
 
          if (scb->cmd.basic_io.lba)
             scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
@@ -3793,7 +3737,6 @@
 
          scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
 
-         scb->cmd.basic_io.reserved = 0;
 
          if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
             /*
@@ -3815,6 +3758,8 @@
       case MODE_SENSE:
          scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+	 scb->cmd.basic_io.segment_4G = 0;
+	 scb->cmd.basic_io.enhanced_sg = 0;
          scb->data_len = sizeof(*ha->enq);
          scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq,
                                             scb->data_len, IPS_DMA_DIR(scb));
@@ -3873,10 +3818,6 @@
 
    /* setup DCDB */
    if (scb->bus > 0) {
-      if (!scb->sg_len)
-         scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
-      else
-         scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
 
       /* If we already know the Device is Not there, no need to attempt a Command   */
       /* This also protects an NT FailOver Controller from getting CDB's sent to it */
@@ -3892,15 +3833,19 @@
                                                (unsigned long)scb);
       scb->cmd.dcdb.reserved = 0;
       scb->cmd.dcdb.reserved2 = 0;
-      scb->cmd.dcdb.reserved3 = 0;   
+      scb->cmd.dcdb.reserved3 = 0;
+      scb->cmd.dcdb.segment_4G = 0;
+      scb->cmd.dcdb.enhanced_sg = 0;
 
       TimeOut = scb->scsi_cmd->timeout_per_command;
 
       if (ha->subsys->param[4] & 0x00100000) {          /* If NEW Tape DCDB is Supported */
-         if (!scb->sg_len)
+         if (!scb->sg_len) {
             scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
-         else
+         } else {
             scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB_SG;
+            scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+         }
  
          tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
          tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id;
@@ -3919,13 +3864,23 @@
          tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
          tapeDCDB->reserved_for_LUN = 0;
          tapeDCDB->transfer_length = scb->data_len;
-         tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr);
+         if(scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
+            tapeDCDB->buffer_pointer = cpu_to_le32(scb->sg_busaddr);
+         else
+            tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr);
          tapeDCDB->sg_count = scb->sg_len;
          tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info);
          tapeDCDB->scsi_status = 0;
          tapeDCDB->reserved = 0;
          memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
       } else {
+         if (!scb->sg_len) {
+            scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
+         } else {
+            scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
+            scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+         }
+
          scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
          scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
 
@@ -3941,7 +3896,10 @@
          scb->dcdb.transfer_length = scb->data_len;
          if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) 
              scb->dcdb.transfer_length = 0;
-         scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
+         if(scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
+            scb->dcdb.buffer_pointer = cpu_to_le32(scb->sg_busaddr);
+         else
+            scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
          scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
          scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info);
          scb->dcdb.sg_count = scb->sg_len;
@@ -4166,7 +4124,7 @@
    strncpy(inquiry.ProductId, "SERVERAID       ", 16);
    strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
 
-   memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen);
+   ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry));
 
    return (1);
 }
@@ -4182,17 +4140,17 @@
 /****************************************************************************/
 static int
 ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
-   IPS_SCSI_CAPACITY *cap;
+   IPS_SCSI_CAPACITY cap;
 
    METHOD_TRACE("ips_rdcap", 1);
 
    if (scb->scsi_cmd->bufflen < 8)
       return (0);
 
-   cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer;
+   cap.lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
+   cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
 
-   cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
-   cap->len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
+   ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof(cap));
 
    return (1);
 }
@@ -4270,7 +4228,7 @@
       return (0);
    } /* end switch */
 
-   memcpy(scb->scsi_cmd->request_buffer, &mdata, scb->scsi_cmd->request_bufflen);
+   ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof(mdata));
 
    return (1);
 }
@@ -4297,7 +4255,7 @@
    reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
    reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
 
-   memcpy(scb->scsi_cmd->request_buffer, &reqsen, scb->scsi_cmd->request_bufflen);
+   ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof(reqsen));
 
    return (1);
 }
@@ -4376,8 +4334,8 @@
 static int
 ips_deallocatescbs(ips_ha_t *ha, int cmds) {
    if (ha->scbs) {
-      pci_free_consistent(ha->pcidev,sizeof(IPS_SG_LIST) * IPS_MAX_SG *
-                          cmds, ha->scbs->sg_list, ha->scbs->sg_busaddr);
+      pci_free_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
+                          cmds, ha->scbs->sg_list.list, ha->scbs->sg_busaddr);
       pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds,
                           ha->scbs, ha->scbs->scb_busaddr);
       ha->scbs = NULL;
@@ -4397,7 +4355,7 @@
 static int
 ips_allocatescbs(ips_ha_t *ha) {
    ips_scb_t *scb_p;
-   IPS_SG_LIST* ips_sg;
+   IPS_SG_LIST ips_sg;
    int        i;
    dma_addr_t command_dma, sg_dma;
    
@@ -4408,9 +4366,9 @@
 	                           &command_dma);
    if (ha->scbs == NULL)
       return 0;
-   ips_sg = pci_alloc_consistent(ha->pcidev, sizeof(IPS_SG_LIST) * IPS_MAX_SG * 
-	                         ha->max_cmds, &sg_dma);
-   if(ips_sg == NULL){
+   ips_sg.list = pci_alloc_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
+                                    ha->max_cmds, &sg_dma);
+   if(ips_sg.list == NULL){
       pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma);
       return 0;
    }
@@ -4421,8 +4379,13 @@
       scb_p = &ha->scbs[i];
       scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i;
       /* set up S/G list */
-      scb_p->sg_list = ips_sg + i * IPS_MAX_SG;
-      scb_p->sg_busaddr = sg_dma + sizeof(IPS_SG_LIST) * IPS_MAX_SG * i;
+      if (IPS_USE_ENH_SGLIST(ha)) {
+         scb_p->sg_list.enh_list = ips_sg.enh_list + i * IPS_MAX_SG;
+         scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
+      } else {
+         scb_p->sg_list.std_list = ips_sg.std_list + i * IPS_MAX_SG;
+         scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
+      }
 
       /* add to the free list */
       if (i < ha->max_cmds - 1) {
@@ -4446,14 +4409,14 @@
 /****************************************************************************/
 static void
 ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
-   IPS_SG_LIST *sg_list;
+   IPS_SG_LIST sg_list;
    uint32_t cmd_busaddr, sg_busaddr;
    METHOD_TRACE("ips_init_scb", 1);
 
    if (scb == NULL)
       return ;
 
-   sg_list = scb->sg_list;
+   sg_list.list = scb->sg_list.list;
    cmd_busaddr = scb->scb_busaddr;
    sg_busaddr = scb->sg_busaddr;
    /* zero fill */
@@ -4469,7 +4432,7 @@
    /* set bus address of scb */
    scb->scb_busaddr = cmd_busaddr;
    scb->sg_busaddr = sg_busaddr;
-   scb->sg_list = sg_list;
+   scb->sg_list.list = sg_list.list;
 
    /* Neptune Fix */
    scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
@@ -4523,8 +4486,7 @@
 
    METHOD_TRACE("ips_freescb", 1);
    if(scb->flags & IPS_SCB_MAP_SG)
-      pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer,
-                   scb->scsi_cmd->use_sg,
+      pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg,
                    IPS_DMA_DIR(scb));
    else if(scb->flags & IPS_SCB_MAP_SINGLE)
       pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
@@ -4953,6 +4915,13 @@
    writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
 
    /* if we get here then everything went OK */
+
+   /* Since we did a RESET, an EraseStripeLock may be needed */
+   if (Post == 0xEF10) {
+      if ( (Config == 0x000F) || (Config == 0x0009) )
+         ha->requires_esl = 1;
+   }
+
    return (1);
 }
 
@@ -5633,7 +5602,6 @@
    scb->cmd.basic_io.lba = 0;
    scb->cmd.basic_io.sector_count = 0;
    scb->cmd.basic_io.log_drv = 0;
-   scb->cmd.basic_io.reserved = 0;
    scb->data_len = sizeof(*ha->enq);
    scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len,
                                       IPS_DMA_DIR(scb));
@@ -5678,7 +5646,6 @@
    scb->cmd.basic_io.lba = 0;
    scb->cmd.basic_io.sector_count = 0;
    scb->cmd.basic_io.log_drv = 0;
-   scb->cmd.basic_io.reserved = 0;
    scb->data_len = sizeof(*ha->subsys);
    scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys,
                                       scb->data_len, IPS_DMA_DIR(scb));
@@ -6504,6 +6471,8 @@
  uint8_t  BiosVersion[ IPS_COMPAT_ID_LENGTH + 1];
  int      MatchError;
  int      rc;
+ char     BiosString[10];
+ char     FirmwareString[10];
 
  METHOD_TRACE("ips_version_check", 1);
 
@@ -6536,28 +6505,30 @@
  MatchError = 0;
 
  if  (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
- {
-     if (ips_cd_boot == 0)                                                                              
-       printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", 
-              ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]);                    
      MatchError = 1;
- }
 
  if  (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
- {
-     if (ips_cd_boot == 0)                                                                          
-       printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", 
-              ha->host_num, BiosVersion, IPS_COMPAT_BIOS);                                          
      MatchError = 1;
- }
 
  ha->nvram->versioning = 1;          /* Indicate the Driver Supports Versioning */
 
  if  (MatchError)
  {
      ha->nvram->version_mismatch = 1;
-     if (ips_cd_boot == 0)                                               
-       printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n");
+     if (ips_cd_boot == 0)
+     {
+         strncpy(&BiosString[0], ha->nvram->bios_high, 4);
+         strncpy(&BiosString[4], ha->nvram->bios_low, 4);
+         BiosString[8] = 0;
+
+         strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8);
+         FirmwareString[8] = 0;
+
+         printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n");
+         printk(KERN_WARNING "Bios = %s, Firmware = %s, Device Driver = %s%s\n",
+                              BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW );
+         printk(KERN_WARNING "These levels should match to avoid possible compatibility problems.\n" );
+     }
  }
  else
  {
@@ -6605,20 +6576,185 @@
    return( rc );
 }
 
-  
-
-static Scsi_Host_Template driver_template = IPS;
-#include "scsi_module.c"
-
-static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_abort_init                                             */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   cleanup routine for a failed adapter initialization                    */
+/****************************************************************************/ 
+static int ips_abort_init(ips_ha_t *ha, int index){
    ha->active = 0;
    ips_free(ha);
-   scsi_unregister(sh);
    ips_ha[index] = 0;
    ips_sh[index] = 0;
    return -1;
 }
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_shift_controllers                                      */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   helper function for ordering adapters                                  */
+/****************************************************************************/
+static void
+ips_shift_controllers(int lowindex, int highindex){
+	ips_ha_t *ha_sav = ips_ha[highindex];
+	struct Scsi_Host *sh_sav = ips_sh[highindex];
+	int i;
+
+	for ( i = highindex; i > lowindex; i--){
+		ips_ha[i] = ips_ha[i - 1];
+		ips_sh[i] = ips_sh[i - 1];
+		ips_ha[i]->host_num = i;
+	}
+	ha_sav->host_num = lowindex;
+	ips_ha[lowindex] = ha_sav;
+	ips_sh[lowindex] = sh_sav;
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_order_controllers                                      */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   place controllers is the "proper" boot order                           */
+/****************************************************************************/
+static void
+ips_order_controllers(void){
+	int i, j, tmp, position = 0;
+	IPS_NVRAM_P5 *nvram;
+	if(!ips_ha[0])
+		return;
+	nvram = ips_ha[0]->nvram;
+
+	if(nvram->adapter_order[0]){
+		for(i = 1; i <= nvram->adapter_order[0]; i++){
+			for(j = position; j < ips_num_controllers; j++){
+				switch(ips_ha[j]->ad_type){
+				case IPS_ADTYPE_SERVERAID6M:
+					if(nvram->adapter_order[i] == 'M'){
+						ips_shift_controllers(position, j);
+						position++;
+					}
+					break;
+				case IPS_ADTYPE_SERVERAID4L:
+				case IPS_ADTYPE_SERVERAID4M:
+				case IPS_ADTYPE_SERVERAID4MX:
+				case IPS_ADTYPE_SERVERAID4LX:
+					if(nvram->adapter_order[i] == 'N'){
+						ips_shift_controllers(position, j);
+						position++;
+					}
+					break;
+				case IPS_ADTYPE_SERVERAID6I:
+				case IPS_ADTYPE_SERVERAID5I2:
+				case IPS_ADTYPE_SERVERAID5I1:
+					if(nvram->adapter_order[i] == 'S'){
+						ips_shift_controllers(position, j);
+						position++;
+					}
+					break;
+				case IPS_ADTYPE_SERVERAID:
+				case IPS_ADTYPE_SERVERAID2:
+				case IPS_ADTYPE_NAVAJO:
+				case IPS_ADTYPE_KIOWA:
+				case IPS_ADTYPE_SERVERAID3L:
+				case IPS_ADTYPE_SERVERAID3:
+				case IPS_ADTYPE_SERVERAID4H:
+					if(nvram->adapter_order[i] == 'A'){
+						ips_shift_controllers(position, j);
+						position++;
+					}
+					break;
+				default:
+				}
+			}
+		}
+		/* if adapter_order[0], then ordering is complete */
+		return;
+	}
+	/* old bios, use older ordering */
+	tmp = 0;
+	for(i = position; i < ips_num_controllers; i++){
+		if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 ||
+		    ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1){
+			ips_shift_controllers(position, i);
+			position++;
+			tmp = 1;
+		}
+	}
+	/* if there were no 5I cards, then don't do any extra ordering */
+	if (!tmp)
+		return;
+	for(i = position; i < ips_num_controllers; i++){
+		if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L ||
+		    ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M ||
+		    ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX ||
+		    ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX){
+			ips_shift_controllers(position, i);
+			position++;
+		}
+	}
+
+	return;
+}
+
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_register_scsi                                          */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   perform any registration and setup with the scsi layer                 */
+/****************************************************************************/
+static int
+ips_register_scsi( int index){
+	struct Scsi_Host *sh;
+	ips_ha_t *ha, *oldha;
+	sh = scsi_register(&ips_driver_template, sizeof(ips_ha_t));
+	if(!sh) {
+		printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" );
+		return -1;
+	}
+	oldha = ips_ha[index];
+	ha = IPS_HA(sh);
+	memcpy(ha, oldha, sizeof(ips_ha_t));
+	free_irq(oldha->irq, oldha);
+	/* Install the interrupt handler with the new ha */
+	if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+		printk(KERN_WARNING "Unable to install interrupt handler\n" );
+		scsi_unregister(sh);
+		return -1;
+	}
 
+	kfree(oldha);
+	ips_sh[index] = sh;
+	ips_ha[index] = ha;
+	scsi_set_pci_device(sh, ha->pcidev);
+
+	/* Store away needed values for later use */
+	sh->io_port = ha->io_addr;
+	sh->n_io_port = ha->io_addr ? 255 : 0;
+	sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr;
+	sh->irq = ha->irq;
+	sh->sg_tablesize = sh->hostt->sg_tablesize;
+	sh->can_queue = sh->hostt->can_queue;
+	sh->cmd_per_lun = sh->hostt->cmd_per_lun;
+	sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
+	sh->use_clustering = sh->hostt->use_clustering;
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
+	sh->max_sectors = 128;
+#endif 
+
+	sh->max_id = ha->ntargets;
+	sh->max_lun = ha->nlun;
+	sh->max_channel = ha->nbus - 1;
+	sh->can_queue = ha->max_cmds-1;
+
+	return 0;
+}
 
 /*---------------------------------------------------------------------------*/
 /*   Routine Name: ips_remove_device                                         */
@@ -6644,6 +6780,43 @@
    }
 }
 
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_module_init                                            */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   function called on module load                                         */
+/****************************************************************************/
+static int __init
+ips_module_init(void){
+	if( pci_module_init(&ips_pci_driver) < 0 )
+		return -ENODEV;
+	ips_driver_template.module = THIS_MODULE;
+	ips_order_controllers();
+	if( scsi_register_host(&ips_driver_template) ){
+		pci_unregister_driver(&ips_pci_driver);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_module_exit                                            */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*   function called on module unload                                       */
+/****************************************************************************/
+static void __exit
+ips_module_exit(void){
+	scsi_unregister_host(&ips_driver_template);
+	pci_unregister_driver(&ips_pci_driver);
+	unregister_reboot_notifier(&ips_notifier);
+}
+
+module_init(ips_module_init);
+module_exit(ips_module_exit);
 
 /*---------------------------------------------------------------------------*/
 /*   Routine Name: ips_insert_device                                         */
@@ -6686,7 +6859,6 @@
 /*---------------------------------------------------------------------------*/
 static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
 {         
-   struct Scsi_Host *sh;
    ips_ha_t         *ha;
    uint32_t          io_addr;
    uint32_t          mem_addr;
@@ -6777,65 +6949,88 @@
     subdevice_id = pci_dev->subsystem_device;
 
     /* found a controller */
-    sh = scsi_register(&driver_template, sizeof(ips_ha_t));
-#if LINUX_VERSION_CODE > LinuxVersionCode(2,5,0) 
-    pci_set_dma_mask(pci_dev, (u64)0xffffffff);
-    scsi_set_pci_device(sh, pci_dev);
-#endif
-    if (sh == NULL) {
-       printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" );
+    ha = kmalloc(sizeof(ips_ha_t), GFP_KERNEL);
+    if (ha == NULL) {
+       printk(KERN_WARNING "Unable to allocate temporary ha struct\n" );
        return -1;
     }
 
-    ha = IPS_HA(sh);
     memset(ha, 0, sizeof(ips_ha_t));
     
-    ips_sh[index] = sh;
+    ips_sh[index] = NULL;
     ips_ha[index] = ha;
     ha->active = 1;
 
-    ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
+    /* Store info in HA structure */
+    ha->irq = irq;
+    ha->io_addr = io_addr;
+    ha->io_len = io_len;
+    ha->mem_addr = mem_addr;
+    ha->mem_len = mem_len;
+    ha->mem_ptr = mem_ptr;
+    ha->ioremap_ptr = ioremap_ptr;
+    ha->host_num = ( uint32_t) index;
+    ha->revision_id = revision_id;
+    ha->slot_num = PCI_SLOT(pci_dev->devfn);
+    ha->device_id = pci_dev->device;
+    ha->subdevice_id = subdevice_id;
+    ha->pcidev = pci_dev;
+
+    /*
+     * Set the pci_dev's dma_mask.  Not all adapters support 64bit
+     * addressing so don't enable it if the adapter can't support
+     * it!  Also, don't use 64bit addressing if dma addresses
+     * are guaranteed to be < 4G.
+     */
+    if ( IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
+         !pci_set_dma_mask(ha->pcidev, (u64)0xffffffffffffffff)) {
+       (ha)->flags |= IPS_HA_ENH_SG;
+    } else {
+       pci_set_dma_mask(ha->pcidev, (u64)0xffffffff);
+    }
+
+    ha->enq = kmalloc(sizeof(IPS_ENQ), IPS_INIT_GFP);
 
     if (!ha->enq) {
        printk(KERN_WARNING "Unable to allocate host inquiry structure\n" );
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
 
     ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) +
                                      sizeof(IPS_IO_CMD), &dma_address);
     if (!ha->adapt) {
        printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n");
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
     ha->adapt->hw_status_start = dma_address;
     ha->dummy = (void *)(ha->adapt + 1);
 
-    ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
+    ha->conf = kmalloc(sizeof(IPS_CONF), IPS_INIT_GFP);
 
     if (!ha->conf) {
        printk(KERN_WARNING "Unable to allocate host conf structure\n" );
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
 
-    ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
+    ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), IPS_INIT_GFP);
 
     if (!ha->nvram) {
        printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" );
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
 
-    ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
+    ha->subsys = kmalloc(sizeof(IPS_SUBSYS), IPS_INIT_GFP);
 
     if (!ha->subsys) {
        printk(KERN_WARNING "Unable to allocate host subsystem structure\n" );
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
 
     for (count = PAGE_SIZE, ha->ioctl_order = 0;
          count < ips_ioctlsize;
          ha->ioctl_order++, count <<= 1);
 
-    ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
+    ha->ioctl_data = (char *) __get_free_pages(IPS_INIT_GFP, ha->ioctl_order);
     ha->ioctl_datasize = count;
 
     if (!ha->ioctl_data) {
@@ -6845,49 +7040,19 @@
        ha->ioctl_datasize = 0;
     }
 
-    /* Store away needed values for later use */
-    sh->io_port = io_addr;
-    sh->n_io_port = io_addr ? 255 : 0;
-    sh->unique_id = (io_addr) ? io_addr : mem_addr;
-    sh->irq = irq;
-    //sh->select_queue_depths = ips_select_queue_depth;
-    sh->sg_tablesize = sh->hostt->sg_tablesize;
-    sh->can_queue = sh->hostt->can_queue;
-    sh->cmd_per_lun = sh->hostt->cmd_per_lun;
-    sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
-    sh->use_clustering = sh->hostt->use_clustering;
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
-    sh->max_sectors = 128;
-#endif                      
-
-    /* Store info in HA structure */
-    ha->irq = irq;
-    ha->io_addr = io_addr;
-    ha->io_len = io_len;
-    ha->mem_addr = mem_addr;
-    ha->mem_len = mem_len;
-    ha->mem_ptr = mem_ptr;
-    ha->ioremap_ptr = ioremap_ptr;
-    ha->host_num = ( uint32_t) index;
-    ha->revision_id = revision_id;
-    ha->slot_num = PCI_SLOT(pci_dev->devfn);
-    ha->device_id = pci_dev->device;
-    ha->subdevice_id = subdevice_id;
-    ha->pcidev = pci_dev;
-
     /*
      * Setup Functions
      */
     ips_setup_funclist(ha);
 
-    if ( IPS_IS_MORPHEUS( ha ) ) {
+    if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) {
         /* If Morpheus appears dead, reset it */
         IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
         if ( IsDead == 0xDEADBEEF ) {
             ips_reset_morpheus( ha );
         }
     }
+
     /*
      * Initialize the card if it isn't already
      */
@@ -6898,31 +7063,14 @@
            * Initialization failed
            */
           printk(KERN_WARNING "Unable to initialize controller\n" );
-          return ips_abort_init(ha, sh, index);
+          return ips_abort_init(ha, index);
        }
     }
 
-    /* Install the interrupt handler */
-     if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
-       printk(KERN_WARNING "Unable to install interrupt handler\n" );
-       return ips_abort_init(ha, sh, index);
-    }
-
-    /*
-     * Allocate a temporary SCB for initialization
-     */
-    ha->max_cmds = 1;
-    if (!ips_allocatescbs(ha)) {
-       printk(KERN_WARNING "Unable to allocate a CCB\n" );
-       free_irq(ha->irq, ha);
-       return ips_abort_init(ha, sh, index);
-    }
-
     *indexPtr = index;
     return SUCCESS;
 }
 
-
 /*---------------------------------------------------------------------------*/
 /*   Routine Name: ips_init_phase2                                           */
 /*                                                                           */
@@ -6934,24 +7082,36 @@
 /*---------------------------------------------------------------------------*/
 static int ips_init_phase2( int index )
 {         
-    struct Scsi_Host *sh;
     ips_ha_t         *ha;
 
     ha = ips_ha[index];
-    sh = ips_sh[index];
 
     METHOD_TRACE("ips_init_phase2", 1);
     if (!ha->active) {
-       scsi_unregister(sh);
        ips_ha[index] = NULL;
-       ips_sh[index] = NULL;
-       return -1;;
+       return -1;
+    }
+
+    /* Install the interrupt handler */
+     if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+       printk(KERN_WARNING "Unable to install interrupt handler\n" );
+       return ips_abort_init(ha, index);
+    }
+
+    /*
+     * Allocate a temporary SCB for initialization
+     */
+    ha->max_cmds = 1;
+    if (!ips_allocatescbs(ha)) {
+       printk(KERN_WARNING "Unable to allocate a CCB\n" );
+       free_irq(ha->irq, ha);
+       return ips_abort_init(ha, index);
     }
 
     if (!ips_hainit(ha)) {
        printk(KERN_WARNING "Unable to initialize controller\n" );
        free_irq(ha->irq, ha);
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
     /* Free the temporary SCB */
     ips_deallocatescbs(ha, 1);
@@ -6960,20 +7120,16 @@
     if (!ips_allocatescbs(ha)) {
        printk(KERN_WARNING "Unable to allocate CCBs\n" );
        free_irq(ha->irq, ha);
-       return ips_abort_init(ha, sh, index);
+       return ips_abort_init(ha, index);
     }
 
-    /* finish setting values */
-    sh->max_id = ha->ntargets;
-    sh->max_lun = ha->nlun;
-    sh->max_channel = ha->nbus - 1;
-    sh->can_queue = ha->max_cmds-1;
-
     return SUCCESS;
 }
 
 
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9)
 MODULE_LICENSE("GPL");
+#endif
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h
--- a/drivers/scsi/ips.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/ips.h	Mon Feb 10 10:39:24 2003
@@ -59,11 +59,7 @@
    extern int ips_eh_abort(Scsi_Cmnd *);
    extern int ips_eh_reset(Scsi_Cmnd *);
    extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
-   extern int ips_biosparam(struct scsi_device *, struct block_device *,
-		   sector_t, int *);
-   extern int ips_slave_configure(Scsi_Device *);
    extern const char * ips_info(struct Scsi_Host *);
-   extern void do_ips(int, void *, struct pt_regs *);
 
    /*
     * Some handy macros
@@ -72,6 +68,13 @@
       #define LinuxVersionCode(x,y,z)  (((x)<<16)+((y)<<8)+(z))
    #endif
 
+   #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,20) || defined CONFIG_HIGHIO
+      #define IPS_HIGHIO
+      #define IPS_HIGHMEM_IO     .highmem_io = 1,
+   #else
+      #define IPS_HIGHMEM_IO
+   #endif
+
    #define IPS_HA(x)                   ((ips_ha_t *) x->hostdata)
    #define IPS_COMMAND_ID(ha, scb)     (int) (scb - ha->scbs)
    #define IPS_IS_TROMBONE(ha)         (((ha->device_id == IPS_DEVICEID_COPPERHEAD) && \
@@ -81,18 +84,55 @@
                                          (ha->revision_id >= IPS_REVID_CLARINETP1) && \
                                          (ha->revision_id <= IPS_REVID_CLARINETP3)) ? 1 : 0)
    #define IPS_IS_MORPHEUS(ha)         (ha->device_id == IPS_DEVICEID_MORPHEUS)
+   #define IPS_IS_MARCO(ha)            (ha->device_id == IPS_DEVICEID_MARCO)
    #define IPS_USE_I2O_DELIVER(ha)     ((IPS_IS_MORPHEUS(ha) || \
                                          (IPS_IS_TROMBONE(ha) && \
                                           (ips_force_i2o))) ? 1 : 0)
-   #define IPS_USE_I2O_STATUS(ha)      (IPS_IS_MORPHEUS(ha))
    #define IPS_USE_MEMIO(ha)           ((IPS_IS_MORPHEUS(ha) || \
                                          ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \
                                           (ips_force_memio))) ? 1 : 0)
 
+    #define IPS_HAS_ENH_SGLIST(ha)    (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha))
+    #define IPS_USE_ENH_SGLIST(ha)    ((ha)->flags & IPS_HA_ENH_SG)
+    #define IPS_SGLIST_SIZE(ha)       (IPS_USE_ENH_SGLIST(ha) ? \
+                                         sizeof(IPS_ENH_SG_LIST) : sizeof(IPS_STD_SG_LIST))
+
+   #if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4)
+      #define pci_set_dma_mask(dev,mask) (1)
+      #define scsi_set_pci_device(sh,dev) (0)
+   #endif
+
+   #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
+      #define scsi_register_host(x)    scsi_register_module(MODULE_SCSI_HA,x)
+      #define scsi_unregister_host(x)  scsi_unregister_module(MODULE_SCSI_HA,x)
+   #endif
+
    #ifndef MDELAY
       #define MDELAY mdelay
    #endif
-   
+
+   #ifndef min
+      #define min(x,y) ((x) < (y) ? x : y)
+   #endif
+
+   #define pci_dma_lo32(a)         (a & 0xffffffff)
+
+   #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO)
+      #define IPS_ENABLE_DMA64        (1)
+      #define pci_dma_hi32(a)         (a >> 32)
+   #else
+      #define IPS_ENABLE_DMA64        (0)
+      #define pci_dma_hi32(a)         (0)
+   #endif
+
+   #if defined(__ia64__)
+      #define IPS_ATOMIC_GFP	(GFP_DMA | GFP_ATOMIC)
+      #define IPS_INIT_GFP	GFP_DMA
+   #else
+      #define IPS_ATOMIC_GFP    GFP_ATOMIC
+      #define IPS_INIT_GFP	GFP_KERNEL
+   #endif
+
    /*
     * Adapter address map equates
     */
@@ -152,7 +192,7 @@
    #define IPS_CMD_DCDB                 0x04
    #define IPS_CMD_DCDB_SG              0x84
    #define IPS_CMD_EXTENDED_DCDB 	    0x95
-	#define IPS_CMD_EXTENDED_DCDB_SG		 0x96
+   #define IPS_CMD_EXTENDED_DCDB_SG	    0x96
    #define IPS_CMD_CONFIG_SYNC          0x58
    #define IPS_CMD_ERROR_TABLE          0x17
    #define IPS_CMD_DOWNLOAD             0x20
@@ -166,6 +206,7 @@
    #define IPS_CSL                      0xFF
    #define IPS_POCL                     0x30
    #define IPS_NORM_STATE               0x00
+   #define IPS_MAX_ADAPTER_TYPES        3
    #define IPS_MAX_ADAPTERS             16
    #define IPS_MAX_IOCTL                1
    #define IPS_MAX_IOCTL_QUEUE          8
@@ -188,15 +229,19 @@
    #define IPS_INTR_IORL                1
    #define IPS_FFDC                     99
    #define IPS_ADAPTER_ID               0xF
-   #define IPS_VENDORID                 0x1014
+   #define IPS_VENDORID_IBM             0x1014
+   #define IPS_VENDORID_ADAPTEC         0x9005
    #define IPS_DEVICEID_COPPERHEAD      0x002E
    #define IPS_DEVICEID_MORPHEUS        0x01BD
+   #define IPS_DEVICEID_MARCO           0x0250
    #define IPS_SUBDEVICEID_4M           0x01BE
    #define IPS_SUBDEVICEID_4L           0x01BF
    #define IPS_SUBDEVICEID_4MX          0x0208
    #define IPS_SUBDEVICEID_4LX          0x020E
    #define IPS_SUBDEVICEID_5I2          0x0259
    #define IPS_SUBDEVICEID_5I1          0x0258
+   #define IPS_SUBDEVICEID_6M           0x0279
+   #define IPS_SUBDEVICEID_6I           0x028C
    #define IPS_IOCTL_SIZE               8192
    #define IPS_STATUS_SIZE              4
    #define IPS_STATUS_Q_SIZE            (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE
@@ -279,6 +324,8 @@
    #define IPS_ADTYPE_SERVERAID4LX      0x0B
    #define IPS_ADTYPE_SERVERAID5I2      0x0C
    #define IPS_ADTYPE_SERVERAID5I1      0x0D
+   #define IPS_ADTYPE_SERVERAID6M       0x0E
+   #define IPS_ADTYPE_SERVERAID6I       0x0F
 
    /*
     * Adapter Command/Status Packet Definitions
@@ -350,6 +397,12 @@
    #define IPS_SCSI_MP3_AllocateSurface 0x08
 
    /*
+    * HA Flags
+    */
+
+   #define IPS_HA_ENH_SG                0x1
+
+   /*
     * SCB Flags
     */
    #define IPS_SCB_MAP_SG               0x00008
@@ -387,34 +440,31 @@
     * Scsi_Host Template
     */
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
-#define IPS{	\
-	.module				= NULL,		\
-	.proc_info			= NULL,		\
-	.name				= NULL,		\
+   static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+   static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]);
+#define IPS {	\
 	.detect				= ips_detect,	\
 	.release			= ips_release,	\
 	.info				= ips_info,	\
-	.command			= NULL,		\
 	.queuecommand			= ips_queue,	\
-	.eh_strategy_handler		= NULL,		\
 	.eh_abort_handler		= ips_eh_abort,	\
-	.eh_device_reset_handler	= NULL,		\
-	.eh_bus_reset_handler		= NULL,		\
 	.eh_host_reset_handler		= ips_eh_reset,	\
-	.abort				= NULL,		\
-	.reset				= NULL,		\
-	.slave_attach			= NULL,		\
 	.bios_param			= ips_biosparam,\
+	.select_queue_depths		= ips_select_queue_depth, \
 	.can_queue			= 0,		\
 	.this_id			= -1,		\
 	.sg_tablesize			= IPS_MAX_SG,	\
-	.cmd_per_lun			= 3,		\
+	.cmd_per_lun			= 16,		\
 	.present			= 0,		\
 	.unchecked_isa_dma		= 0,		\
 	.use_clustering			= ENABLE_CLUSTERING,\
-	.use_new_eh_code		= 1 \
+	.use_new_eh_code		= 1, \
+	IPS_HIGHMEM_IO \
 }
 #else
+   static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
+		sector_t capacity, int geom[]);
+   int ips_slave_configure(Scsi_Device *SDptr);
 #define IPS {	\
 	.detect			= ips_detect,		\
 	.release		= ips_release,		\
@@ -436,7 +486,7 @@
 #endif
 
 /*
- * IBM PCI Raid Command Formats
+ * Raid Command Formats
  */
 typedef struct {
    uint8_t  op_code;
@@ -446,7 +496,8 @@
    uint32_t lba;
    uint32_t sg_addr;
    uint16_t sector_count;
-   uint16_t reserved;
+   uint8_t  segment_4G;
+   uint8_t  enhanced_sg;
    uint32_t ccsar;
    uint32_t cccr;
 } IPS_IO_CMD, *PIPS_IO_CMD;
@@ -497,7 +548,9 @@
    uint16_t reserved;
    uint32_t reserved2;
    uint32_t dcdb_address;
-   uint32_t reserved3;
+   uint16_t reserved3;
+   uint8_t  segment_4G;
+   uint8_t  enhanced_sg;
    uint32_t ccsar;
    uint32_t cccr;
 } IPS_DCDB_CMD, *PIPS_DCDB_CMD;
@@ -714,7 +767,7 @@
    uint16_t usConfigUpdateCount;
    uint8_t  ucBlkFlag;
    uint8_t  reserved;
-   uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
+   uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * (IPS_MAX_TARGETS + 1)];
 } IPS_ENQ, *PIPS_ENQ;
 
 typedef struct {
@@ -790,7 +843,8 @@
    uint8_t   ReservedForOS2[8];
    uint8_t   bios_high[4];                 /* Adapter's Flashed BIOS Version   */
    uint8_t   bios_low[4];
-   uint8_t   Filler[76];
+   uint8_t   adapter_order[16];            /* BIOS Telling us the Sort Order   */
+   uint8_t   Filler[60];
 } IPS_NVRAM_P5, *PIPS_NVRAM_P5;
 
 /*--------------------------------------------------------------------------*/
@@ -940,7 +994,20 @@
 typedef struct ips_sglist {
    uint32_t address;
    uint32_t length;
-} IPS_SG_LIST, *PIPS_SG_LIST;
+} IPS_STD_SG_LIST;
+
+typedef struct ips_enh_sglist {
+   uint32_t address_lo;
+   uint32_t address_hi;
+   uint32_t length;
+   uint32_t reserved;
+} IPS_ENH_SG_LIST;
+
+typedef union {
+   void             *list;
+   IPS_STD_SG_LIST  *std_list;
+   IPS_ENH_SG_LIST  *enh_list;
+} IPS_SG_LIST;
 
 typedef struct _IPS_INFOSTR {
    char *buffer;
@@ -1040,6 +1107,7 @@
    char              *ioctl_data;         /* IOCTL data area            */
    uint32_t           ioctl_datasize;     /* IOCTL data size            */
    uint32_t           cmd_in_progress;    /* Current command in progress*/
+   int                flags;              /*                            */
    uint8_t            waitflag;           /* are we waiting for cmd     */
    uint8_t            active;
    int                ioctl_reset;        /* IOCTL Requested Reset Flag */
@@ -1050,7 +1118,6 @@
    uint8_t            slot_num;           /* PCI Slot Number            */
    uint16_t           subdevice_id;       /* Subsystem device ID        */
    uint8_t            ioctl_order;        /* Number of pages in ioctl   */
-   uint8_t            reserved2;          /* Empty                      */
    uint8_t            bios_version[8];    /* BIOS Revision              */
    uint32_t           mem_addr;           /* Memory mapped address      */
    uint32_t           io_len;             /* Size of IO Address         */
@@ -1060,8 +1127,9 @@
    ips_hw_func_t      func;               /* hw function pointers       */
    struct pci_dev    *pcidev;             /* PCI device handle          */
    char              *flash_data;         /* Save Area for flash data   */
-   u8                 flash_order;        /* Save Area for flash size order  */
-   u32                flash_datasize;   /* Save Area for flash data size */
+   u8                 flash_order;        /* Save Area for flash size order */
+   u32                flash_datasize;     /* Save Area for flash data size */
+   uint8_t            requires_esl;       /* Requires an EraseStripeLock */
 } ips_ha_t;
 
 typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *);
@@ -1087,7 +1155,7 @@
    uint32_t          sg_len;
    uint32_t          flags;
    uint32_t          op_code;
-   IPS_SG_LIST      *sg_list;
+   IPS_SG_LIST       sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
@@ -1148,58 +1216,64 @@
 
 #define IPS_VER_MAJOR 5
 #define IPS_VER_MAJOR_STRING "5"
-#define IPS_VER_MINOR 10
-#define IPS_VER_MINOR_STRING "10"
-#define IPS_VER_BUILD_STRING "13"
-#define IPS_VER_STRING  "5.10.13-BETA"
-#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."
-#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002."
+#define IPS_VER_MINOR 99
+#define IPS_VER_MINOR_STRING "99"
+#define IPS_VER_BUILD 00
+#define IPS_VER_BUILD_STRING "00"
+#define IPS_VER_STRING "5.99.00"
+#define IPS_BUILD_IDENT 1132
 
 /* Version numbers for various adapters */
-#define IPS_VER_SERVERAID1    "2.25.01"
-#define IPS_VER_SERVERAID2    "2.88.13"
-#define IPS_VER_NAVAJO        "2.88.13"
-#define IPS_VER_SERVERAID3    "5.10.01"
-#define IPS_VER_SERVERAID4H   "5.10.01"
-#define IPS_VER_SERVERAID4MLx "5.10.01"
-#define IPS_VER_SARASOTA      "5.10.05"
+#define IPS_VER_SERVERAID1 "2.25.01"
+#define IPS_VER_SERVERAID2 "2.88.13"
+#define IPS_VER_NAVAJO "2.88.13"
+#define IPS_VER_SERVERAID3 "5.11.05"
+#define IPS_VER_SERVERAID4H "5.11.05"
+#define IPS_VER_SERVERAID4MLx "5.11.05"
+#define IPS_VER_SARASOTA "5.11.05"
+#define IPS_VER_MARCO "0.00.00"
+#define IPS_VER_SEBRING "0.00.00"
 
 /* Compatability IDs for various adapters */
-#define IPS_COMPAT_UNKNOWN      ""
-#define IPS_COMPAT_CURRENT      "SA510"
-#define IPS_COMPAT_SERVERAID1   "2.25.01"
-#define IPS_COMPAT_SERVERAID2   "2.88.13"
-#define IPS_COMPAT_NAVAJO       "2.88.13"
-#define IPS_COMPAT_KIOWA        "2.88.13"
-#define IPS_COMPAT_SERVERAID3H  "5.10.01"
-#define IPS_COMPAT_SERVERAID3L  "5.10.01"
-#define IPS_COMPAT_SERVERAID4H  "5.10.01"
+#define IPS_COMPAT_UNKNOWN ""
+#define IPS_COMPAT_CURRENT "SB610"
+#define IPS_COMPAT_SERVERAID1 "2.25.01"
+#define IPS_COMPAT_SERVERAID2 "2.88.13"
+#define IPS_COMPAT_NAVAJO  "2.88.13"
+#define IPS_COMPAT_KIOWA "2.88.13"
+#define IPS_COMPAT_SERVERAID3H  "SA510"
+#define IPS_COMPAT_SERVERAID3L  "SA510"
+#define IPS_COMPAT_SERVERAID4H  "SA510"
 #define IPS_COMPAT_SERVERAID4M  "SA510"
 #define IPS_COMPAT_SERVERAID4L  "SA510"
 #define IPS_COMPAT_SERVERAID4Mx "SA510"
 #define IPS_COMPAT_SERVERAID4Lx "SA510"
 #define IPS_COMPAT_SARASOTA     "SA510"
-#define IPS_COMPAT_BIOS         "SA510"
+#define IPS_COMPAT_MARCO        "SA000"
+#define IPS_COMPAT_SEBRING      "SA000"
+#define IPS_COMPAT_BIOS "SA510"
 
-#define IPS_COMPAT_MAX_ADAPTER_TYPE 14
-#define IPS_COMPAT_ID_LENGTH         8
+#define IPS_COMPAT_MAX_ADAPTER_TYPE 16
+#define IPS_COMPAT_ID_LENGTH 8
 
 #define IPS_DEFINE_COMPAT_TABLE(tablename) \
    char tablename[IPS_COMPAT_MAX_ADAPTER_TYPE] [IPS_COMPAT_ID_LENGTH] = { \
-      IPS_COMPAT_UNKNOWN,      \
-      IPS_COMPAT_SERVERAID1,   \
-      IPS_COMPAT_SERVERAID2,   \
-      IPS_COMPAT_NAVAJO,       \
-      IPS_COMPAT_KIOWA,        \
-      IPS_COMPAT_SERVERAID3H,  \
-      IPS_COMPAT_SERVERAID3L,  \
-      IPS_COMPAT_SERVERAID4H,  \
-      IPS_COMPAT_SERVERAID4M,  \
-      IPS_COMPAT_SERVERAID4L,  \
+      IPS_COMPAT_UNKNOWN, \
+      IPS_COMPAT_SERVERAID1, \
+      IPS_COMPAT_SERVERAID2, \
+      IPS_COMPAT_NAVAJO, \
+      IPS_COMPAT_KIOWA, \
+      IPS_COMPAT_SERVERAID3H, \
+      IPS_COMPAT_SERVERAID3L, \
+      IPS_COMPAT_SERVERAID4H, \
+      IPS_COMPAT_SERVERAID4M, \
+      IPS_COMPAT_SERVERAID4L, \
       IPS_COMPAT_SERVERAID4Mx, \
       IPS_COMPAT_SERVERAID4Lx, \
-      IPS_COMPAT_SARASOTA,     \
-      IPS_COMPAT_SARASOTA      \
+      IPS_COMPAT_SARASOTA,         /* one-channel variety of SARASOTA */  \
+      IPS_COMPAT_SARASOTA,         /* two-channel variety of SARASOTA */  \
+      IPS_COMPAT_MARCO, \
+      IPS_COMPAT_SEBRING \
    }
 
 
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Mon Feb 10 10:39:22 2003
+++ b/drivers/scsi/megaraid.c	Mon Feb 10 10:39:22 2003
@@ -443,7 +443,7 @@
  * Mon Aug 6 14:59:29 BST 2001 - "Michael Johnson" <johnsom@home.com>
  *
  * Make the HP print formatting and check for buggy firmware runtime not
- * ifdef dependant.
+ * ifdef dependent.
  *
  *
  * Version 1.17d
@@ -863,8 +863,8 @@
 {
 	if (SCpnt->result) {
 		TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n",
-			SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
-			SCpnt->target, SCpnt->lun, SCpnt->result));
+			SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel,
+			SCpnt->device->id, SCpnt->device->lun, SCpnt->result));
 	}
 	SCpnt->scsi_done (SCpnt);
 }
@@ -1077,10 +1077,10 @@
 		panic(KERN_ERR "megaraid:Problem...!\n");
 	}
 
-	islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
-					(SCpnt->channel <= megaCfg->host->max_channel) );
+	islogical = ( (SCpnt->device->channel >= megaCfg->productInfo.SCSIChanPresent) &&
+					(SCpnt->device->channel <= megaCfg->host->max_channel) );
 #if 0
-	islogical = (SCpnt->channel == megaCfg->host->max_channel);
+	islogical = (SCpnt->device->channel == megaCfg->host->max_channel);
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
@@ -1119,7 +1119,7 @@
 			status = 0xF0;
 		}
 #endif
-		if( IS_RAID_CH(SCpnt->channel) && ((c & 0x1F ) == TYPE_DISK) ) {
+		if( IS_RAID_CH(SCpnt->device->channel) && ((c & 0x1F ) == TYPE_DISK) ) {
 			status = 0xF0;
 		}
 	}
@@ -1206,7 +1206,7 @@
 	mega_ext_passthru *epthru;
 	long seg;
 	char islogical;
-	int lun = SCpnt->lun;
+	int lun = SCpnt->device->lun;
 	int		max_lun;
 
 	if ((SCpnt->cmnd[0] == MEGADEVIOC))
@@ -1224,11 +1224,11 @@
 	}
 #endif
 
-	islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
-					(SCpnt->channel <= megaCfg->host->max_channel) );
+	islogical = ( (SCpnt->device->channel >= megaCfg->productInfo.SCSIChanPresent) &&
+					(SCpnt->device->channel <= megaCfg->host->max_channel) );
 #if 0
-	islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */
-						(SCpnt->channel == megaCfg->host->max_channel));
+	islogical = (IS_RAID_CH(SCpnt->device->channel) && /* virtual ch is raid - AM */
+						(SCpnt->device->channel == megaCfg->host->max_channel));
 #endif
 
 	if ( ! megaCfg->support_ext_cdb ) {
@@ -1239,7 +1239,7 @@
 		}
 	}
 
-	if (!islogical && SCpnt->target == skip_id) {
+	if (!islogical && SCpnt->device->id == skip_id) {
 		SCpnt->result = (DID_BAD_TARGET << 16);
 		callDone (SCpnt);
 		return NULL;
@@ -1248,7 +1248,7 @@
 	if (islogical) {
 
 		/* have just LUN 0 for each target on virtual channels */
-		if( SCpnt->lun != 0 ) {
+		if( SCpnt->device->lun != 0 ) {
 			SCpnt->result = (DID_BAD_TARGET << 16);
 			callDone (SCpnt);
 			return NULL;
@@ -1561,11 +1561,11 @@
 	int		lun;
 	int		virt_chan;
 
-	tgt = sc->target;
+	tgt = sc->device->id;
 	
 	if ( tgt > 7 ) tgt--;	/* we do not get inquires for tgt 7 */
 
-	virt_chan = sc->channel - this_hba->productInfo.SCSIChanPresent;
+	virt_chan = sc->device->channel - this_hba->productInfo.SCSIChanPresent;
 	lun = (virt_chan * 15) + tgt;
 
 	/*
@@ -1610,11 +1610,11 @@
 	pthru->ars = 1;
 	pthru->reqsenselen = 14;
 	pthru->islogical = 0;
-	pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
+	pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->device->channel;
 	pthru->target = (megacfg->flag & BOARD_40LD) ?
-	    (sc->channel << 4) | sc->target : sc->target;
+	    (sc->device->channel << 4) | sc->device->id : sc->device->id;
 	pthru->cdblen = sc->cmd_len;
-	pthru->logdrv = sc->lun;
+	pthru->logdrv = sc->device->lun;
 
 	memcpy (pthru->cdb, sc->cmnd, sc->cmd_len);
 
@@ -1666,11 +1666,11 @@
 	epthru->ars = 1;
 	epthru->reqsenselen = 14;
 	epthru->islogical = 0;
-	epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
+	epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->device->channel;
 	epthru->target = (megacfg->flag & BOARD_40LD) ?
-	    (sc->channel << 4) | sc->target : sc->target;
+	    (sc->device->channel << 4) | sc->device->id : sc->device->id;
 	epthru->cdblen = sc->cmd_len;
-	epthru->logdrv = sc->lun;
+	epthru->logdrv = sc->device->lun;
 
 	memcpy(epthru->cdb, sc->cmnd, sc->cmd_len);
 
@@ -3535,21 +3535,21 @@
 	mega_scb *pScb;
 	char *user_area = NULL;
 
-	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
+	megaCfg = (mega_host_config *) SCpnt->device->host->hostdata;
 	DRIVER_LOCK (megaCfg);
 
-	if (!(megaCfg->flag & (1L << SCpnt->channel))) {
-		if (SCpnt->channel < megaCfg->productInfo.SCSIChanPresent)
+	if (!(megaCfg->flag & (1L << SCpnt->device->channel))) {
+		if (SCpnt->device->channel < megaCfg->productInfo.SCSIChanPresent)
 			printk ( KERN_NOTICE
 				"scsi%d: scanning channel %d for devices.\n",
-				megaCfg->host->host_no, SCpnt->channel);
+				megaCfg->host->host_no, SCpnt->device->channel);
 		else
 			printk ( KERN_NOTICE
 				"scsi%d: scanning virtual channel %d for logical drives.\n",
 				megaCfg->host->host_no,
-				SCpnt->channel-megaCfg->productInfo.SCSIChanPresent+1);
+				SCpnt->device->channel-megaCfg->productInfo.SCSIChanPresent+1);
 
-		megaCfg->flag |= (1L << SCpnt->channel);
+		megaCfg->flag |= (1L << SCpnt->device->channel);
 	}
 
 	SCpnt->scsi_done = pktComp;
@@ -3698,7 +3698,7 @@
 
 	rc = SCSI_ABORT_NOT_RUNNING;
 
-	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
+	megaCfg = (mega_host_config *) SCpnt->device->host->hostdata;
 
 	megaCfg->flag |= IN_ABORT;
 
@@ -3796,18 +3796,18 @@
 	mega_scb *pScb;
 
 	rc = SCSI_RESET_NOT_RUNNING;
-	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
+	megaCfg = (mega_host_config *) SCpnt->device->host->hostdata;
 
 	megaCfg->flag |= IN_RESET;
 
 	printk
 	    ("megaraid_RESET: %.08lx cmd=%.02x <c=%d.t=%d.l=%d>, flag = %x\n",
-	     SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
-	     SCpnt->target, SCpnt->lun, rstflags);
+	     SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel,
+	     SCpnt->device->id, SCpnt->device->lun, rstflags);
 
 	TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
-		SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
-		SCpnt->target, SCpnt->lun));
+		SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel,
+		SCpnt->device->id, SCpnt->device->lun));
 
 	/*
 	 * Walk list of SCBs for any that are still outstanding
@@ -4515,7 +4515,7 @@
 		if(scsicmd == NULL) return -ENOMEM;
 
 		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
-		scsicmd->host = shpnt;
+		scsicmd->device->host = shpnt;
 
 		if( outlen || inlen ) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
@@ -4652,7 +4652,7 @@
 		if(scsicmd == NULL) return -ENOMEM;
 
 		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
-		scsicmd->host = shpnt;
+		scsicmd->device->host = shpnt;
 
 		if (outlen || inlen) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/ncr53c8xx.c	Mon Feb 10 10:39:24 2003
@@ -3196,8 +3196,8 @@
 
 static void PRINT_ADDR(Scsi_Cmnd *cmd)
 {
-	struct host_data *host_data = (struct host_data *) cmd->host->hostdata;
-	PRINT_LUN(host_data->ncb, cmd->target, cmd->lun);
+	struct host_data *host_data = (struct host_data *) cmd->device->host->hostdata;
+	PRINT_LUN(host_data->ncb, cmd->device->id, cmd->device->lun);
 }
 
 /*==========================================================
@@ -4345,8 +4345,8 @@
 static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
 {
 /*	Scsi_Device        *device    = cmd->device; */
-	tcb_p tp                      = &np->target[cmd->target];
-	lcb_p lp		      = tp->lp[cmd->lun];
+	tcb_p tp                      = &np->target[cmd->device->id];
+	lcb_p lp		      = tp->lp[cmd->device->lun];
 	ccb_p cp;
 
 	int	segments;
@@ -4361,9 +4361,9 @@
 	**
 	**---------------------------------------------
 	*/
-	if ((cmd->target == np->myaddr	  ) ||
-		(cmd->target >= MAX_TARGET) ||
-		(cmd->lun    >= MAX_LUN   )) {
+	if ((cmd->device->id == np->myaddr	  ) ||
+		(cmd->device->id >= MAX_TARGET) ||
+		(cmd->device->lun    >= MAX_LUN   )) {
 		return(DID_BAD_TARGET);
         }
 
@@ -4403,7 +4403,7 @@
 			np->settle_time = tlimit;
 	}
 
-        if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
+        if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->device->id, cmd->device->lun))) {
 		insert_into_waiting_list(np, cmd);
 		return(DID_OK);
 	}
@@ -4418,7 +4418,7 @@
 #if 0	/* This stuff was only useful for linux-1.2.13 */
 	if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) {
 		lp->numtags = tp->usrtags;
-		ncr_setup_tags (np, cmd->target, cmd->lun);
+		ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
 	}
 #endif
 
@@ -4429,7 +4429,7 @@
 	**----------------------------------------------------
 	*/
 
-	idmsg = M_IDENTIFY | cmd->lun;
+	idmsg = M_IDENTIFY | cmd->device->lun;
 
 	if (cp ->tag != NO_TAG ||
 		(cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC)))
@@ -4662,7 +4662,7 @@
 	/*
 	**	select
 	*/
-	cp->phys.select.sel_id		= cmd->target;
+	cp->phys.select.sel_id		= cmd->device->id;
 	cp->phys.select.sel_scntl3	= tp->wval;
 	cp->phys.select.sel_sxfer	= tp->sval;
 	/*
@@ -5199,8 +5199,8 @@
 
 	cmd = cp->cmd;
 	cp->cmd = NULL;
-	tp = &np->target[cmd->target];
-	lp = tp->lp[cmd->lun];
+	tp = &np->target[cmd->device->id];
+	lp = tp->lp[cmd->device->lun];
 
 	/*
 	**	We donnot queue more than 1 ccb per target 
@@ -5296,7 +5296,7 @@
 		**	Allocate the lcb if not yet.
 		*/
 		if (!lp)
-			ncr_alloc_lcb (np, cmd->target, cmd->lun);
+			ncr_alloc_lcb (np, cmd->device->id, cmd->device->lun);
 
 		/*
 		**	On standard INQUIRY response (EVPD and CmDt 
@@ -5306,7 +5306,7 @@
 		if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) &&
 		    cmd->cmnd[4] >= 7 && !cmd->use_sg) {
 			sync_scsi_data(np, cmd);	/* SYNC the data */
-			ncr_setup_lcb (np, cmd->target, cmd->lun,
+			ncr_setup_lcb (np, cmd->device->id, cmd->device->lun,
 				       (char *) cmd->request_buffer);
 		}
 
@@ -5322,7 +5322,7 @@
 			if (lp->num_good >= 1000) {
 				lp->num_good = 0;
 				++lp->numtags;
-				ncr_setup_tags (np, cmd->target, cmd->lun);
+				ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
 			}
 		}
 	} else if ((cp->host_status == HS_COMPLETE)
@@ -5902,7 +5902,7 @@
 	*/
 	for (cp = np->ccb; cp; cp = cp->link_ccb) {
 		if (!cp->cmd) continue;
-		if (cp->cmd->target != target) continue;
+		if (cp->cmd->device->id != target) continue;
 #if 0
 		cp->sync_status = tp->sval;
 		cp->wide_status = tp->wval;
@@ -5932,7 +5932,7 @@
 	cmd = cp->cmd;
 	if (!cmd) return;
 
-	assert (target == (cmd->target & 0xf));
+	assert (target == (cmd->device->id & 0xf));
 
 	tp = &np->target[target];
 
@@ -6017,7 +6017,7 @@
 	cmd = cp->cmd;
 	if (!cmd) return;
 
-	assert (target == (cmd->target & 0xf));
+	assert (target == (cmd->device->id & 0xf));
 
 	tp = &np->target[target];
 	tp->widedone  =  wide+1;
@@ -7057,8 +7057,8 @@
 static void ncr_sir_to_redo(ncb_p np, int num, ccb_p cp)
 {
 	Scsi_Cmnd *cmd	= cp->cmd;
-	tcb_p tp	= &np->target[cmd->target];
-	lcb_p lp	= tp->lp[cmd->lun];
+	tcb_p tp	= &np->target[cmd->device->id];
+	lcb_p lp	= tp->lp[cmd->device->lun];
 	XPT_QUEHEAD	*qp;
 	ccb_p		cp2;
 	int		disc_cnt = 0;
@@ -7104,7 +7104,7 @@
 		if (disc_cnt < lp->numtags) {
 			lp->numtags	= disc_cnt > 2 ? disc_cnt : 2;
 			lp->num_good	= 0;
-			ncr_setup_tags (np, cmd->target, cmd->lun);
+			ncr_setup_tags (np, cmd->device->id, cmd->device->lun);
 		}
 		/*
 		**	Requeue the command to the start queue.
@@ -7136,7 +7136,7 @@
 		**
 		**	identify message
 		*/
-		cp->scsi_smsg2[0]	= M_IDENTIFY | cmd->lun;
+		cp->scsi_smsg2[0]	= M_IDENTIFY | cmd->device->lun;
 		cp->phys.smsg.addr	= cpu_to_scr(CCB_PHYS (cp, scsi_smsg2));
 		cp->phys.smsg.size	= cpu_to_scr(1);
 
@@ -7150,7 +7150,7 @@
 		**	patch requested size into sense command
 		*/
 		cp->sensecmd[0]		= 0x03;
-		cp->sensecmd[1]		= cmd->lun << 5;
+		cp->sensecmd[1]		= cmd->device->lun << 5;
 		cp->sensecmd[4]		= sizeof(cp->sense_buf);
 
 		/*
@@ -8731,7 +8731,7 @@
 
 int ncr53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
 {
-     ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+     ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
      unsigned long flags;
      int sts;
 
@@ -8798,9 +8798,9 @@
      if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n");
 
      if (done_list) {
-          NCR_LOCK_SCSI_DONE(done_list->host, flags);
+          NCR_LOCK_SCSI_DONE(done_list->device->host, flags);
           ncr_flush_done_cmds(done_list);
-          NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
+          NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags);
      }
 }
 
@@ -8821,9 +8821,9 @@
      NCR_UNLOCK_NCB(np, flags);
 
      if (done_list) {
-          NCR_LOCK_SCSI_DONE(done_list->host, flags);
+          NCR_LOCK_SCSI_DONE(done_list->device->host, flags);
           ncr_flush_done_cmds(done_list);
-          NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
+          NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags);
      }
 }
 
@@ -8837,7 +8837,7 @@
 int ncr53c8xx_reset(Scsi_Cmnd *cmd)
 #endif
 {
-	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+	ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
 	Scsi_Cmnd *done_list;
@@ -8899,7 +8899,7 @@
 
 int ncr53c8xx_abort(Scsi_Cmnd *cmd)
 {
-	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+	ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
 	Scsi_Cmnd *done_list;
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/scsi/nsp32.c	Mon Feb 10 10:39:25 2003
@@ -458,7 +458,7 @@
 		/* XXX: Auto DiscPriv detection is progressing... */
 		0x40 |		/* DiscPriv */
 #endif
-		SCpnt->lun;	/* LUNTRN */
+		SCpnt->device->lun;	/* LUNTRN */
 
 	data->msgoutlen = pos;
 }
@@ -532,9 +532,9 @@
  */
 static int nsp32hw_start_selection(Scsi_Cmnd *SCpnt, nsp32_hw_data *data)
 {
-	unsigned int   host_id = SCpnt->host->this_id;
-	unsigned int   base    = SCpnt->host->io_port;
-	unsigned char  target  = SCpnt->target;
+	unsigned int   host_id = SCpnt->device->host->this_id;
+	unsigned int   base    = SCpnt->device->host->io_port;
+	unsigned char  target  = SCpnt->device->id;
 	unsigned char  *param  = data->autoparam;
 	unsigned char  phase, arbit;
 	int	       i, time;
@@ -744,7 +744,7 @@
 	 * set SCSIOUT LATCH(initiator)/TARGET(target) (ORed) ID
 	 */
 	nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID,
-		((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->target)));
+		((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->device->id)));
 
 	/*
 	 * set SCSI MSGOUT REG
@@ -1021,7 +1021,7 @@
 
 static int nsp32_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
 	struct nsp32_target *target;
 	struct nsp32_lunt *curlunt;
 	int ret;
@@ -1029,7 +1029,7 @@
 	nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND,
 		  "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x "
 		  "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x",
-		  SCpnt->target, SCpnt->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
+		  SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
 		  SCpnt->use_sg, SCpnt->request_buffer, SCpnt->request_bufflen);
 
 	if (data->CurrentSC != NULL ) {
@@ -1042,14 +1042,14 @@
 	}
 
 	/* check target ID is not same as this initiator ID */
-	if (SCpnt->target == NSP32_HOST_SCSIID) {
+	if (SCpnt->device->id == NSP32_HOST_SCSIID) {
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
 		return 1;
 	}
 
 	/* check target LUN is allowable value */
-	if (SCpnt->lun >= MAX_LUN) {
+	if (SCpnt->device->lun >= MAX_LUN) {
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
 		return 1;
@@ -1071,13 +1071,13 @@
 	/* initialize data */
 	data->msgoutlen		= 0;
 	data->msginlen		= 0;
-	curlunt			= data->lunt[SCpnt->target][SCpnt->lun];
+	curlunt			= data->lunt[SCpnt->device->id][SCpnt->device->lun];
 	curlunt->SCpnt		= SCpnt;
 	curlunt->save_datp	= 0;
 	curlunt->msgin03	= FALSE;
 	data->curlunt		= curlunt;
-	data->pid		= SCpnt->target;
-	data->plun		= SCpnt->lun;
+	data->pid		= SCpnt->device->id;
+	data->plun		= SCpnt->device->lun;
 
 	ret = nsp32hw_setup_sg_table(SCpnt, data);
 	if (ret == FALSE) {
@@ -1093,7 +1093,7 @@
 	 * (target don't have SDTR_DONE and SDTR_INITIATOR), sync
 	 * message SDTR is needed to do synchronous transfer.
 	 */
-	target = &data->target[SCpnt->target];
+	target = &data->target[SCpnt->device->id];
 	data->curtarget = target;
 
 	if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) {
@@ -1139,7 +1139,7 @@
 
 	nsp32_dbg(NSP32_DEBUG_TARGETFLAG,
 		  "target: %d sync_flag: 0x%x syncreg: 0x%x ackwidth: 0x%x",
-		  SCpnt->target, target->sync_flag, target->syncreg,
+		  SCpnt->device->id, target->sync_flag, target->syncreg,
 		  target->ackwidth);
 
 	/* Selection */
@@ -1920,7 +1920,7 @@
 
 static int nsp32_eh_abort(Scsi_Cmnd *SCpnt)
 {
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
 	unsigned int base = data->BaseAddress;
 
 	nsp32_msg(KERN_WARNING, "abort");
@@ -1942,7 +1942,7 @@
 
 static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt)
 {
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
 	unsigned int base = data->BaseAddress;
 
 	nsp32_msg(KERN_INFO, "Bus Reset");	
@@ -1997,7 +1997,7 @@
 
 static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt)
 {
-	struct Scsi_Host *host = SCpnt->host;
+	struct Scsi_Host *host = SCpnt->device->host;
 	nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata;
 	unsigned int base = data->BaseAddress;
 
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/osst.c	Mon Feb 10 10:39:27 2003
@@ -4211,7 +4211,7 @@
 	unsigned short flags;
 	int            i, b_size, new_session = FALSE, retval = 0;
 	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt;
+	Scsi_Request * SRpnt = NULL;
 	OS_Scsi_Tape * STp;
 	ST_mode      * STm;
 	ST_partstat  * STps;
diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
--- a/drivers/scsi/pci2000.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/pci2000.c	Mon Feb 10 10:39:29 2003
@@ -390,7 +390,7 @@
 	OpDone (SCpnt, DID_OK << 16);
 
 irq_return:
-    spin_unlock_irqrestore(&shost->host_lock, flags);
+    spin_unlock_irqrestore(shost->host_lock, flags);
 out:;
 }
 /****************************************************************
@@ -407,11 +407,11 @@
 int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 	{
 	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB
-	PADAPTER2000	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
+	PADAPTER2000	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
 	int				rc		 = -1;								// command return code
-	UCHAR			bus		 = SCpnt->channel;
-	UCHAR			pun		 = SCpnt->target;
-	UCHAR			lun		 = SCpnt->lun;
+	UCHAR			bus		 = SCpnt->device->channel;
+	UCHAR			pun		 = SCpnt->device->id;
+	UCHAR			lun		 = SCpnt->device->lun;
 	UCHAR			cmd;
 	PDEV2000		pdev	 = &padapter->dev[bus][pun];
 
@@ -506,13 +506,16 @@
 			
 			if ( SCpnt->use_sg )
 				{
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)SCpnt->request_buffer)->address, 
-										  SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
+				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
+									  ((struct scatterlist *)SCpnt->request_buffer)->address,
+									  SCpnt->request_bufflen,
+									  scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
 				}
 			else
 				{
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 
-										  SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
+				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer,
+									  SCpnt->request_bufflen,
+									  scsi_to_pci_dma_dir (SCpnt->sc_data_direction));
 				}
 			outl (SCpnt->SCp.have_data_in, padapter->mb2);
 			outl (SCpnt->request_bufflen, padapter->mb3);
diff -Nru a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
--- a/drivers/scsi/pci2000.h	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/pci2000.h	Mon Feb 10 10:39:32 2003
@@ -202,15 +202,15 @@
 #endif
 
 /* screen is 80 columns wide, damnit! */
-#define PCI2000 {				\
+#define PCI2000 {				                        \
 	.proc_name	= "pci2000",					\
 	.name		= "PCI-2000 SCSI Intelligent Disk Controller",	\
-	.detect		= Pci2000_Detect,					\
+	.detect		= Pci2000_Detect,				\
 	.release	= Pci2000_Release,				\
 	.command	= Pci2000_Command,				\
 	.queuecommand	= Pci2000_QueueCommand,				\
-	.abort		= Pci2000_Abort,					\
-	.reset		= Pci2000_Reset,					\
+	.abort		= Pci2000_Abort,				\
+	.reset		= Pci2000_Reset,				\
 	.bios_param	= Pci2000_BiosParam,				\
 	.can_queue	= 16,						\
 	.this_id	= -1,						\
diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
--- a/drivers/scsi/pci2220i.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/pci2220i.c	Mon Feb 10 10:39:23 2003
@@ -1156,7 +1156,7 @@
 static void TimerExpiry (unsigned long data)
 	{
 	PADAPTER2220I	padapter = (PADAPTER2220I)data;
-	struct Scsi_Host *host = padapter->SCpnt->host;
+	struct Scsi_Host *host = padapter->SCpnt->device->host;
 	POUR_DEVICE		pdev = padapter->pdev;
 	UCHAR			status = IDE_STATUS_BUSY;
 	UCHAR			temp, temp1;
@@ -1334,7 +1334,7 @@
 static void ReconTimerExpiry (unsigned long data)
 	{
 	PADAPTER2220I	padapter = (PADAPTER2220I)data;
-	struct Scsi_Host *host = padapter->SCpnt->host;
+	struct Scsi_Host *host = padapter->SCpnt->device->host;
 	POUR_DEVICE		pdev;
 	ULONG			testsize = 0;
 	PIDENTIFY_DATA	pid;
@@ -2041,8 +2041,8 @@
 int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 	{
 	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
+	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
+	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
 	UCHAR			rc;											// command return code
 	int				z; 
 	PDEVICE_RAID1	pdr;
@@ -2073,9 +2073,9 @@
 		{
 		UCHAR			zlo, zhi;
 
-		DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->target, SCpnt->lun, *cdb));
+		DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->device->id, SCpnt->device->lun, *cdb));
 		padapter->pdev = pdev;
-		if ( !pdev->byte6 || SCpnt->lun )
+		if ( !pdev->byte6 || SCpnt->device->lun )
 			{
 			OpDone (padapter, DID_BAD_TARGET << 16);
 			return 0;
@@ -2138,7 +2138,7 @@
 		padapter->reconTimer.data = 0;
 		}
 		
-	if ( (SCpnt->target >= padapter->numberOfDrives) || SCpnt->lun )
+	if ( (SCpnt->device->id >= padapter->numberOfDrives) || SCpnt->device->lun )
 		{
 		OpDone (padapter, DID_BAD_TARGET << 16);
 		return 0;
@@ -2791,8 +2791,8 @@
  ****************************************************************/
 int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
 	{
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
+	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
+	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
 
 	if ( !padapter->SCpnt )
 		return SCSI_ABORT_NOT_RUNNING;
@@ -2823,8 +2823,8 @@
  ****************************************************************/
 int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
 	{
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
+	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
+	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
 
 	if ( padapter->atapi )
 		{
diff -Nru a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig
--- a/drivers/scsi/pcmcia/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/pcmcia/Kconfig	Mon Feb 10 10:39:29 2003
@@ -23,7 +23,7 @@
 	  Say Y here if you intend to attach this type of PCMCIA SCSI host
 	  adapter to your computer.
 
-	  This driver is also available as a module called aha152x_cs.o ( =
+	  This driver is also available as a module called aha152x_cs ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -35,7 +35,7 @@
 	  Say Y here if you intend to attach this type of PCMCIA SCSI host
 	  adapter to your computer.
 
-	  This driver is also available as a module called fdomain_cs.o ( =
+	  This driver is also available as a module called fdomain_cs ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -48,7 +48,7 @@
 	  your computer, say Y here and read
 	  <file:Documentation/scsi/NinjaSCSI.txt>.
 
-	  This driver is also available as a module called nsp_cs.o ( =
+	  This driver is also available as a module called nsp_cs ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -60,7 +60,7 @@
 	  Say Y here if you intend to attach this type of PCMCIA SCSI host
 	  adapter to your computer.
 
-	  This driver is also available as a module called qlogic_cs.o ( =
+	  This driver is also available as a module called qlogic_cs ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
--- a/drivers/scsi/pcmcia/aha152x_stub.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/scsi/pcmcia/aha152x_stub.c	Mon Feb 10 10:39:32 2003
@@ -142,6 +142,7 @@
     if (!info) return NULL;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
+    init_timer(&link->release);
     link->release.function = &aha152x_release_cs;
     link->release.data = (u_long)link;
 
@@ -350,7 +351,7 @@
 
     DEBUG(0, "aha152x_release_cs(0x%p)\n", link);
 
-#warning This doesn't protect you.  You need some real fix for your races.
+#warning This does not protect you.  You need some real fix for your races.
 #if 0
     if (GET_USE_COUNT(driver_template.module) != 0) {
 	DEBUG(1, "aha152x_cs: release postponed, "
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	Mon Feb 10 10:39:29 2003
@@ -122,6 +122,7 @@
     if (!info) return NULL;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
+    init_timer(&link->release);
     link->release.function = &fdomain_release;
     link->release.data = (u_long)link;
 
@@ -313,7 +314,7 @@
 
     DEBUG(0, "fdomain_release(0x%p)\n", link);
 
-#warning This doesn't protect you.  You need some real fix for your races.
+#warning This does not protect you.  You need some real fix for your races.
 #if 0
     if (GET_USE_COUNT(&__this_module) != 0) {
 	DEBUG(1, "fdomain_cs: release postponed, "
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	Mon Feb 10 10:39:27 2003
@@ -126,6 +126,7 @@
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
+	init_timer(&link->release);
 	link->release.function = &qlogic_release;
 	link->release.data = (u_long) link;
 
@@ -329,7 +330,7 @@
 
 	DEBUG(0, "qlogic_release(0x%p)\n", link);
 
-#warning This doesn't protect you.  You need some real fix for your races.
+#warning This does not protect you.  You need some real fix for your races.
 #if 0
 	if (GET_USE_COUNT(&__this_module) != 0) {
 		DEBUG(0, "qlogic_cs: release postponed, device still open\n");
diff -Nru a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
--- a/drivers/scsi/pluto.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/pluto.c	Mon Feb 10 10:39:24 2003
@@ -156,12 +156,12 @@
 		
 		pluto->fc = fc;
 	
-		SCpnt->host = host;
 		SCpnt->cmnd[0] = INQUIRY;
 		SCpnt->cmnd[4] = 255;
 		
 		/* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */
 		SCpnt->device = &dev;
+		dev.host = host;
 		
 		SCpnt->cmd_len = COMMAND_SIZE(INQUIRY);
 	
@@ -325,16 +325,18 @@
  */
 static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd)
 {
-	PLND(("encode addr %d %d %d\n", SCpnt->channel, SCpnt->target, SCpnt->cmnd[1] & 0xe0))
+	PLND(("encode addr %d %d %d\n", SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd[1] & 0xe0))
 	/* We don't support LUNs - neither does SSA :) */
-	if (SCpnt->cmnd[1] & 0xe0) return -EINVAL;
-	if (!SCpnt->channel) {
-		if (SCpnt->target) return -EINVAL;
+	if (SCpnt->cmnd[1] & 0xe0)
+		return -EINVAL;
+	if (!SCpnt->device->channel) {
+		if (SCpnt->device->id)
+			return -EINVAL;
 		memset (addr, 0, 4 * sizeof(u16));
 	} else {
 		addr[0] = 1;
-		addr[1] = SCpnt->channel - 1;
-		addr[2] = SCpnt->target;
+		addr[1] = SCpnt->device->channel - 1;
+		addr[2] = SCpnt->device->id;
 		addr[3] = 0;
 	}
 	/* We're Point-to-Point, so target it to the default DID */
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/qla1280.c	Mon Feb 10 10:39:33 2003
@@ -107,8 +107,8 @@
 	- Provide compat macros for pci_enable_device(), pci_find_subsys()
 	  and scsi_set_pci_device()
 	- Call scsi_set_pci_device() for all devices
-	- Reduce size of kernel version dependant device probe code
-	- Move duplicate probe/init code to seperate function
+	- Reduce size of kernel version dependent device probe code
+	- Move duplicate probe/init code to separate function
 	- Handle error if qla1280_mem_alloc() fails
 	- Kill OFFSET() macro and use Linux's PCI definitions instead
         - Kill private structure defining PCI config space (struct config_reg)
@@ -588,9 +588,9 @@
 #define ENTER_INTR(x)		dprintk(3, "qla1280 : Entering %s()\n", x);
 #define LEAVE_INTR(x)		dprintk(3, "qla1280 : Leaving %s()\n", x);
 
-#define SCSI_BUS_32(scp)	scp->channel
-#define SCSI_TCN_32(scp)	scp->target
-#define SCSI_LUN_32(scp)	scp->lun
+#define SCSI_BUS_32(scp)	scp->device->channel
+#define SCSI_TCN_32(scp)	scp->device->id
+#define SCSI_LUN_32(scp)	scp->device->lun
 
 /****************************************************************************/
 /*  LINUX -  Loadable Module Functions.                                     */
@@ -866,19 +866,17 @@
 			"qla1280", ha)) {
 		printk("qla1280 : Failed to reserve interrupt %d already "
 		       "in use\n", host->irq);
-		goto error_mem_alloced;
+		goto error_unmap;
 	}
 #if !MEMORY_MAPPED_IO
 	/* Register the I/O space with Linux */
-	if (check_region(host->io_port, 0xff)) {
+	if (!request_region(host->io_port, 0xff, "qla1280")) {
 		printk("qla1280 : Failed to reserve i/o region 0x%04lx-0x%04lx"
 		       " already in use\n",
 		       host->io_port, host->io_port + 0xff);
-		free_irq(host->irq, ha);
-		goto error_mem_alloced;
+		goto error_irq;
 	}
 
-	request_region(host->io_port, 0xff, "qla1280");
 #endif
 
 	reg = ha->iobase;
@@ -886,7 +884,7 @@
 	/* load the F/W, read paramaters, and init the H/W */
 	if (qla1280_initialize_adapter(ha)) {
 		printk(KERN_INFO "qla1x160:Failed to initialize adapter\n");
-		goto error_mem_alloced;
+		goto error_region;
 	}
 
 	/* set our host ID  (need to do something about our two IDs) */
@@ -894,6 +892,21 @@
 
 	return host;
 
+ error_region:
+#if !MEMORY_MAPPED_IO
+	release_region(host->io_port, 0xff);
+#endif
+
+ error_irq:
+	free_irq(host->irq, ha);
+
+ error_unmap:
+#if MEMORY_MAPPED_IO
+	if (ha->mmpbase)
+		iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
+#endif
+
+
  error_mem_alloced:
 	qla1280_mem_free(ha);
 
@@ -1157,7 +1170,7 @@
 	/*ENTER("qla1280_queuecommand");
 	 */
 
-	host = cmd->host;
+	host = cmd->device->host;
 	ha = (struct scsi_qla_host *)host->hostdata;
 
 	/* send command to adapter */
@@ -1232,8 +1245,8 @@
 	u16 data;
 
 	ENTER("qla1280_abort");
-	ha = (struct scsi_qla_host *)cmd->host->hostdata;
-	host = cmd->host;
+	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
+	host = cmd->device->host;
 
 	/* Get the SCSI request ptr */
 	sp = (srb_t *)CMD_SP(cmd);
@@ -1365,7 +1378,7 @@
 	u16 data;
 
 	ENTER("qla1280_abort");
-	host = cmd->host;
+	host = cmd->device->host;
 	ha = (struct scsi_qla_host *)host->hostdata;
 
 	/* Get the SCSI request ptr */
@@ -1523,7 +1536,7 @@
 		       "pointer, failing.\n");
 		return SCSI_RESET_SNOOZE;
 	}
-	ha = (struct scsi_qla_host *)cmd->host->hostdata;
+	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
 	sp = (srb_t *)CMD_SP(cmd);
 
 #if STOP_ON_RESET
@@ -1820,7 +1833,7 @@
 		/* device->queue_depth = 20; */
 		printk(KERN_INFO "scsi(%li:%d:%d:%d): Enabled tagged queuing, "
 		       "queue depth %d.\n", p->host_no, device->channel,
-		       device->id, device->lun, device->new_queue_depth);
+		       device->id, device->lun, device->queue_depth);
 	} else {
 		scsi_adjust_queue_depth(device, 0 /* TCQ off */, 3);
 	}
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/qlogicfas.c	Mon Feb 10 10:39:33 2003
@@ -348,7 +348,7 @@
 	 /**/ outb(qlcfg5, qbase + 5);	/* select timer */
 	outb(qlcfg9 & 7, qbase + 9);	/* prescaler */
 /*	outb(0x99, qbase + 5);	*/
-	outb(cmd->target, qbase + 4);
+	outb(cmd->device->id, qbase + 4);
 
 	for (i = 0; i < cmd->cmd_len; i++)
 		outb(cmd->cmnd[i], qbase + 2);
@@ -573,7 +573,7 @@
 	 *	Non-irq version
 	 */
 	 
-	if (cmd->target == qinitid)
+	if (cmd->device->id == qinitid)
 		return (DID_BAD_TARGET << 16);
 	ql_icmd(cmd);
 	if ((k = ql_wai()))
@@ -590,7 +590,7 @@
 
 int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
-	if (cmd->target == qinitid) {
+	if (cmd->device->id == qinitid) {
 		cmd->result = DID_BAD_TARGET << 16;
 		done(cmd);
 		return 0;
diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
--- a/drivers/scsi/qlogicfc.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/qlogicfc.c	Mon Feb 10 10:39:30 2003
@@ -397,7 +397,7 @@
 #define MBOX_PORT_LOGOUT                0x0071
 
 /*
- *	Firmware if needed (note this is a hack, it belongs in a seperate
+ *	Firmware if needed (note this is a hack, it belongs in a separate
  *	module.
  */
  
@@ -1148,7 +1148,7 @@
 
 	ENTER("isp2x00_queuecommand");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp2x00_hostdata *) host->hostdata;
 	Cmnd->scsi_done = done;
 
@@ -1233,10 +1233,10 @@
 
 	cmd->hdr.entry_type = ENTRY_COMMAND;
 	cmd->hdr.entry_cnt = 1;
-	cmd->target_lun = Cmnd->lun;
-	cmd->expanded_lun = cpu_to_le16(Cmnd->lun);
+	cmd->target_lun = Cmnd->device->lun;
+	cmd->expanded_lun = cpu_to_le16(Cmnd->device->lun);
 #if ISP2x00_PORTDB
-	cmd->target_id = hostdata->port_db[Cmnd->target].loop_id;
+	cmd->target_id = hostdata->port_db[Cmnd->device->id].loop_id;
 #else
 	cmd->target_id = Cmnd->target;
 #endif
@@ -1312,9 +1312,9 @@
 		cmd->control_flags = cpu_to_le16(CFLAG_READ);
 
 	if (Cmnd->device->tagged_supported) {
-		if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (2 * SCSI_TIMEOUT)) {
+		if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) {
 			cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
-			hostdata->tag_ages[Cmnd->target] = jiffies;
+			hostdata->tag_ages[Cmnd->device->id] = jiffies;
 		} else
 			switch (Cmnd->tag) {
 			case HEAD_OF_QUEUE_TAG:
@@ -1383,8 +1383,8 @@
 		}
 		
 	        for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++){ 
-		        if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){
-                                if (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id != hostdata->port_db[0].loop_id){
+		        if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){
+                                if (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id != hostdata->port_db[0].loop_id){
 					Scsi_Cmnd *Cmnd = hostdata->handle_ptrs[i];
 
 					 if (Cmnd->use_sg)
@@ -1581,7 +1581,7 @@
 				 * the device may well be back in a couple of
 				 * seconds.
 				 */
-				if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->target].wwn){
+				if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->device->id].wwn){
 					outw(out_ptr, host->io_port + MBOX5);
 					continue;
 				}
@@ -1709,7 +1709,7 @@
 
 	ENTER("isp2x00_abort");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp2x00_hostdata *) host->hostdata;
 
 	for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++)
@@ -1724,7 +1724,7 @@
 
 	param[0] = MBOX_ABORT_IOCB;
 #if ISP2x00_PORTDB
-	param[1] = (((u_short) hostdata->port_db[Cmnd->target].loop_id) << 8) | Cmnd->lun;
+	param[1] = (((u_short) hostdata->port_db[Cmnd->device->id].loop_id) << 8) | Cmnd->device->lun;
 #else
 	param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
 #endif
@@ -1766,7 +1766,7 @@
 
 	ENTER("isp2x00_reset");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp2x00_hostdata *) host->hostdata;
 	param[0] = MBOX_BUS_RESET;
 	param[1] = 3;
diff -Nru a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c
--- a/drivers/scsi/qlogicisp.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/qlogicisp.c	Mon Feb 10 10:39:33 2003
@@ -802,7 +802,7 @@
 
 	ENTER("isp1020_queuecommand");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp1020_hostdata *) host->hostdata;
 	Cmnd->scsi_done = done;
 
@@ -853,8 +853,8 @@
 	cmd->hdr.entry_type = ENTRY_COMMAND;
 	cmd->hdr.entry_cnt = 1;
 
-	cmd->target_lun = Cmnd->lun;
-	cmd->target_id = Cmnd->target;
+	cmd->target_lun = Cmnd->device->lun;
+	cmd->target_id = Cmnd->device->id;
 	cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len);
 	cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE);
 	cmd->time_out = cpu_to_le16(30);
@@ -1175,7 +1175,7 @@
 
 	ENTER("isp1020_abort");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp1020_hostdata *) host->hostdata;
 
 	for (i = 0; i < QLOGICISP_REQ_QUEUE_LEN + 1; i++)
@@ -1186,7 +1186,7 @@
 	isp1020_disable_irqs(host);
 
 	param[0] = MBOX_ABORT;
-	param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
+	param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun;
 	param[2] = cmd_cookie >> 16;
 	param[3] = cmd_cookie & 0xffff;
 
@@ -1214,7 +1214,7 @@
 
 	ENTER("isp1020_reset");
 
-	host = Cmnd->host;
+	host = Cmnd->device->host;
 	hostdata = (struct isp1020_hostdata *) host->hostdata;
 
 	param[0] = MBOX_BUS_RESET;
diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/qlogicpti.c	Mon Feb 10 10:39:29 2003
@@ -1004,16 +1004,16 @@
 	memset(cmd, 0, sizeof(struct Command_Entry));
 	cmd->hdr.entry_cnt = 1;
 	cmd->hdr.entry_type = ENTRY_COMMAND;
-	cmd->target_id = Cmnd->target;
-	cmd->target_lun = Cmnd->lun;
+	cmd->target_id = Cmnd->device->id;
+	cmd->target_lun = Cmnd->device->lun;
 	cmd->cdb_length = Cmnd->cmd_len;
 	cmd->control_flags = 0;
 	if (Cmnd->device->tagged_supported) {
-		if (qpti->cmd_count[Cmnd->target] == 0)
-			qpti->tag_ages[Cmnd->target] = jiffies;
-		if ((jiffies - qpti->tag_ages[Cmnd->target]) > (5*HZ)) {
+		if (qpti->cmd_count[Cmnd->device->id] == 0)
+			qpti->tag_ages[Cmnd->device->id] = jiffies;
+		if ((jiffies - qpti->tag_ages[Cmnd->device->id]) > (5*HZ)) {
 			cmd->control_flags = CFLAG_ORDERED_TAG;
-			qpti->tag_ages[Cmnd->target] = jiffies;
+			qpti->tag_ages[Cmnd->device->id] = jiffies;
 		} else
 			cmd->control_flags = CFLAG_SIMPLE_TAG;
 	}
@@ -1097,7 +1097,7 @@
 	cmd->handle = in_ptr;
 	qpti->cmd_slots[in_ptr] = Cmnd;
 
-	qpti->cmd_count[Cmnd->target]++;
+	qpti->cmd_count[Cmnd->device->id]++;
 	sbus_writew(in_ptr, qpti->qregs + MBOX4);
 	qpti->req_in_ptr = in_ptr;
 
@@ -1118,8 +1118,8 @@
  */
 static void ourdone(Scsi_Cmnd *Cmnd)
 {
-	struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata;
-	int tgt = Cmnd->target;
+	struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata;
+	int tgt = Cmnd->device->id;
 	void (*done) (Scsi_Cmnd *);
 
 	/* This grot added by DaveM, blame him for ugliness.
@@ -1170,7 +1170,7 @@
 static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd,
 				       void (*done)(Scsi_Cmnd *))
 {
-	struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata;
+	struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata;
 	unsigned long flags;
 
 	/*
@@ -1229,7 +1229,7 @@
 	 * and can rock on..
 	 */
 	if (qpti == NULL)
-		Cmnd->host->hostt->queuecommand = qlogicpti_queuecommand;
+		Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand;
 
 	spin_unlock_irqrestore(&qpti->lock, flags);
 
@@ -1246,7 +1246,7 @@
  */
 static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
 {
-	struct Scsi_Host *host = Cmnd->host;
+	struct Scsi_Host *host = Cmnd->device->host;
 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
 	struct Command_Entry *cmd;
 	unsigned long flags;
@@ -1431,7 +1431,7 @@
 					  Cmnd->request_bufflen,
 					  scsi_to_sbus_dma_dir(Cmnd->sc_data_direction));
 		}
-		qpti->cmd_count[Cmnd->target]--;
+		qpti->cmd_count[Cmnd->device->id]--;
 		sbus_writew(out_ptr, qpti->qregs + MBOX5);
 		Cmnd->host_scribble = (unsigned char *) done_queue;
 		done_queue = Cmnd;
@@ -1468,7 +1468,7 @@
 static int qlogicpti_abort(Scsi_Cmnd *Cmnd)
 {
 	u_short param[6];
-	struct Scsi_Host *host = Cmnd->host;
+	struct Scsi_Host *host = Cmnd->device->host;
 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
 	int return_status = SUCCESS;
 	unsigned long flags;
@@ -1476,7 +1476,7 @@
 	int i;
 
 	printk(KERN_WARNING "qlogicpti : Aborting cmd for tgt[%d] lun[%d]\n",
-	       (int)Cmnd->target, (int)Cmnd->lun);
+	       (int)Cmnd->device->id, (int)Cmnd->device->lun);
 
 	spin_lock_irqsave(&qpti->lock, flags);
 
@@ -1491,7 +1491,7 @@
 	cmd_cookie = i;
 
 	param[0] = MBOX_ABORT;
-	param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
+	param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun;
 	param[2] = cmd_cookie >> 16;
 	param[3] = cmd_cookie & 0xffff;
 	if (qlogicpti_mbox_command(qpti, param, 0) ||
@@ -1510,7 +1510,7 @@
 static int qlogicpti_reset(Scsi_Cmnd *Cmnd)
 {
 	u_short param[6];
-	struct Scsi_Host *host = Cmnd->host;
+	struct Scsi_Host *host = Cmnd->device->host;
 	struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
 	int return_status = SUCCESS;
 	unsigned long flags;
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/scsi.c	Mon Feb 10 10:39:27 2003
@@ -145,7 +145,6 @@
  * Function prototypes.
  */
 extern void scsi_times_out(Scsi_Cmnd * SCpnt);
-void scsi_build_commandblocks(Scsi_Device * SDpnt);
 
 #ifdef MODULE
 MODULE_PARM(scsi_logging_level, "i");
@@ -196,14 +195,6 @@
 }
 
 /*
- * This lock protects the freelist for all devices on the system.
- * We could make this finer grained by having a single lock per
- * device if it is ever found that there is excessive contention
- * on this lock.
- */
-static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
-
-/*
  * Function:    scsi_allocate_request
  *
  * Purpose:     Allocate a request descriptor.
@@ -265,7 +256,7 @@
 {
 	if( req->sr_command != NULL )
 	{
-		scsi_release_command(req->sr_command);
+		scsi_put_command(req->sr_command);
 		req->sr_command = NULL;
 	}
 
@@ -273,235 +264,6 @@
 }
 
 /*
- * FIXME(eric) - this is not at all optimal.  Given that
- * single lun devices are rare and usually slow
- * (i.e. CD changers), this is good enough for now, but
- * we may want to come back and optimize this later.
- *
- * Scan through all of the devices attached to this
- * host, and see if any are active or not.  If so,
- * we need to defer this command.
- *
- * We really need a busy counter per device.  This would
- * allow us to more easily figure out whether we should
- * do anything here or not.
- */
-static int check_all_luns(struct Scsi_Host *shost, struct scsi_device *myself)
-{
-	struct scsi_device *sdev;
-
-	list_for_each_entry(sdev, &myself->same_target_siblings,
-		       	same_target_siblings) {
-		if (atomic_read(&sdev->device_active))
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * Function:    scsi_allocate_device
- *
- * Purpose:     Allocate a command descriptor.
- *
- * Arguments:   device    - device for which we want a command descriptor
- *              wait      - 1 if we should wait in the event that none
- *                          are available.
- *              interruptible - 1 if we should unblock and return NULL
- *                          in the event that we must wait, and a signal
- *                          arrives.
- *
- * Lock status: No locks assumed to be held.  This function is SMP-safe.
- *
- * Returns:     Pointer to command descriptor.
- *
- * Notes:       Prior to the new queue code, this function was not SMP-safe.
- *
- *              If the wait flag is true, and we are waiting for a free
- *              command block, this function will interrupt and return
- *              NULL in the event that a signal arrives that needs to
- *              be handled.
- *
- *              This function is deprecated, and drivers should be
- *              rewritten to use Scsi_Request instead of Scsi_Cmnd.
- */
-struct scsi_cmnd *scsi_allocate_device(struct scsi_device *sdev, int wait)
-{
-	DECLARE_WAITQUEUE(wq, current);
-	struct Scsi_Host *shost = sdev->host;
-	struct scsi_cmnd *scmnd;
-	unsigned long flags;
-
-	spin_lock_irqsave(&device_request_lock, flags);
-	while (1) {
-		if (sdev->device_blocked)
-			goto busy;
-		if (sdev->single_lun && check_all_luns(shost, sdev))
-			goto busy;
-
-		/*
-		 * Now we can check for a free command block for this device.
-		 */
-		for (scmnd = sdev->device_queue; scmnd; scmnd = scmnd->next)
-			if (!scmnd->request)
-				goto found;
-
-busy:
-		if (!wait)
-			goto fail;
-
-		/*
-		 * We need to wait for a free commandblock.  We need to
-		 * insert ourselves into the list before we release the
-		 * lock.  This way if a block were released the same
-		 * microsecond that we released the lock, the call
-		 * to schedule() wouldn't block (well, it might switch,
-		 * but the current task will still be schedulable.
-		 */
-		add_wait_queue(&sdev->scpnt_wait, &wq);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-
-		spin_unlock_irqrestore(&device_request_lock, flags);
-		schedule();
-		spin_lock_irqsave(&device_request_lock, flags);
-
-		remove_wait_queue(&sdev->scpnt_wait, &wq);
-		set_current_state(TASK_RUNNING);
-	}
-
-found:
-	scmnd->request = NULL;
-	atomic_inc(&scmnd->host->host_active);
-	atomic_inc(&scmnd->device->device_active);
-
-	scmnd->buffer  = NULL;
-	scmnd->bufflen = 0;
-	scmnd->request_buffer = NULL;
-	scmnd->request_bufflen = 0;
-
-	scmnd->use_sg = 0;	/* Reset the scatter-gather flag */
-	scmnd->old_use_sg = 0;
-	scmnd->transfersize = 0;	/* No default transfer size */
-	scmnd->cmd_len = 0;
-
-	scmnd->sc_data_direction = SCSI_DATA_UNKNOWN;
-	scmnd->sc_request = NULL;
-	scmnd->sc_magic = SCSI_CMND_MAGIC;
-
-	scmnd->result = 0;
-	scmnd->underflow = 0;	/* Do not flag underflow conditions */
-	scmnd->old_underflow = 0;
-	scmnd->resid = 0;
-	scmnd->state = SCSI_STATE_INITIALIZING;
-	scmnd->owner = SCSI_OWNER_HIGHLEVEL;
-
-	spin_unlock_irqrestore(&device_request_lock, flags);
-
-	SCSI_LOG_MLQUEUE(5, printk("Activating command for device %d (%d)\n",
-				scmnd->target,
-				atomic_read(&scmnd->host->host_active)));
-
-	return scmnd;
-
-fail:
-	spin_unlock_irqrestore(&device_request_lock, flags);
-	return NULL;
-}
-
-inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
-{
-	unsigned long flags;
-        Scsi_Device * SDpnt;
-	int alloc_cmd = 0;
-
-	spin_lock_irqsave(&device_request_lock, flags);
-
-        SDpnt = SCpnt->device;
-
-	SCpnt->request = NULL;
-	SCpnt->state = SCSI_STATE_UNUSED;
-	SCpnt->owner = SCSI_OWNER_NOBODY;
-	atomic_dec(&SCpnt->host->host_active);
-	atomic_dec(&SDpnt->device_active);
-
-	SCSI_LOG_MLQUEUE(5, printk("Deactivating command for device %d (active=%d, failed=%d)\n",
-				   SCpnt->target,
-				   atomic_read(&SCpnt->host->host_active),
-				   SCpnt->host->host_failed));
-
-	if(SDpnt->current_queue_depth > SDpnt->new_queue_depth) {
-		Scsi_Cmnd *prev, *next;
-		/*
-		 * Release the command block and decrement the queue
-		 * depth.
-		 */
-		for(prev = NULL, next = SDpnt->device_queue;
-				next != SCpnt;
-				prev = next, next = next->next) ;
-		if(prev == NULL)
-			SDpnt->device_queue = next->next;
-		else
-			prev->next = next->next;
-		kfree((char *)SCpnt);
-		SDpnt->current_queue_depth--;
-	} else if(SDpnt->current_queue_depth < SDpnt->new_queue_depth) {
-		alloc_cmd = 1;
-		SDpnt->current_queue_depth++;
-	}
-	spin_unlock_irqrestore(&device_request_lock, flags);
-
-        /*
-         * Wake up anyone waiting for this device.  Do this after we
-         * have released the lock, as they will need it as soon as
-         * they wake up.  
-         */
-	wake_up(&SDpnt->scpnt_wait);
-
-	/*
-	 * We are happy to release command blocks in the scope of the
-	 * device_request_lock since that's nice and quick, but allocation
-	 * can take more time so do it outside that scope instead.
-	 */
-	if(alloc_cmd) {
-		Scsi_Cmnd *newSCpnt;
-
-		newSCpnt = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC |
-				(SDpnt->host->unchecked_isa_dma ?
-				 GFP_DMA : 0));
-		if(newSCpnt) {
-			memset(newSCpnt, 0, sizeof(Scsi_Cmnd));
-			init_timer(&newSCpnt->eh_timeout);
-			newSCpnt->host = SDpnt->host;
-			newSCpnt->device = SDpnt;
-			newSCpnt->target = SDpnt->id;
-			newSCpnt->lun = SDpnt->lun;
-			newSCpnt->channel = SDpnt->channel;
-			newSCpnt->request = NULL;
-			newSCpnt->use_sg = 0;
-			newSCpnt->old_use_sg = 0;
-			newSCpnt->old_cmd_len = 0;
-			newSCpnt->underflow = 0;
-			newSCpnt->old_underflow = 0;
-			newSCpnt->transfersize = 0;
-			newSCpnt->resid = 0;
-			newSCpnt->serial_number = 0;
-			newSCpnt->serial_number_at_timeout = 0;
-			newSCpnt->host_scribble = NULL;
-			newSCpnt->state = SCSI_STATE_UNUSED;
-			newSCpnt->owner = SCSI_OWNER_NOBODY;
-			spin_lock_irqsave(&device_request_lock, flags);
-			newSCpnt->next = SDpnt->device_queue;
-			SDpnt->device_queue = newSCpnt;
-			spin_unlock_irqrestore(&device_request_lock, flags);
-		} else {
-			spin_lock_irqsave(&device_request_lock, flags);
-			SDpnt->current_queue_depth--;
-			spin_unlock_irqrestore(&device_request_lock, flags);
-		}
-	}
-}
-
-/*
  * Function:    scsi_mlqueue_insert()
  *
  * Purpose:     Insert a command in the midlevel queue.
@@ -520,9 +282,9 @@
  * Notes:       This could be called either from an interrupt context or a
  *              normal process context.
  */
-int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
+static int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
 {
-	struct Scsi_Host *host = cmd->host;
+	struct Scsi_Host *host = cmd->device->host;
 	struct scsi_device *device = cmd->device;
 
 	SCSI_LOG_MLQUEUE(1,
@@ -582,43 +344,190 @@
 	return 0;
 }
 
+struct scsi_host_cmd_pool {
+	kmem_cache_t	*slab;
+	unsigned int	users;
+	char		*name;
+	unsigned int	slab_flags;
+	unsigned int	gfp_mask;
+};
+
+static struct scsi_host_cmd_pool scsi_cmd_pool = {
+	.name		= "scsi_cmd_cache",
+	.slab_flags	= SLAB_HWCACHE_ALIGN,
+};
+
+static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
+	.name		= "scsi_cmd_cache(DMA)",
+	.slab_flags	= SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA,
+	.gfp_mask	= __GFP_DMA,
+};
+
+static DECLARE_MUTEX(host_cmd_pool_mutex);
+
+static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
+					    int gfp_mask)
+{
+	struct scsi_cmnd *cmd;
+
+	cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+			gfp_mask | shost->cmd_pool->gfp_mask);
+
+	if (unlikely(!cmd)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&shost->free_list_lock, flags);
+		if (likely(!list_empty(&shost->free_list))) {
+			cmd = list_entry(shost->free_list.next,
+					 struct scsi_cmnd, list);
+			list_del_init(&cmd->list);
+		}
+		spin_unlock_irqrestore(&shost->free_list_lock, flags);
+	}
+
+	return cmd;
+}
+
 /*
- * Function:    scsi_release_command
+ * Function:	scsi_get_command()
  *
- * Purpose:     Release a command block.
+ * Purpose:	Allocate and setup a scsi command block
  *
- * Arguments:   SCpnt - command block we are releasing.
+ * Arguments:	dev	- parent scsi device
+ *		gfp_mask- allocator flags
  *
- * Notes:       The command block can no longer be used by the caller once
- *              this funciton is called.  This is in effect the inverse
- *              of scsi_allocate_device.  Note that we also must perform
- *              a couple of additional tasks.  We must first wake up any
- *              processes that might have blocked waiting for a command
- *              block, and secondly we must hit the queue handler function
- *              to make sure that the device is busy.  Note - there is an
- *              option to not do this - there were instances where we could
- *              recurse too deeply and blow the stack if this happened
- *              when we were indirectly called from the request function
- *              itself.
- *
- *              The idea is that a lot of the mid-level internals gunk
- *              gets hidden in this function.  Upper level drivers don't
- *              have any chickens to wave in the air to get things to
- *              work reliably.
+ * Returns:	The allocated scsi command structure.
+ */
+struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
+{
+	struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask);
+
+	if (likely(cmd != NULL)) {
+		unsigned long flags;
+
+		memset(cmd, 0, sizeof(*cmd));
+		cmd->device = dev;
+		cmd->state = SCSI_STATE_UNUSED;
+		cmd->owner = SCSI_OWNER_NOBODY;
+		init_timer(&cmd->eh_timeout);
+		INIT_LIST_HEAD(&cmd->list);
+		spin_lock_irqsave(&dev->list_lock, flags);
+		list_add_tail(&cmd->list, &dev->cmd_list);
+		spin_unlock_irqrestore(&dev->list_lock, flags);
+	}
+
+	return cmd;
+}				
+
+/*
+ * Function:	scsi_put_command()
+ *
+ * Purpose:	Free a scsi command block
  *
- *              This function is deprecated, and drivers should be
- *              rewritten to use Scsi_Request instead of Scsi_Cmnd.
+ * Arguments:	cmd	- command block to free
+ *
+ * Returns:	Nothing.
+ *
+ * Notes:	The command must not belong to any lists.
  */
-void scsi_release_command(Scsi_Cmnd * SCpnt)
+void scsi_put_command(struct scsi_cmnd *cmd)
 {
-        __scsi_release_command(SCpnt);
-        /*
-         * Finally, hit the queue request function to make sure that
-         * the device is actually busy if there are requests present.
-         * This won't block - if the device cannot take any more, life
-         * will go on.  
-         */
-        scsi_queue_next_request(SCpnt->device->request_queue, NULL);
+	struct Scsi_Host *shost = cmd->device->host;
+	unsigned long flags;
+	
+	/* serious error if the command hasn't come from a device list */
+	spin_lock_irqsave(&cmd->device->list_lock, flags);
+	BUG_ON(list_empty(&cmd->list));
+	list_del_init(&cmd->list);
+	spin_unlock(&cmd->device->list_lock);
+	/* changing locks here, don't need to restore the irq state */
+	spin_lock(&shost->free_list_lock);
+	if (unlikely(list_empty(&shost->free_list))) {
+		list_add(&cmd->list, &shost->free_list);
+		cmd = NULL;
+	}
+	spin_unlock_irqrestore(&shost->free_list_lock, flags);
+
+	if (likely(cmd != NULL))
+		kmem_cache_free(shost->cmd_pool->slab, cmd);
+}
+
+/*
+ * Function:	scsi_setup_command_freelist()
+ *
+ * Purpose:	Setup the command freelist for a scsi host.
+ *
+ * Arguments:	shost	- host to allocate the freelist for.
+ *
+ * Returns:	Nothing.
+ */
+int scsi_setup_command_freelist(struct Scsi_Host *shost)
+{
+	struct scsi_host_cmd_pool *pool;
+	struct scsi_cmnd *cmd;
+
+	spin_lock_init(&shost->free_list_lock);
+	INIT_LIST_HEAD(&shost->free_list);
+
+	/*
+	 * Select a command slab for this host and create it if not
+	 * yet existant.
+	 */
+	down(&host_cmd_pool_mutex);
+	pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
+	if (!pool->users) {
+		pool->slab = kmem_cache_create(pool->name,
+				sizeof(struct scsi_cmnd), 0,
+				pool->slab_flags, NULL, NULL);
+		if (!pool->slab)
+			goto fail;
+	}
+
+	pool->users++;
+	shost->cmd_pool = pool;
+	up(&host_cmd_pool_mutex);
+
+	/*
+	 * Get one backup command for this host.
+	 */
+	cmd = kmem_cache_alloc(shost->cmd_pool->slab,
+			GFP_KERNEL | shost->cmd_pool->gfp_mask);
+	if (!cmd)
+		goto fail2;
+	list_add(&cmd->list, &shost->free_list);		
+	return 0;
+
+ fail2:
+	if (!--pool->users)
+		kmem_cache_destroy(pool->slab);
+	return -ENOMEM;
+ fail:
+	up(&host_cmd_pool_mutex);
+	return -ENOMEM;
+
+}
+
+/*
+ * Function:	scsi_destroy_command_freelist()
+ *
+ * Purpose:	Release the command freelist for a scsi host.
+ *
+ * Arguments:	shost	- host that's freelist is going to be destroyed
+ */
+void scsi_destroy_command_freelist(struct Scsi_Host *shost)
+{
+	while (!list_empty(&shost->free_list)) {
+		struct scsi_cmnd *cmd;
+
+		cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list);
+		list_del_init(&cmd->list);
+		kmem_cache_free(shost->cmd_pool->slab, cmd);
+	}
+
+	down(&host_cmd_pool_mutex);
+	if (!--shost->cmd_pool->users)
+		kmem_cache_destroy(shost->cmd_pool->slab);
+	up(&host_cmd_pool_mutex);
 }
 
 /*
@@ -649,7 +558,7 @@
 #endif
 #endif
 
-	host = SCpnt->host;
+	host = SCpnt->device->host;
 
 	ASSERT_LOCK(host->host_lock, 0);
 
@@ -663,7 +572,7 @@
 	 */
 	if (SCpnt->device->scsi_level <= SCSI_2)
 		SCpnt->cmnd[1] = (SCpnt->cmnd[1] & 0x1f) |
-			(SCpnt->lun << 5 & 0xe0);
+			(SCpnt->device->lun << 5 & 0xe0);
 
 	/*
 	 * We will wait MIN_RESET_DELAY clock ticks after the last reset so
@@ -695,7 +604,7 @@
 	 */
 	SCSI_LOG_MLQUEUE(3, printk("scsi_dispatch_cmnd (host = %d, channel = %d, target = %d, "
 	       "command = %p, buffer = %p, \nbufflen = %d, done = %p)\n",
-	SCpnt->host->host_no, SCpnt->channel, SCpnt->target, SCpnt->cmnd,
+	SCpnt->device->host->host_no, SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd,
 			    SCpnt->buffer, SCpnt->bufflen, SCpnt->done));
 
 	SCpnt->state = SCSI_STATE_QUEUED;
@@ -707,7 +616,7 @@
 		 * Before we queue this command, check if the command
 		 * length exceeds what the host adapter can handle.
 		 */
-		if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) {
+		if (CDB_SIZE(SCpnt) <= SCpnt->device->host->max_cmd_len) {
 			spin_lock_irqsave(host->host_lock, flags);
 			rtn = host->hostt->queuecommand(SCpnt, scsi_done);
 			spin_unlock_irqrestore(host->host_lock, flags);
@@ -750,13 +659,6 @@
 	return rtn;
 }
 
-/*
- * scsi_do_cmd sends all the commands out to the low-level driver.  It
- * handles the specifics required for each low level driver - ie queued
- * or non queued.  It also prevents conflicts when different high level
- * drivers go for the same host at the same time.
- */
-
 void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd ,
  		  void *buffer, unsigned bufflen, 
  		  int timeout, int retries)
@@ -772,7 +674,7 @@
 	SRpnt->sr_request->waiting = NULL;
 	if( SRpnt->sr_command != NULL )
 	{
-		scsi_release_command(SRpnt->sr_command);
+		scsi_put_command(SRpnt->sr_command);
 		SRpnt->sr_command = NULL;
 	}
 
@@ -816,12 +718,11 @@
 	SCSI_LOG_MLQUEUE(4,
 			 {
 			 int i;
-			 int target = SDpnt->id;
 			 int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]);
 			 printk("scsi_do_req (host = %d, channel = %d target = %d, "
 		    "buffer =%p, bufflen = %d, done = %p, timeout = %d, "
 				"retries = %d)\n"
-				"command : ", host->host_no, SDpnt->channel, target, buffer,
+				"command : ", host->host_no, SDpnt->channel, SDpnt->id, buffer,
 				bufflen, done, timeout, retries);
 			 for (i	 = 0; i < size; ++i)
 			 	printk("%02x  ", ((unsigned char *) cmnd)[i]);
@@ -839,7 +740,7 @@
 	 */
 	if( SRpnt->sr_command != NULL )
 	{
-		scsi_release_command(SRpnt->sr_command);
+		scsi_put_command(SRpnt->sr_command);
 		SRpnt->sr_command = NULL;
 	}
 
@@ -906,7 +807,7 @@
  */
 void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt)
 {
-	struct Scsi_Host *host = SCpnt->host;
+	struct Scsi_Host *host = SCpnt->device->host;
 
 	ASSERT_LOCK(host->host_lock, 0);
 
@@ -965,121 +866,6 @@
 	SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n"));
 }
 
-/*
- * Function:    scsi_do_cmd
- *
- * Purpose:     Queue a SCSI command
- *
- * Arguments:   SCpnt     - command descriptor.
- *              cmnd      - actual SCSI command to be performed.
- *              buffer    - data buffer.
- *              bufflen   - size of data buffer.
- *              done      - completion function to be run.
- *              timeout   - how long to let it run before timeout.
- *              retries   - number of retries we allow.
- *
- * Lock status: With the new queueing code, this is SMP-safe, and no locks
- *              need be held upon entry.   The old queueing code the lock was
- *              assumed to be held upon entry.
- *
- * Returns:     Nothing.
- *
- * Notes:       Prior to the new queue code, this function was not SMP-safe.
- *              Also, this function is now only used for queueing requests
- *              for things like ioctls and character device requests - this
- *              is because we essentially just inject a request into the
- *              queue for the device. Normal block device handling manipulates
- *              the queue directly.
- */
-void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
-	      void *buffer, unsigned bufflen, void (*done) (Scsi_Cmnd *),
-		 int timeout, int retries)
-{
-	struct Scsi_Host *host = SCpnt->host;
-
-	ASSERT_LOCK(host->host_lock, 0);
-
-	SCpnt->pid = scsi_pid++;
-	SCpnt->owner = SCSI_OWNER_MIDLEVEL;
-
-	SCSI_LOG_MLQUEUE(4,
-			 {
-			 int i;
-			 int target = SCpnt->target;
-			 int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]);
-			 printk("scsi_do_cmd (host = %d, channel = %d target = %d, "
-		    "buffer =%p, bufflen = %d, done = %p, timeout = %d, "
-				"retries = %d)\n"
-				"command : ", host->host_no, SCpnt->channel, target, buffer,
-				bufflen, done, timeout, retries);
-			 for (i = 0; i < size; ++i)
-			 	printk("%02x  ", ((unsigned char *) cmnd)[i]);
-			 	printk("\n");
-			 });
-
-	if (!host) {
-		panic("Invalid or not present host.\n");
-	}
-	/*
-	 * We must prevent reentrancy to the lowlevel host driver.  This prevents
-	 * it - we enter a loop until the host we want to talk to is not busy.
-	 * Race conditions are prevented, as interrupts are disabled in between the
-	 * time we check for the host being not busy, and the time we mark it busy
-	 * ourselves.
-	 */
-
-
-	/*
-	 * Our own function scsi_done (which marks the host as not busy, disables
-	 * the timeout counter, etc) will be called by us or by the
-	 * scsi_hosts[host].queuecommand() function needs to also call
-	 * the completion function for the high level driver.
-	 */
-
-	memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd, 
-               sizeof(SCpnt->data_cmnd));
-	SCpnt->reset_chain = NULL;
-	SCpnt->serial_number = 0;
-	SCpnt->serial_number_at_timeout = 0;
-	SCpnt->bufflen = bufflen;
-	SCpnt->buffer = buffer;
-	SCpnt->flags = 0;
-	SCpnt->retries = 0;
-	SCpnt->allowed = retries;
-	SCpnt->done = done;
-	SCpnt->timeout_per_command = timeout;
-
-	memcpy((void *) SCpnt->cmnd, (const void *) cmnd, 
-               sizeof(SCpnt->cmnd));
-	/* Zero the sense buffer.  Some host adapters automatically request
-	 * sense on error.  0 is not a valid sense code.
-	 */
-	memset((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer);
-	SCpnt->request_buffer = buffer;
-	SCpnt->request_bufflen = bufflen;
-	SCpnt->old_use_sg = SCpnt->use_sg;
-	if (SCpnt->cmd_len == 0)
-		SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
-	SCpnt->old_cmd_len = SCpnt->cmd_len;
-	SCpnt->sc_old_data_direction = SCpnt->sc_data_direction;
-	SCpnt->old_underflow = SCpnt->underflow;
-
-	/* Start the timer ticking.  */
-
-	SCpnt->internal_timeout = NORMAL_TIMEOUT;
-	SCpnt->abort_reason = 0;
-	SCpnt->result = 0;
-
-	/*
-	 * At this point, we merely set up the command, stick it in the normal
-	 * request queue, and return.  Eventually that request will come to the
-	 * top of the list, and will be dispatched.
-	 */
-	scsi_insert_special_cmd(SCpnt, 0);
-
-	SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_cmd()\n"));
-}
-
 /**
  * scsi_done - Mark this command as done
  * @SCpnt: The SCSI Command which we think we've completed.
@@ -1180,8 +966,8 @@
 				/*
 				 * Add to BH queue.
 				 */
-				SCSI_LOG_MLCOMPLETE(3, printk("Command finished %d %d 0x%x\n", SCpnt->host->host_busy,
-						SCpnt->host->host_failed,
+				SCSI_LOG_MLCOMPLETE(3, printk("Command finished %d %d 0x%x\n", SCpnt->device->host->host_busy,
+						SCpnt->device->host->host_failed,
 							 SCpnt->result));
 
 				scsi_finish_command(SCpnt);
@@ -1194,8 +980,8 @@
 				 * track of the number of tries, so we don't
 				 * end up looping, of course.
 				 */
-				SCSI_LOG_MLCOMPLETE(3, printk("Command needs retry %d %d 0x%x\n", SCpnt->host->host_busy,
-				SCpnt->host->host_failed, SCpnt->result));
+				SCSI_LOG_MLCOMPLETE(3, printk("Command needs retry %d %d 0x%x\n", SCpnt->device->host->host_busy,
+				SCpnt->device->host->host_failed, SCpnt->result));
 
 				scsi_retry_command(SCpnt);
 				break;
@@ -1219,11 +1005,11 @@
 				 * Here we have a fatal error of some sort.
 				 * Turn it over to the error handler.
 				 */
-				SCSI_LOG_MLCOMPLETE(3, printk("Command failed %p %x active=%d busy=%d failed=%d\n",
-						    SCpnt, SCpnt->result,
-				  atomic_read(&SCpnt->host->host_active),
-						  SCpnt->host->host_busy,
-					      SCpnt->host->host_failed));
+				SCSI_LOG_MLCOMPLETE(3,
+					printk("Command failed %p %x busy=%d failed=%d\n",
+						SCpnt, SCpnt->result,
+						SCpnt->device->host->host_busy,
+						SCpnt->device->host->host_failed));
 
 				/*
 				 * Dump the sense information too.
@@ -1231,12 +1017,12 @@
 				if ((status_byte(SCpnt->result) & CHECK_CONDITION) != 0) {
 					SCSI_LOG_MLCOMPLETE(3, print_sense("bh", SCpnt));
 				}
-				if (SCpnt->host->eh_wait != NULL) {
+				if (SCpnt->device->host->eh_wait != NULL) {
 					scsi_eh_eflags_set(SCpnt, SCSI_EH_CMD_FAILED | SCSI_EH_CMD_ERR);
 					SCpnt->owner = SCSI_OWNER_ERROR_HANDLER;
 					SCpnt->state = SCSI_STATE_FAILED;
 
-					scsi_host_failed_inc_and_test(SCpnt->host);
+					scsi_host_failed_inc_and_test(SCpnt->device->host);
 				} else {
 					/*
 					 * We only get here if the error
@@ -1288,7 +1074,7 @@
 	Scsi_Device *device;
 	Scsi_Request * SRpnt;
 
-	host = SCpnt->host;
+	host = SCpnt->device->host;
 	device = SCpnt->device;
 
 	ASSERT_LOCK(host->host_lock, 0);
@@ -1345,98 +1131,6 @@
 }
 
 /*
- * Function:    scsi_release_commandblocks()
- *
- * Purpose:     Release command blocks associated with a device.
- *
- * Arguments:   SDpnt   - device
- *
- * Returns:     Nothing
- *
- * Lock status: No locking assumed or required.
- *
- * Notes:
- */
-void scsi_release_commandblocks(Scsi_Device * SDpnt)
-{
-	Scsi_Cmnd *SCpnt, *SCnext;
-	unsigned long flags;
-
- 	spin_lock_irqsave(&device_request_lock, flags);
-	for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) {
-		SDpnt->device_queue = SCnext = SCpnt->next;
-		kfree((char *) SCpnt);
-	}
-	SDpnt->current_queue_depth = 0;
-	SDpnt->new_queue_depth = 0;
-	spin_unlock_irqrestore(&device_request_lock, flags);
-}
-
-/*
- * Function:    scsi_build_commandblocks()
- *
- * Purpose:     Allocate command blocks associated with a device.
- *
- * Arguments:   SDpnt   - device
- *
- * Returns:     Nothing
- *
- * Lock status: No locking assumed or required.
- *
- * Notes:	We really only allocate one command here.  We will allocate
- *		more commands as needed once the device goes into real use.
- */
-void scsi_build_commandblocks(Scsi_Device * SDpnt)
-{
-	unsigned long flags;
-	Scsi_Cmnd *SCpnt;
-
-	if (SDpnt->current_queue_depth != 0)
-		return;
-		
-	SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC |
-			(SDpnt->host->unchecked_isa_dma ? GFP_DMA : 0));
-	if (NULL == SCpnt) {
-		/*
-		 * Since we don't currently have *any* command blocks on this
-		 * device, go ahead and try an atomic allocation...
-		 */
-		SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC |
-			(SDpnt->host->unchecked_isa_dma ? GFP_DMA : 0));
-		if (NULL == SCpnt)
-			return;	/* Oops, we aren't going anywhere for now */
-	}
-
-	memset(SCpnt, 0, sizeof(Scsi_Cmnd));
-	init_timer(&SCpnt->eh_timeout);
-	SCpnt->host = SDpnt->host;
-	SCpnt->device = SDpnt;
-	SCpnt->target = SDpnt->id;
-	SCpnt->lun = SDpnt->lun;
-	SCpnt->channel = SDpnt->channel;
-	SCpnt->request = NULL;
-	SCpnt->use_sg = 0;
-	SCpnt->old_use_sg = 0;
-	SCpnt->old_cmd_len = 0;
-	SCpnt->underflow = 0;
-	SCpnt->old_underflow = 0;
-	SCpnt->transfersize = 0;
-	SCpnt->resid = 0;
-	SCpnt->serial_number = 0;
-	SCpnt->serial_number_at_timeout = 0;
-	SCpnt->host_scribble = NULL;
-	SCpnt->state = SCSI_STATE_UNUSED;
-	SCpnt->owner = SCSI_OWNER_NOBODY;
-	spin_lock_irqsave(&device_request_lock, flags);
-	if(SDpnt->new_queue_depth == 0)
-		SDpnt->new_queue_depth = 1;
-	SDpnt->current_queue_depth++;
-	SCpnt->next = SDpnt->device_queue;
-	SDpnt->device_queue = SCpnt;
-	spin_unlock_irqrestore(&device_request_lock, flags);
-}
-
-/*
  * Function:	scsi_adjust_queue_depth()
  *
  * Purpose:	Allow low level drivers to tell us to change the queue depth
@@ -1457,28 +1151,10 @@
  * 		the right thing depending on whether or not the device is
  * 		currently active and whether or not it even has the
  * 		command blocks built yet.
- *
- * 		If cmdblocks != 0 then we are a live device.  We just set the
- * 		new_queue_depth variable and when the scsi completion handler
- * 		notices that current_queue_depth != new_queue_depth it will
- * 		work to rectify the situation.  If new_queue_depth is less than
- * 		current_queue_depth, then it will free the completed command
- * 		instead of putting it back on the free list and dec
- * 		current_queue_depth.  Otherwise	it will try to allocate a new
- * 		command block for the device and put it on the free list along
- * 		with the command that is being
- *		completed.  Obviously, if the device isn't doing anything then
- *		neither is this code, so it will bring the devices queue depth
- *		back into line when the device is actually being used.  This
- *		keeps us from needing to fire off a kernel thread or some such
- *		nonsense (this routine can be called from interrupt code, so
- *		handling allocations here would be tricky and risky, making
- *		a kernel thread a much safer way to go if we wanted to handle
- *		the work immediately instead of letting it get done a little
- *		at a time in the completion handler).
  */
 void scsi_adjust_queue_depth(Scsi_Device *SDpnt, int tagged, int tags)
 {
+	static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
 	unsigned long flags;
 
 	/*
@@ -1495,7 +1171,7 @@
 		return;
 
 	spin_lock_irqsave(&device_request_lock, flags);
-	SDpnt->new_queue_depth = tags;
+	SDpnt->queue_depth = tags;
 	switch(tagged) {
 		case MSG_ORDERED_TAG:
 			SDpnt->ordered_tags = 1;
@@ -1512,7 +1188,7 @@
 				SDpnt->channel, SDpnt->id, SDpnt->lun); 
 		case 0:
 			SDpnt->ordered_tags = SDpnt->simple_tags = 0;
-			SDpnt->new_queue_depth = tags;
+			SDpnt->queue_depth = tags;
 			break;
 	}
 	spin_unlock_irqrestore(&device_request_lock, flags);
@@ -1863,28 +1539,6 @@
  */
 int scsi_slave_attach(struct scsi_device *sdev)
 {
-	/* all this code is now handled elsewhere 
-	if (sdev->attached++ == 0) {
-		scsi_build_commandblocks(sdev);
-		if (sdev->current_queue_depth == 0) {
-			printk(KERN_ERR "scsi: Allocation failure during"
-			       " attach, some SCSI devices might not be"
-			       " configured\n");
-			return -ENOMEM;
-		}
-		if (sdev->host->hostt->slave_configure != NULL) {
-			if (sdev->host->hostt->slave_configure(sdev) != 0) {
-				printk(KERN_INFO "scsi: failed low level driver"
-				       " attach, some SCSI device might not be"
-				       " configured\n");
-				scsi_release_commandblocks(sdev);
-				return -ENOMEM;
-			}
-		} else if (sdev->host->cmd_per_lun != 0)
-			scsi_adjust_queue_depth(sdev, 0,
-						sdev->host->cmd_per_lun);
-	}
-		 */
 	sdev->attached++;
 	return 0;
 }
@@ -1901,11 +1555,6 @@
  */
 void scsi_slave_detach(struct scsi_device *sdev)
 {
-	/*
-	if (--sdev->attached == 0) {
-		scsi_release_commandblocks(sdev);
-	}
-	*/
 	sdev->attached--;
 }
 /*
@@ -1955,17 +1604,16 @@
 {
 	Scsi_Device *SDpnt;
 	struct Scsi_Host *shpnt;
-	
 
 	/*
 	 * Next, detach the devices from the driver.
 	 */
-
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
 		list_for_each_entry(SDpnt, &shpnt->my_devices, siblings)
 			(*tpnt->detach) (SDpnt);
 	}
+
 	/*
 	 * Extract the template from the linked list.
 	 */
@@ -1974,11 +1622,6 @@
 	up_write(&scsi_devicelist_mutex);
 
 	scsi_upper_driver_unregister(tpnt);
-
-	/*
-	 * Final cleanup for the driver is done in the driver sources in the
-	 * cleanup function.
-	 */
 	return 0;
 }
 
@@ -2021,10 +1664,9 @@
 
 #endif
 
+/* FIXME(hch): add proper error handling */
 static int __init init_scsi(void)
 {
-	printk(KERN_INFO "SCSI subsystem driver " REVISION "\n");
-
 	scsi_init_queue();
 	scsi_init_procfs();
 	devfs_mk_dir(NULL, "scsi", NULL);
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/scsi.h	Mon Feb 10 10:39:24 2003
@@ -446,8 +446,10 @@
  * Prototypes for functions in scsi.c
  */
 extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
-extern void scsi_release_commandblocks(Scsi_Device * SDpnt);
-extern void scsi_build_commandblocks(Scsi_Device * SDpnt);
+extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
+extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int flags);
+extern void scsi_put_command(struct scsi_cmnd *cmd);
 extern void scsi_adjust_queue_depth(Scsi_Device *, int, int);
 extern int scsi_track_queue_full(Scsi_Device *, int);
 extern int scsi_slave_attach(struct scsi_device *);
@@ -457,14 +459,6 @@
 extern void scsi_done(Scsi_Cmnd * SCpnt);
 extern void scsi_finish_command(Scsi_Cmnd *);
 extern int scsi_retry_command(Scsi_Cmnd *);
-extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int);
-extern void __scsi_release_command(Scsi_Cmnd *);
-extern void scsi_release_command(Scsi_Cmnd *);
-extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
-			void *buffer, unsigned bufflen,
-			void (*done) (struct scsi_cmnd *),
-			int timeout, int retries);
-extern int scsi_mlqueue_insert(struct scsi_cmnd *, int);
 extern int scsi_attach_device(struct scsi_device *);
 extern void scsi_detach_device(struct scsi_device *);
 extern int scsi_get_device_flags(unsigned char *vendor, unsigned char *model);
@@ -576,14 +570,11 @@
 					   device is busy */
 	struct Scsi_Host *host;
 	request_queue_t *request_queue;
-        atomic_t                device_active; /* commands checked out for device */
 	volatile unsigned short device_busy;	/* commands actually active on low-level */
-	struct list_head free_cmnds;    /* list of available Scsi_Cmnd structs */
-	struct list_head busy_cmnds;    /* list of Scsi_Cmnd structs in use */
-	Scsi_Cmnd *device_queue;	/* queue of SCSI Command structures */
+	spinlock_t list_lock;
+	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
         Scsi_Cmnd *current_cmnd;	/* currently active command */
-	unsigned short current_queue_depth;/* How deep of a queue we have */
-	unsigned short new_queue_depth; /* How deep of a queue we want */
+	unsigned short queue_depth;	/* How deep of a queue we want */
 	unsigned short last_queue_full_depth; /* These two are used by */
 	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
 	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
@@ -728,14 +719,13 @@
 struct scsi_cmnd {
 	int     sc_magic;
 
-	struct Scsi_Host *host;
+	struct scsi_device *device;
 	unsigned short state;
 	unsigned short owner;
-	Scsi_Device *device;
 	Scsi_Request *sc_request;
-	struct scsi_cmnd *next;
 	struct scsi_cmnd *reset_chain;
-	struct list_head list_entry; /* Used to place us on the cmd lists */
+
+	struct list_head list;  /* scsi_cmnd participates in queue lists */
 
 	int eh_state;		/* Used for state tracking in error handlr */
 	int eh_eflags;		/* Used by error handlr */
@@ -770,10 +760,6 @@
 	unsigned volatile char internal_timeout;
 	struct scsi_cmnd *bh_next;	/* To enumerate the commands waiting 
 					   to be processed. */
-
-	unsigned int target;
-	unsigned int lun;
-	unsigned int channel;
 	unsigned char cmd_len;
 	unsigned char old_cmd_len;
 	unsigned char sc_data_direction;
@@ -990,4 +976,4 @@
 extern int scsi_sysfs_register(void);
 extern void scsi_sysfs_unregister(void);
 
-#endif
+#endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/scsi_debug.c	Mon Feb 10 10:39:29 2003
@@ -217,7 +217,7 @@
 	int block, upper_blk, num;
 	unsigned char *buff;
 	int errsts = 0;
-	int target = SCpnt->target;
+	int target = SCpnt->device->id;
 	int bufflen = SCpnt->request_bufflen;
 	unsigned long capac;
 	struct sdebug_dev_info * devip = NULL;
@@ -247,7 +247,7 @@
 		return schedule_resp(SCpnt, NULL, done, 0, 0);
         }
 
-	if (SCpnt->lun >= scsi_debug_max_luns)
+	if (SCpnt->device->lun >= scsi_debug_max_luns)
 		return schedule_resp(SCpnt, NULL, done, 
 				     DID_NO_CONNECT << 16, 0);
 	devip = devInfoReg(SCpnt);
@@ -868,19 +868,19 @@
 		return devip;
 	for (k = 0; k < scsi_debug_num_devs; ++k) {
 		devip = &devInfop[k];
-		if ((devip->channel == scmd->channel) &&
-		    (devip->target == scmd->target) &&
-		    (devip->lun == scmd->lun) &&
-		    (devip->host == scmd->host))
+		if ((devip->channel == scmd->device->channel) &&
+		    (devip->target == scmd->device->id) &&
+		    (devip->lun == scmd->device->lun) &&
+		    (devip->host == scmd->device->host))
 			return devip;
 	}
 	for (k = 0; k < scsi_debug_num_devs; ++k) {
 		devip = &devInfop[k];
 		if (!devip->used) {
-			devip->channel = scmd->channel;
-			devip->target = scmd->target;
-			devip->lun = scmd->lun;
-			devip->host = scmd->host;
+			devip->channel = scmd->device->channel;
+			devip->target = scmd->device->id;
+			devip->lun = scmd->device->lun;
+			devip->host = scmd->device->host;
 			devip->reset = 1;
 			devip->used = 1;
 			memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN);
@@ -962,7 +962,7 @@
 	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
 		printk(KERN_INFO "scsi_debug: bus_reset\n");
 	++num_bus_resets;
-	if (SCpnt && ((sdp = SCpnt->device)) && ((hp = SCpnt->host))) {
+	if (SCpnt && ((sdp = SCpnt->device)) && ((hp = SCpnt->device->host))) {
 		for (k = 0; k < scsi_debug_num_devs; ++k) {
 			if (hp == devInfop[k].host)
 				devInfop[k].reset = 1;
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/scsi_error.c	Mon Feb 10 10:39:23 2003
@@ -131,23 +131,22 @@
  **/
 void scsi_times_out(Scsi_Cmnd *scmd)
 {
+	struct Scsi_Host *shost = scmd->device->host;
+
 	/* Set the serial_number_at_timeout to the current serial_number */
 	scmd->serial_number_at_timeout = scmd->serial_number;
 
 	scsi_eh_eflags_set(scmd, SCSI_EH_CMD_TIMEOUT | SCSI_EH_CMD_ERR);
 
-	if( scmd->host->eh_wait == NULL ) {
+	if (unlikely(shost->eh_wait == NULL)) {
 		panic("Error handler thread not present at %p %p %s %d",
-		      scmd, scmd->host, __FILE__, __LINE__);
+		      scmd, shost, __FILE__, __LINE__);
 	}
 
-	scsi_host_failed_inc_and_test(scmd->host);
+	scsi_host_failed_inc_and_test(shost);
 
-	SCSI_LOG_TIMEOUT(3, printk("Command timed out active=%d busy=%d "
-				   " failed=%d\n",
-				   atomic_read(&scmd->host->host_active),
-				   scmd->host->host_busy,
-				   scmd->host->host_failed));
+	SCSI_LOG_TIMEOUT(3, printk("Command timed out busy=%d failed=%d\n",
+				   shost->host_busy, shost->host_failed));
 }
 
 /**
@@ -234,7 +233,10 @@
 
 	found = 0;
 	list_for_each_entry(sdev, &shost->my_devices, siblings) {
-		for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&sdev->list_lock, flags);
+		list_for_each_entry(scmd, &sdev->cmd_list, list) {
 			if (scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) {
 				scmd->bh_next = *sc_list;
 				*sc_list = scmd;
@@ -263,10 +265,11 @@
 							  " cmds still active"
 							  " (%p %x %d)\n",
 					       scmd, scmd->state,
-					       scmd->target));
+					       scmd->device->id));
 				}
 			}
 		}
+		spin_unlock_irqrestore(&sdev->list_lock, flags);
 	}
 
 	SCSI_LOG_ERROR_RECOVERY(1, scsi_eh_prt_fail_stats(*sc_list, shost));
@@ -426,8 +429,8 @@
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
 					  scmd));
 
-	if (scmd->host->eh_action != NULL)
-		up(scmd->host->eh_action);
+	if (scmd->device->host->eh_action != NULL)
+		up(scmd->device->host->eh_action);
 	else
 		printk("%s: eh_action NULL\n", __FUNCTION__);
 }
@@ -458,8 +461,8 @@
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
 					  __FUNCTION__, scmd, scmd->result));
 
-	if (scmd->host->eh_action != NULL)
-		up(scmd->host->eh_action);
+	if (scmd->device->host->eh_action != NULL)
+		up(scmd->device->host->eh_action);
 }
 
 /**
@@ -477,7 +480,7 @@
 static int scsi_send_eh_cmnd(Scsi_Cmnd *scmd, int timeout)
 {
 	unsigned long flags;
-	struct Scsi_Host *host = scmd->host;
+	struct Scsi_Host *host = scmd->device->host;
 	int rtn = SUCCESS;
 
 	ASSERT_LOCK(host->host_lock, 0);
@@ -490,7 +493,7 @@
 
 	if (scmd->device->scsi_level <= SCSI_2)
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
-			(scmd->lun << 5 & 0xe0);
+			(scmd->device->lun << 5 & 0xe0);
 
 	if (host->can_queue) {
 		DECLARE_MUTEX_LOCKED(sem);
@@ -500,16 +503,16 @@
 		/*
 		 * set up the semaphore so we wait for the command to complete.
 		 */
-		scmd->host->eh_action = &sem;
+		scmd->device->host->eh_action = &sem;
 		scmd->request->rq_status = RQ_SCSI_BUSY;
 
-		spin_lock_irqsave(scmd->host->host_lock, flags);
+		spin_lock_irqsave(scmd->device->host->host_lock, flags);
 		host->hostt->queuecommand(scmd, scsi_eh_done);
-		spin_unlock_irqrestore(scmd->host->host_lock, flags);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 		down(&sem);
 
-		scmd->host->eh_action = NULL;
+		scmd->device->host->eh_action = NULL;
 
 		/*
 		 * see if timeout.  if so, tell the host to forget about it.
@@ -529,10 +532,10 @@
 			 * abort a timed out command or not.  not sure how
 			 * we should treat them differently anyways.
 			 */
-			spin_lock_irqsave(scmd->host->host_lock, flags);
-			if (scmd->host->hostt->eh_abort_handler)
-				scmd->host->hostt->eh_abort_handler(scmd);
-			spin_unlock_irqrestore(scmd->host->host_lock, flags);
+			spin_lock_irqsave(scmd->device->host->host_lock, flags);
+			if (scmd->device->host->hostt->eh_abort_handler)
+				scmd->device->host->hostt->eh_abort_handler(scmd);
+			spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 			
 			scmd->request->rq_status = RQ_SCSI_DONE;
 			scmd->owner = SCSI_OWNER_ERROR_HANDLER;
@@ -600,7 +603,7 @@
 	memcpy((void *) scmd->cmnd, (void *) generic_sense,
 	       sizeof(generic_sense));
 
-	scsi_result = (!scmd->host->hostt->unchecked_isa_dma)
+	scsi_result = (!scmd->device->host->hostt->unchecked_isa_dma)
 	    ? &scsi_result0[0] : kmalloc(512, GFP_ATOMIC | GFP_DMA);
 
 	if (scsi_result == NULL) {
@@ -732,7 +735,7 @@
 
 		SCSI_LOG_ERROR_RECOVERY(2, printk("%s: requesting sense"
 						  " for tgt: %d\n",
-						  __FUNCTION__, scmd->target));
+						  __FUNCTION__, scmd->device->id));
 		rtn = scsi_request_sense(scmd);
 		if (rtn != SUCCESS)
 			continue;
@@ -790,7 +793,7 @@
 	int rtn = FAILED;
 	unsigned long flags;
 
-	if (scmd->host->hostt->eh_abort_handler == NULL) {
+	if (scmd->device->host->hostt->eh_abort_handler == NULL) {
 		return rtn;
 	}
 	/*
@@ -802,9 +805,9 @@
 
 	scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-	spin_lock_irqsave(scmd->host->host_lock, flags);
-	rtn = scmd->host->hostt->eh_abort_handler(scmd);
-	spin_unlock_irqrestore(scmd->host->host_lock, flags);
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	rtn = scmd->device->host->hostt->eh_abort_handler(scmd);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 	return rtn;
 }
 
@@ -912,14 +915,14 @@
 	unsigned long flags;
 	int rtn = FAILED;
 
-	if (scmd->host->hostt->eh_device_reset_handler == NULL) {
+	if (scmd->device->host->hostt->eh_device_reset_handler == NULL) {
 		return rtn;
 	}
 	scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-	spin_lock_irqsave(scmd->host->host_lock, flags);
-	rtn = scmd->host->hostt->eh_device_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->host->host_lock, flags);
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
 		scmd->device->was_reset = 1;
@@ -990,20 +993,20 @@
 	scmd->owner = SCSI_OWNER_LOWLEVEL;
 	scmd->serial_number_at_timeout = scmd->serial_number;
 
-	if (scmd->host->hostt->eh_bus_reset_handler == NULL)
+	if (scmd->device->host->hostt->eh_bus_reset_handler == NULL)
 		return FAILED;
 
-	spin_lock_irqsave(scmd->host->host_lock, flags);
-	rtn = scmd->host->hostt->eh_bus_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->host->host_lock, flags);
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
 		scsi_sleep(BUS_RESET_SETTLE_TIME);
 		/*
 		 * Mark all affected devices to expect a unit attention.
 		 */
-		list_for_each_entry(sdev, &scmd->host->my_devices, siblings)
-			if (scmd->channel == sdev->channel) {
+		list_for_each_entry(sdev, &scmd->device->host->my_devices, siblings)
+			if (scmd->device->channel == sdev->channel) {
 				sdev->was_reset = 1;
 				sdev->expecting_cc_ua = 1;
 			}
@@ -1026,20 +1029,20 @@
 	scmd->owner = SCSI_OWNER_LOWLEVEL;
 	scmd->serial_number_at_timeout = scmd->serial_number;
 
-	if (scmd->host->hostt->eh_host_reset_handler == NULL)
+	if (scmd->device->host->hostt->eh_host_reset_handler == NULL)
 		return FAILED;
 
-	spin_lock_irqsave(scmd->host->host_lock, flags);
-	rtn = scmd->host->hostt->eh_host_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->host->host_lock, flags);
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
 		scsi_sleep(HOST_RESET_SETTLE_TIME);
 		/*
 		 * Mark all affected devices to expect a unit attention.
 		 */
-		list_for_each_entry(sdev, &scmd->host->my_devices, siblings)
-			if (scmd->channel == sdev->channel) {
+		list_for_each_entry(sdev, &scmd->device->host->my_devices, siblings)
+			if (scmd->device->channel == sdev->channel) {
 				sdev->was_reset = 1;
 				sdev->expecting_cc_ua = 1;
 			}
@@ -1078,7 +1081,7 @@
 		for (scmd = sc_todo; scmd; scmd = scmd->bh_next) {
 			if (!scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR))
 				continue;
-			if (channel == scmd->channel) {
+			if (channel == scmd->device->channel) {
 				chan_scmd = scmd;
 				break;
 				/*
@@ -1102,7 +1105,7 @@
 		if (rtn == SUCCESS) {
 			for (scmd = sc_todo; scmd; scmd = scmd->bh_next) {
 				if (!scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)
-				    || channel != scmd->channel)
+				    || channel != scmd->device->channel)
 					continue;
 				if (!scsi_eh_tur(scmd)) {
 					rtn = scsi_eh_retry_cmd(scmd);
@@ -1335,7 +1338,7 @@
 
 	case RESERVATION_CONFLICT:
 		printk("scsi%d (%d,%d,%d) : reservation conflict\n",
-		       scmd->host->host_no, scmd->channel,
+		       scmd->device->host->host_no, scmd->device->channel,
 		       scmd->device->id, scmd->device->lun);
 		return SUCCESS; /* causes immediate i/o error */
 	default:
@@ -1371,7 +1374,7 @@
 	scmd->sc_request = NULL;
 	sreq->sr_command = NULL;
 
-	scsi_release_command(scmd);
+	scsi_put_command(scmd);
 	scsi_release_request(sreq);
 }
 
@@ -1576,10 +1579,10 @@
 	int rtn;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	lock_kernel();
 
@@ -1594,6 +1597,7 @@
 	 */
 
 	sprintf(current->comm, "scsi_eh_%d", shost->host_no);
+	current->flags |= PF_IOTHREAD;
 
 	shost->eh_wait = &sem;
 	shost->ehandler = current;
@@ -1739,29 +1743,13 @@
 int
 scsi_reset_provider(Scsi_Device *dev, int flag)
 {
-	struct scsi_cmnd SC, *SCpnt = &SC;
+	struct scsi_cmnd *SCpnt = scsi_get_command(dev, GFP_KERNEL);
 	struct request req;
 	int rtn;
 
 	SCpnt->request = &req;
 	memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout));
-	SCpnt->host                    	= dev->host;
-	SCpnt->device                  	= dev;
-	SCpnt->target                  	= dev->id;
-	SCpnt->lun                     	= dev->lun;
-	SCpnt->channel                 	= dev->channel;
 	SCpnt->request->rq_status      	= RQ_SCSI_BUSY;
-	SCpnt->request->waiting        	= NULL;
-	SCpnt->use_sg                  	= 0;
-	SCpnt->old_use_sg              	= 0;
-	SCpnt->old_cmd_len             	= 0;
-	SCpnt->underflow               	= 0;
-	SCpnt->transfersize            	= 0;
-	SCpnt->resid			= 0;
-	SCpnt->serial_number           	= 0;
-	SCpnt->serial_number_at_timeout	= 0;
-	SCpnt->host_scribble           	= NULL;
-	SCpnt->next                    	= NULL;
 	SCpnt->state                   	= SCSI_STATE_INITIALIZING;
 	SCpnt->owner	     		= SCSI_OWNER_MIDLEVEL;
     
@@ -1794,5 +1782,6 @@
 	rtn = scsi_new_reset(SCpnt, flag);
 
 	scsi_delete_timer(SCpnt);
+	scsi_put_command(SCpnt);
 	return rtn;
 }
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/scsi_lib.c	Mon Feb 10 10:39:27 2003
@@ -33,15 +33,16 @@
 struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { 
 	SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
 }; 	
-#undef SP 	
+#undef SP
+
 
 /*
  * Function:    scsi_insert_special_cmd()
  *
  * Purpose:     Insert pre-formed command into request queue.
  *
- * Arguments:   SCpnt   - command that is ready to be queued.
- *              at_head - boolean.  True if we should insert at head
+ * Arguments:   cmd	- command 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.
@@ -55,10 +56,10 @@
  *              for now), and then call the queue request function to actually
  *              process it.
  */
-int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head)
+int scsi_insert_special_cmd(struct scsi_cmnd *cmd, int at_head)
 {
-	blk_insert_request(SCpnt->device->request_queue, SCpnt->request,
-		       	   at_head, SCpnt);
+	blk_insert_request(cmd->device->request_queue, cmd->request,
+		       	   at_head, cmd);
 	return 0;
 }
 
@@ -67,8 +68,8 @@
  *
  * Purpose:     Insert pre-formed request into request queue.
  *
- * Arguments:   SRpnt   - request that is ready to be queued.
- *              at_head - boolean.  True if we should insert at head
+ * 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.
@@ -82,24 +83,24 @@
  *              for now), and then call the queue request function to actually
  *              process it.
  */
-int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head)
+int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
 {
-	/* This is used to insert SRpnt specials.  Because users of
-	 * this function are apt to reuse requests with no modification,
-	 * we have to sanitise the request flags here
-	 */
-	SRpnt->sr_request->flags &= ~REQ_DONTPREP;
-	blk_insert_request(SRpnt->sr_device->request_queue, SRpnt->sr_request,
-		       	   at_head, SRpnt);
+	/*
+	 * 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;
 }
 
 /*
  * Function:    scsi_init_cmd_errh()
  *
- * Purpose:     Initialize SCpnt fields related to error handling.
+ * Purpose:     Initialize cmd fields related to error handling.
  *
- * Arguments:   SCpnt   - command that is ready to be queued.
+ * Arguments:   cmd	- command that is ready to be queued.
  *
  * Returns:     Nothing
  *
@@ -107,21 +108,20 @@
  *              fields related to error handling.   Typically this will
  *              be called once for each command, as required.
  */
-static int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt)
+static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
 {
-	SCpnt->owner = SCSI_OWNER_MIDLEVEL;
-	SCpnt->reset_chain = NULL;
-	SCpnt->serial_number = 0;
-	SCpnt->serial_number_at_timeout = 0;
-	SCpnt->flags = 0;
-	SCpnt->retries = 0;
-
-	SCpnt->abort_reason = 0;
+	cmd->owner = SCSI_OWNER_MIDLEVEL;
+	cmd->reset_chain = NULL;
+	cmd->serial_number = 0;
+	cmd->serial_number_at_timeout = 0;
+	cmd->flags = 0;
+	cmd->retries = 0;
+	cmd->abort_reason = 0;
 
-	memset((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer);
+	memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
 
-	if (SCpnt->cmd_len == 0)
-		SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
+	if (cmd->cmd_len == 0)
+		cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
 
 	/*
 	 * We need saved copies of a number of fields - this is because
@@ -130,19 +130,16 @@
 	 * we will need to restore these values prior to running the actual
 	 * command.
 	 */
-	SCpnt->old_use_sg = SCpnt->use_sg;
-	SCpnt->old_cmd_len = SCpnt->cmd_len;
-	SCpnt->sc_old_data_direction = SCpnt->sc_data_direction;
-	SCpnt->old_underflow = SCpnt->underflow;
-	memcpy((void *) SCpnt->data_cmnd,
-	       (const void *) SCpnt->cmnd, sizeof(SCpnt->cmnd));
-	SCpnt->buffer = SCpnt->request_buffer;
-	SCpnt->bufflen = SCpnt->request_bufflen;
-
-	SCpnt->reset_chain = NULL;
-
-	SCpnt->internal_timeout = NORMAL_TIMEOUT;
-	SCpnt->abort_reason = 0;
+	cmd->old_use_sg = cmd->use_sg;
+	cmd->old_cmd_len = cmd->cmd_len;
+	cmd->sc_old_data_direction = cmd->sc_data_direction;
+	cmd->old_underflow = cmd->underflow;
+	memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
+	cmd->buffer = cmd->request_buffer;
+	cmd->bufflen = cmd->request_bufflen;
+	cmd->reset_chain = NULL;
+	cmd->internal_timeout = NORMAL_TIMEOUT;
+	cmd->abort_reason = 0;
 
 	return 1;
 }
@@ -152,23 +149,22 @@
  *
  * Purpose:    Restore the command state for a retry
  *
- * Arguments:  SCpnt   - command to be restored
+ * Arguments:  cmd	- command to be restored
  *
  * Returns:    Nothing
  *
  * Notes:      Immediately prior to retrying a command, we need
  *             to restore certain fields that we saved above.
  */
-void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt)
+void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
 {
-	memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-		sizeof(SCpnt->data_cmnd));
-	SCpnt->request_buffer = SCpnt->buffer;
-	SCpnt->request_bufflen = SCpnt->bufflen;
-	SCpnt->use_sg = SCpnt->old_use_sg;
-	SCpnt->cmd_len = SCpnt->old_cmd_len;
-	SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-	SCpnt->underflow = SCpnt->old_underflow;
+	memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd));
+	cmd->request_buffer = cmd->buffer;
+	cmd->request_bufflen = cmd->bufflen;
+	cmd->use_sg = cmd->old_use_sg;
+	cmd->cmd_len = cmd->old_cmd_len;
+	cmd->sc_data_direction = cmd->sc_old_data_direction;
+	cmd->underflow = cmd->old_underflow;
 }
 
 /*
@@ -176,7 +172,7 @@
  *
  * Purpose:     Handle post-processing of completed commands.
  *
- * Arguments:   SCpnt   - command that may need to be requeued.
+ * Arguments:   cmd	- command that may need to be requeued.
  *
  * Returns:     Nothing
  *
@@ -186,7 +182,7 @@
  *              that a medium error occurred, and the sectors after
  *              the bad block need to be re-read.
  *
- *              If SCpnt is NULL, it means that the previous command
+ *              If cmd is NULL, it means that the previous command
  *              was completely finished, and we should simply start
  *              a new command, if possible.
  *
@@ -207,17 +203,17 @@
  *		permutations grows as 2**N, and if too many more special cases
  *		get added, we start to get screwed.
  */
-void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
+void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd)
 {
-	int all_clear;
+	struct scsi_device *sdev, *sdev2;
+	struct Scsi_Host *shost;
 	unsigned long flags;
-	Scsi_Device *SDpnt, *SDpnt2;
-	struct Scsi_Host *SHpnt;
+	int all_clear;
 
 	ASSERT_LOCK(q->queue_lock, 0);
 
 	spin_lock_irqsave(q->queue_lock, flags);
-	if (SCpnt != NULL) {
+	if (cmd != NULL) {
 
 		/*
 		 * For some reason, we are not done with this request.
@@ -225,16 +221,18 @@
 		 * in which case we need to request the blocks that come after
 		 * the bad sector.
 		 */
-		SCpnt->request->special = (void *) SCpnt;
-		if(blk_rq_tagged(SCpnt->request))
-			blk_queue_end_tag(q, SCpnt->request);
-		/* set REQ_SPECIAL - we have a command
+		cmd->request->special = cmd;
+		if (blk_rq_tagged(cmd->request))
+			blk_queue_end_tag(q, cmd->request);
+
+		/*
+		 * set REQ_SPECIAL - we have a command
 		 * clear REQ_DONTPREP - we assume the sg table has been 
 		 *	nuked so we need to set it up again.
 		 */
-		SCpnt->request->flags |= REQ_SPECIAL;
-		SCpnt->request->flags &= ~REQ_DONTPREP;
-		__elv_add_request(q, SCpnt->request, 0, 0);
+		cmd->request->flags |= REQ_SPECIAL;
+		cmd->request->flags &= ~REQ_DONTPREP;
+		__elv_add_request(q, cmd->request, 0, 0);
 	}
 
 	/*
@@ -242,8 +240,8 @@
 	 */
 	__blk_run_queue(q);
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	SHpnt = SDpnt->host;
+	sdev = q->queuedata;
+	shost = sdev->host;
 
 	/*
 	 * If this is a single-lun device, and we are currently finished
@@ -252,15 +250,15 @@
 	 * with special case code, then spin off separate versions and
 	 * use function pointers to pick the right one.
 	 */
-	if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0 &&
-			!SHpnt->host_blocked && !SHpnt->host_self_blocked &&
-			!((SHpnt->can_queue > 0) && (SHpnt->host_busy >=
-				       		     SHpnt->can_queue))) {
-		list_for_each_entry(SDpnt2, &SDpnt->same_target_siblings,
+	if (sdev->single_lun && blk_queue_empty(q) && sdev->device_busy ==0 &&
+			!shost->host_blocked && !shost->host_self_blocked &&
+			!((shost->can_queue > 0) && (shost->host_busy >=
+				       		     shost->can_queue))) {
+		list_for_each_entry(sdev2, &sdev->same_target_siblings,
 			       same_target_siblings) {
-			if (!SDpnt2->device_blocked &&
-			    !blk_queue_empty(SDpnt2->request_queue)) {
-				__blk_run_queue(SDpnt2->request_queue);
+			if (!sdev2->device_blocked &&
+			    !blk_queue_empty(sdev2->request_queue)) {
+				__blk_run_queue(sdev2->request_queue);
 				break;
 			}
 		}
@@ -275,22 +273,21 @@
 	 * other device might have become starved along the way.
 	 */
 	all_clear = 1;
-	if (SHpnt->some_device_starved) {
-		list_for_each_entry(SDpnt, &SHpnt->my_devices, siblings) {
-			if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
-			    || (SHpnt->host_blocked) 
-			    || (SHpnt->host_self_blocked)) {
+	if (shost->some_device_starved) {
+		list_for_each_entry(sdev, &shost->my_devices, siblings) {
+			if (shost->can_queue > 0 &&
+			    shost->host_busy >= shost->can_queue)
 				break;
-			}
-			if (SDpnt->device_blocked || !SDpnt->starved) {
+			if (shost->host_blocked || shost->host_self_blocked)
+				break;
+			if (sdev->device_blocked || !sdev->starved)
 				continue;
-			}
-			__blk_run_queue(SDpnt->request_queue);
+			__blk_run_queue(sdev->request_queue);
 			all_clear = 0;
 		}
-		if (SDpnt == NULL && all_clear) {
-			SHpnt->some_device_starved = 0;
-		}
+
+		if (sdev == NULL && all_clear)
+			shost->some_device_starved = 0;
 	}
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
@@ -301,7 +298,7 @@
  * Purpose:     Post-processing of completed commands called from interrupt
  *              handler or a bottom-half handler.
  *
- * Arguments:   SCpnt    - command that is complete.
+ * Arguments:   cmd	 - command that is complete.
  *              uptodate - 1 if I/O indicates success, 0 for I/O error.
  *              sectors  - number of sectors we want to mark.
  *		requeue  - indicates whether we should requeue leftovers.
@@ -318,13 +315,11 @@
  *		We are guaranteeing that the request queue will be goosed
  *		at some point during this call.
  */
-static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, 
-				     int uptodate, 
-				     int sectors,
-				     int requeue)
+static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
+					  int sectors, int requeue)
 {
-	request_queue_t *q = SCpnt->device->request_queue;
-	struct request *req = SCpnt->request;
+	request_queue_t *q = cmd->device->request_queue;
+	struct request *req = cmd->request;
 	unsigned long flags;
 
 	ASSERT_LOCK(q->queue_lock, 0);
@@ -334,15 +329,14 @@
 	 * to queue the remainder of them.
 	 */
 	if (end_that_request_first(req, uptodate, sectors)) {
-		if (!requeue)
-			return SCpnt;
-
-		/*
-		 * Bleah.  Leftovers again.  Stick the leftovers in
-		 * the front of the queue, and goose the queue again.
-		 */
-		scsi_queue_next_request(q, SCpnt);
-		return SCpnt;
+		if (requeue) {
+			/*
+			 * Bleah.  Leftovers again.  Stick the leftovers in
+			 * the front of the queue, and goose the queue again.
+			 */
+			scsi_queue_next_request(q, cmd);
+		}
+		return cmd;
 	}
 
 	add_disk_randomness(req->rq_disk);
@@ -357,39 +351,39 @@
 	 * This will goose the queue request function at the end, so we don't
 	 * need to worry about launching another command.
 	 */
-	__scsi_release_command(SCpnt);
+	scsi_put_command(cmd);
 	scsi_queue_next_request(q, NULL);
 	return NULL;
 }
 
-static struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask)
+static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, int gfp_mask)
 {
 	struct scsi_host_sg_pool *sgp;
 	struct scatterlist *sgl;
 
-	BUG_ON(!SCpnt->use_sg);
+	BUG_ON(!cmd->use_sg);
 
-	switch (SCpnt->use_sg) {
+	switch (cmd->use_sg) {
 	case 1 ... 8:
-		SCpnt->sglist_len = 0;
+		cmd->sglist_len = 0;
 		break;
 	case 9 ... 16:
-		SCpnt->sglist_len = 1;
+		cmd->sglist_len = 1;
 		break;
 	case 17 ... 32:
-		SCpnt->sglist_len = 2;
+		cmd->sglist_len = 2;
 		break;
 	case 33 ... 64:
-		SCpnt->sglist_len = 3;
+		cmd->sglist_len = 3;
 		break;
 	case 65 ... MAX_PHYS_SEGMENTS:
-		SCpnt->sglist_len = 4;
+		cmd->sglist_len = 4;
 		break;
 	default:
 		return NULL;
 	}
 
-	sgp = scsi_sg_pools + SCpnt->sglist_len;
+	sgp = scsi_sg_pools + cmd->sglist_len;
 	sgl = mempool_alloc(sgp->pool, gfp_mask);
 	if (sgl)
 		memset(sgl, 0, sgp->size);
@@ -406,13 +400,12 @@
 	mempool_free(sgl, sgp->pool);
 }
 
-
 /*
  * Function:    scsi_release_buffers()
  *
  * Purpose:     Completion processing for block device I/O requests.
  *
- * Arguments:   SCpnt   - command that we are bailing.
+ * Arguments:   cmd	- command that we are bailing.
  *
  * Lock status: Assumed that no lock is held upon entry.
  *
@@ -424,28 +417,28 @@
  *		the scatter-gather table, and potentially any bounce
  *		buffers.
  */
-static void scsi_release_buffers(Scsi_Cmnd * SCpnt)
+static void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-	struct request *req = SCpnt->request;
+	struct request *req = cmd->request;
 
-	ASSERT_LOCK(SCpnt->host->host_lock, 0);
+	ASSERT_LOCK(cmd->device->host->host_lock, 0);
 
 	/*
 	 * Free up any indirection buffers we allocated for DMA purposes. 
 	 */
-	if (SCpnt->use_sg)
-		scsi_free_sgtable(SCpnt->request_buffer, SCpnt->sglist_len);
-	else if (SCpnt->request_buffer != req->buffer)
-		kfree(SCpnt->request_buffer);
+	if (cmd->use_sg)
+		scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+	else if (cmd->request_buffer != req->buffer)
+		kfree(cmd->request_buffer);
 
 	/*
 	 * Zero these out.  They now point to freed memory, and it is
 	 * dangerous to hang onto the pointers.
 	 */
-	SCpnt->buffer  = NULL;
-	SCpnt->bufflen = 0;
-	SCpnt->request_buffer = NULL;
-	SCpnt->request_bufflen = 0;
+	cmd->buffer  = NULL;
+	cmd->bufflen = 0;
+	cmd->request_buffer = NULL;
+	cmd->request_bufflen = 0;
 }
 
 /*
@@ -476,7 +469,7 @@
  *
  * Purpose:     Completion processing for block device I/O requests.
  *
- * Arguments:   SCpnt   - command that is finished.
+ * Arguments:   cmd   - command that is finished.
  *
  * Lock status: Assumed that no lock is held upon entry.
  *
@@ -488,13 +481,13 @@
  *              (the normal case for most drivers), we don't need
  *              the logic to deal with cleaning up afterwards.
  */
-void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
+void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors,
 			int block_sectors)
 {
-	int result = SCpnt->result;
-	int this_count = SCpnt->bufflen >> 9;
-	request_queue_t *q = SCpnt->device->request_queue;
-	struct request *req = SCpnt->request;
+	int result = cmd->result;
+	int this_count = cmd->bufflen >> 9;
+	request_queue_t *q = cmd->device->request_queue;
+	struct request *req = cmd->request;
 	int clear_errors = 1;
 
 	/*
@@ -517,44 +510,43 @@
 	 * For the case of a READ, we need to copy the data out of the
 	 * bounce buffer and into the real buffer.
 	 */
-	if (SCpnt->use_sg)
-		scsi_free_sgtable(SCpnt->buffer, SCpnt->sglist_len);
-	else if (SCpnt->buffer != req->buffer) {
+	if (cmd->use_sg)
+		scsi_free_sgtable(cmd->buffer, cmd->sglist_len);
+	else if (cmd->buffer != req->buffer) {
 		if (rq_data_dir(req) == READ) {
 			unsigned long flags;
 			char *to = bio_kmap_irq(req->bio, &flags);
-			memcpy(to, SCpnt->buffer, SCpnt->bufflen);
+			memcpy(to, cmd->buffer, cmd->bufflen);
 			bio_kunmap_irq(to, &flags);
 		}
-		kfree(SCpnt->buffer);
+		kfree(cmd->buffer);
 	}
 
 	if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
 		req->errors = (driver_byte(result) & DRIVER_SENSE) ?
 			      (CHECK_CONDITION << 1) : (result & 0xff);
-		if (!result) 
-			req->data_len -= SCpnt->bufflen;
-		else {
+		if (result) {
 			clear_errors = 0;
-			if (SCpnt->sense_buffer[0] & 0x70) {
-				int len = 8 + SCpnt->sense_buffer[7];
+			if (cmd->sense_buffer[0] & 0x70) {
+				int len = 8 + cmd->sense_buffer[7];
 
 				if (len > SCSI_SENSE_BUFFERSIZE)
 					len = SCSI_SENSE_BUFFERSIZE;
-				memcpy(req->sense, SCpnt->sense_buffer,  len);
+				memcpy(req->sense, cmd->sense_buffer,  len);
 				req->sense_len = len;
 			}
-		}
+		} else
+			req->data_len -= cmd->bufflen;
 	}
 
 	/*
 	 * Zero these out.  They now point to freed memory, and it is
 	 * dangerous to hang onto the pointers.
 	 */
-	SCpnt->buffer  = NULL;
-	SCpnt->bufflen = 0;
-	SCpnt->request_buffer = NULL;
-	SCpnt->request_bufflen = 0;
+	cmd->buffer  = NULL;
+	cmd->bufflen = 0;
+	cmd->request_buffer = NULL;
+	cmd->request_bufflen = 0;
 
 	/*
 	 * Next deal with any sectors which we were able to correctly
@@ -563,7 +555,7 @@
 	if (good_sectors >= 0) {
 		SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d sectors done.\n",
 					      req->nr_sectors, good_sectors));
-		SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg));
+		SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", cmd->use_sg));
 
 		if (clear_errors)
 			req->errors = 0;
@@ -578,13 +570,13 @@
 		 * requeueing right here - we will requeue down below
 		 * when we handle the bad sectors.
 		 */
-		SCpnt = scsi_end_request(SCpnt, 1, good_sectors, result == 0);
+		cmd = scsi_end_request(cmd, 1, good_sectors, result == 0);
 
 		/*
 		 * If the command completed without error, then either finish off the
 		 * rest of the command, or start a new one.
 		 */
-		if (result == 0 || SCpnt == NULL ) {
+		if (result == 0 || cmd == NULL ) {
 			return;
 		}
 	}
@@ -600,28 +592,28 @@
 			 * Not yet implemented.  A read will fail after being remapped,
 			 * a write will call the strategy routine again.
 			 */
-			if (SCpnt->device->remap) {
+			if (cmd->device->remap) {
 				result = 0;
 			}
 #endif
 		}
-		if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
+		if ((cmd->sense_buffer[0] & 0x7f) == 0x70) {
 			/*
 			 * If the device is in the process of becoming ready,
 			 * retry.
 			 */
-			if (SCpnt->sense_buffer[12] == 0x04 &&
-			    SCpnt->sense_buffer[13] == 0x01) {
-				scsi_queue_next_request(q, SCpnt);
+			if (cmd->sense_buffer[12] == 0x04 &&
+			    cmd->sense_buffer[13] == 0x01) {
+				scsi_queue_next_request(q, cmd);
 				return;
 			}
-			if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
-				if (SCpnt->device->removable) {
+			if ((cmd->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
+				if (cmd->device->removable) {
 					/* detected disc change.  set a bit 
 					 * and quietly refuse further access.
 		 			 */
-					SCpnt->device->changed = 1;
-					SCpnt = scsi_end_request(SCpnt, 0,
+					cmd->device->changed = 1;
+					cmd = scsi_end_request(cmd, 0,
 							this_count, 1);
 					return;
 				} else {
@@ -631,7 +623,7 @@
 				 	* media change, so we just retry the
 				 	* request and see what happens.  
 				 	*/
-					scsi_queue_next_request(q, SCpnt);
+					scsi_queue_next_request(q, cmd);
 					return;
 				}
 			}
@@ -643,35 +635,35 @@
 		 * past the end of the disk.
 		 */
 
-		switch (SCpnt->sense_buffer[2]) {
+		switch (cmd->sense_buffer[2]) {
 		case ILLEGAL_REQUEST:
-			if (SCpnt->device->ten) {
-				SCpnt->device->ten = 0;
+			if (cmd->device->ten) {
+				cmd->device->ten = 0;
 				/*
 				 * This will cause a retry with a 6-byte
 				 * command.
 				 */
-				scsi_queue_next_request(q, SCpnt);
+				scsi_queue_next_request(q, cmd);
 				result = 0;
 			} else {
-				SCpnt = scsi_end_request(SCpnt, 0, this_count, 1);
+				cmd = scsi_end_request(cmd, 0, this_count, 1);
 				return;
 			}
 			break;
 		case NOT_READY:
 			printk(KERN_INFO "Device %s not ready.\n",
 			       req->rq_disk ? req->rq_disk->disk_name : "");
-			SCpnt = scsi_end_request(SCpnt, 0, this_count, 1);
+			cmd = scsi_end_request(cmd, 0, this_count, 1);
 			return;
 			break;
 		case MEDIUM_ERROR:
 		case VOLUME_OVERFLOW:
 			printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ",
-			       SCpnt->host->host_no, (int) SCpnt->channel,
-			       (int) SCpnt->target, (int) SCpnt->lun);
-			print_command(SCpnt->data_cmnd);
-			print_sense("sd", SCpnt);
-			SCpnt = scsi_end_request(SCpnt, 0, block_sectors, 1);
+			       cmd->device->host->host_no, (int) cmd->device->channel,
+			       (int) cmd->device->id, (int) cmd->device->lun);
+			print_command(cmd->data_cmnd);
+			print_sense("sd", cmd);
+			cmd = scsi_end_request(cmd, 0, block_sectors, 1);
 			return;
 		default:
 			break;
@@ -683,28 +675,28 @@
 		 * recovery reasons.  Just retry the request
 		 * and see what happens.  
 		 */
-		scsi_queue_next_request(q, SCpnt);
+		scsi_queue_next_request(q, cmd);
 		return;
 	}
 	if (result) {
-		struct Scsi_Device_Template *STpnt;
+		struct Scsi_Device_Template *sdt;
 
-		STpnt = scsi_get_request_dev(SCpnt->request);
+		sdt = scsi_get_request_dev(cmd->request);
 		printk("SCSI %s error : host %d channel %d id %d lun %d return code = %x\n",
-		       (STpnt ? STpnt->name : "device"),
-		       SCpnt->device->host->host_no,
-		       SCpnt->device->channel,
-		       SCpnt->device->id,
-		       SCpnt->device->lun, result);
+		       (sdt ? sdt->name : "device"),
+		       cmd->device->host->host_no,
+		       cmd->device->channel,
+		       cmd->device->id,
+		       cmd->device->lun, result);
 
 		if (driver_byte(result) & DRIVER_SENSE)
-			print_sense("sd", SCpnt);
+			print_sense("sd", cmd);
 		/*
 		 * Mark a single buffer as not uptodate.  Queue the remainder.
 		 * We sometimes get this cruft in the event that a medium error
 		 * isn't properly reported.
 		 */
-		SCpnt = scsi_end_request(SCpnt, 0, req->current_nr_sectors, 1);
+		cmd = scsi_end_request(cmd, 0, req->current_nr_sectors, 1);
 		return;
 	}
 }
@@ -714,26 +706,26 @@
  *
  * Purpose:     SCSI I/O initialize function.
  *
- * Arguments:   SCpnt   - Command descriptor we wish to initialize
+ * Arguments:   cmd   - Command descriptor we wish to initialize
  *
  * Returns:     0 on success
  *		BLKPREP_DEFER if the failure is retryable
  *		BLKPREP_KILL if the failure is fatal
  */
-static int scsi_init_io(Scsi_Cmnd *SCpnt)
+static int scsi_init_io(struct scsi_cmnd *cmd)
 {
-	struct request     *req = SCpnt->request;
+	struct request     *req = cmd->request;
 	struct scatterlist *sgpnt;
-	int count, ret = 0;
+	int		   count;
 
 	/*
 	 * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
 	 */
 	if ((req->flags & REQ_BLOCK_PC) && !req->bio) {
-		SCpnt->request_bufflen = req->data_len;
-		SCpnt->request_buffer = req->data;
+		cmd->request_bufflen = req->data_len;
+		cmd->request_buffer = req->data;
 		req->buffer = req->data;
-		SCpnt->use_sg = 0;
+		cmd->use_sg = 0;
 		return 0;
 	}
 
@@ -742,113 +734,112 @@
 	 * but now we do (it makes highmem I/O easier to support without
 	 * kmapping pages)
 	 */
-	SCpnt->use_sg = req->nr_phys_segments;
+	cmd->use_sg = req->nr_phys_segments;
 
 	/*
 	 * if sg table allocation fails, requeue request later.
 	 */
-	sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC);
+	sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
 	if (unlikely(!sgpnt)) {
 		req->flags |= REQ_SPECIAL;
-		ret = BLKPREP_DEFER;
-		goto out;
+		return BLKPREP_DEFER;
 	}
 
-	SCpnt->request_buffer = (char *) sgpnt;
-	SCpnt->request_bufflen = req->nr_sectors << 9;
+	cmd->request_buffer = (char *) sgpnt;
+	cmd->request_bufflen = req->nr_sectors << 9;
 	if (blk_pc_request(req))
-		SCpnt->request_bufflen = req->data_len;
+		cmd->request_bufflen = req->data_len;
 	req->buffer = NULL;
 
 	/* 
 	 * Next, walk the list, and fill in the addresses and sizes of
 	 * each segment.
 	 */
-	count = blk_rq_map_sg(req->q, req, SCpnt->request_buffer);
+	count = blk_rq_map_sg(req->q, req, cmd->request_buffer);
 
 	/*
 	 * mapped well, send it off
 	 */
-	if (count <= SCpnt->use_sg) {
-		SCpnt->use_sg = count;
+	if (likely(count <= cmd->use_sg)) {
+		cmd->use_sg = count;
 		return 0;
 	}
 
 	printk(KERN_ERR "Incorrect number of segments after building list\n");
-	printk(KERN_ERR "counted %d, received %d\n", count, SCpnt->use_sg);
+	printk(KERN_ERR "counted %d, received %d\n", count, cmd->use_sg);
 	printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
 			req->current_nr_sectors);
 
-	/*
-	 * kill it. there should be no leftover blocks in this request
-	 */
-	SCpnt = scsi_end_request(SCpnt, 0, req->nr_sectors, 1);
-	BUG_ON(SCpnt);
-	ret = BLKPREP_KILL;
-out:
-	return ret;
+	/* release the command and kill it */
+	scsi_put_command(cmd);
+	return BLKPREP_KILL;
 }
 
-int scsi_prep_fn(struct request_queue *q, struct request *req)
+/*
+ * The target associated with myself can only handle one active command at
+ * a time. Scan through all of the luns on the same target as myself,
+ * return 1 if any are active.
+ */
+static int check_all_luns(struct scsi_device *myself)
 {
-	struct Scsi_Device_Template *STpnt;
-	Scsi_Cmnd *SCpnt;
-	Scsi_Device *SDpnt;
+	struct scsi_device *sdev;
+
+	list_for_each_entry(sdev, &myself->same_target_siblings,
+			    same_target_siblings)
+		if (sdev->device_busy)
+			return 1;
+	return 0;
+}
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	BUG_ON(!SDpnt);
+int scsi_prep_fn(struct request_queue *q, struct request *req)
+{
+	struct Scsi_Device_Template *sdt;
+	struct scsi_device *sdev = q->queuedata;
+	struct scsi_cmnd *cmd;
 
 	/*
 	 * Find the actual device driver associated with this command.
 	 * The SPECIAL requests are things like character device or
 	 * ioctls, which did not originate from ll_rw_blk.  Note that
-	 * the special field is also used to indicate the SCpnt for
+	 * the special field is also used to indicate the cmd for
 	 * the remainder of a partially fulfilled request that can 
 	 * come up when there is a medium error.  We have to treat
 	 * these two cases differently.  We differentiate by looking
 	 * at request->cmd, as this tells us the real story.
 	 */
 	if (req->flags & REQ_SPECIAL) {
-		Scsi_Request *SRpnt;
+		struct scsi_request *sreq = req->special;
 
-		STpnt = NULL;
-		SCpnt = (Scsi_Cmnd *) req->special;
-		SRpnt = (Scsi_Request *) req->special;
-		
-		if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) {
-			SCpnt = scsi_allocate_device(SRpnt->sr_device, 0);
-			if (!SCpnt)
+		if (sreq->sr_magic == SCSI_REQ_MAGIC) {
+			cmd = scsi_get_command(sreq->sr_device, GFP_ATOMIC);
+			if (unlikely(!cmd))
 				return BLKPREP_DEFER;
-			scsi_init_cmd_from_req(SCpnt, SRpnt);
-		}
-		
+			scsi_init_cmd_from_req(cmd, sreq);
+		} else
+			cmd = req->special;
 	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
 		/*
 		 * Now try and find a command block that we can use.
 		 */
-		if (req->special) {
-			SCpnt = (Scsi_Cmnd *) req->special;
-		} else {
-			SCpnt = scsi_allocate_device(SDpnt, 0);
-		}
-		/*
-		 * if command allocation failure, wait a bit
-		 */
-		if (unlikely(!SCpnt))
-			return BLKPREP_DEFER;
+		if (!req->special) {
+			cmd = scsi_get_command(sdev, GFP_ATOMIC);
+			if (unlikely(!cmd))
+				return BLKPREP_DEFER;
+		} else
+			cmd = req->special;
 		
 		/* pull a tag out of the request if we have one */
-		SCpnt->tag = req->tag;
+		cmd->tag = req->tag;
 	} else {
 		blk_dump_rq_flags(req, "SCSI bad req");
 		return BLKPREP_KILL;
 	}
 	
 	/* note the overloading of req->special.  When the tag
-	 * is active it always means SCpnt.  If the tag goes
+	 * is active it always means cmd.  If the tag goes
 	 * back for re-queueing, it may be reset */
-	req->special = SCpnt;
-	SCpnt->request = req;
+	req->special = cmd;
+	cmd->request = req;
 	
 	/*
 	 * FIXME: drop the lock here because the functions below
@@ -857,7 +848,6 @@
 	 * lock.  We hope REQ_STARTED prevents anything untoward from
 	 * happening now.
 	 */
-
 	if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
 		int ret;
 
@@ -873,25 +863,30 @@
 		 * some kinds of consistency checking may cause the	
 		 * request to be rejected immediately.
 		 */
-		STpnt = scsi_get_request_dev(req);
-		BUG_ON(!STpnt);
+		sdt = scsi_get_request_dev(req);
+		BUG_ON(!sdt);
 
 		/* 
 		 * This sets up the scatter-gather table (allocating if
 		 * required).
 		 */
-		if ((ret = scsi_init_io(SCpnt)))
+		ret = scsi_init_io(cmd);
+		if (ret)	/* BLKPREP_KILL return also releases the command */
 			return ret;
 		
 		/*
 		 * Initialize the actual SCSI command for this request.
 		 */
-		if (!STpnt->init_command(SCpnt)) {
-			scsi_release_buffers(SCpnt);
+		if (unlikely(!sdt->init_command(cmd))) {
+			scsi_release_buffers(cmd);
+			scsi_put_command(cmd);
 			return BLKPREP_KILL;
 		}
 	}
-	/* The request is now prepped, no need to come back here */
+
+	/*
+	 * The request is now prepped, no need to come back here
+	 */
 	req->flags |= REQ_DONTPREP;
 	return BLKPREP_OK;
 }
@@ -899,48 +894,34 @@
 /*
  * Function:    scsi_request_fn()
  *
- * Purpose:     Generic version of request function for SCSI hosts.
+ * Purpose:     Main strategy routine for SCSI.
  *
  * Arguments:   q       - Pointer to actual queue.
  *
  * Returns:     Nothing
  *
  * Lock status: IO request lock assumed to be held when called.
- *
- * Notes:       The theory is that this function is something which individual
- *              drivers could also supply if they wished to.   The problem
- *              is that we have 30 some odd low-level drivers in the kernel
- *              tree already, and it would be most difficult to retrofit
- *              this crap into all of them.   Thus this function has the job
- *              of acting as a generic queue manager for all of those existing
- *              drivers.
  */
-void scsi_request_fn(request_queue_t * q)
+void scsi_request_fn(request_queue_t *q)
 {
+	struct scsi_device *sdev = q->queuedata;
+	struct Scsi_Host *shost = sdev->host;
+	struct scsi_cmnd *cmd;
 	struct request *req;
-	Scsi_Cmnd *SCpnt;
-	Scsi_Device *SDpnt;
-	struct Scsi_Host *SHpnt;
 
 	ASSERT_LOCK(q->queue_lock, 1);
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	if (!SDpnt) {
-		panic("Missing device");
-	}
-	SHpnt = SDpnt->host;
-
 	/*
 	 * To start with, we keep looping until the queue is empty, or until
 	 * the host is no longer able to accept any more requests.
 	 */
-	while (1 == 1) {
+	for (;;) {
 		/*
 		 * Check this again - each time we loop through we will have
 		 * released the lock and grabbed it again, so each time
 		 * we need to check to see if the queue is plugged or not.
 		 */
-		if (SHpnt->in_recovery || blk_queue_plugged(q))
+		if (shost->in_recovery || blk_queue_plugged(q))
 			return;
 
 		/*
@@ -951,33 +932,43 @@
 		 */
 		req = elv_next_request(q);
 
-		if(SHpnt->host_busy == 0 && SHpnt->host_blocked) {
+		if (sdev->device_busy >= sdev->queue_depth)
+			break;
+
+		if (sdev->single_lun && check_all_luns(sdev))
+			break;
+
+		if (shost->host_busy == 0 && shost->host_blocked) {
 			/* unblock after host_blocked iterates to zero */
-			if(--SHpnt->host_blocked == 0) {
-				SCSI_LOG_MLQUEUE(3, printk("scsi%d unblocking host at zero depth\n", SHpnt->host_no));
+			if (--shost->host_blocked == 0) {
+				SCSI_LOG_MLQUEUE(3,
+					printk("scsi%d unblocking host at zero depth\n",
+						shost->host_no));
 			} else {
 				blk_plug_device(q);
 				break;
 			}
 		}
-		if(SDpnt->device_busy == 0 && SDpnt->device_blocked) {
+
+		if (sdev->device_busy == 0 && sdev->device_blocked) {
 			/* unblock after device_blocked iterates to zero */
-			if(--SDpnt->device_blocked == 0) {
-				SCSI_LOG_MLQUEUE(3, printk("scsi%d (%d:%d) unblocking device at zero depth\n", SHpnt->host_no, SDpnt->id, SDpnt->lun));
+			if (--sdev->device_blocked == 0) {
+				SCSI_LOG_MLQUEUE(3,
+					printk("scsi%d (%d:%d) unblocking device at zero depth\n",
+						shost->host_no, sdev->id, sdev->lun));
 			} else {
 				blk_plug_device(q);
 				break;
 			}
 		}
+
 		/*
 		 * If the device cannot accept another request, then quit.
 		 */
-		if (SDpnt->device_blocked) {
+		if (sdev->device_blocked)
 			break;
-		}
-		if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
-		    || (SHpnt->host_blocked) 
-		    || (SHpnt->host_self_blocked)) {
+		if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
+		    shost->host_blocked || shost->host_self_blocked) {
 			/*
 			 * If we are unable to process any commands at all for
 			 * this device, then we consider it to be starved.
@@ -986,14 +977,13 @@
 			 * little help getting it started again
 			 * once the host isn't quite so busy.
 			 */
-			if (SDpnt->device_busy == 0) {
-				SDpnt->starved = 1;
-				SHpnt->some_device_starved = 1;
+			if (sdev->device_busy == 0) {
+				sdev->starved = 1;
+				shost->some_device_starved = 1;
 			}
 			break;
-		} else {
-			SDpnt->starved = 0;
-		}
+		} else
+			sdev->starved = 0;
 
 		/*
 		 * If we couldn't find a request that could be queued, then we
@@ -1002,21 +992,22 @@
 		if (blk_queue_empty(q))
 			break;
 
-		if(!req) {
+		if (!req) {
 			/* If the device is busy, a returning I/O
 			 * will restart the queue.  Otherwise, we have
 			 * to plug the queue */
-			if(SDpnt->device_busy == 0)
+			if(sdev->device_busy == 0)
 				blk_plug_device(q);
 			break;
 		}
 
-		SCpnt = (struct scsi_cmnd *)req->special;
+		cmd = req->special;
 
-		/* Should be impossible for a correctly prepared request
+		/*
+		 * Should be impossible for a correctly prepared request
 		 * please mail the stack trace to linux-scsi@vger.kernel.org
 		 */
-		BUG_ON(!SCpnt);
+		BUG_ON(!cmd);
 
 		/*
 		 * Finally, before we release the lock, we copy the
@@ -1026,27 +1017,27 @@
 		 * reason to search the list, because all of the
 		 * commands in this queue are for the same device.
 		 */
-		if(!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0)))
+		if (!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0)))
 			blkdev_dequeue_request(req);
 	
 		/*
 		 * Now bump the usage count for both the host and the
 		 * device.
 		 */
-		SHpnt->host_busy++;
-		SDpnt->device_busy++;
+		shost->host_busy++;
+		sdev->device_busy++;
 		spin_unlock_irq(q->queue_lock);
 
 		/*
 		 * Finally, initialize any error handling parameters, and set up
 		 * the timers for timeouts.
 		 */
-		scsi_init_cmd_errh(SCpnt);
+		scsi_init_cmd_errh(cmd);
 
 		/*
 		 * Dispatch the command to the low-level driver.
 		 */
-		scsi_dispatch_cmd(SCpnt);
+		scsi_dispatch_cmd(cmd);
 
 		/*
 		 * Now we need to grab the lock again.  We are about to mess
@@ -1062,7 +1053,7 @@
  * Purpose:     Utility function used by low-level drivers to prevent further
  *		commands from being queued to the device.
  *
- * Arguments:   SHpnt       - Host in question
+ * Arguments:   shost       - Host in question
  *
  * Returns:     Nothing
  *
@@ -1072,9 +1063,9 @@
  *		get unblocked other than the low-level driver calling
  *		scsi_unblock_requests().
  */
-void scsi_block_requests(struct Scsi_Host * SHpnt)
+void scsi_block_requests(struct Scsi_Host *shost)
 {
-	SHpnt->host_self_blocked = 1;
+	shost->host_self_blocked = 1;
 }
 
 /*
@@ -1083,7 +1074,7 @@
  * Purpose:     Utility function used by low-level drivers to allow further
  *		commands from being queued to the device.
  *
- * Arguments:   SHpnt       - Host in question
+ * Arguments:   shost       - Host in question
  *
  * Returns:     Nothing
  *
@@ -1097,14 +1088,17 @@
  *		internals of the scsi mid-layer won't require wholesale
  *		changes to drivers that use this feature.
  */
-void scsi_unblock_requests(struct Scsi_Host * SHpnt)
+void scsi_unblock_requests(struct Scsi_Host *shost)
 {
-	Scsi_Device *SDloop;
+	struct scsi_device *sdev;
+
+	shost->host_self_blocked = 0;
 
-	SHpnt->host_self_blocked = 0;
-	/* Now that we are unblocked, try to start the queues. */
-	list_for_each_entry(SDloop, &SHpnt->my_devices, siblings)
-		scsi_queue_next_request(SDloop->request_queue, NULL);
+	/*
+	 * Now that we are unblocked, try to start the queues.
+	 */
+	list_for_each_entry(sdev, &shost->my_devices, siblings)
+		scsi_queue_next_request(sdev->request_queue, NULL);
 }
 
 /*
@@ -1113,7 +1107,7 @@
  * Purpose:     Utility function used by low-level drivers to report that
  *		they have observed a bus reset on the bus being handled.
  *
- * Arguments:   SHpnt       - Host in question
+ * Arguments:   shost       - Host in question
  *		channel     - channel on which reset was observed.
  *
  * Returns:     Nothing
@@ -1128,13 +1122,14 @@
  *		The main purpose of this is to make sure that a CHECK_CONDITION
  *		is properly treated.
  */
-void scsi_report_bus_reset(struct Scsi_Host * SHpnt, int channel)
+void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
 {
-	Scsi_Device *SDloop;
-	list_for_each_entry(SDloop, &SHpnt->my_devices, siblings) {
-		if (channel == SDloop->channel) {
-			SDloop->was_reset = 1;
-			SDloop->expecting_cc_ua = 1;
+	struct scsi_device *sdev;
+
+	list_for_each_entry(sdev, &shost->my_devices, siblings) {
+		if (channel == sdev->channel) {
+			sdev->was_reset = 1;
+			sdev->expecting_cc_ua = 1;
 		}
 	}
 }
@@ -1148,11 +1143,11 @@
  * The details of the implementation remain to be settled, however the
  * stubs are here now so that the actual drivers will properly compile.
  */
-void scsi_register_blocked_host(struct Scsi_Host * SHpnt)
+void scsi_register_blocked_host(struct Scsi_Host * shost)
 {
 }
 
-void scsi_deregister_blocked_host(struct Scsi_Host * SHpnt)
+void scsi_deregister_blocked_host(struct Scsi_Host * shost)
 {
 }
 
diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
--- a/drivers/scsi/scsi_proc.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/scsi_proc.c	Mon Feb 10 10:39:23 2003
@@ -345,10 +345,9 @@
 	i = 0;
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
-		printk(KERN_INFO " %d %d %d : %d %d\n",
+		printk(KERN_INFO " %d %d : %d %d\n",
 		       shpnt->host_failed,
 		       shpnt->host_busy,
-		       atomic_read(&shpnt->host_active),
 		       shpnt->host_blocked,
 		       shpnt->host_self_blocked);
 	}
@@ -360,15 +359,18 @@
 		printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) "
 			"(ret all flg) (to/cmd to ito) cmd snse result\n");
 		list_for_each_entry(SDpnt, &shpnt->my_devices, siblings) {
-			for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&SDpnt->list_lock, flags);
+			list_for_each_entry(SCpnt, &SDpnt->cmd_list, list) {
 				/*  (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x      */
 				printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4llu %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n",
 				       i++,
 
-				       SCpnt->host->host_no,
-				       SCpnt->channel,
-                                       SCpnt->target,
-                                       SCpnt->lun,
+				       SCpnt->device->host->host_no,
+				       SCpnt->device->channel,
+                                       SCpnt->device->id,
+                                       SCpnt->device->lun,
 
                                        SCpnt->request->rq_disk ?
                                        SCpnt->request->rq_disk->disk_name : "?",
@@ -390,6 +392,7 @@
 				       SCpnt->sense_buffer[2],
 				       SCpnt->result);
 			}
+			spin_unlock_irqrestore(&SDpnt->list_lock, flags);
 		}
 	}
 }
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/scsi/scsi_scan.c	Mon Feb 10 10:39:30 2003
@@ -449,6 +449,8 @@
 		sdev->online = TRUE;
 		INIT_LIST_HEAD(&sdev->siblings);
 		INIT_LIST_HEAD(&sdev->same_target_siblings);
+		INIT_LIST_HEAD(&sdev->cmd_list);
+		spin_lock_init(&sdev->list_lock);
 		/*
 		 * Some low level driver could use device->type
 		 */
@@ -471,10 +473,6 @@
 
 		sdev->request_queue->queuedata = sdev;
 		scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
-		scsi_build_commandblocks(sdev);
-		if (sdev->current_queue_depth == 0) {
-			goto out_bail;
-		}
 		init_waitqueue_head(&sdev->scpnt_wait);
 
 		if (shost->hostt->slave_alloc)
@@ -515,7 +513,6 @@
 	} else if (sdev->request_queue)
 		scsi_free_queue(sdev->request_queue);
 
-	scsi_release_commandblocks(sdev);
 	kfree(sdev);
 	return NULL;
 }
@@ -535,7 +532,6 @@
 
 	if (sdev->request_queue)
 		scsi_free_queue(sdev->request_queue);
-	scsi_release_commandblocks(sdev);
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
 	if (sdev->inquiry)
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/scsi/scsi_syms.c	Mon Feb 10 10:39:27 2003
@@ -39,8 +39,6 @@
 EXPORT_SYMBOL(scsicam_bios_param);
 EXPORT_SYMBOL(scsi_partsize);
 EXPORT_SYMBOL(scsi_bios_ptable);
-EXPORT_SYMBOL(scsi_allocate_device);
-EXPORT_SYMBOL(scsi_do_cmd);
 EXPORT_SYMBOL(scsi_ioctl);
 EXPORT_SYMBOL(print_command);
 EXPORT_SYMBOL(print_sense);
@@ -50,7 +48,6 @@
 EXPORT_SYMBOL(scsi_sense_key_string);
 EXPORT_SYMBOL(scsi_extd_sense_format);
 EXPORT_SYMBOL(kernel_scsi_ioctl);
-EXPORT_SYMBOL(scsi_release_command);
 EXPORT_SYMBOL(print_Scsi_Cmnd);
 EXPORT_SYMBOL(scsi_block_when_processing_errors);
 EXPORT_SYMBOL(scsi_ioctl_send_command);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/scsi_sysfs.c	Mon Feb 10 10:39:24 2003
@@ -210,8 +210,7 @@
  * Create the actual show/store functions and data structures.
  */
 sdev_rd_attr (device_blocked, "%d\n");
-sdev_rd_attr (current_queue_depth, "%d\n");
-sdev_rd_attr (new_queue_depth, "%d\n");
+sdev_rd_attr (queue_depth, "%d\n");
 sdev_rd_attr (type, "%d\n");
 sdev_rd_attr (scsi_level, "%d\n");
 sdev_rd_attr (access_count, "%d\n");
@@ -222,8 +221,7 @@
 
 static struct device_attribute * const sdev_attrs[] = {
 	&dev_attr_device_blocked,
-	&dev_attr_current_queue_depth,
-	&dev_attr_new_queue_depth,
+	&dev_attr_queue_depth,
 	&dev_attr_type,
 	&dev_attr_scsi_level,
 	&dev_attr_access_count,
diff -Nru a/drivers/scsi/scsiiom.c b/drivers/scsi/scsiiom.c
--- a/drivers/scsi/scsiiom.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/scsi/scsiiom.c	Mon Feb 10 10:39:23 2003
@@ -1591,15 +1591,15 @@
 	       //dc390_Going_remove (pDCB, pSRB);
 	       dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
 	       
-	       if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
-		  ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) )
+	       if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
+		  ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) )
 		 pACB->scan_devices = 0;
 	    }
 	    else
 	    {
 	        /* device present: add */
-		if( (pcmd->target == pACB->pScsiHost->max_id - 1) && 
-		    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
+		if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && 
+		    (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
 		    pACB->scan_devices = END_SCAN ;
 	        /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
 	    }
@@ -1624,8 +1624,8 @@
 	     dc390_add_dev (pACB, pDCB, ptr);
 	     if (pACB->scan_devices) pACB->DeviceCnt++;
 	  }
-	if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
-	    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
+	if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
+	    (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
 	  pACB->scan_devices = 0;
      };
 
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/scsi/sg.c	Mon Feb 10 10:39:26 2003
@@ -19,7 +19,7 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
-static char *sg_version_str = "Version: 3.5.27 (20020812)";
+static char *sg_version_str = "Version: 3.5.27 (20030130)";
 #endif
 static int sg_version_num = 30527;	/* 2 digits for each component */
 /*
@@ -842,7 +842,7 @@
 			__put_user((int) sdp->device->type, &sg_idp->scsi_type);
 			__put_user((short) sdp->device->host->cmd_per_lun,
 				   &sg_idp->h_cmd_per_lun);
-			__put_user((short) sdp->device->new_queue_depth,
+			__put_user((short) sdp->device->queue_depth,
 				   &sg_idp->d_queue_depth);
 			__put_user(0, &sg_idp->unused[0]);
 			__put_user(0, &sg_idp->unused[1]);
@@ -1455,9 +1455,9 @@
 	sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
 
 	memset(&sdp->sg_driverfs_dev, 0, sizeof (struct device));
-	sprintf(sdp->sg_driverfs_dev.bus_id, "%s:gen",
+	snprintf(sdp->sg_driverfs_dev.bus_id, BUS_ID_SIZE, "%s:gen",
 		scsidp->sdev_driverfs_dev.bus_id);
-	sprintf(sdp->sg_driverfs_dev.name, "%sgeneric",
+	snprintf(sdp->sg_driverfs_dev.name, DEVICE_NAME_SIZE, "%sgeneric",
 		scsidp->sdev_driverfs_dev.name);
 	sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
 	sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus;
@@ -2982,7 +2982,7 @@
 				   scsidp->host->host_no, scsidp->channel,
 				   scsidp->id, scsidp->lun, (int) scsidp->type,
 				   (int) scsidp->access_count,
-				   (int) scsidp->new_queue_depth,
+				   (int) scsidp->queue_depth,
 				   (int) scsidp->device_busy,
 				   (int) scsidp->online);
 		else
diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
--- a/drivers/scsi/sim710.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/scsi/sim710.c	Mon Feb 10 10:39:31 2003
@@ -22,96 +22,41 @@
  * Some multiboard fixes from Rolf Eike Beer.
  * Auto probing of EISA config space from Trevor Hemsley.
  *
- * Various bits of code in this driver have been copied from 53c7,8xx,c,
- * which is coyright Drew Eckhardt.  The scripts for the SCSI chip are
- * compiled with the script compiler written by Drew.
- *
- * This is a simple driver for the NCR53c710.  More complex drivers
- * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
- * do DMA block moves between memory and on-chip registers, which can
- * be a problem if those registers are in the I/O address space.  There
- * can also be problems on hardware where the registers are memory
- * mapped, if the design is such that memory-to-memory transfers initiated
- * by the scsi chip cannot access the chip registers.
- *
- * This driver is designed to avoid these problems and is intended to
- * work with any Intel machines using 53c710 chips, including various
- * Compaq and NCR machines.  It was initially written for the Tadpole
- * TP34V VME board which is 68030 based.
- *
- * The driver supports boot-time parameters similar to
- *	sim710=addr:0x9000,irq:15
- * and insmod parameters similar to
- *	sim710="addr:0x9000 irq:15"
- *
- * Multiple controllers can also be set up by command line, provided the
- * addr: parameter is specified first for each controller.  e.g.
- *      sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
- *
- * To seperate the different options, ' ', '+', and ',' can be used, except
- * that ',' can not be used in module parameters.  ' ' can be a pain, because
- * it needs to be quoted, which causes problems with some installers.
- * The command line above is completely equivalent to
- *      sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
- *
- * The complete list of options are:
- *
- * addr:0x9000		Specifies the base I/O port (or address) of the 53C710.
- * irq:15		Specifies the IRQ number used by the 53c710.
- * debug:0xffff		Generates lots of debug output.
- * ignore:0x0a		Makes the driver ignore SCSI IDs 0 and 2.
- * nodisc:0x70		Prevents disconnects from IDs 6, 5 and 4.
- * noneg:0x10		Prevents SDTR negotiation on ID 4.
- * disabled:1		Completely disables the driver. When present, overrides
- *			all other options.
- *
- * The driver will auto-probe chip addresses and IRQs now, so typically no
- * parameters are needed.  Auto-probing of addresses is disabled if any addr:
- * parameters are specified.
- *
- * Current limitations:
- *
- * o  Async only
- * o  Severely lacking in error recovery
- * o  'debug:' should be per host really.
+ * Rewritten to use 53c700.c by James.Bottomley@SteelEye.com
  *
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/device.h>
 #include <linux/init.h>
+#ifdef CONFIG_MCA
 #include <linux/mca.h>
-#include <linux/interrupt.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/byteorder.h>
-#include <linux/blk.h>
+#endif
+#ifdef CONFIG_EISA
+#include <linux/eisa.h>
+#endif
 
-/* All targets are I/O mapped at the moment */
-#define IO_MAPPED
+#include "scsi.h"
+#include "hosts.h"
+#include "53c700.h"
 
-#if defined(CONFIG_MCA)
+/* Must be enough for both EISA and MCA */
+#define MAX_SLOTS 8
+static __u8 __initdata id_array[MAX_SLOTS] = { [0 ... MAX_SLOTS-1] = 7 };
+
+/* info is used to communicate global data across the driver register
+ * because the struct device_driver doesn't have any info fields.  Sigh */
+struct sim710_info {
+	Scsi_Host_Template *tpnt;
+	int found;
+};
 
-/*
- * For each known microchannel card using the 53c710 we need a list
- * of possible IRQ and IO settings, as well as their corresponding
- * bit assignment in pos[].  This might get cumbersome if there
- * are more than a few cards (I only know of 2 at this point).
- */
+static __initdata struct sim710_info sim710_global_info;
 
-#define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f }
+#if defined(CONFIG_MCA)
 
 /* CARD ID 01BB and 01BA use the same pos values */
 
@@ -130,63 +75,6 @@
 
 #endif
 
-#include "scsi.h"
-#include "hosts.h"
-#include "sim710.h"
-
-#include<linux/stat.h>
-
-#define DEBUG
-#undef DEBUG_LIMIT_INTS		/* Define to 10 to hang driver after 10 ints */
-
-/* Debug options available via the "debug:0x1234" parameter		*/
-
-#define DEB_NONE	0x0000	/* Nothing				*/
-#define DEB_HALT	0x0001	/* Detailed trace of chip halt funtion	*/
-#define DEB_REGS	0x0002	/* All chip register read/writes	*/
-#define DEB_SYNC	0x0004	/* Sync/async negotiation		*/
-#define DEB_PMM		0x0008	/* Phase mis-match handling		*/
-#define DEB_INTS	0x0010	/* General interrupt trace		*/
-#define DEB_TOUT	0x0020	/* Selection timeouts			*/
-#define DEB_RESUME	0x0040	/* Resume addresses for the script	*/
-#define DEB_CMND	0x0080	/* Commands and status returned		*/
-#define DEB_FIXUP	0x0100	/* Fixup of scsi addresses		*/
-#define DEB_DISC	0x0200	/* Disconnect/reselect handling		*/
-
-#define DEB_ANY		0xffff	/* Any and all debug options		*/
-
-#ifdef DEBUG
-#define DEB(m,x) if (sim710_debug & m) x
-int sim710_debug;
-#else
-#define DEB(m,x)
-#endif
-
-/* Redefine scsi_done to force renegotiation of (a)sync transfers
- * following any failed command.
- */
-
-#define SCSI_DONE(cmd)	{ \
-	DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
-		host->host_no, cmd->result)); \
-	if (cmd->result) \
-	    hostdata->negotiate |= (1 << cmd->target); \
-	cmd->scsi_done(cmd); \
-    }
-
-#ifndef offsetof
-#define offsetof(t, m)      ((size_t) (&((t *)0)->m))
-#endif
-
-#define STATE_INITIALISED	0
-#define STATE_HALTED		1
-#define STATE_IDLE		2
-#define STATE_BUSY		3
-#define STATE_DISABLED		4
-
-#define MAXBOARDS 4	/* Increase this and the sizes of the
-			   arrays below, if you need more.. */
-
 #ifdef MODULE
 
 char *sim710;		/* command line passed by insmod */
@@ -199,1583 +87,294 @@
 
 #endif
 
-static int sim710_errors;		/* Count of error interrupts */
-static int sim710_intrs;		/* Count of all interrupts */
-static int ignore_ids[MAXBOARDS];	/* Accept all SCSI IDs */
-static int opt_nodisc[MAXBOARDS];	/* Allow disconnect on all IDs */
-static int opt_noneg[MAXBOARDS];	/* Allow SDTR negotiation on all IDs */
-static int hostdata_order;		/* Encoded size of hostdata for free_pages() */
-static int no_of_boards;		/* Actual number of boards/chips */
-static unsigned int bases[MAXBOARDS];	/* Base addresses of chips */
-static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */
-
-/* The SCSI Script!!! */
-
-#include "sim710_d.h"
-
-/* Now define offsets in the DSA, as (A_dsa_xxx/4) */
-
-#define DSA_SELECT	(A_dsa_select/4)
-#define DSA_MSGOUT	(A_dsa_msgout/4)
-#define DSA_CMND	(A_dsa_cmnd/4)
-#define DSA_STATUS	(A_dsa_status/4)
-#define DSA_MSGIN	(A_dsa_msgin/4)
-#define DSA_DATAIN	(A_dsa_datain/4)
-#define DSA_DATAOUT	(A_dsa_dataout/4)
-#define DSA_SIZE	(A_dsa_size/4)
-
-#define MAX_SG		128	/* Scatter/Gather elements */
-
-#define MAX_MSGOUT	8
-#define MAX_MSGIN	8
-#define MAX_CMND	12
-#define MAX_STATUS	1
-
-struct sim710_hostdata{
-    int state;
-    Scsi_Cmnd * issue_queue;
-    Scsi_Cmnd * running;
-    int chip;
-    u8 negotiate;
-    u8 reselected_identify;
-    u8 msgin_buf[MAX_MSGIN];
-    u8 msg_reject;
-    u32 test1_src __attribute__ ((aligned (4)));
-    u32 test1_dst;
-
-    struct sim710_target {
-	Scsi_Cmnd *cur_cmd;
-	u32 resume_offset;
-	u32 data_in_jump;
-	u32 data_out_jump;
-	u32 dsa[DSA_SIZE];		/* SCSI Script DSA area */
-	u8  dsa_msgout[MAX_MSGOUT];
-	u8  dsa_msgin[MAX_MSGIN];
-	u8  dsa_cdb[MAX_CMND];
-	u8  dsa_status[MAX_STATUS];
-    } target[8];
-
-    u32 script[sizeof(SCRIPT)/4] __attribute__ ((aligned (4)));
-};
-
-
-/* Template to request asynchronous transfers */
-
-static const unsigned char async_message[] = {
-    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */};
-
-
-static void sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
-static void do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
-static __inline__ void run_process_issue_queue(struct sim710_hostdata *);
-static void process_issue_queue (struct sim710_hostdata *, unsigned long flags);
-static int full_reset(struct Scsi_Host * host);
-
-
-/*
- * Function : static void ncr_dump (struct Scsi_Host *host)
- *
- * Purpose :  Dump (possibly) useful info
- *
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void
-ncr_dump (struct Scsi_Host *host)
-{
-    unsigned long flags;
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-       host->hostdata[0];
-
-    save_flags(flags);
-    cli();
-    printk("scsi%d: Chip register contents:\n", host->host_no);
-    printk(" (script at virt %p, bus %lx)\n",
-           hostdata->script, virt_to_bus(hostdata->script));
-    printk(" 00  sien:  %02x  sdid:  %02x  scntl1:%02x  scntl0:%02x\n"
-	   " 04  socl:  %02x  sodl:  %02x  sxfer: %02x  scid:  %02x\n"
-	   " 08  sbcl:  %02x  sbdl:  %02x  sidl:  %02x  sfbr:  %02x\n"
-	   " 0C  sstat2:%02x  sstat1:%02x  sstat0:%02x  dstat: %02x\n"
-	   " 10  dsa:   %08x\n"
-	   " 14  ctest3:%02x  ctest2:%02x  ctest1:%02x  ctest0:%02x\n"
-	   " 18  ctest7:%02x  ctest6:%02x  ctest5:%02x  ctest4:%02x\n"
-	   " 1C  temp:  %08x\n"
-	   " 20  lcrc:  %02x  ctest8:%02x  istat: %02x  dfifo: %02x\n"
-	   " 24  dbc:   %08x  dnad:  %08x  dsp:   %08x\n"
-	   " 30  dsps:  %08x  scratch:%08x\n"
-	   " 38  dcntl: %02x  dwt:   %02x  dien:  %02x  dmode: %02x\n"
-	   " 3C  adder: %08x\n",
-	  NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG),
-	  NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG),
-	  NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG),
-	  NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG),
-	  NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG),
-	  NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG),
-	  NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG),
-	  NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG),
-	  NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG),
-	  NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG),
-	  NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG),
-	  NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG),
-	  NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG),
-	  NCR_read32(ADDER_REG));
-
-    restore_flags(flags);
-}
-
-
-/*
- * Function: int param_setup(char *str)
- */
+#ifdef MODULE
+#define ARG_SEP ' '
+#else
+#define ARG_SEP ','
+#endif
 
 __init int
 param_setup(char *str)
 {
-    char *cur = str;
-    char *p, *pc, *pv;
-    int val;
-    int c;
-
-    no_of_boards = 0;
-    while (no_of_boards < MAXBOARDS && cur != NULL &&
-		(pc = strchr(cur, ':')) != NULL) {
-	char *pe;
-
-	val = 0;
-	pv = pc;
-	c = *++pv;
+	char *pos = str, *next;
+	int slot = -1;
 
-	val = (int) simple_strtoul(pv, &pe, 0);
+	while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
+		int val = (int)simple_strtoul(++next, NULL, 0);
 
-	if (!strncmp(cur, "addr:", 5)) {
-	    bases[no_of_boards++] = val;
-	}
-#ifdef DEBUG
-	else if (!strncmp(cur, "debug:", 6)) {
-	    sim710_debug = val;
-	}
-#endif
-	else if (no_of_boards == 0) {
-	    printk("sim710: Invalid parameters, addr: must come first\n");
-	    no_of_boards = -1;
-	    return 1;
-	}
-	else if	(!strncmp(cur, "irq:", 4))
-	    irq_vectors[no_of_boards-1] = val;
-	else if	(!strncmp(cur, "ignore:", 7))
-	    ignore_ids[no_of_boards-1] = val;
-	else if	(!strncmp(cur, "nodisc:", 7))
-	    opt_nodisc[no_of_boards-1] = val;
-	else if	(!strncmp(cur, "noneg:", 6))
-	    opt_noneg[no_of_boards-1] = val;
-	else if	(!strncmp(cur, "disabled:", 9)) {
-	    no_of_boards = -1;
-	    return 1;
-	}
-	else {
-	    printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
-	    no_of_boards = -1;
-	    return 1;
+		if(!strncmp(pos, "slot:", 5))
+			slot = val;
+		else if(!strncmp(pos, "id:", 3)) {
+			if(slot == -1) {
+				printk(KERN_WARNING "sim710: Must specify slot for id parameter\n");
+			} else if(slot > MAX_SLOTS) {
+				printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val);
+			} else {
+				id_array[slot] = val;
+			}
+		}
+		if((pos = strchr(pos, ARG_SEP)) != NULL)
+			pos++;
 	}
-
-	/* Allow ',', ' ', or '+' seperators.  Used to be ',' at boot and
-	 * ' ' for module load, some installers crap out on the space and
-	 * insmod doesn't like the comma.
-	 */
-       if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) ||
-               (p = strchr(cur, '+')))
-           cur = p + 1;
-        else
-           break;
-    }
-    return 1;
+	return 1;
 }
 
 #ifndef MODULE
 __setup("sim710=", param_setup);
 #endif
 
-
-/*
- * Function: static const char *sbcl_to_phase (int sbcl)
- */
-
-static const char *
-sbcl_to_phase (int sbcl) {
-    switch (sbcl & SBCL_PHASE_MASK) {
-    case SBCL_PHASE_DATAIN:
-	return "DATAIN";
-    case SBCL_PHASE_DATAOUT:
-	return "DATAOUT";
-    case SBCL_PHASE_MSGIN:
-	return "MSGIN";
-    case SBCL_PHASE_MSGOUT:
-	return "MSGOUT";
-    case SBCL_PHASE_CMDOUT:
-	return "CMDOUT";
-    case SBCL_PHASE_STATIN:
-	return "STATUSIN";
-    default:
-	return "unknown";
-    }
-}
-
-
-/*
- * Function : static int ncr_halt (struct Scsi_Host *host)
- *
- * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
- *
- * Inputs : host - SCSI chip to halt
- *
- * Returns : 0 on success
- */
-
-static int
-ncr_halt (struct Scsi_Host *host)
-{
-    unsigned long flags;
-    unsigned char istat, tmp;
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-	host->hostdata[0];
-    int stage;
-    int timeout;
-    int res = 0;
-
-    save_flags(flags);
-    cli();
-    /* Stage 0 : eat all interrupts
-       Stage 1 : set ABORT
-       Stage 2 : eat all but abort interrupts
-       Stage 3 : eat all interrupts
-       We loop for 50000 times with a delay of 10us which should give us
-       about half a second.
-     */
-    for (stage = 0, timeout = 50000; timeout; timeout--) {
-	if (stage == 1) {
-	    DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n"));
-	    NCR_write8(ISTAT_REG, ISTAT_ABRT);
-	    ++stage;
-	}
-	istat = NCR_read8 (ISTAT_REG);
-	if (istat & ISTAT_SIP) {
-	    DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat));
-	    tmp = NCR_read8(SSTAT0_REG);
-	    DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp));
-	} else if (istat & ISTAT_DIP) {
-	    DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat));
-	    tmp = NCR_read8(DSTAT_REG);
-	    DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp));
-	    if (stage == 2) {
-		if (tmp & DSTAT_ABRT) {
-	    	    DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
-		    NCR_write8(ISTAT_REG, 0);
-		    ++stage;
-		} else {
-		    res = 1;
-		    break;
-	    	}
-    	    }
-	}
-	if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
-	    if (stage == 0)
-	    	++stage;
-	    else if (stage == 3)
-		break;
-	}
-	udelay(10);
-    }
-    restore_flags(flags);
-
-    if (timeout == 0 || res) {
-	printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no);
-	return 1;
-    }
-    else {
-	hostdata->state = STATE_HALTED;
-	return 0;
-    }
-}
-
-/*
- * Function : static void sim710_soft_reset (struct Scsi_Host *host)
- *
- * Purpose :  perform a soft reset of the NCR53c7xx chip
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : sim710_init must have been called for this
- *      host.
- *
- */
-
-static void
-sim710_soft_reset (struct Scsi_Host *host)
-{
-    unsigned long flags;
-
-    save_flags(flags);
-    cli();
-    /*
-     * Do a soft reset of the chip so that everything is
-     * reinitialized to the power-on state.
-     *
-     * Basically follow the procedure outlined in the NCR53c700
-     * data manual under Chapter Six, How to Use, Steps Necessary to
-     * Start SCRIPTS, with the exception of actually starting the
-     * script and setting up the synchronous transfer gunk.
-     */
-
-    /* XXX Should we reset the scsi bus here? */
-
-    NCR_write8(SCNTL1_REG, SCNTL1_RST);		/* Reset the bus */
-    udelay(50);
-    NCR_write8(SCNTL1_REG, 0);
-
-    udelay(500);
-
-    NCR_write8(ISTAT_REG, ISTAT_10_SRST);	/* Reset the chip */
-    udelay(50);
-    NCR_write8(ISTAT_REG, 0);
-
-    mdelay(1000);				/* Let devices recover */
-
-    NCR_write32(SCRATCH_REG, 0);
-    NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3);
-    NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD);
-    NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2);
-    NCR_write8(SCID_REG, 1 << host->this_id);
-    NCR_write8(SBCL_REG, 0);
-    NCR_write8(SXFER_REG, 0);
-    NCR_write8(SCNTL1_REG, SCNTL1_ESR_700);
-    NCR_write8(SCNTL0_REG, SCNTL0_EPC | SCNTL0_EPG_700 | SCNTL0_ARB1 |
-		SCNTL0_ARB2);
-
-    NCR_write8(DIEN_REG, DIEN_700_BF |
-		DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC);
-
-    NCR_write8(SIEN_REG_700,
-	    SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
-
-    restore_flags(flags);
-}
-
-
-/*
- * Function : static void sim710_driver_init (struct Scsi_Host *host)
- *
- * Purpose : Initialize internal structures, as required on startup, or
- *	after a SCSI bus reset.
- *
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void
-sim710_driver_init (struct Scsi_Host *host)
-{
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-	host->hostdata[0];
-    int i;
-
-    hostdata->running = NULL;
-    memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT));
-    for (i = 0; i < PATCHES; i++)
-	hostdata->script[LABELPATCHES[i]] += isa_virt_to_bus(hostdata->script);
-    patch_abs_32 (hostdata->script, 0, reselected_identify, 
-    	isa_virt_to_bus((void *)&(hostdata->reselected_identify)));
-    patch_abs_32 (hostdata->script, 0, msgin_buf, 
-    	isa_virt_to_bus((void *)&(hostdata->msgin_buf[0])));
-    patch_abs_32 (hostdata->script, 0, msg_reject,
-	isa_virt_to_bus((void *)&(hostdata->msg_reject)));
-    patch_abs_32 (hostdata->script, 0, test1_src,
-	isa_virt_to_bus((void *)&(hostdata->test1_src)));
-    patch_abs_32 (hostdata->script, 0, test1_dst,
-	isa_virt_to_bus((void *)&(hostdata->test1_dst)));
-    hostdata->state = STATE_INITIALISED;
-    hostdata->negotiate = 0xff;
-}
-
-
-/* Handle incoming Synchronous data transfer request.  If our negotiate
- * flag is set then this is a response to our request, otherwise it is
- * spurious request from the target.  Don't really expect target initiated
- * SDTRs, because we always negotiate on the first command.  Could still
- * get them though..
- * The chip is currently paused with ACK asserted on the last byte of the
- * SDTR.
- * resa is the resume address if the message is in response to our outgoing
- * SDTR.  Only possible on initial identify.
- * resb is the resume address if the message exchange is initiated by the
- * target.
- */
-
-static u32
-handle_sdtr (struct Scsi_Host * host, Scsi_Cmnd * cmd, u32 resa, u32 resb)
-{
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
-    struct sim710_target *targdata = hostdata->target + cmd->target;
-    u32 resume_offset;
-
-    if (resa && hostdata->negotiate & (1 << cmd->target)) {
-	DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n",
-		host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
-	/* We always issue an SDTR with the identify, so we must issue
-	 * the CDB next.
-	 */
-	resume_offset = resa;
-	hostdata->negotiate &= ~(1 << cmd->target);
-    }
-    else {
-	DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
-		host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
-	memcpy(targdata->dsa_msgout, async_message, sizeof(async_message));
-	targdata->dsa[DSA_MSGOUT] = sizeof(async_message);
-	/* I guess the target could do this anytime; we have to send our
-	 * response, and then continue (sending the CDB if not already done).
-	 */
-	resume_offset = resb;
-    }
-    return resume_offset;
-}
-
-
-/*
- * Function : static int datapath_residual (Scsi_Host *host)
- *
- * Purpose : return residual data count of what's in the chip.
- *
- * Inputs : host - SCSI host
- */
-
-static int
-datapath_residual (struct Scsi_Host *host) {
-    int count, synchronous, sstat;
-    unsigned int ddir;
-
-    count = ((NCR_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
-	(NCR_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
-    synchronous = NCR_read8 (SXFER_REG) & SXFER_MO_MASK;
-    ddir = NCR_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
-
-    if (ddir) {
-    /* Receive */
-	if (synchronous) 
-	    count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
-	else
-	    if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF)
-		++count;
-    } else {
-    /* Send */
-	sstat = NCR_read8 (SSTAT1_REG);
-	if (sstat & SSTAT1_OLF)
-	    ++count;
-	if (synchronous && (sstat & SSTAT1_ORF))
-	    ++count;
-    }
-    return count;
-}
-
-
-static u32
-handle_idd (struct Scsi_Host * host, Scsi_Cmnd * cmd)
+__init int
+sim710_probe_common(struct device *dev, unsigned long base_addr,
+		    int irq, int clock, int differential, int scsi_id)
 {
-    struct sim710_hostdata *hostdata =
-		(struct sim710_hostdata *)host->hostdata[0];
-    struct sim710_target *targdata = hostdata->target + cmd->target;
-    u32 resume_offset = 0, index;
-
-    index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
-
-    switch (index) {
-    case Ent_wait_disc_complete/4 + 2:
-	cmd->result = targdata->dsa_status[0];
-        SCSI_DONE(cmd);
-	targdata->cur_cmd = NULL;
-	resume_offset = Ent_reselect;
-	break;
-    case Ent_wait_disc2/4 + 2:
-	/* Disconnect after command - just wait for a reselect */
-	targdata->resume_offset = Ent_resume_msgin2a;
-	resume_offset = Ent_reselect;
-	break;
-    case Ent_wait_disc3/4 + 2:
-	/* Disconnect after the data phase */
-	targdata->resume_offset = Ent_resume_msgin3a;
-	resume_offset = Ent_reselect;
-	break;
-    case Ent_wait_disc1/4 + 2:
-	/* Disconnect before command - not expected */
-	targdata->resume_offset = Ent_resume_msgin1a;
-	resume_offset = Ent_reselect;
-	break;
-    default:
-	printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
-		host->host_no, index);
-	sim710_errors++;
-	/* resume_offset is zero, which will cause host reset */
-    }
-    return resume_offset;
-}
+	struct Scsi_Host * host = NULL;
+	struct NCR_700_Host_Parameters *hostdata =
+		kmalloc(sizeof(struct NCR_700_Host_Parameters),	GFP_KERNEL);
 
+	printk(KERN_NOTICE "sim710: %s\n", dev->name);
+	printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n",
+	       irq, clock, base_addr, scsi_id);
 
-/* Handle a phase mismatch.
- */
-
-static u32
-handle_phase_mismatch (struct Scsi_Host * host, Scsi_Cmnd * cmd)
-{
-    struct sim710_hostdata *hostdata =
-		(struct sim710_hostdata *)host->hostdata[0];
-    struct sim710_target *targdata = hostdata->target + cmd->target;
-    u32 resume_offset = 0, index;
-    unsigned char sbcl;
-
-    sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
-    index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
-
-    DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
-	host->host_no, sbcl_to_phase(sbcl), sbcl, index));
-    DEB(DEB_PMM, print_command(cmd->cmnd));
-
-    if (index == Ent_done_ident/4) {
-	/* Sending initial message out - probably rejecting our sync
-	 * negotiation request.
-	 */
-	NCR_write8(SOCL_REG, 0);	/* Negate ATN */
-	if (sbcl == SBCL_PHASE_MSGIN)
-	    resume_offset = Ent_resume_rej_ident;
-	else if (sbcl == SBCL_PHASE_CMDOUT) {
-	    /* Some old devices (SQ555) switch to cmdout after the first
-	     * byte of an identify message, regardless of whether we
-	     * have more bytes to send!
-	     */
-	    printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
-		host->host_no);
-	    resume_offset = Ent_resume_cmd;
+	if(hostdata == NULL) {
+		printk(KERN_ERR "sim710: Failed to allocate host data\n");
+		goto out;
 	}
-	else if (sbcl == SBCL_PHASE_STATIN) {
-	    /* Some devices do this on parity error, at least */
-	    printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n",
-		host->host_no);
-	    resume_offset = Ent_end_data_trans;
-	}
-	else {
-	    printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
-		host->host_no, sbcl_to_phase(sbcl));
-	    /* resume_offset is zero, which will cause a host reset */
-	}
-	hostdata->negotiate &= ~(1 << cmd->target);
-    }
-    else if (index > Ent_patch_input_data/4 &&
-		index < Ent_patch_output_data/4) {
-	/* DataIn transfer phase */
-	u32 sg_id, oaddr, olen, naddr, nlen;
-	int residual;
-
-	sg_id = (index - Ent_patch_input_data/4 - 4) / 2;
-	targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
-		isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_id * 2 + 2);
-	olen  = targdata->dsa[DSA_DATAIN + sg_id * 2];
-	oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1];
-	residual = datapath_residual (host);
-	if (residual)
-	    printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
-		host->host_no, residual);
-	naddr = NCR_read32(DNAD_REG) - residual;
-	nlen  = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
-	DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
-		host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
-	if (oaddr+olen != naddr+nlen) {
-	    printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
-		host->host_no, oaddr, olen, naddr, nlen);
-	}
-	else {
-	    targdata->dsa[DSA_DATAIN + sg_id * 2]     = nlen;
-	    targdata->dsa[DSA_DATAIN + sg_id * 2 + 1] = naddr;
-	    resume_offset = Ent_resume_pmm;
-	}
-    }
-    else if (index > Ent_patch_output_data/4 &&
-		index <= Ent_end_data_trans/4) {
-	/* Dataout transfer phase */
-	u32 sg_id, oaddr, olen, naddr, nlen;
-	int residual;
-
-	sg_id = (index - Ent_patch_output_data/4 - 4) / 2;
-	targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
-		isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_id * 2 + 2);
-	olen  = targdata->dsa[DSA_DATAOUT + sg_id * 2];
-	oaddr = targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1];
-	residual = datapath_residual (host);
-	naddr = NCR_read32(DNAD_REG) - residual;
-	nlen  = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
-	DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
-		host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
-	if (oaddr+olen != naddr+nlen) {
-	    printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
-		host->host_no, oaddr, olen, naddr, nlen);
-	}
-	else {
-	    targdata->dsa[DSA_DATAOUT + sg_id * 2]     = nlen;
-	    targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1] = naddr;
-	    resume_offset = Ent_resume_pmm;
-	}
-    }
-    else if (sbcl == SBCL_PHASE_STATIN) {
-	/* Change to Status In at some random point; probably wants to report a
-	 * parity error or similar.
-	 */
-	printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
-		host->host_no, index);
-	resume_offset = Ent_end_data_trans;
-    }
-    else {
-	printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
-		host->host_no, sbcl_to_phase(sbcl), index);
-	/* resume_offset is zero, which will cause a host reset */
-    }
-    /* Flush DMA FIFO */
-    NCR_write8 (CTEST8_REG, CTEST8_10_CLF);
-    while (NCR_read8 (CTEST8_REG) & CTEST8_10_CLF);
-
-    return resume_offset;
-}
-
-
-static u32
-handle_script_int(struct Scsi_Host * host, Scsi_Cmnd * cmd)
-{
-    struct sim710_hostdata *hostdata =
-		(struct sim710_hostdata *)host->hostdata[0];
-    struct sim710_target *targdata = hostdata->target + cmd->target;
-    u32 dsps, resume_offset = 0;
-    unsigned char sbcl;
-
-    dsps = NCR_read32(DSPS_REG);
-
-    switch (dsps) {
-    case A_int_cmd_complete:
-	cmd->result = targdata->dsa_status[0];
-        SCSI_DONE(cmd);
-	targdata->cur_cmd = NULL;
-	resume_offset = Ent_reselect;
-	break;
-    case A_int_msg_sdtr1:
-	resume_offset = handle_sdtr(host, cmd,
-		Ent_resume_msgin1a, Ent_resume_msgin1b);
-	break;
-    case A_int_msg_sdtr2:
-	resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin2b);
-	break;
-    case A_int_msg_sdtr3:
-	resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin3b);
-	break;
-    case A_int_disc1:
-	/* Disconnect before command - not expected */
-	targdata->resume_offset = Ent_resume_msgin1a;
-	resume_offset = Ent_reselect;
-	break;
-    case A_int_disc2:
-	/* Disconnect after command - just wait for a reselect */
-	targdata->resume_offset = Ent_resume_msgin2a;
-	resume_offset = Ent_reselect;
-	break;
-    case A_int_disc3:
-	/* Disconnect after the data phase */
-	targdata->resume_offset = Ent_resume_msgin3a;
-	resume_offset = Ent_reselect;
-	break;
-    case A_int_reselected:
-	hostdata->script[Ent_patch_output_data/4+1] = targdata->data_out_jump;
-	hostdata->script[Ent_patch_input_data/4+1] = targdata->data_in_jump;
-	NCR_write32(DSA_REG, isa_virt_to_bus(targdata->dsa));
-	resume_offset = targdata->resume_offset;
-	break;
-    case A_int_data_bad_phase:
-	sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
-	printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
-		host->host_no, sbcl_to_phase(sbcl), sbcl);
-	break;
-    case A_int_bad_msg1:
-    case A_int_bad_msg2:
-    case A_int_bad_msg3:
-    case A_int_cmd_bad_phase:
-    case A_int_no_msgout1:
-    case A_int_no_msgout2:
-    case A_int_no_msgout3:
-    case A_int_not_cmd_complete:
-    case A_int_sel_no_ident:
-    case A_int_sel_not_cmd:
-    case A_int_status_not_msgin:
-    case A_int_resel_not_msgin:
-    case A_int_selected:
-    case A_int_not_rej:
-    default:
-	sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
-	printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
-		host->host_no, dsps, sbcl_to_phase(sbcl));
-	sim710_errors++;
-	/* resume_offset is zero, which will cause a host reset */
-    }
-    return resume_offset;
-}
-
-
-/* A quick wrapper for sim710_intr_handle to grab the spin lock */
-
-static void
-do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct Scsi_Host *host = dev_id;
-    unsigned long flags;
+	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
 
-    spin_lock_irqsave(host->host_lock, flags);
-    sim710_intr_handle(irq, host, regs);
-    spin_unlock_irqrestore(host->host_lock, flags);
-}
-
-
-/* A "high" level interrupt handler */
-
-static void
-sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct Scsi_Host * host = (struct Scsi_Host *)dev_id;
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
-    Scsi_Cmnd * cmd;
-    unsigned char istat, dstat;
-    unsigned char sstat0;
-    u32 scratch, dsps, resume_offset = 0;
-
-    istat = NCR_read8(ISTAT_REG);
-    if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
-	return;
-    else {
-	sim710_intrs++;
-	dsps = NCR_read32(DSPS_REG);
-	hostdata->state = STATE_HALTED;
-	sstat0 = dstat = 0;
-	scratch = NCR_read32(SCRATCH_REG);
-	if (istat & ISTAT_SIP) {
-	    sstat0 = NCR_read8(SSTAT0_REG);
-	}
-	if (istat & ISTAT_DIP) {
-	    udelay(10);		/* Some comment somewhere about 10cycles
-				 * between accesses to sstat0 and dstat ??? */
-	    dstat = NCR_read8(DSTAT_REG);
-	}
-	DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
-		"dstat %02x, dsp [%04x], scratch %02x\n",
-	    host->host_no, sim710_intrs, istat, sstat0, dstat,
-	    (u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
-	    scratch));
-	if (scratch & 0x100) {
-	    u8 *p = hostdata->msgin_buf;
-	    
-	    DEB(DEB_INTS, printk("  msgin_buf: %02x %02x %02x %02x\n",
-			p[0], p[1], p[2], p[3]));
-	}
-	if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) {
-	    /* Reselected.  Identify the target from LCRC_REG, and
-	     * update current command.  If we were trying to select
-	     * a device, then that command needs to go back on the
-	     * issue_queue for later.
-	     */
-	    unsigned char lcrc = NCR_read8(LCRC_REG_10);
-	    int id = 0;
-
-	    if (!(lcrc & 0x7f)) {
-		printk("scsi%d: Reselected with LCRC = %02x\n",
-			host->host_no, lcrc);
-		cmd = NULL;
-	    }
-	    else {
-		while (!(lcrc & 1)) {
-		    id++;
-		    lcrc >>= 1;
-		}
-		DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n",
-			host->host_no, id));
-		if (hostdata->running) {
-		    /* Clear SIGP */
-		    (void)NCR_read8(CTEST2_REG_700);
-
-		    DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted "
-				"by reselect from %d (%p)\n",
-				host->host_no, hostdata->running->target,
-				id, hostdata->target[id].cur_cmd));
-		    cmd = hostdata->running;
-		    hostdata->target[cmd->target].cur_cmd = NULL;
-		    cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
-		    hostdata->issue_queue = cmd;
-		}
-		cmd = hostdata->running = hostdata->target[id].cur_cmd;
-	    }
+	if(request_region(base_addr, 64, "sim710") == NULL) {
+		printk(KERN_ERR "sim710: Failed to reserve IO region 0x%lx\n",
+		       base_addr);
+		goto out_free;
 	}
-	else
-	    cmd = hostdata->running;
 
-	if (!cmd) {
-	    printk("scsi%d: No active command!\n", host->host_no);
-	    printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
-		"dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
-		host->host_no, sim710_intrs, istat, sstat0, dstat,
-		(u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
-		NCR_read32(SCRATCH_REG), dsps);
-	    /* resume_offset is zero, which will cause a host reset */
-	}
-	else if (sstat0 & SSTAT0_700_STO) {
-	    DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no));
-	    cmd->result = DID_NO_CONNECT << 16;
-	    SCSI_DONE(cmd);
-	    hostdata->target[cmd->target].cur_cmd = NULL;
-	    resume_offset = Ent_reselect;
-	}
-	else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
-	    printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
-			    sstat0);
-	    sim710_errors++;
-	    /* resume_offset is zero, which will cause a host reset */
-	}
-	else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) {
-	    printk("scsi%d: Serious error, dstat = %02x\n", host->host_no,
-			    dstat);
-	    sim710_errors++;
-	    /* resume_offset is zero, which will cause a host reset */
-	}
-	else if (dstat & DSTAT_SIR)
-	    resume_offset = handle_script_int(host, cmd);
-	else if (sstat0 & SSTAT0_MA)
-	    resume_offset = handle_phase_mismatch(host, cmd);
-	else if (dstat & DSTAT_IID) {
-	    /* This can be due to a quick reselect while doing a WAIT
-	     * DISCONNECT.
-	     */
-	    resume_offset = handle_idd(host, cmd);
-	}
-	else {
-	    sim710_errors++;
-	    printk("scsi%d: Spurious interrupt!\n", host->host_no);
-	    /* resume_offset is zero, which will cause a host reset */
-	}
-    }
+	/* Fill in the three required pieces of hostdata */
+	hostdata->base = base_addr;
+	hostdata->differential = differential;
+	hostdata->clock = clock;
+	hostdata->chip710 = 1;
 
-    if (resume_offset) {
-	if (resume_offset == Ent_reselect) {
-	    hostdata->running = NULL;
-	    hostdata->state = STATE_IDLE;
+	/* and register the chip */
+	if((host = NCR_700_detect(sim710_global_info.tpnt, hostdata)) == NULL) {
+		printk(KERN_ERR "sim710: No host detected; card configuration problem?\n");
+		goto out_release;
 	}
-	else
-	    hostdata->state = STATE_BUSY;
-	DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n",
-		host->host_no, resume_offset/4));
-#ifdef DEBUG_LIMIT_INTS
-	if (sim710_intrs < DEBUG_LIMIT_INTS)
-#endif
-	{
-	    NCR_write32(SCRATCH_REG, 0);
-	    NCR_write32(DSP_REG,
-		    isa_virt_to_bus(hostdata->script+resume_offset/4));
-	}
-	if (resume_offset == Ent_reselect)
-	    run_process_issue_queue(hostdata);
-    }
-    else {
-	printk("scsi%d: Failed to handle interrupt.  Failing commands "
-		"and resetting SCSI bus and chip\n", host->host_no);
-	mdelay(1000);		/* Give chance to read screen!! */
-	full_reset(host);
-    }
-
-}
 
+	host->irq = irq;
+	host->this_id = scsi_id;
 
-static void
-run_command (struct sim710_hostdata *hostdata, Scsi_Cmnd *cmd)
-{
-    struct Scsi_Host *host = cmd->host;
-    struct sim710_target *targdata = hostdata->target + cmd->target;
-    int i, datain, dataout, sg_start;
-    u32 *dip, *dop, dsa;
-
-    DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no,
-		cmd->target));
-    DEB(DEB_CMND, print_command(cmd->cmnd));
-
-    switch (cmd->cmnd[0]) {
-    case INQUIRY:
-    case MODE_SENSE:
-    case READ_6:
-    case READ_10:
-    case READ_CAPACITY:
-    case REQUEST_SENSE:
-    case READ_BLOCK_LIMITS:
-    case READ_TOC:
-        datain = 1;
-	dataout = 0;
-        break;
-    case MODE_SELECT:
-    case WRITE_6:
-    case WRITE_10:
-        datain = 0;
-        dataout = 1;
-        break;
-    case TEST_UNIT_READY:
-    case ALLOW_MEDIUM_REMOVAL:
-    case START_STOP:
-        datain = dataout = 0;
-        break;
-    default:
-        datain = dataout = 1;
-    }
-
-    memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND);
-
-    targdata->dsa_msgout[0] =
-		IDENTIFY((opt_nodisc[hostdata->chip] & (1<<cmd->target)) ? 0 : 1 ,0);
-    if (hostdata->negotiate & (1 << cmd->target)) {
-	if (opt_noneg[hostdata->chip] & (1 << cmd->target)) {
-	    hostdata->negotiate ^= (1 << cmd->target);
-	    targdata->dsa[DSA_MSGOUT] = 1;
-	}
-	else {
-	    DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers "
-		"for ID %d\n",
-		host->host_no, cmd->target));
-	    memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message));
-	    targdata->dsa[DSA_MSGOUT] = sizeof(async_message) + 1;
-	}
-    }
-    else
-	targdata->dsa[DSA_MSGOUT] = 1;
-
-    targdata->dsa_msgin[0] = 0xff;
-    targdata->dsa_status[0] = 0xff;
-
-    targdata->dsa[DSA_SELECT]		= (1 << cmd->target) << 16;
-    targdata->dsa[DSA_MSGOUT+1]		= isa_virt_to_bus(targdata->dsa_msgout);
-    targdata->dsa[DSA_CMND]		= cmd->cmd_len;
-    targdata->dsa[DSA_CMND+1]		= isa_virt_to_bus(targdata->dsa_cdb);
-    targdata->dsa[DSA_STATUS]		= 1;
-    targdata->dsa[DSA_STATUS+1]		= isa_virt_to_bus(targdata->dsa_status);
-    targdata->dsa[DSA_MSGIN]		= 1;
-    targdata->dsa[DSA_MSGIN+1]		= isa_virt_to_bus(targdata->dsa_msgin);
-
-    sg_start = (MAX_SG - (cmd->use_sg ? cmd->use_sg : 1)) * 2;
-    dip = targdata->dsa + DSA_DATAIN + sg_start;
-    dop = targdata->dsa + DSA_DATAOUT + sg_start;
-
-    for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; i++) {
-	struct scatterlist *sgl = &((struct scatterlist *)cmd->buffer)[i];
-	void *vbuf = cmd->use_sg ?
-		(page_address(sgl->page) + sgl->offset) :
-		(cmd->request_buffer);
-	u32 bbuf = isa_virt_to_bus(vbuf);
-	u32 cnt = cmd->use_sg ? sgl->length : cmd->request_bufflen;
-
-	if (datain) {
-	    *dip++	= cnt;
-	    *dip++	= bbuf;
-	}
-	if (dataout) {
-	    *dop++	= cnt;
-	    *dop++	= bbuf;
+	if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "sim710", host)) {
+		printk(KERN_ERR "sim710: irq problem with %d, detaching\n",
+		       irq);
+		goto out_unregister;
 	}
-    }
-    targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
-	isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_start + 2);
-    targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
-	isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_start + 2);
-
-    for (i = 0, dsa = isa_virt_to_bus(targdata->dsa); i < 4; i++) {
-	u32 v = hostdata->script[Ent_patch_new_dsa/4 + i * 2];
-
-	v &= ~0x0000ff00;
-	v |= (dsa & 0xff) << 8;
-	hostdata->script[Ent_patch_new_dsa/4 + i * 2] = v;
-	dsa >>= 8;
-    }
-    hostdata->running = targdata->cur_cmd = cmd;
-    hostdata->state = STATE_BUSY;
 
-    NCR_write8(ISTAT_REG, ISTAT_10_SIGP);
-}
-
-
-static volatile int process_issue_queue_running = 0;
- 
-static __inline__ void 
-run_process_issue_queue(struct sim710_hostdata *hostdata)
-{
-    unsigned long flags;
-    save_flags (flags);
-    cli();
-    if (!process_issue_queue_running) {
-	process_issue_queue_running = 1;
-	process_issue_queue(hostdata, flags);
-	/*
-	 * process_issue_queue_running is cleared in process_issue_queue
-	 * once it can't do more work, and process_issue_queue exits with
-	 * interrupts disabled.
-	 */
-    }
-    restore_flags (flags);
-}
+	scsi_set_device(host, dev);
+	hostdata->dev = dev;
 
+	sim710_global_info.found++;
 
-/*
- * Function : process_issue_queue (hostdata, flags)
- *
- * Purpose : Start next command for any idle target.
- * 
- * NOTE : process_issue_queue exits with interrupts *disabled*, so the 
- *	caller must reenable them if it desires.
- * 
- * NOTE : process_issue_queue should be called from both 
- *	sim710_queue_command() and from the interrupt handler 
- *	after command completion.
- */
-
-static void 
-process_issue_queue (struct sim710_hostdata *hostdata, unsigned long flags)
-{
-    Scsi_Cmnd *tmp, *prev;
-    int done;
-
-    /*
-     * We run (with interrupts disabled) until we're sure that none of 
-     * the host adapters have anything that can be done, at which point 
-     * we set process_issue_queue_running to 0 and exit.
-     *
-     * Interrupts are enabled before doing various other internal 
-     * instructions, after we've decided that we need to run through
-     * the loop again.
-     *
-     */
-
-    do {
-	cli(); /* Freeze request queues */
-	done = 1;
-	if (hostdata->issue_queue) {
-	    if (hostdata->state == STATE_DISABLED) {
-		tmp = (Scsi_Cmnd *) hostdata->issue_queue;
-		hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
-		tmp->result = (DID_BAD_TARGET << 16);
-		tmp->scsi_done (tmp);
-		done = 0;
-	    }
-	    else if (hostdata->state == STATE_IDLE) {
-		for (tmp = hostdata->issue_queue, prev = NULL; tmp;
-				prev = tmp, tmp = (Scsi_Cmnd *) tmp->SCp.ptr) {
-		    if (hostdata->target[tmp->target].cur_cmd == NULL) {
-			if (prev)
-			    prev->SCp.ptr = tmp->SCp.ptr;
-			else
-			    hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
-			tmp->SCp.ptr = NULL;
-			run_command (hostdata, tmp);
-			done = 0;
-		    } /* if target/lun is not busy */
-		} /* scan issue queue for work */
-	    } /* host is idle */
-	} /* if hostdata->issue_queue */
-	if (!done)
-	    restore_flags (flags);
-    } while (!done);
-    process_issue_queue_running = 0;
-}
-
-
-int
-sim710_queuecommand(Scsi_Cmnd * cmd, void (*done)(Scsi_Cmnd *))
-{
-    struct Scsi_Host *host = cmd->host;
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
-    Scsi_Cmnd *tmp;
-    unsigned long flags;
-
-    if (cmd->lun) {
-	/* Silently ignore luns other than zero! */
-	cmd->result = (DID_BAD_TARGET << 16);
-	done(cmd);
-	return 0;
-    }
-
-    DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no,
-		cmd->target));
-    DEB(DEB_CMND, print_command(cmd->cmnd));
-
-    cmd->scsi_done = done;
-    cmd->host_scribble = NULL;
-    cmd->SCp.ptr = NULL;
-    cmd->SCp.buffer = NULL;
-
-    save_flags(flags);
-    cli();
-
-    if (ignore_ids[hostdata->chip] & (1 << cmd->target)) {
-	printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target);
-	cmd->result = (DID_BAD_TARGET << 16);
-	done(cmd);
-	restore_flags (flags);
-	return 0;
-    }
-#ifdef DEBUG_LIMIT_INTS
-    if (sim710_intrs > DEBUG_LIMIT_INTS) {
-	cmd->result = (DID_BAD_TARGET << 16);
-	done(cmd);
-	restore_flags (flags);
 	return 0;
-    }
-#endif
-    if (cmd->use_sg > MAX_SG)
-	panic ("cmd->use_sg = %d\n", cmd->use_sg);
 
-    if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-        cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
-        hostdata->issue_queue = cmd;
-    } else {
-        for (tmp = hostdata->issue_queue; tmp->SCp.ptr;
-                tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
-        tmp->SCp.ptr = (unsigned char *) cmd;
-    }
-    restore_flags (flags);
-    run_process_issue_queue(hostdata);
-    return 0;
+ out_unregister:
+	scsi_unregister(host);
+ out_release:
+	release_region(host->base, 64);
+ out_free:
+	kfree(hostdata);
+ out:
+	return -ENODEV;
 }
 
+#ifdef CONFIG_MCA
+static short sim710_mca_id_table[] = { 0x01bb, 0x01ba, 0x004f, 0};
 
 __init int
-sim710_detect(Scsi_Host_Template * tpnt)
+sim710_mca_probe(struct device *dev)
 {
-    unsigned char scsi_id;
-    unsigned int base_addr;
-    struct Scsi_Host * host = NULL;
-    struct sim710_hostdata *hostdata;
-    unsigned long timeout;
-    unsigned long irq_mask;
-    int requested_irq;
-    int probed_irq;
-    u32 dsps;
-    int chips = 0;
-    int limit;
-    int indx;
-    int revision;
-    int size;
-    volatile u8 tmp;
-    struct Scsi_Host *our_hosts[MAXBOARDS+1];
-
-#ifdef MODULE
-    if (sim710)
-	param_setup(sim710);
-#endif
-
-    if (no_of_boards < 0) {
-	printk("sim710: NCR53C710 driver disabled\n");
-	return 0;
-    }
-
-#ifdef CONFIG_MCA
-    /* If board details have been specified via boot/module parameters,
-     * then don't bother probing.
-     */
-    if (no_of_boards == 0) {
-	int slot;
+	struct mca_device *mca_dev = to_mca_device(dev);
+	int slot = mca_dev->slot;
 	int pos[3];
-	int mca_53c710_ids[] = MCA_53C710_IDS;
-	int *id_to_check = mca_53c710_ids;
+	unsigned int base;
+	int irq_vector;
+	short id = sim710_mca_id_table[mca_dev->index];
 	static int io_004f_by_pos[] = MCA_004F_IO_PORTS;
 	static int irq_004f_by_pos[] = MCA_004F_IRQS;
 	static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS;
 	static int irq_01bb_by_pos[] = MCA_01BB_IRQS;
+	char *name;
+	int clock;
 
-	while ( *id_to_check && no_of_boards < MAXBOARDS) {
-	    if (!MCA_bus)
-		return 0;
-
-	    if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) {
-
-		pos[0] = mca_read_stored_pos(slot, 2);
-		pos[1] = mca_read_stored_pos(slot, 3);
-		pos[2] = mca_read_stored_pos(slot, 4);
-
-		/*
-		 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
-		 *
-		 *    000000  <disabled>   001010  0x2800
-		 *    000001  <invalid>    001011  0x2C00
-		 *    000010  0x0800       001100  0x3000
-		 *    000011  0x0C00       001101  0x3400
-		 *    000100  0x1000       001110  0x3800
-		 *    000101  0x1400       001111  0x3C00
-		 *    000110  0x1800       010000  0x4000
-		 *    000111  0x1C00       010001  0x4400
-		 *    001000  0x2000       010010  0x4800
-		 *    001001  0x2400       010011  0x4C00
-		 *                         010100  0x5000
-		 *
-		 * 00F4 port base by bits 3,2,1 in pos[0]
-		 *
-		 *    000  <disabled>      001    0x200
-		 *    010  0x300           011    0x400
-		 *    100  0x500           101    0x600
-		 *
-		 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
-		 *
-		 *    00   3               10   11
-		 *    01   5               11   14
-		 *
-		 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
-		 *
-		 *    100   5              101    9
-		 *    110   14
-		 */
-
-		if ( *id_to_check == 0x01bb || *id_to_check == 0x01ba ) {
-		    bases[no_of_boards] = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
-		    irq_vectors[no_of_boards] =
-				irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
-		    if (bases[no_of_boards] == 0x0000)
-			printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
-		    else {
-			no_of_boards++;
-			if ( *id_to_check == 0x01bb )
-			    mca_set_adapter_name( slot,
-				    "NCR 3360/3430 SCSI SubSystem" );
-			else
-			    mca_set_adapter_name(slot,
-				    "NCR Dual SIOP SCSI Host Adapter Board");
-		    }
-		}
-		else if ( *id_to_check == 0x004f ) {
-		    bases[no_of_boards] = io_004f_by_pos[((pos[0] & 0x0E) >> 1)];
-		    irq_vectors[no_of_boards] =
-				irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
-		    if (bases[no_of_boards] == 0x0000)
-			printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
-		    else {
-			no_of_boards++;
-			mca_set_adapter_name(slot,
-				"NCR 53c710 SCSI Host Adapter Board");
-		    }
-		}
-	    }
-	    id_to_check++;
-	}
-    }
-#endif
+	pos[0] = mca_device_read_stored_pos(mca_dev, 2);
+	pos[1] = mca_device_read_stored_pos(mca_dev, 3);
+	pos[2] = mca_device_read_stored_pos(mca_dev, 4);
+
+	/*
+	 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
+	 *
+	 *    000000  <disabled>   001010  0x2800
+	 *    000001  <invalid>    001011  0x2C00
+	 *    000010  0x0800       001100  0x3000
+	 *    000011  0x0C00       001101  0x3400
+	 *    000100  0x1000       001110  0x3800
+	 *    000101  0x1400       001111  0x3C00
+	 *    000110  0x1800       010000  0x4000
+	 *    000111  0x1C00       010001  0x4400
+	 *    001000  0x2000       010010  0x4800
+	 *    001001  0x2400       010011  0x4C00
+	 *                         010100  0x5000
+	 *
+	 * 00F4 port base by bits 3,2,1 in pos[0]
+	 *
+	 *    000  <disabled>      001    0x200
+	 *    010  0x300           011    0x400
+	 *    100  0x500           101    0x600
+	 *
+	 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
+	 *
+	 *    00   3               10   11
+	 *    01   5               11   14
+	 *
+	 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
+	 *
+	 *    100   5              101    9
+	 *    110   14
+	 */
+
+	if (id == 0x01bb || id == 0x01ba) {
+		base = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
+		irq_vector =
+			irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
+
+		clock = 50;
+		if (id == 0x01bb)
+			name = "NCR 3360/3430 SCSI SubSystem";
+		else
+			name = "NCR Dual SIOP SCSI Host Adapter Board";
+	} else if ( id == 0x004f ) {
+		base = io_004f_by_pos[((pos[0] & 0x0E) >> 1)];
+		irq_vector =
+			irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
+		clock = 50;
+		name = "NCR 53c710 SCSI Host Adapter Board";
+	} else {
+		return -ENODEV;
+	}
+	strncpy(dev->name, name, sizeof(dev->name));
+	mca_device_set_claim(mca_dev, 1);
+	base = mca_device_transform_ioport(mca_dev, base);
+	irq_vector = mca_device_transform_irq(mca_dev, irq_vector);
+
+	return sim710_probe_common(dev, base, irq_vector, clock,
+				   0, id_array[slot]);
+}
+
+struct mca_driver sim710_mca_driver = {
+	.id_table = sim710_mca_id_table,
+	.driver = {
+		.name = "sim710",
+		.bus = &mca_bus_type,
+		.probe = sim710_mca_probe,
+	},
+};
+
+#endif /* CONFIG_MCA */
 
 #ifdef CONFIG_EISA
-    /* Auto probe, if no boards specified in boot parameters */
-    if (no_of_boards == 0) {
-	int io_addr;
-	/* reverse probe, so my on-board controller at 0x9000 is always scsi0 */
-	for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) {
-	    if (request_region(io_addr, 0x40, "sim710") != NULL) {
-		int id0 = inw(io_addr + 0xc80);
-		int id1 = inw(io_addr + 0xc82);
-		/* The on-board controller on my Proliant 2000 is 0x1044,
-		 * my EISA card is 0x1144.
-		 */
-		if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) {
-		    bases[no_of_boards] = io_addr;
+struct eisa_device_id sim710_eisa_ids[] = {
+	{ "CPQ4410" },
+	{ "CPQ4411" },
+	{ "HWP0C80" },
+	{ "" }
+};
+
+__init int
+sim710_eisa_probe(struct device *dev)
+{
+	struct eisa_device *edev = to_eisa_device(dev);
+	unsigned long io_addr = edev->base_addr;
+	char eisa_cpq_irqs[] = { 11, 14, 15, 10, 9, 0 };
+	char eisa_hwp_irqs[] = { 3, 4, 5, 7, 12, 10, 11, 0};
+	char *eisa_irqs;
+	unsigned char irq_index;
+	unsigned char irq, differential = 0, scsi_id = 7;
+
+	if(strcmp(edev->id.sig, "HWP0C80") == 0) {
+		eisa_irqs =  eisa_hwp_irqs;
+		irq_index = (inb(io_addr + 0xc85) & 0x7) - 1;
 #if 0
-		    /* This should detect the IRQ, but I havn't proved it for
-		     * myself.  Leave the old probe code active for now, as
-		     * no-one has reported problems with it.
-		     */
-		    switch (inb(io_addr + 0xc88)) {
-			case (0x00):
-			    irq_vectors[no_of_boards] = 11;
-			    break;
-			case (0x01):
-			    irq_vectors[no_of_boards] = 14;
-			    break;
-			case (0x02):
-			    irq_vectors[no_of_boards] = 15;
-			    break;
-			case (0x03):
-			    irq_vectors[no_of_boards] = 10;
-			    break;
-			case (0x04):
-			    irq_vectors[no_of_boards] = 9;
-			    break;
-			default:
-			    printk("sim710.c: irq nasty\n");
-		    }
-#endif
-		    no_of_boards++;
-		}
-		release_region(io_addr, 64);
-	    }
-	}
-    }
+		/* this doesn't seem to work at the moment */
+		scsi_id = ffs(inb(io_addr + 0x4));
 #endif
-      
-    if (!no_of_boards) {
-	printk("sim710: No NCR53C710 adapter found.\n");
-	return 0;
-    }
-
-    size = sizeof(struct sim710_hostdata);
-    hostdata_order = 0;
-    while (size > (PAGE_SIZE << hostdata_order))
-	hostdata_order++;
-    size = PAGE_SIZE << hostdata_order;
-
-    DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n",
-	sizeof(struct sim710_hostdata), size, hostdata_order));
-
-    tpnt->proc_name = "sim710";
-
-    memset(our_hosts, 0, sizeof(our_hosts));
-    for (indx = 0; indx < no_of_boards; indx++) {
-        unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order);
-        if(page == 0UL)
-        {
-		printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
-		break;
-        }
-	host = scsi_register(tpnt, 4);
-	if(host == NULL) {
-	    free_pages(host->hostdata[0], hostdata_order);
-	    break;
-	}
-	our_hosts[chips] = host;
-	host->hostdata[0] = page;
-	hostdata = (struct sim710_hostdata *)host->hostdata[0];
-	memset(hostdata, 0, size);
-	scsi_id = 7;
-	base_addr = bases[indx];
-	requested_irq = irq_vectors[indx];
-	printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
-			host->host_no, scsi_id, base_addr, requested_irq);
-	DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
-			hostdata, sizeof(struct sim710_hostdata),
-			 hostdata->target[0].dsa));
-	hostdata->chip = indx;
-	host->irq = requested_irq;
-	host->this_id = scsi_id;
-	host->unique_id = base_addr;
-	host->base = base_addr;
-	hostdata->msg_reject = MESSAGE_REJECT;
-
-	if (ncr_halt(host)) {
-	    free_pages(host->hostdata[0], hostdata_order);
-	    scsi_unregister (host);
-	    printk("scsi%d: Failed to initialise 53c710 at address %x\n",
-			host->host_no, base_addr);
-	    continue;
-	}
-	DEB(DEB_ANY,ncr_dump(host));
-	revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4;
-	printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
-	sim710_soft_reset(host);
-
-	sim710_driver_init(host);
-
-	request_region((u32)host->base, 64, "sim710");
-	/* Now run test1 */
-	hostdata->test1_src = 0x53c710aa;
-	hostdata->test1_dst = 0x76543210;
-	NCR_write32(DSPS_REG, 0x89abcdef);
-	irq_mask = probe_irq_on();
-	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4));
-	timeout = 5;
-	while (hostdata->test1_dst != hostdata->test1_src && timeout--)
-	    mdelay(100);
-	tmp = NCR_read8(ISTAT_REG);
-	tmp = NCR_read8(SSTAT0_REG);
-	udelay(10);
-	tmp = NCR_read8(DSTAT_REG);
-	probed_irq = probe_irq_off(irq_mask);
-	if (requested_irq == 0) {
-	    if (probed_irq > 0) {
-		printk("scsi%d: Chip is using IRQ %d\n", host->host_no,
-			probed_irq);
-		requested_irq = host->irq = probed_irq;
-	    }
-	    else {
-		printk("scsi%d: Failed to probe for IRQ (returned %d)\n",
-			host->host_no, probed_irq);
-		ncr_halt(host);
-		free_pages(host->hostdata[0], hostdata_order);
-		scsi_unregister (host);
-		release_region((u32)host->base, 64);
-		continue;
-	    }
+	} else {
+		eisa_irqs = eisa_cpq_irqs;
+		irq_index = inb(io_addr + 0xc88);
 	}
-	else if (probed_irq > 0 && probed_irq != requested_irq)
-	    printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n",
-			host->host_no, requested_irq, probed_irq);
-	else if (probed_irq <= 0)
-	    printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n",
-			host->host_no, probed_irq);
-	
-	dsps = NCR_read32(DSPS_REG);
-	if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) {
-	    if (hostdata->test1_dst != 0x53c710aa)
-		printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
-			host->host_no, hostdata->test1_dst);
-	    if (dsps != A_int_test1)
-		printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
-			host->host_no, A_int_test1, dsps);
-	    ncr_dump(host);
-	    ncr_halt(host);
-	    free_pages(host->hostdata[0], hostdata_order);
-	    scsi_unregister (host);
-	    release_region((u32)host->base, 64);
-	    continue;
-	}
-	printk("scsi%d: test 1 completed ok.\n", host->host_no);
 
-	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
-	hostdata->state = STATE_IDLE;
-	chips++;
-    }
-    /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...).
-     * Couldn't call request_irq earlier, as probing would have failed.
-     */
-    for (indx = 0, limit = chips; indx < limit; indx++) {
-	host = our_hosts[indx];
-	if (request_irq(host->irq, do_sim710_intr_handle,
-                       SA_INTERRUPT | SA_SHIRQ, "sim710", host))
-	{
-	    printk("scsi%d : IRQ%d not free, detaching\n",
-			host->host_no, host->irq);
-	    ncr_halt(host);
-	    free_pages(host->hostdata[0], hostdata_order);
-	    scsi_unregister (host);
-	    chips--;
+	if(irq_index >= strlen(eisa_irqs)) {
+		printk("sim710.c: irq nasty\n");
+		return -ENODEV;
 	}
-    }
-
-    return chips;
-}
-
-int
-sim710_abort(Scsi_Cmnd * cmd)
-{
-    struct Scsi_Host * host = cmd->host;
 
-    printk("scsi%d: Unable to abort command for target %d\n",
-	   host->host_no, cmd->target);
-    return FAILED;
+	irq = eisa_irqs[irq_index];
+		
+	return sim710_probe_common(dev, io_addr, irq, 50,
+				   differential, scsi_id);
 }
 
-/*
- * This is a device reset.  Need to select and send a Bus Device Reset msg.
- */
+struct eisa_driver sim710_eisa_driver = {
+	.id_table = sim710_eisa_ids,
+	.driver = {
+		.name =		"sim710",
+		.probe =	sim710_eisa_probe,
+		.remove =	__devexit_p(sim710_device_remove),
+	},
+};
 
-int
-sim710_dev_reset(Scsi_Cmnd * SCpnt)
-{
-    struct Scsi_Host * host = SCpnt->host;
+#endif /* CONFIG_EISA */
 
-    printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
-	   host->host_no, SCpnt->target);
-    return FAILED;
-}
-
-/*
- * This is bus reset.  We need to reset the bus and fail any active commands.
- */
 
 int
-sim710_bus_reset(Scsi_Cmnd * SCpnt)
+sim710_release(struct Scsi_Host *host)
 {
-    struct Scsi_Host * host = SCpnt->host;
+	struct D700_Host_Parameters *hostdata = 
+		(struct D700_Host_Parameters *)host->hostdata[0];
 
-    printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no);
-    return FAILED;
+	NCR_700_release(host);
+	kfree(hostdata);
+	free_irq(host->irq, host);
+	/* should do a refcount here and unregister the drivers when
+	 * it reaches zero */
+	return 1;
 }
 
-static int
-full_reset(struct Scsi_Host * host)
+int __init
+sim710_detect(Scsi_Host_Template *tpnt)
 {
-    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
-	    host->hostdata[0];
-    int target;
-    Scsi_Cmnd *cmd;
-
-    u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch;
-    unsigned long flags;
-
-    save_flags(flags);
-    cli();
-
-    istat = NCR_read8(ISTAT_REG);
-    if (istat & ISTAT_SIP) {
-	sstat0 = NCR_read8(SSTAT0_REG);
-	sstat1 = NCR_read8(SSTAT1_REG);
-	udelay(10);
-    }
-    if (istat & ISTAT_DIP)
-	dstat = NCR_read8(DSTAT_REG);
-
-    if (ncr_halt(host)) {
-	restore_flags(flags);
-	return FAILED;
-    }
-    restore_flags(flags);
-    dsp = NCR_read32(DSP_REG);
-    dsps = NCR_read32(DSPS_REG);
-    scratch = NCR_read32(SCRATCH_REG);
-    printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
-		host->host_no, istat, sstat0, sstat1, dstat);
-    printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
-		host->host_no, dsp,
-		((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch);
-
-    for (target = 0; target < 7; target++) {
-	if ((cmd = hostdata->target[target].cur_cmd)) {
-	    printk("scsi%d: Failing command for ID%d\n",
-			host->host_no, target);
-	    cmd->result = DID_RESET << 16;
-	    cmd->scsi_done(cmd);
-	    hostdata->target[target].cur_cmd = NULL;
-	}
-    }
-
-    sim710_soft_reset(host);
-    sim710_driver_init(host);
-
-    NCR_write32(DSP_REG, isa_virt_to_bus(hostdata->script+Ent_reselect/4));
-    hostdata->state = STATE_IDLE;
-
-    run_process_issue_queue(hostdata);
-
-    return SUCCESS;
-}
-
-/*
- * This is host reset.  We need to reset the chip and the bus.
- */
-
-int
-sim710_host_reset(Scsi_Cmnd * SCpnt)
-{
-    struct Scsi_Host * host = SCpnt->host;
-
-    printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no);
-
-    return full_reset(host);
-}
+	sim710_global_info.tpnt = tpnt;
+	sim710_global_info.found = 0;
 
 #ifdef MODULE
+	if (sim710)
+		param_setup(sim710);
+#endif
 
-int
-sim710_release(struct Scsi_Host *host)
-{
-    ncr_halt(host);
-    free_pages(host->hostdata[0], hostdata_order);
-    free_irq(host->irq, host);
-    release_region((u32)host->base, 64);
-    return 1;
-}
+#ifdef CONFIG_MCA
+	if(MCA_bus)
+		mca_register_driver(&sim710_mca_driver);
+#endif
 
+#ifdef CONFIG_EISA
+	eisa_driver_register(&sim710_eisa_driver);
 #endif
+	return sim710_global_info.found;
+}
 
-static Scsi_Host_Template driver_template = SIM710_SCSI;
+static Scsi_Host_Template driver_template = {
+	.name =			"LSI (Symbios) 710 MCA/EISA",
+	.proc_name =		"sim710",
+	.detect =		sim710_detect,
+	.release =		sim710_release,
+	.this_id =		7,
+};
 
 #include "scsi_module.c"
diff -Nru a/drivers/scsi/sim710.h b/drivers/scsi/sim710.h
--- a/drivers/scsi/sim710.h	Mon Feb 10 10:39:27 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,851 +0,0 @@
-#ifndef _SIM710_H
-#define _SIM710_H
-
-/*
- * sim710.h - Copyright (C) 1999 Richard Hirst
- */
-
-#include <linux/types.h>
-
-int sim710_detect(Scsi_Host_Template *);
-int sim710_command(Scsi_Cmnd *);
-int sim710_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int sim710_abort(Scsi_Cmnd * SCpnt);
-int sim710_bus_reset(Scsi_Cmnd * SCpnt);
-int sim710_dev_reset(Scsi_Cmnd * SCpnt);
-int sim710_host_reset(Scsi_Cmnd * SCpnt);
-#ifdef MODULE
-int sim710_release(struct Scsi_Host *);
-#else
-#define sim710_release	NULL
-#endif
-
-#include <scsi/scsicam.h>
-
-#define SIM710_SCSI { .proc_name		= "sim710",		\
-		      .name			= "53c710",	 	\
-		      .detect			= sim710_detect,		\
-		      .release			= sim710_release,		\
-		      .queuecommand		= sim710_queuecommand,	\
-		      .eh_abort_handler		= sim710_abort,		\
-		      .eh_device_reset_handler	= sim710_dev_reset,	\
-		      .eh_bus_reset_handler	= sim710_bus_reset,	\
-		      .eh_host_reset_handler	= sim710_host_reset,	\
-		      .can_queue		= 8,		 	\
-		      .this_id			= 7, 			\
-		      .sg_tablesize		= 128,		 	\
-		      .cmd_per_lun		= 1,		 	\
-		      .use_clustering		= DISABLE_CLUSTERING }
-
-#ifndef HOSTS_C
-
-#ifdef __BIG_ENDIAN
-#define	bE	3	/* 0 for little endian, 3 for big endian */
-#else
-#define bE	0
-#endif
-
-/* SCSI control 0 rw, default = 0xc0 */
-#define SCNTL0_REG 		(0x00^bE)
-#define SCNTL0_ARB1		0x80	/* 0 0 = simple arbitration */
-#define SCNTL0_ARB2		0x40	/* 1 1 = full arbitration */
-#define SCNTL0_STRT		0x20	/* Start Sequence */
-#define SCNTL0_WATN		0x10	/* Select with ATN */
-#define SCNTL0_EPC		0x08	/* Enable parity checking */
-/* Bit 2 is reserved on 800 series chips */
-#define SCNTL0_EPG_700		0x04	/* Enable parity generation */
-#define SCNTL0_AAP		0x02	/*  ATN/ on parity error */
-#define SCNTL0_TRG		0x01	/* Target mode */
-
-/* SCSI control 1 rw, default = 0x00 */
-
-#define SCNTL1_REG 		(0x01^bE)
-#define SCNTL1_EXC		0x80	/* Extra Clock Cycle of Data setup */
-#define SCNTL1_ADB		0x40	/*  contents of SODL on bus */
-#define SCNTL1_ESR_700		0x20	/* Enable SIOP response to selection
-					   and reselection */
-#define SCNTL1_CON		0x10	/* Connected */
-#define SCNTL1_RST		0x08	/* SCSI RST/ */
-#define SCNTL1_AESP		0x04	/* Force bad parity */
-#define SCNTL1_SND_700		0x02	/* Start SCSI send */
-#define SCNTL1_IARB_800		0x02	/* Immediate Arbitration, start
-					   arbitration immediately after
-					   busfree is detected */
-#define SCNTL1_RCV_700		0x01	/* Start SCSI receive */
-#define SCNTL1_SST_800		0x01	/* Start SCSI transfer */
-
-/* SCSI control 2 rw, */
-
-#define SCNTL2_REG_800		(0x02^bE)
-#define SCNTL2_800_SDU		0x80	/* SCSI disconnect unexpected */
-
-/* SCSI control 3 rw */
-
-#define SCNTL3_REG_800 		(0x03^bE)
-#define SCNTL3_800_SCF_SHIFT	4
-#define SCNTL3_800_SCF_MASK	0x70
-#define SCNTL3_800_SCF2		0x40	/* Synchronous divisor */
-#define SCNTL3_800_SCF1		0x20	/* 0x00 = SCLK/3 */
-#define SCNTL3_800_SCF0		0x10	/* 0x10 = SCLK/1 */
-					/* 0x20 = SCLK/1.5
-					   0x30 = SCLK/2
-					   0x40 = SCLK/3 */
-
-#define SCNTL3_800_CCF_SHIFT	0
-#define SCNTL3_800_CCF_MASK	0x07
-#define SCNTL3_800_CCF2		0x04	/* 0x00 50.01 to 66 */
-#define SCNTL3_800_CCF1		0x02	/* 0x01 16.67 to 25 */
-#define SCNTL3_800_CCF0		0x01	/* 0x02	25.01 - 37.5
-					   0x03	37.51 - 50
-					   0x04 50.01 - 66 */
-
-/*
- * SCSI destination ID rw - the appropriate bit is set for the selected
- * target ID.  This is written by the SCSI SCRIPTS processor.
- * default = 0x00
- */
-#define SDID_REG_700  		(0x02^bE)
-#define SDID_REG_800  		(0x06^bE)
-
-#define GP_REG_800		(0x07^bE) /* General purpose IO */
-#define GP_800_IO1		0x02
-#define GP_800_IO2		0x01
-
-/* SCSI interrupt enable rw, default = 0x00 */
-#define SIEN_REG_700		(0x03^bE)
-#define SIEN0_REG_800		(0x40^bE)
-#define SIEN_MA			0x80	/* Phase mismatch (ini) or ATN (tgt) */
-#define SIEN_FC			0x40	/* Function complete */
-#define SIEN_700_STO		0x20	/* Selection or reselection timeout */
-#define SIEN_800_SEL		0x20	/* Selected */
-#define SIEN_700_SEL		0x10	/* Selected or reselected */
-#define SIEN_800_RESEL		0x10	/* Reselected */
-#define SIEN_SGE		0x08	/* SCSI gross error */
-#define SIEN_UDC		0x04	/* Unexpected disconnect */
-#define SIEN_RST		0x02	/* SCSI RST/ received */
-#define SIEN_PAR		0x01	/* Parity error */
-
-/*
- * SCSI chip ID rw
- * NCR53c700 :
- * 	When arbitrating, the highest bit is used, when reselection or selection
- * 	occurs, the chip responds to all IDs for which a bit is set.
- * 	default = 0x00
- */
-#define SCID_REG		(0x04^bE)
-/* Bit 7 is reserved on 800 series chips */
-#define SCID_800_RRE		0x40	/* Enable response to reselection */
-#define SCID_800_SRE		0x20	/* Enable response to selection */
-/* Bits four and three are reserved on 800 series chips */
-#define SCID_800_ENC_MASK	0x07	/* Encoded SCSI ID */
-
-/* SCSI transfer rw, default = 0x00 */
-#define SXFER_REG		(0x05^bE)
-#define SXFER_DHP		0x80	/* Disable halt on parity */
-
-#define SXFER_TP2		0x40	/* Transfer period msb */
-#define SXFER_TP1		0x20
-#define SXFER_TP0		0x10	/* lsb */
-#define SXFER_TP_MASK		0x70
-/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */
-#define SXFER_TP_SHIFT		5
-#define SXFER_TP_4		0x00	/* Divisors */
-#define SXFER_TP_5		0x10<<1
-#define SXFER_TP_6		0x20<<1
-#define SXFER_TP_7		0x30<<1
-#define SXFER_TP_8		0x40<<1
-#define SXFER_TP_9		0x50<<1
-#define SXFER_TP_10		0x60<<1
-#define SXFER_TP_11		0x70<<1
-
-#define SXFER_MO3		0x08	/* Max offset msb */
-#define SXFER_MO2		0x04
-#define SXFER_MO1		0x02
-#define SXFER_MO0		0x01	/* lsb */
-#define SXFER_MO_MASK		0x0f
-#define SXFER_MO_SHIFT		0
-
-/*
- * SCSI output data latch rw
- * The contents of this register are driven onto the SCSI bus when
- * the Assert Data Bus bit of the SCNTL1 register is set and
- * the CD, IO, and MSG bits of the SOCL register match the SCSI phase
- */
-#define SODL_REG_700		(0x06^bE)
-#define SODL_REG_800		(0x54^bE)
-
-
-/*
- * SCSI output control latch rw, default = 0
- * Note that when the chip is being manually programmed as an initiator,
- * the MSG, CD, and IO bits must be set correctly for the phase the target
- * is driving the bus in.  Otherwise no data transfer will occur due to
- * phase mismatch.
- */
-
-#define SOCL_REG		(0x07^bE)
-#define SOCL_REQ		0x80	/*  REQ */
-#define SOCL_ACK		0x40	/*  ACK */
-#define SOCL_BSY		0x20	/*  BSY */
-#define SOCL_SEL		0x10	/*  SEL */
-#define SOCL_ATN		0x08	/*  ATN */
-#define SOCL_MSG		0x04	/*  MSG */
-#define SOCL_CD			0x02	/*  C/D */
-#define SOCL_IO			0x01	/*  I/O */
-
-/*
- * SCSI first byte received latch ro
- * This register contains the first byte received during a block MOVE
- * SCSI SCRIPTS instruction, including
- *
- * Initiator mode	Target mode
- * Message in		Command
- * Status		Message out
- * Data in		Data out
- *
- * It also contains the selecting or reselecting device's ID and our
- * ID.
- *
- * Note that this is the register the various IF conditionals can
- * operate on.
- */
-#define SFBR_REG		(0x08^bE)
-
-/*
- * SCSI input data latch ro
- * In initiator mode, data is latched into this register on the rising
- * edge of REQ/. In target mode, data is latched on the rising edge of
- * ACK/
- */
-#define SIDL_REG_700		(0x09^bE)
-#define SIDL_REG_800		(0x50^bE)
-
-/*
- * SCSI bus data lines ro
- * This register reflects the instantaneous status of the SCSI data
- * lines.  Note that SCNTL0 must be set to disable parity checking,
- * otherwise reading this register will latch new parity.
- */
-#define SBDL_REG_700		(0x0a^bE)
-#define SBDL_REG_800		(0x58^bE)
-
-#define SSID_REG_800		(0x0a^bE)
-#define SSID_800_VAL		0x80	/* Exactly two bits asserted at sel */
-#define SSID_800_ENCID_MASK	0x07	/* Device which performed operation */
-
-
-
-/*
- * SCSI bus control lines rw,
- * instantaneous readout of control lines
- */
-#define SBCL_REG		(0x0b^bE)
-#define SBCL_REQ		0x80	/*  REQ ro */
-#define SBCL_ACK		0x40	/*  ACK ro */
-#define SBCL_BSY		0x20	/*  BSY ro */
-#define SBCL_SEL		0x10	/*  SEL ro */
-#define SBCL_ATN		0x08	/*  ATN ro */
-#define SBCL_MSG		0x04	/*  MSG ro */
-#define SBCL_CD			0x02	/*  C/D ro */
-#define SBCL_IO			0x01	/*  I/O ro */
-#define SBCL_PHASE_CMDOUT	SBCL_CD
-#define SBCL_PHASE_DATAIN	SBCL_IO
-#define SBCL_PHASE_DATAOUT	0
-#define SBCL_PHASE_MSGIN	(SBCL_CD|SBCL_IO|SBCL_MSG)
-#define SBCL_PHASE_MSGOUT	(SBCL_CD|SBCL_MSG)
-#define SBCL_PHASE_STATIN	(SBCL_CD|SBCL_IO)
-#define SBCL_PHASE_MASK		(SBCL_CD|SBCL_IO|SBCL_MSG)
-/*
- * Synchronous SCSI Clock Control bits
- * 0 - set by DCNTL
- * 1 - SCLK / 1.0
- * 2 - SCLK / 1.5
- * 3 - SCLK / 2.0
- */
-#define SBCL_SSCF1		0x02	/* wo, -66 only */
-#define SBCL_SSCF0		0x01	/* wo, -66 only */
-#define SBCL_SSCF_MASK		0x03
-
-/*
- * XXX note : when reading the DSTAT and STAT registers to clear interrupts,
- * insure that 10 clocks elapse between the two
- */
-/* DMA status ro */
-#define DSTAT_REG		(0x0c^bE)
-#define DSTAT_DFE		0x80	/* DMA FIFO empty */
-#define DSTAT_800_MDPE		0x40	/* Master Data Parity Error */
-#define DSTAT_BF		0x20	/* Bus Fault */
-#define DSTAT_ABRT		0x10	/* Aborted - set on error */
-#define DSTAT_SSI		0x08	/* SCRIPTS single step interrupt */
-#define DSTAT_SIR		0x04	/* SCRIPTS interrupt received -
-					   set when INT instruction is
-					   executed */
-#define DSTAT_WTD		0x02	/* Watchdog timeout detected */
-#define DSTAT_OPC		0x01	/* Illegal instruction */
-#define DSTAT_IID		0x01	/* Same thing, different name */
-
-
-#define SSTAT0_REG		(0x0d^bE)	/* SCSI status 0 ro */
-#define SIST0_REG_800		(0x42^bE)	/* SCSI status 0 ro */
-#define SSTAT0_MA		0x80	/* ini : phase mismatch,
-					 * tgt : ATN/ asserted
-					 */
-#define SSTAT0_CMP		0x40	/* function complete */
-#define SSTAT0_700_STO		0x20	/* Selection or reselection timeout */
-#define SSTAT0_800_SEL		0x20	/* Selected */
-#define SSTAT0_700_SEL		0x10	/* Selected or reselected */
-#define SIST0_800_RSL		0x10	/* Reselected */
-#define SSTAT0_SGE		0x08	/* SCSI gross error */
-#define SSTAT0_UDC		0x04	/* Unexpected disconnect */
-#define SSTAT0_RST		0x02	/* SCSI RST/ received */
-#define SSTAT0_PAR		0x01	/* Parity error */
-
-#define SSTAT1_REG		(0x0e^bE)	/* SCSI status 1 ro */
-#define SSTAT1_ILF		0x80	/* SIDL full */
-#define SSTAT1_ORF		0x40	/* SODR full */
-#define SSTAT1_OLF		0x20	/* SODL full */
-#define SSTAT1_AIP		0x10	/* Arbitration in progress */
-#define SSTAT1_LOA		0x08	/* Lost arbitration */
-#define SSTAT1_WOA		0x04	/* Won arbitration */
-#define SSTAT1_RST		0x02	/* Instant readout of RST/ */
-#define SSTAT1_SDP		0x01	/* Instant readout of SDP/ */
-
-#define SSTAT2_REG		(0x0f^bE)	/* SCSI status 2 ro */
-#define SSTAT2_FF3		0x80 	/* number of bytes in synchronous */
-#define SSTAT2_FF2		0x40	/* data FIFO */
-#define SSTAT2_FF1		0x20
-#define SSTAT2_FF0		0x10
-#define SSTAT2_FF_MASK		0xf0
-#define SSTAT2_FF_SHIFT		4
-
-/*
- * Latched signals, latched on the leading edge of REQ/ for initiators,
- * ACK/ for targets.
- */
-#define SSTAT2_SDP		0x08	/* SDP */
-#define SSTAT2_MSG		0x04	/* MSG */
-#define SSTAT2_CD		0x02	/* C/D */
-#define SSTAT2_IO		0x01	/* I/O */
-#define SSTAT2_PHASE_CMDOUT	SSTAT2_CD
-#define SSTAT2_PHASE_DATAIN	SSTAT2_IO
-#define SSTAT2_PHASE_DATAOUT	0
-#define SSTAT2_PHASE_MSGIN	(SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-#define SSTAT2_PHASE_MSGOUT	(SSTAT2_CD|SSTAT2_MSG)
-#define SSTAT2_PHASE_STATIN	(SSTAT2_CD|SSTAT2_IO)
-#define SSTAT2_PHASE_MASK	(SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-
-
-#define DSA_REG			0x10	/* DATA structure address */
-
-#define CTEST0_REG_700		(0x14^bE)	/* Chip test 0 ro */
-#define CTEST0_REG_800		(0x18^bE)	/* Chip test 0 ro */
-/* 0x80 - 0x04 are reserved */
-#define CTEST0_700_RTRG		0x02	/* Real target mode */
-#define CTEST0_700_DDIR		0x01	/* Data direction, 1 =
-					 * SCSI bus to host, 0  =
-					 * host to SCSI.
-					 */
-
-#define CTEST1_REG_700		(0x15^bE)	/* Chip test 1 ro */
-#define CTEST1_REG_800		(0x19^bE)	/* Chip test 1 ro */
-#define CTEST1_FMT3		0x80	/* Identify which byte lanes are empty */
-#define CTEST1_FMT2		0x40 	/* in the DMA FIFO */
-#define CTEST1_FMT1		0x20
-#define CTEST1_FMT0		0x10
-
-#define CTEST1_FFL3		0x08	/* Identify which bytes lanes are full */
-#define CTEST1_FFL2		0x04	/* in the DMA FIFO */
-#define CTEST1_FFL1		0x02
-#define CTEST1_FFL0		0x01
-
-#define CTEST2_REG_700		(0x16^bE)	/* Chip test 2 ro */
-#define CTEST2_REG_800		(0x1a^bE)	/* Chip test 2 ro */
-
-#define CTEST2_800_DDIR		0x80	/* 1 = SCSI->host */
-#define CTEST2_800_SIGP		0x40	/* A copy of SIGP in ISTAT.
-					   Reading this register clears */
-#define CTEST2_800_CIO		0x20	/* Configured as IO */.
-#define CTEST2_800_CM		0x10	/* Configured as memory */
-
-/* 0x80 - 0x40 are reserved on 700 series chips */
-#define CTEST2_700_SOFF		0x20	/* SCSI Offset Compare,
-					 * As an initiator, this bit is
-					 * one when the synchronous offset
-					 * is zero, as a target this bit
-					 * is one when the synchronous
-					 * offset is at the maximum
-					 * defined in SXFER
-					 */
-#define CTEST2_700_SFP		0x10	/* SCSI FIFO parity bit,
-					 * reading CTEST3 unloads a byte
-					 * from the FIFO and sets this
-					 */
-#define CTEST2_700_DFP		0x08	/* DMA FIFO parity bit,
-					 * reading CTEST6 unloads a byte
-					 * from the FIFO and sets this
-					 */
-#define CTEST2_TEOP		0x04	/* SCSI true end of process,
-					 * indicates a totally finished
-					 * transfer
-					 */
-#define CTEST2_DREQ		0x02	/* Data request signal */
-/* 0x01 is reserved on 700 series chips */
-#define CTEST2_800_DACK		0x01
-
-/*
- * Chip test 3 ro
- * Unloads the bottom byte of the eight deep SCSI synchronous FIFO,
- * check SSTAT2 FIFO full bits to determine size.  Note that a GROSS
- * error results if a read is attempted on this register.  Also note
- * that 16 and 32 bit reads of this register will cause corruption.
- */
-#define CTEST3_REG_700		(0x17^bE)
-/*  Chip test 3 rw */
-#define CTEST3_REG_800		(0x1b^bE)
-#define CTEST3_800_V3		0x80	/* Chip revision */
-#define CTEST3_800_V2		0x40
-#define CTEST3_800_V1		0x20
-#define CTEST3_800_V0		0x10
-#define CTEST3_800_FLF		0x08	/* Flush DMA FIFO */
-#define CTEST3_800_CLF		0x04	/* Clear DMA FIFO */
-#define CTEST3_800_FM		0x02	/* Fetch mode pin */
-/* bit 0 is reserved on 800 series chips */
-
-#define CTEST4_REG_700		(0x18^bE)	/* Chip test 4 rw */
-#define CTEST4_REG_800		(0x21^bE)	/* Chip test 4 rw */
-/* 0x80 is reserved on 700 series chips */
-#define CTEST4_800_BDIS		0x80	/* Burst mode disable */
-#define CTEST4_ZMOD		0x40	/* High impedance mode */
-#define CTEST4_SZM		0x20	/* SCSI bus high impedance */
-#define CTEST4_700_SLBE		0x10	/* SCSI loopback enabled */
-#define CTEST4_800_SRTM		0x10	/* Shadow Register Test Mode */
-#define CTEST4_700_SFWR		0x08	/* SCSI FIFO write enable,
-					 * redirects writes from SODL
-					 * to the SCSI FIFO.
-					 */
-#define CTEST4_800_MPEE		0x08	/* Enable parity checking
-					   during master cycles on PCI
-					   bus */
-
-/*
- * These bits send the contents of the CTEST6 register to the appropriate
- * byte lane of the 32 bit DMA FIFO.  Normal operation is zero, otherwise
- * the high bit means the low two bits select the byte lane.
- */
-#define CTEST4_FBL2		0x04
-#define CTEST4_FBL1		0x02
-#define CTEST4_FBL0		0x01
-#define CTEST4_FBL_MASK		0x07
-#define CTEST4_FBL_0		0x04	/* Select DMA FIFO byte lane 0 */
-#define CTEST4_FBL_1		0x05	/* Select DMA FIFO byte lane 1 */
-#define CTEST4_FBL_2		0x06	/* Select DMA FIFO byte lane 2 */
-#define CTEST4_FBL_3		0x07	/* Select DMA FIFO byte lane 3 */
-#define CTEST4_800_SAVE		(CTEST4_800_BDIS)
-
-
-#define CTEST5_REG_700		(0x19^bE)	/* Chip test 5 rw */
-#define CTEST5_REG_800		(0x22^bE)	/* Chip test 5 rw */
-/*
- * Clock Address Incrementor.  When set, it increments the
- * DNAD register to the next bus size boundary.  It automatically
- * resets itself when the operation is complete.
- */
-#define CTEST5_ADCK		0x80
-/*
- * Clock Byte Counter.  When set, it decrements the DBC register to
- * the next bus size boundary.
- */
-#define CTEST5_BBCK		0x40
-/*
- * Reset SCSI Offset.  Setting this bit to 1 clears the current offset
- * pointer in the SCSI synchronous offset counter (SSTAT).  This bit
- * is set to 1 if a SCSI Gross Error Condition occurs.  The offset should
- * be cleared when a synchronous transfer fails.  When written, it is
- * automatically cleared after the SCSI synchronous offset counter is
- * reset.
- */
-/* Bit 5 is reserved on 800 series chips */
-#define CTEST5_700_ROFF		0x20
-/*
- * Master Control for Set or Reset pulses. When 1, causes the low
- * four bits of register to set when set, 0 causes the low bits to
- * clear when set.
- */
-#define CTEST5_MASR 		0x10
-#define CTEST5_DDIR		0x08	/* DMA direction */
-/*
- * Bits 2-0 are reserved on 800 series chips
- */
-#define CTEST5_700_EOP		0x04	/* End of process */
-#define CTEST5_700_DREQ		0x02	/* Data request */
-#define CTEST5_700_DACK		0x01	/* Data acknowledge */
-
-/*
- * Chip test 6 rw - writing to this register writes to the byte
- * lane in the DMA FIFO as determined by the FBL bits in the CTEST4
- * register.
- */
-#define CTEST6_REG_700		(0x1a^bE)
-#define CTEST6_REG_800		(0x23^bE)
-
-#define CTEST7_REG		(0x1b^bE)	/* Chip test 7 rw */
-#define CTEST7_10_CDIS		0x80	/* Cache burst disable */
-#define CTEST7_10_SC1		0x40	/* Snoop control bits */
-#define CTEST7_10_SC0		0x20
-#define CTEST7_10_SC_MASK	0x60
-#define CTEST7_STD		0x10	/* Selection timeout disable */
-#define CTEST7_DFP		0x08	/* DMA FIFO parity bit for CTEST6 */
-#define CTEST7_EVP		0x04	/* 1 = host bus even parity, 0 = odd */
-#define CTEST7_10_TT1		0x02	/* Transfer type */
-#define CTEST7_DIFF		0x01	/* Differential mode */
-
-#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF )
-
-
-#define TEMP_REG		0x1c	/* through 0x1f Temporary stack rw */
-
-#define DFIFO_REG		(0x20^bE)	/* DMA FIFO rw */
-/*
- * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been
- * moved into the CTEST8 register.
- */
-#define DFIFO_BO6		0x40
-#define DFIFO_BO5		0x20
-#define DFIFO_BO4		0x10
-#define DFIFO_BO3		0x08
-#define DFIFO_BO2		0x04
-#define DFIFO_BO1		0x02
-#define DFIFO_BO0		0x01
-#define DFIFO_10_BO_MASK	0x7f	/* 7 bit counter */
-
-/*
- * Interrupt status rw
- * Note that this is the only register which can be read while SCSI
- * SCRIPTS are being executed.
- */
-#define ISTAT_REG_700		(0x21^bE)
-#define ISTAT_REG_800		(0x14^bE)
-#define ISTAT_ABRT		0x80	/* Software abort, write
-					 *1 to abort, wait for interrupt. */
-#define ISTAT_10_SRST		0x40	/* software reset */
-#define ISTAT_10_SIGP		0x20	/* signal script */
-#define ISTAT_CON		0x08	/* 1 when connected */
-#define ISTAT_800_INTF		0x04	/* Interrupt on the fly */
-#define ISTAT_700_PRE		0x04	/* Pointer register empty.
-					 * Set to 1 when DSPS and DSP
-					 * registers are empty in pipeline
-					 * mode, always set otherwise.
-					 */
-#define ISTAT_SIP		0x02	/* SCSI interrupt pending from
-					 * SCSI portion of SIOP see
-					 * SSTAT0
-					 */
-#define ISTAT_DIP		0x01	/* DMA interrupt pending
-					 * see DSTAT
-					 */
-
-#define CTEST8_REG		(0x22^bE)	/* Chip test 8 rw */
-#define CTEST8_10_V3		0x80	/* Chip revision */
-#define CTEST8_10_V2		0x40
-#define CTEST8_10_V1		0x20
-#define CTEST8_10_V0		0x10
-#define CTEST8_10_V_MASK	0xf0
-#define CTEST8_10_FLF		0x08	/* Flush FIFOs */
-#define CTEST8_10_CLF		0x04	/* Clear FIFOs */
-#define CTEST8_10_FM		0x02	/* Fetch pin mode */
-#define CTEST8_10_SM		0x01	/* Snoop pin mode */
-
-
-#define LCRC_REG_10		(0x23^bE)
-
-/*
- * 0x24 through 0x27 are the DMA byte counter register.  Instructions
- * write their high 8 bits into the DCMD register, the low 24 bits into
- * the DBC register.
- *
- * Function is dependent on the command type being executed.
- */
-
-
-#define DBC_REG			0x24
-/*
- * For Block Move Instructions, DBC is a 24 bit quantity representing
- *     the number of bytes to transfer.
- * For Transfer Control Instructions, DBC is bit fielded as follows :
- */
-/* Bits 20 - 23 should be clear */
-#define DBC_TCI_TRUE		(1 << 19) 	/* Jump when true */
-#define DBC_TCI_COMPARE_DATA	(1 << 18)	/* Compare data */
-#define DBC_TCI_COMPARE_PHASE	(1 << 17)	/* Compare phase with DCMD field */
-#define DBC_TCI_WAIT_FOR_VALID	(1 << 16)	/* Wait for REQ */
-/* Bits 8 - 15 are reserved on some implementations ? */
-#define DBC_TCI_MASK_MASK	0xff00 		/* Mask for data compare */
-#define DBC_TCI_MASK_SHIFT	8
-#define DBC_TCI_DATA_MASK	0xff		/* Data to be compared */
-#define DBC_TCI_DATA_SHIFT	0
-
-#define DBC_RWRI_IMMEDIATE_MASK	0xff00		/* Immediate data */
-#define DBC_RWRI_IMMEDIATE_SHIFT 8		/* Amount to shift */
-#define DBC_RWRI_ADDRESS_MASK	0x3f0000	/* Register address */
-#define DBC_RWRI_ADDRESS_SHIFT 	16
-
-
-/*
- * DMA command r/w
- */
-#define DCMD_REG		(0x27^bE)
-#define DCMD_TYPE_MASK		0xc0	/* Masks off type */
-#define DCMD_TYPE_BMI		0x00	/* Indicates a Block Move instruction */
-#define DCMD_BMI_IO		0x01	/* I/O, CD, and MSG bits selecting   */
-#define DCMD_BMI_CD		0x02	/* the phase for the block MOVE      */
-#define DCMD_BMI_MSG		0x04	/* instruction 			     */
-
-#define DCMD_BMI_OP_MASK	0x18	/* mask for opcode */
-#define DCMD_BMI_OP_MOVE_T	0x00	/* MOVE */
-#define DCMD_BMI_OP_MOVE_I	0x08	/* MOVE Initiator */
-
-#define DCMD_BMI_INDIRECT	0x20	/*  Indirect addressing */
-
-#define DCMD_TYPE_TCI		0x80	/* Indicates a Transfer Control
-					   instruction */
-#define DCMD_TCI_IO		0x01	/* I/O, CD, and MSG bits selecting   */
-#define DCMD_TCI_CD		0x02	/* the phase for the block MOVE      */
-#define DCMD_TCI_MSG		0x04	/* instruction 			     */
-#define DCMD_TCI_OP_MASK	0x38	/* mask for opcode */
-#define DCMD_TCI_OP_JUMP	0x00	/* JUMP */
-#define DCMD_TCI_OP_CALL	0x08	/* CALL */
-#define DCMD_TCI_OP_RETURN	0x10	/* RETURN */
-#define DCMD_TCI_OP_INT		0x18	/* INT */
-
-#define DCMD_TYPE_RWRI		0x40	/* Indicates I/O or register Read/Write
-					   instruction */
-#define DCMD_RWRI_OPC_MASK	0x38	/* Opcode mask */
-#define DCMD_RWRI_OPC_WRITE	0x28	/* Write SFBR to register */
-#define DCMD_RWRI_OPC_READ	0x30	/* Read register to SFBR */
-#define DCMD_RWRI_OPC_MODIFY	0x38	/* Modify in place */
-
-#define DCMD_RWRI_OP_MASK	0x07
-#define DCMD_RWRI_OP_MOVE	0x00
-#define DCMD_RWRI_OP_SHL	0x01
-#define DCMD_RWRI_OP_OR		0x02
-#define DCMD_RWRI_OP_XOR	0x03
-#define DCMD_RWRI_OP_AND	0x04
-#define DCMD_RWRI_OP_SHR	0x05
-#define DCMD_RWRI_OP_ADD	0x06
-#define DCMD_RWRI_OP_ADDC	0x07
-
-#define DCMD_TYPE_MMI		0xc0	/* Indicates a Memory Move instruction
-					   (three words) */
-
-
-#define DNAD_REG		0x28	/* through 0x2b DMA next address for
-					   data */
-#define DSP_REG			0x2c	/* through 0x2f DMA SCRIPTS pointer rw */
-#define DSPS_REG		0x30	/* through 0x33 DMA SCRIPTS pointer
-					   save rw */
-#define DMODE_BL1		0x80	/* Burst length bits */
-#define DMODE_BL0		0x40
-#define DMODE_BL_MASK		0xc0
-/* Burst lengths (800) */
-#define DMODE_BL_2	0x00	/* 2 transfer */
-#define DMODE_BL_4	0x40	/* 4 transfers */
-#define DMODE_BL_8	0x80	/* 8 transfers */
-#define DMODE_BL_16	0xc0	/* 16 transfers */
-
-#define DMODE_10_BL_1	0x00	/* 1 transfer */
-#define DMODE_10_BL_2	0x40	/* 2 transfers */
-#define DMODE_10_BL_4	0x80	/* 4 transfers */
-#define DMODE_10_BL_8	0xc0	/* 8 transfers */
-#define DMODE_10_FC2	0x20	/* Driven to FC2 pin */
-#define DMODE_10_FC1	0x10	/* Driven to FC1 pin */
-#define DMODE_710_PD	0x08	/* Program/data on FC0 pin */
-#define DMODE_710_UO	0x02	/* User prog. output */
-
-#define DMODE_MAN		0x01	/* Manual start mode,
-					 * requires a 1 to be written
-					 * to the start DMA bit in the DCNTL
-					 * register to run scripts
-					 */
-
-/* NCR53c800 series only */
-#define SCRATCHA_REG_800	0x34	/* through 0x37 Scratch A rw */
-/* NCR53c710 only */
-#define SCRATCHB_REG_10		0x34	/* through 0x37 scratch rw */
-
-#define DMODE_REG	    	(0x38^bE)	/* DMA mode rw, NCR53c710 and newer */
-#define DMODE_800_SIOM		0x20	/* Source IO = 1 */
-#define DMODE_800_DIOM		0x10	/* Destination IO = 1 */
-#define DMODE_800_ERL		0x08	/* Enable Read Line */
-
-#define DIEN_REG		(0x39^bE)	/* DMA interrupt enable rw */
-/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */
-#define DIEN_800_MDPE		0x40	/* Master data parity error */
-#define DIEN_800_BF		0x20	/* BUS fault */
-#define DIEN_700_BF		0x20	/* BUS fault */
-#define DIEN_ABRT		0x10	/* Enable aborted interrupt */
-#define DIEN_SSI		0x08	/* Enable single step interrupt */
-#define DIEN_SIR		0x04	/* Enable SCRIPTS INT command
-					 * interrupt
-					 */
-#define DIEN_700_WTD		0x02	/* Enable watchdog timeout interrupt */
-#define DIEN_700_OPC		0x01	/* Enable illegal instruction
-					 * interrupt
-					 */
-#define DIEN_800_IID		0x01	/*  Same meaning, different name */
-
-/*
- * DMA watchdog timer rw
- * set in 16 CLK input periods.
- */
-#define DWT_REG			(0x3a^bE)
-
-/* DMA control rw */
-#define DCNTL_REG		(0x3b^bE)
-#define DCNTL_700_CF1		0x80	/* Clock divisor bits */
-#define DCNTL_700_CF0		0x40
-#define DCNTL_700_CF_MASK	0xc0
-/* Clock divisors 			   Divisor SCLK range (MHZ) */
-#define DCNTL_700_CF_2		0x00    /* 2.0	   37.51-50.00 */
-#define DCNTL_700_CF_1_5	0x40	/* 1.5	   25.01-37.50 */
-#define DCNTL_700_CF_1		0x80	/* 1.0     16.67-25.00 */
-#define DCNTL_700_CF_3		0xc0	/* 3.0	   50.01-66.67 (53c700-66) */
-
-#define DCNTL_700_S16		0x20	/* Load scripts 16 bits at a time */
-#define DCNTL_SSM		0x10	/* Single step mode */
-#define DCNTL_700_LLM		0x08	/* Low level mode, can only be set
-					 * after selection */
-#define DCNTL_800_IRQM		0x08	/* Totem pole IRQ pin */
-#define DCNTL_STD		0x04	/* Start DMA / SCRIPTS */
-/* 0x02 is reserved */
-#define DCNTL_10_COM		0x01	/* 700 software compatibility mode */
-#define DCNTL_10_EA		0x20	/* Enable Ack - needed for MVME16x */
-
-#define SCRATCHB_REG_800	0x5c	/* through 0x5f scratch b rw */
-/* NCR53c710 only */
-#define ADDER_REG_10		0x3c	/* Adder, NCR53c710 only */
-
-#define SIEN1_REG_800		(0x41^bE)
-#define SIEN1_800_STO		0x04	/* selection/reselection timeout */
-#define SIEN1_800_GEN		0x02	/* general purpose timer */
-#define SIEN1_800_HTH		0x01	/* handshake to handshake */
-
-#define SIST1_REG_800		(0x43^bE)
-#define SIST1_800_STO		0x04	/* selection/reselection timeout */
-#define SIST1_800_GEN		0x02	/* general purpose timer */
-#define SIST1_800_HTH		0x01	/* handshake to handshake */
-
-#define SLPAR_REG_800		(0x44^bE)	/* Parity */
-
-#define MACNTL_REG_800		(0x46^bE)	/* Memory access control */
-#define MACNTL_800_TYP3		0x80
-#define MACNTL_800_TYP2		0x40
-#define MACNTL_800_TYP1		0x20
-#define MACNTL_800_TYP0		0x10
-#define MACNTL_800_DWR		0x08
-#define MACNTL_800_DRD		0x04
-#define MACNTL_800_PSCPT	0x02
-#define MACNTL_800_SCPTS	0x01
-
-#define GPCNTL_REG_800		(0x47^bE)	/* General Purpose Pin Control */
-
-/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */
-#define STIME0_REG_800		(0x48^bE)	/* SCSI Timer Register 0 */
-#define STIME0_800_HTH_MASK	0xf0	/* Handshake to Handshake timeout */
-#define STIME0_800_HTH_SHIFT	4
-#define STIME0_800_SEL_MASK	0x0f	/* Selection timeout */
-#define STIME0_800_SEL_SHIFT	0
-
-#define STIME1_REG_800		(0x49^bE)
-#define STIME1_800_GEN_MASK	0x0f	/* General purpose timer */
-
-#define RESPID_REG_800		(0x4a^bE)	/* Response ID, bit fielded.  8
-					   bits on narrow chips, 16 on WIDE */
-
-#define STEST0_REG_800		(0x4c^bE)
-#define STEST0_800_SLT		0x08	/* Selection response logic test */
-#define STEST0_800_ART		0x04	/* Arbitration priority encoder test */
-#define STEST0_800_SOZ		0x02	/* Synchronous offset zero */
-#define STEST0_800_SOM		0x01	/* Synchronous offset maximum */
-
-#define STEST1_REG_800		(0x4d^bE)
-#define STEST1_800_SCLK		0x80	/* Disable SCSI clock */
-
-#define STEST2_REG_800		(0x4e^bE)
-#define STEST2_800_SCE		0x80	/* Enable SOCL/SODL */
-#define STEST2_800_ROF		0x40	/* Reset SCSI sync offset */
-#define STEST2_800_SLB		0x10	/* Enable SCSI loopback mode */
-#define STEST2_800_SZM		0x08	/* SCSI high impedance mode */
-#define STEST2_800_EXT		0x02	/* Extend REQ/ACK filter 30 to 60ns */
-#define STEST2_800_LOW		0x01	/* SCSI low level mode */
-
-#define STEST3_REG_800		(0x4f^bE)
-#define STEST3_800_TE		0x80	/* Enable active negation */
-#define STEST3_800_STR		0x40	/* SCSI FIFO test read */
-#define STEST3_800_HSC		0x20	/* Halt SCSI clock */
-#define STEST3_800_DSI		0x10	/* Disable single initiator response */
-#define STEST3_800_TTM		0x04	/* Time test mode */
-#define STEST3_800_CSF		0x02	/* Clear SCSI FIFO */
-#define STEST3_800_STW		0x01	/* SCSI FIFO test write */
-
-#define ISTAT_REG	ISTAT_REG_700
-#define SCRATCH_REG	SCRATCHB_REG_10
-#define ADDER_REG	ADDER_REG_10
-#define SIEN_REG	SIEN_REG_700
-#define SDID_REG	SDID_REG_700
-#define CTEST0_REG	CTEST0_REG_700
-#define CTEST1_REG	CTEST1_REG_700
-#define CTEST2_REG	CTEST2_REG_700
-#define CTEST3_REG	CTEST3_REG_700
-#define CTEST4_REG	CTEST4_REG_700
-#define CTEST5_REG	CTEST5_REG_700
-#define CTEST6_REG	CTEST6_REG_700
-#define SODL_REG	SODL_REG_700
-#define SBDL_REG	SBDL_REG_700
-#define SIDL_REG	SIDL_REG_700
-#define LCRC_REG	LCRC_REG_10
-
-#ifdef MEM_MAPPED
-#define NCR_read8(address) 					\
-	(unsigned int)readb((u32)(host->base) + ((u32)(address)))
-
-#define NCR_read32(address) 					\
-	(unsigned int) readl((u32)(host->base) + (u32)(address))
-
-#define NCR_write8(address,value) 				\
-	{ DEB(DEB_REGS, printk("NCR: %02x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \
-	*(volatile unsigned char *)					\
-		((u32)(host->base) + (u32)(address)) = (value); }
-
-#define NCR_write32(address,value) 				\
-	{ DEB(DEB_REGS, printk("NCR: %08x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \
-	*(volatile unsigned long *)					\
-		((u32)(host->base) + (u32)(address)) = (value); }
-#else
-#define NCR_read8(address) 					\
-	inb((u32)(host->base) + (address))
-
-#define NCR_read32(address) 					\
-	inl((u32)(host->base) + (address))
-
-#define NCR_write8(address,value) 				\
-	{ DEB(DEB_REGS, printk("NCR: %02x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \
-	outb((value), (u32)(host->base) + (u32)(address)); }
-
-#define NCR_write32(address,value) 				\
-	{ DEB(DEB_REGS, printk("NCR: %08x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \
-	outl((value), (u32)(host->base) + (u32)(address)); }
-#endif
-
-/* Patch arbitrary 32 bit words in the script */
-#define patch_abs_32(script, offset, symbol, value)			\
-    	for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof 		\
-    	    (u32)); ++i) {					\
-	    (script)[A_##symbol##_used[i] - (offset)] += (value);	\
-	      DEB(DEB_FIXUP, printk("scsi%d: %s reference %d at 0x%x in %s is now 0x%x\n",\
-		host->host_no, #symbol, i, A_##symbol##_used[i] - 	\
-		(int)(offset), #script, (script)[A_##symbol##_used[i] -	\
-		(offset)]));						\
-    	}
-
-#endif
-#endif
diff -Nru a/drivers/scsi/sim710.scr b/drivers/scsi/sim710.scr
--- a/drivers/scsi/sim710.scr	Mon Feb 10 10:39:23 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,576 +0,0 @@
-/*
- * sim710.scr - Copyright (C) 1999 Richard Hirst
- */
-
-/* Offsets from DSA, allow 128 elements of scatter/gather */
-
-ABSOLUTE dsa_select  = 0
-ABSOLUTE dsa_msgout  = 8
-ABSOLUTE dsa_cmnd    = 16
-ABSOLUTE dsa_status  = 24
-ABSOLUTE dsa_msgin   = 32
-ABSOLUTE dsa_datain  = 40	/* 8 * 128 = 1024 bytes */
-ABSOLUTE dsa_dataout = 1064	/* 8 * 128 = 1024 bytes */
-ABSOLUTE dsa_size     = 2088
-
-ABSOLUTE reselected_identify = 0
-ABSOLUTE msgin_buf = 0
-ABSOLUTE msg_reject = 0
-ABSOLUTE test1_src = 0
-ABSOLUTE test1_dst = 0
-
-/* Interrupt values passed back to driver */
-
-ABSOLUTE int_bad_msg1		= 0xab930006
-ABSOLUTE int_bad_msg2		= 0xab930007
-ABSOLUTE int_bad_msg3		= 0xab930008
-ABSOLUTE int_cmd_bad_phase	= 0xab930009
-ABSOLUTE int_cmd_complete	= 0xab93000a
-ABSOLUTE int_data_bad_phase	= 0xab93000b
-ABSOLUTE int_msg_sdtr1		= 0xab93000c
-ABSOLUTE int_msg_sdtr2		= 0xab93000d
-ABSOLUTE int_msg_sdtr3		= 0xab93000e
-ABSOLUTE int_no_msgout1		= 0xab93000f
-ABSOLUTE int_no_msgout2		= 0xab930010
-ABSOLUTE int_no_msgout3		= 0xab930011
-ABSOLUTE int_not_cmd_complete	= 0xab930012
-ABSOLUTE int_sel_no_ident	= 0xab930013
-ABSOLUTE int_sel_not_cmd	= 0xab930014
-ABSOLUTE int_status_not_msgin	= 0xab930015
-ABSOLUTE int_resel_not_msgin	= 0xab930016
-ABSOLUTE int_reselected		= 0xab930017
-ABSOLUTE int_selected		= 0xab930018
-ABSOLUTE int_disc1		= 0xab930019
-ABSOLUTE int_disc2		= 0xab93001a
-ABSOLUTE int_disc3		= 0xab93001b
-ABSOLUTE int_not_rej		= 0xab93001c
-ABSOLUTE int_test1		= 0xab93001d
-
-/* Bit field settings used to record status in SCRATCH0 */
-
-ABSOLUTE had_select	= 0x01
-ABSOLUTE had_msgout	= 0x02
-ABSOLUTE had_cmdout	= 0x04
-ABSOLUTE had_datain	= 0x08
-ABSOLUTE had_dataout	= 0x10
-ABSOLUTE had_status	= 0x20
-ABSOLUTE had_msgin	= 0x40
-ABSOLUTE had_extmsg	= 0x80
-
-/* Bit field settings used to record status in SCRATCH1 */
-
-ABSOLUTE did_reject	= 0x01
-
-/* These scripts are heavily based on the examples in the NCR 53C710
- * Programmer's Guide (Preliminary).
- */
-
-ENTRY do_select
-do_select:
-	CLEAR TARGET
-	; Enable selection timer
-	MOVE CTEST7 & 0xef TO CTEST7
-	SELECT ATN FROM dsa_select, reselect
-	JUMP get_status, WHEN STATUS
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-	MOVE SCRATCH0 | had_select TO SCRATCH0
-	INT int_sel_no_ident, IF NOT MSG_OUT
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-	MOVE FROM dsa_msgout, when MSG_OUT
-ENTRY done_ident
-done_ident:
-	JUMP get_status, IF STATUS
-redo_msgin1:
-	JUMP get_msgin1, WHEN MSG_IN
-	INT int_sel_not_cmd, IF NOT CMD
-ENTRY resume_cmd
-resume_cmd:
-	MOVE SCRATCH0 | had_cmdout TO SCRATCH0
-	MOVE FROM dsa_cmnd, WHEN CMD
-ENTRY resume_pmm
-resume_pmm:
-redo_msgin2:
-	JUMP get_msgin2, WHEN MSG_IN
-	JUMP get_status, IF STATUS
-	JUMP input_data, IF DATA_IN
-	JUMP output_data, IF DATA_OUT
-	INT int_cmd_bad_phase
-
-get_status:
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-	MOVE FROM dsa_status, WHEN STATUS
-	INT int_status_not_msgin, WHEN NOT MSG_IN
-	MOVE FROM dsa_msgin, WHEN MSG_IN
-	INT int_not_cmd_complete, IF NOT 0x00
-	CLEAR ACK
-ENTRY wait_disc_complete
-wait_disc_complete:
-	WAIT DISCONNECT
-	INT int_cmd_complete
-
-input_data:
-	MOVE SCRATCH0 | had_datain TO SCRATCH0
-ENTRY patch_input_data
-patch_input_data:
-	JUMP 0
-	MOVE FROM dsa_datain+0x0000, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0008, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0010, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0018, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0020, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0028, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0030, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0038, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0040, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0048, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0050, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0058, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0060, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0068, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0070, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0078, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0080, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0088, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0090, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0098, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0100, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0108, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0110, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0118, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0120, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0128, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0130, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0138, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0140, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0148, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0150, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0158, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0160, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0168, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0170, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0178, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0180, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0188, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0190, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0198, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0200, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0208, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0210, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0218, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0220, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0228, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0230, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0238, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0240, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0248, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0250, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0258, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0260, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0268, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0270, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0278, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0280, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0288, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0290, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0298, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0300, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0308, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0310, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0318, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0320, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0328, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0330, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0338, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0340, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0348, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0350, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0358, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0360, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0368, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0370, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0378, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0380, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0388, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0390, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x0398, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN
-	MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN
-	JUMP end_data_trans
-
-output_data:
-	MOVE SCRATCH0 | had_dataout TO SCRATCH0
-ENTRY patch_output_data
-patch_output_data:
-	JUMP 0
-	MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT
-	MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT
-ENTRY end_data_trans
-end_data_trans:
-redo_msgin3:
-	JUMP get_status, WHEN STATUS
-	JUMP get_msgin3, WHEN MSG_IN
-	INT int_data_bad_phase
-
-get_msgin1:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-	MOVE 1, msgin_buf, WHEN MSG_IN
-	JUMP ext_msg1, IF 0x01		; Extended Message
-	JUMP ignore_msg1, IF 0x02	; Save Data Pointers
-	JUMP ignore_msg1, IF 0x03	; Save Restore Pointers
-	JUMP disc1, IF 0x04		; Disconnect
-	INT int_bad_msg1
-ignore_msg1:
-	CLEAR ACK
-	JUMP redo_msgin1
-ext_msg1:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-	CLEAR ACK
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP reject_msg1, IF NOT 0x03	; Only handle SDTR
-	CLEAR ACK
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP reject_msg1, IF NOT 0x01	; Only handle SDTR
-	CLEAR ACK
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-	INT int_msg_sdtr1
-reject_msg1:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-	SET ATN
-	CLEAR ACK
-	JUMP reject_msg1a, WHEN NOT MSG_IN
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-	JUMP reject_msg1
-reject_msg1a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-	JUMP redo_msgin1
-disc1:
-	CLEAR ACK
-ENTRY wait_disc1
-wait_disc1:
-	WAIT DISCONNECT
-	INT int_disc1
-ENTRY resume_msgin1a
-resume_msgin1a:
-	CLEAR ACK
-	JUMP redo_msgin1
-ENTRY resume_msgin1b
-resume_msgin1b:
-	SET ATN
-	CLEAR ACK
-	INT int_no_msgout1, WHEN NOT MSG_OUT
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-	MOVE FROM dsa_msgout, when MSG_OUT
-	JUMP redo_msgin1
-
-get_msgin2:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-	MOVE 1, msgin_buf, WHEN MSG_IN
-	JUMP ext_msg2, IF 0x01		; Extended Message
-	JUMP ignore_msg2, IF 0x02	; Save Data Pointers
-	JUMP ignore_msg2, IF 0x03	; Save Restore Pointers
-	JUMP disc2, IF 0x04		; Disconnect
-	INT int_bad_msg2
-ignore_msg2:
-	CLEAR ACK
-	JUMP redo_msgin2
-ext_msg2:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-	CLEAR ACK
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP reject_msg2, IF NOT 0x03	; Only handle SDTR
-	CLEAR ACK
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP reject_msg2, IF NOT 0x01	; Only handle SDTR
-	CLEAR ACK
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-	INT int_msg_sdtr2
-reject_msg2:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-	SET ATN
-	CLEAR ACK
-	JUMP reject_msg2a, WHEN NOT MSG_IN
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-	JUMP reject_msg2
-reject_msg2a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-	JUMP redo_msgin2
-disc2:
-	CLEAR ACK
-ENTRY wait_disc2
-wait_disc2:
-	WAIT DISCONNECT
-	INT int_disc2
-ENTRY resume_msgin2a
-resume_msgin2a:
-	CLEAR ACK
-	JUMP redo_msgin2
-ENTRY resume_msgin2b
-resume_msgin2b:
-	SET ATN
-	CLEAR ACK
-	INT int_no_msgout2, WHEN NOT MSG_OUT
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-	MOVE FROM dsa_msgout, when MSG_OUT
-	JUMP redo_msgin2
-
-get_msgin3:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-	MOVE 1, msgin_buf, WHEN MSG_IN
-	JUMP ext_msg3, IF 0x01		; Extended Message
-	JUMP ignore_msg3, IF 0x02	; Save Data Pointers
-	JUMP ignore_msg3, IF 0x03	; Save Restore Pointers
-	JUMP disc3, IF 0x04		; Disconnect
-	INT int_bad_msg3
-ignore_msg3:
-	CLEAR ACK
-	JUMP redo_msgin3
-ext_msg3:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-	CLEAR ACK
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-	JUMP reject_msg3, IF NOT 0x03	; Only handle SDTR
-	CLEAR ACK
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-	JUMP reject_msg3, IF NOT 0x01	; Only handle  SDTR
-	CLEAR ACK
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-	INT int_msg_sdtr3
-reject_msg3:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-	SET ATN
-	CLEAR ACK
-	JUMP reject_msg3a, WHEN NOT MSG_IN
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-	JUMP reject_msg3
-reject_msg3a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-	JUMP redo_msgin3
-disc3:
-	CLEAR ACK
-ENTRY wait_disc3
-wait_disc3:
-	WAIT DISCONNECT
-	INT int_disc3
-ENTRY resume_msgin3a
-resume_msgin3a:
-	CLEAR ACK
-	JUMP redo_msgin3
-ENTRY resume_msgin3b
-resume_msgin3b:
-	SET ATN
-	CLEAR ACK
-	INT int_no_msgout3, WHEN NOT MSG_OUT
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-	MOVE FROM dsa_msgout, when MSG_OUT
-	JUMP redo_msgin3
-
-ENTRY resume_rej_ident
-resume_rej_ident:
-	CLEAR ATN
-	MOVE 1, msgin_buf, WHEN MSG_IN
-	INT int_not_rej, IF NOT 0x07		; Reject
-	CLEAR ACK
-	JUMP done_ident
-
-ENTRY reselect
-reselect:
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-	WAIT RESELECT resel_err
-	INT int_resel_not_msgin, WHEN NOT MSG_IN
-	MOVE 1, reselected_identify, WHEN MSG_IN
-	INT int_reselected
-resel_err:
-	MOVE CTEST2 & 0x40 TO SFBR
-	JUMP selected, IF 0x00
-	MOVE SFBR & 0 TO SFBR
-ENTRY patch_new_dsa
-patch_new_dsa:
-	MOVE SFBR | 0x11 TO DSA0
-	MOVE SFBR | 0x22 TO DSA1
-	MOVE SFBR | 0x33 TO DSA2
-	MOVE SFBR | 0x44 TO DSA3
-	JUMP do_select
-
-selected:
-	INT int_selected
-
-ENTRY test1
-test1:
-	MOVE MEMORY 4, test1_src, test1_dst
-	INT int_test1
-
diff -Nru a/drivers/scsi/sim710_d.h_shipped b/drivers/scsi/sim710_d.h_shipped
--- a/drivers/scsi/sim710_d.h_shipped	Mon Feb 10 10:39:26 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2452 +0,0 @@
-/* DO NOT EDIT - Generated automatically by script_asm.pl */
-static u32 SCRIPT[] = {
-/*
-
-
-
-
-
-
-ABSOLUTE dsa_select  = 0
-ABSOLUTE dsa_msgout  = 8
-ABSOLUTE dsa_cmnd    = 16
-ABSOLUTE dsa_status  = 24
-ABSOLUTE dsa_msgin   = 32
-ABSOLUTE dsa_datain  = 40	
-ABSOLUTE dsa_dataout = 1064	
-ABSOLUTE dsa_size     = 2088
-
-ABSOLUTE reselected_identify = 0
-ABSOLUTE msgin_buf = 0
-ABSOLUTE msg_reject = 0
-ABSOLUTE test1_src = 0
-ABSOLUTE test1_dst = 0
-
-
-
-ABSOLUTE int_bad_msg1		= 0xab930006
-ABSOLUTE int_bad_msg2		= 0xab930007
-ABSOLUTE int_bad_msg3		= 0xab930008
-ABSOLUTE int_cmd_bad_phase	= 0xab930009
-ABSOLUTE int_cmd_complete	= 0xab93000a
-ABSOLUTE int_data_bad_phase	= 0xab93000b
-ABSOLUTE int_msg_sdtr1		= 0xab93000c
-ABSOLUTE int_msg_sdtr2		= 0xab93000d
-ABSOLUTE int_msg_sdtr3		= 0xab93000e
-ABSOLUTE int_no_msgout1		= 0xab93000f
-ABSOLUTE int_no_msgout2		= 0xab930010
-ABSOLUTE int_no_msgout3		= 0xab930011
-ABSOLUTE int_not_cmd_complete	= 0xab930012
-ABSOLUTE int_sel_no_ident	= 0xab930013
-ABSOLUTE int_sel_not_cmd	= 0xab930014
-ABSOLUTE int_status_not_msgin	= 0xab930015
-ABSOLUTE int_resel_not_msgin	= 0xab930016
-ABSOLUTE int_reselected		= 0xab930017
-ABSOLUTE int_selected		= 0xab930018
-ABSOLUTE int_disc1		= 0xab930019
-ABSOLUTE int_disc2		= 0xab93001a
-ABSOLUTE int_disc3		= 0xab93001b
-ABSOLUTE int_not_rej		= 0xab93001c
-ABSOLUTE int_test1		= 0xab93001d
-
-
-
-ABSOLUTE had_select	= 0x01
-ABSOLUTE had_msgout	= 0x02
-ABSOLUTE had_cmdout	= 0x04
-ABSOLUTE had_datain	= 0x08
-ABSOLUTE had_dataout	= 0x10
-ABSOLUTE had_status	= 0x20
-ABSOLUTE had_msgin	= 0x40
-ABSOLUTE had_extmsg	= 0x80
-
-
-
-ABSOLUTE did_reject	= 0x01
-
-
-
-
-
-ENTRY do_select
-do_select:
-	CLEAR TARGET
-
-at 0x00000000 : */	0x60000200,0x00000000,
-/*
-	; Enable selection timer
-	MOVE CTEST7 & 0xef TO CTEST7
-
-at 0x00000002 : */	0x7c1bef00,0x00000000,
-/*
-	SELECT ATN FROM dsa_select, reselect
-
-at 0x00000004 : */	0x43000000,0x00000cd0,
-/*
-	JUMP get_status, WHEN STATUS
-
-at 0x00000006 : */	0x830b0000,0x00000098,
-/*
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000008 : */	0x7a1b1000,0x00000000,
-/*
-	MOVE SCRATCH0 | had_select TO SCRATCH0
-
-at 0x0000000a : */	0x7a340100,0x00000000,
-/*
-	INT int_sel_no_ident, IF NOT MSG_OUT
-
-at 0x0000000c : */	0x9e020000,0xab930013,
-/*
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-
-at 0x0000000e : */	0x7a340200,0x00000000,
-/*
-	MOVE FROM dsa_msgout, when MSG_OUT
-
-at 0x00000010 : */	0x1e000000,0x00000008,
-/*
-ENTRY done_ident
-done_ident:
-	JUMP get_status, IF STATUS
-
-at 0x00000012 : */	0x830a0000,0x00000098,
-/*
-redo_msgin1:
-	JUMP get_msgin1, WHEN MSG_IN
-
-at 0x00000014 : */	0x870b0000,0x00000918,
-/*
-	INT int_sel_not_cmd, IF NOT CMD
-
-at 0x00000016 : */	0x9a020000,0xab930014,
-/*
-ENTRY resume_cmd
-resume_cmd:
-	MOVE SCRATCH0 | had_cmdout TO SCRATCH0
-
-at 0x00000018 : */	0x7a340400,0x00000000,
-/*
-	MOVE FROM dsa_cmnd, WHEN CMD
-
-at 0x0000001a : */	0x1a000000,0x00000010,
-/*
-ENTRY resume_pmm
-resume_pmm:
-redo_msgin2:
-	JUMP get_msgin2, WHEN MSG_IN
-
-at 0x0000001c : */	0x870b0000,0x00000a48,
-/*
-	JUMP get_status, IF STATUS
-
-at 0x0000001e : */	0x830a0000,0x00000098,
-/*
-	JUMP input_data, IF DATA_IN
-
-at 0x00000020 : */	0x810a0000,0x000000d8,
-/*
-	JUMP output_data, IF DATA_OUT
-
-at 0x00000022 : */	0x800a0000,0x000004f0,
-/*
-	INT int_cmd_bad_phase
-
-at 0x00000024 : */	0x98080000,0xab930009,
-/*
-
-get_status:
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000026 : */	0x7a1b1000,0x00000000,
-/*
-	MOVE FROM dsa_status, WHEN STATUS
-
-at 0x00000028 : */	0x1b000000,0x00000018,
-/*
-	INT int_status_not_msgin, WHEN NOT MSG_IN
-
-at 0x0000002a : */	0x9f030000,0xab930015,
-/*
-	MOVE FROM dsa_msgin, WHEN MSG_IN
-
-at 0x0000002c : */	0x1f000000,0x00000020,
-/*
-	INT int_not_cmd_complete, IF NOT 0x00
-
-at 0x0000002e : */	0x98040000,0xab930012,
-/*
-	CLEAR ACK
-
-at 0x00000030 : */	0x60000040,0x00000000,
-/*
-ENTRY wait_disc_complete
-wait_disc_complete:
-	WAIT DISCONNECT
-
-at 0x00000032 : */	0x48000000,0x00000000,
-/*
-	INT int_cmd_complete
-
-at 0x00000034 : */	0x98080000,0xab93000a,
-/*
-
-input_data:
-	MOVE SCRATCH0 | had_datain TO SCRATCH0
-
-at 0x00000036 : */	0x7a340800,0x00000000,
-/*
-ENTRY patch_input_data
-patch_input_data:
-	JUMP 0
-
-at 0x00000038 : */	0x80080000,0x00000000,
-/*
-	MOVE FROM dsa_datain+0x0000, WHEN DATA_IN
-
-at 0x0000003a : */	0x19000000,0x00000028,
-/*
-	MOVE FROM dsa_datain+0x0008, WHEN DATA_IN
-
-at 0x0000003c : */	0x19000000,0x00000030,
-/*
-	MOVE FROM dsa_datain+0x0010, WHEN DATA_IN
-
-at 0x0000003e : */	0x19000000,0x00000038,
-/*
-	MOVE FROM dsa_datain+0x0018, WHEN DATA_IN
-
-at 0x00000040 : */	0x19000000,0x00000040,
-/*
-	MOVE FROM dsa_datain+0x0020, WHEN DATA_IN
-
-at 0x00000042 : */	0x19000000,0x00000048,
-/*
-	MOVE FROM dsa_datain+0x0028, WHEN DATA_IN
-
-at 0x00000044 : */	0x19000000,0x00000050,
-/*
-	MOVE FROM dsa_datain+0x0030, WHEN DATA_IN
-
-at 0x00000046 : */	0x19000000,0x00000058,
-/*
-	MOVE FROM dsa_datain+0x0038, WHEN DATA_IN
-
-at 0x00000048 : */	0x19000000,0x00000060,
-/*
-	MOVE FROM dsa_datain+0x0040, WHEN DATA_IN
-
-at 0x0000004a : */	0x19000000,0x00000068,
-/*
-	MOVE FROM dsa_datain+0x0048, WHEN DATA_IN
-
-at 0x0000004c : */	0x19000000,0x00000070,
-/*
-	MOVE FROM dsa_datain+0x0050, WHEN DATA_IN
-
-at 0x0000004e : */	0x19000000,0x00000078,
-/*
-	MOVE FROM dsa_datain+0x0058, WHEN DATA_IN
-
-at 0x00000050 : */	0x19000000,0x00000080,
-/*
-	MOVE FROM dsa_datain+0x0060, WHEN DATA_IN
-
-at 0x00000052 : */	0x19000000,0x00000088,
-/*
-	MOVE FROM dsa_datain+0x0068, WHEN DATA_IN
-
-at 0x00000054 : */	0x19000000,0x00000090,
-/*
-	MOVE FROM dsa_datain+0x0070, WHEN DATA_IN
-
-at 0x00000056 : */	0x19000000,0x00000098,
-/*
-	MOVE FROM dsa_datain+0x0078, WHEN DATA_IN
-
-at 0x00000058 : */	0x19000000,0x000000a0,
-/*
-	MOVE FROM dsa_datain+0x0080, WHEN DATA_IN
-
-at 0x0000005a : */	0x19000000,0x000000a8,
-/*
-	MOVE FROM dsa_datain+0x0088, WHEN DATA_IN
-
-at 0x0000005c : */	0x19000000,0x000000b0,
-/*
-	MOVE FROM dsa_datain+0x0090, WHEN DATA_IN
-
-at 0x0000005e : */	0x19000000,0x000000b8,
-/*
-	MOVE FROM dsa_datain+0x0098, WHEN DATA_IN
-
-at 0x00000060 : */	0x19000000,0x000000c0,
-/*
-	MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN
-
-at 0x00000062 : */	0x19000000,0x000000c8,
-/*
-	MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN
-
-at 0x00000064 : */	0x19000000,0x000000d0,
-/*
-	MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN
-
-at 0x00000066 : */	0x19000000,0x000000d8,
-/*
-	MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN
-
-at 0x00000068 : */	0x19000000,0x000000e0,
-/*
-	MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN
-
-at 0x0000006a : */	0x19000000,0x000000e8,
-/*
-	MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN
-
-at 0x0000006c : */	0x19000000,0x000000f0,
-/*
-	MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN
-
-at 0x0000006e : */	0x19000000,0x000000f8,
-/*
-	MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN
-
-at 0x00000070 : */	0x19000000,0x00000100,
-/*
-	MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN
-
-at 0x00000072 : */	0x19000000,0x00000108,
-/*
-	MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN
-
-at 0x00000074 : */	0x19000000,0x00000110,
-/*
-	MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN
-
-at 0x00000076 : */	0x19000000,0x00000118,
-/*
-	MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN
-
-at 0x00000078 : */	0x19000000,0x00000120,
-/*
-	MOVE FROM dsa_datain+0x0100, WHEN DATA_IN
-
-at 0x0000007a : */	0x19000000,0x00000128,
-/*
-	MOVE FROM dsa_datain+0x0108, WHEN DATA_IN
-
-at 0x0000007c : */	0x19000000,0x00000130,
-/*
-	MOVE FROM dsa_datain+0x0110, WHEN DATA_IN
-
-at 0x0000007e : */	0x19000000,0x00000138,
-/*
-	MOVE FROM dsa_datain+0x0118, WHEN DATA_IN
-
-at 0x00000080 : */	0x19000000,0x00000140,
-/*
-	MOVE FROM dsa_datain+0x0120, WHEN DATA_IN
-
-at 0x00000082 : */	0x19000000,0x00000148,
-/*
-	MOVE FROM dsa_datain+0x0128, WHEN DATA_IN
-
-at 0x00000084 : */	0x19000000,0x00000150,
-/*
-	MOVE FROM dsa_datain+0x0130, WHEN DATA_IN
-
-at 0x00000086 : */	0x19000000,0x00000158,
-/*
-	MOVE FROM dsa_datain+0x0138, WHEN DATA_IN
-
-at 0x00000088 : */	0x19000000,0x00000160,
-/*
-	MOVE FROM dsa_datain+0x0140, WHEN DATA_IN
-
-at 0x0000008a : */	0x19000000,0x00000168,
-/*
-	MOVE FROM dsa_datain+0x0148, WHEN DATA_IN
-
-at 0x0000008c : */	0x19000000,0x00000170,
-/*
-	MOVE FROM dsa_datain+0x0150, WHEN DATA_IN
-
-at 0x0000008e : */	0x19000000,0x00000178,
-/*
-	MOVE FROM dsa_datain+0x0158, WHEN DATA_IN
-
-at 0x00000090 : */	0x19000000,0x00000180,
-/*
-	MOVE FROM dsa_datain+0x0160, WHEN DATA_IN
-
-at 0x00000092 : */	0x19000000,0x00000188,
-/*
-	MOVE FROM dsa_datain+0x0168, WHEN DATA_IN
-
-at 0x00000094 : */	0x19000000,0x00000190,
-/*
-	MOVE FROM dsa_datain+0x0170, WHEN DATA_IN
-
-at 0x00000096 : */	0x19000000,0x00000198,
-/*
-	MOVE FROM dsa_datain+0x0178, WHEN DATA_IN
-
-at 0x00000098 : */	0x19000000,0x000001a0,
-/*
-	MOVE FROM dsa_datain+0x0180, WHEN DATA_IN
-
-at 0x0000009a : */	0x19000000,0x000001a8,
-/*
-	MOVE FROM dsa_datain+0x0188, WHEN DATA_IN
-
-at 0x0000009c : */	0x19000000,0x000001b0,
-/*
-	MOVE FROM dsa_datain+0x0190, WHEN DATA_IN
-
-at 0x0000009e : */	0x19000000,0x000001b8,
-/*
-	MOVE FROM dsa_datain+0x0198, WHEN DATA_IN
-
-at 0x000000a0 : */	0x19000000,0x000001c0,
-/*
-	MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN
-
-at 0x000000a2 : */	0x19000000,0x000001c8,
-/*
-	MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN
-
-at 0x000000a4 : */	0x19000000,0x000001d0,
-/*
-	MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN
-
-at 0x000000a6 : */	0x19000000,0x000001d8,
-/*
-	MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN
-
-at 0x000000a8 : */	0x19000000,0x000001e0,
-/*
-	MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN
-
-at 0x000000aa : */	0x19000000,0x000001e8,
-/*
-	MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN
-
-at 0x000000ac : */	0x19000000,0x000001f0,
-/*
-	MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN
-
-at 0x000000ae : */	0x19000000,0x000001f8,
-/*
-	MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN
-
-at 0x000000b0 : */	0x19000000,0x00000200,
-/*
-	MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN
-
-at 0x000000b2 : */	0x19000000,0x00000208,
-/*
-	MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN
-
-at 0x000000b4 : */	0x19000000,0x00000210,
-/*
-	MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN
-
-at 0x000000b6 : */	0x19000000,0x00000218,
-/*
-	MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN
-
-at 0x000000b8 : */	0x19000000,0x00000220,
-/*
-	MOVE FROM dsa_datain+0x0200, WHEN DATA_IN
-
-at 0x000000ba : */	0x19000000,0x00000228,
-/*
-	MOVE FROM dsa_datain+0x0208, WHEN DATA_IN
-
-at 0x000000bc : */	0x19000000,0x00000230,
-/*
-	MOVE FROM dsa_datain+0x0210, WHEN DATA_IN
-
-at 0x000000be : */	0x19000000,0x00000238,
-/*
-	MOVE FROM dsa_datain+0x0218, WHEN DATA_IN
-
-at 0x000000c0 : */	0x19000000,0x00000240,
-/*
-	MOVE FROM dsa_datain+0x0220, WHEN DATA_IN
-
-at 0x000000c2 : */	0x19000000,0x00000248,
-/*
-	MOVE FROM dsa_datain+0x0228, WHEN DATA_IN
-
-at 0x000000c4 : */	0x19000000,0x00000250,
-/*
-	MOVE FROM dsa_datain+0x0230, WHEN DATA_IN
-
-at 0x000000c6 : */	0x19000000,0x00000258,
-/*
-	MOVE FROM dsa_datain+0x0238, WHEN DATA_IN
-
-at 0x000000c8 : */	0x19000000,0x00000260,
-/*
-	MOVE FROM dsa_datain+0x0240, WHEN DATA_IN
-
-at 0x000000ca : */	0x19000000,0x00000268,
-/*
-	MOVE FROM dsa_datain+0x0248, WHEN DATA_IN
-
-at 0x000000cc : */	0x19000000,0x00000270,
-/*
-	MOVE FROM dsa_datain+0x0250, WHEN DATA_IN
-
-at 0x000000ce : */	0x19000000,0x00000278,
-/*
-	MOVE FROM dsa_datain+0x0258, WHEN DATA_IN
-
-at 0x000000d0 : */	0x19000000,0x00000280,
-/*
-	MOVE FROM dsa_datain+0x0260, WHEN DATA_IN
-
-at 0x000000d2 : */	0x19000000,0x00000288,
-/*
-	MOVE FROM dsa_datain+0x0268, WHEN DATA_IN
-
-at 0x000000d4 : */	0x19000000,0x00000290,
-/*
-	MOVE FROM dsa_datain+0x0270, WHEN DATA_IN
-
-at 0x000000d6 : */	0x19000000,0x00000298,
-/*
-	MOVE FROM dsa_datain+0x0278, WHEN DATA_IN
-
-at 0x000000d8 : */	0x19000000,0x000002a0,
-/*
-	MOVE FROM dsa_datain+0x0280, WHEN DATA_IN
-
-at 0x000000da : */	0x19000000,0x000002a8,
-/*
-	MOVE FROM dsa_datain+0x0288, WHEN DATA_IN
-
-at 0x000000dc : */	0x19000000,0x000002b0,
-/*
-	MOVE FROM dsa_datain+0x0290, WHEN DATA_IN
-
-at 0x000000de : */	0x19000000,0x000002b8,
-/*
-	MOVE FROM dsa_datain+0x0298, WHEN DATA_IN
-
-at 0x000000e0 : */	0x19000000,0x000002c0,
-/*
-	MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN
-
-at 0x000000e2 : */	0x19000000,0x000002c8,
-/*
-	MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN
-
-at 0x000000e4 : */	0x19000000,0x000002d0,
-/*
-	MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN
-
-at 0x000000e6 : */	0x19000000,0x000002d8,
-/*
-	MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN
-
-at 0x000000e8 : */	0x19000000,0x000002e0,
-/*
-	MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN
-
-at 0x000000ea : */	0x19000000,0x000002e8,
-/*
-	MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN
-
-at 0x000000ec : */	0x19000000,0x000002f0,
-/*
-	MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN
-
-at 0x000000ee : */	0x19000000,0x000002f8,
-/*
-	MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN
-
-at 0x000000f0 : */	0x19000000,0x00000300,
-/*
-	MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN
-
-at 0x000000f2 : */	0x19000000,0x00000308,
-/*
-	MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN
-
-at 0x000000f4 : */	0x19000000,0x00000310,
-/*
-	MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN
-
-at 0x000000f6 : */	0x19000000,0x00000318,
-/*
-	MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN
-
-at 0x000000f8 : */	0x19000000,0x00000320,
-/*
-	MOVE FROM dsa_datain+0x0300, WHEN DATA_IN
-
-at 0x000000fa : */	0x19000000,0x00000328,
-/*
-	MOVE FROM dsa_datain+0x0308, WHEN DATA_IN
-
-at 0x000000fc : */	0x19000000,0x00000330,
-/*
-	MOVE FROM dsa_datain+0x0310, WHEN DATA_IN
-
-at 0x000000fe : */	0x19000000,0x00000338,
-/*
-	MOVE FROM dsa_datain+0x0318, WHEN DATA_IN
-
-at 0x00000100 : */	0x19000000,0x00000340,
-/*
-	MOVE FROM dsa_datain+0x0320, WHEN DATA_IN
-
-at 0x00000102 : */	0x19000000,0x00000348,
-/*
-	MOVE FROM dsa_datain+0x0328, WHEN DATA_IN
-
-at 0x00000104 : */	0x19000000,0x00000350,
-/*
-	MOVE FROM dsa_datain+0x0330, WHEN DATA_IN
-
-at 0x00000106 : */	0x19000000,0x00000358,
-/*
-	MOVE FROM dsa_datain+0x0338, WHEN DATA_IN
-
-at 0x00000108 : */	0x19000000,0x00000360,
-/*
-	MOVE FROM dsa_datain+0x0340, WHEN DATA_IN
-
-at 0x0000010a : */	0x19000000,0x00000368,
-/*
-	MOVE FROM dsa_datain+0x0348, WHEN DATA_IN
-
-at 0x0000010c : */	0x19000000,0x00000370,
-/*
-	MOVE FROM dsa_datain+0x0350, WHEN DATA_IN
-
-at 0x0000010e : */	0x19000000,0x00000378,
-/*
-	MOVE FROM dsa_datain+0x0358, WHEN DATA_IN
-
-at 0x00000110 : */	0x19000000,0x00000380,
-/*
-	MOVE FROM dsa_datain+0x0360, WHEN DATA_IN
-
-at 0x00000112 : */	0x19000000,0x00000388,
-/*
-	MOVE FROM dsa_datain+0x0368, WHEN DATA_IN
-
-at 0x00000114 : */	0x19000000,0x00000390,
-/*
-	MOVE FROM dsa_datain+0x0370, WHEN DATA_IN
-
-at 0x00000116 : */	0x19000000,0x00000398,
-/*
-	MOVE FROM dsa_datain+0x0378, WHEN DATA_IN
-
-at 0x00000118 : */	0x19000000,0x000003a0,
-/*
-	MOVE FROM dsa_datain+0x0380, WHEN DATA_IN
-
-at 0x0000011a : */	0x19000000,0x000003a8,
-/*
-	MOVE FROM dsa_datain+0x0388, WHEN DATA_IN
-
-at 0x0000011c : */	0x19000000,0x000003b0,
-/*
-	MOVE FROM dsa_datain+0x0390, WHEN DATA_IN
-
-at 0x0000011e : */	0x19000000,0x000003b8,
-/*
-	MOVE FROM dsa_datain+0x0398, WHEN DATA_IN
-
-at 0x00000120 : */	0x19000000,0x000003c0,
-/*
-	MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN
-
-at 0x00000122 : */	0x19000000,0x000003c8,
-/*
-	MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN
-
-at 0x00000124 : */	0x19000000,0x000003d0,
-/*
-	MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN
-
-at 0x00000126 : */	0x19000000,0x000003d8,
-/*
-	MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN
-
-at 0x00000128 : */	0x19000000,0x000003e0,
-/*
-	MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN
-
-at 0x0000012a : */	0x19000000,0x000003e8,
-/*
-	MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN
-
-at 0x0000012c : */	0x19000000,0x000003f0,
-/*
-	MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN
-
-at 0x0000012e : */	0x19000000,0x000003f8,
-/*
-	MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN
-
-at 0x00000130 : */	0x19000000,0x00000400,
-/*
-	MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN
-
-at 0x00000132 : */	0x19000000,0x00000408,
-/*
-	MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN
-
-at 0x00000134 : */	0x19000000,0x00000410,
-/*
-	MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN
-
-at 0x00000136 : */	0x19000000,0x00000418,
-/*
-	MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN
-
-at 0x00000138 : */	0x19000000,0x00000420,
-/*
-	JUMP end_data_trans
-
-at 0x0000013a : */	0x80080000,0x00000900,
-/*
-
-output_data:
-	MOVE SCRATCH0 | had_dataout TO SCRATCH0
-
-at 0x0000013c : */	0x7a341000,0x00000000,
-/*
-ENTRY patch_output_data
-patch_output_data:
-	JUMP 0
-
-at 0x0000013e : */	0x80080000,0x00000000,
-/*
-	MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT
-
-at 0x00000140 : */	0x18000000,0x00000428,
-/*
-	MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT
-
-at 0x00000142 : */	0x18000000,0x00000430,
-/*
-	MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT
-
-at 0x00000144 : */	0x18000000,0x00000438,
-/*
-	MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT
-
-at 0x00000146 : */	0x18000000,0x00000440,
-/*
-	MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT
-
-at 0x00000148 : */	0x18000000,0x00000448,
-/*
-	MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT
-
-at 0x0000014a : */	0x18000000,0x00000450,
-/*
-	MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT
-
-at 0x0000014c : */	0x18000000,0x00000458,
-/*
-	MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT
-
-at 0x0000014e : */	0x18000000,0x00000460,
-/*
-	MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT
-
-at 0x00000150 : */	0x18000000,0x00000468,
-/*
-	MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT
-
-at 0x00000152 : */	0x18000000,0x00000470,
-/*
-	MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT
-
-at 0x00000154 : */	0x18000000,0x00000478,
-/*
-	MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT
-
-at 0x00000156 : */	0x18000000,0x00000480,
-/*
-	MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT
-
-at 0x00000158 : */	0x18000000,0x00000488,
-/*
-	MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT
-
-at 0x0000015a : */	0x18000000,0x00000490,
-/*
-	MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT
-
-at 0x0000015c : */	0x18000000,0x00000498,
-/*
-	MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT
-
-at 0x0000015e : */	0x18000000,0x000004a0,
-/*
-	MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT
-
-at 0x00000160 : */	0x18000000,0x000004a8,
-/*
-	MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT
-
-at 0x00000162 : */	0x18000000,0x000004b0,
-/*
-	MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT
-
-at 0x00000164 : */	0x18000000,0x000004b8,
-/*
-	MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT
-
-at 0x00000166 : */	0x18000000,0x000004c0,
-/*
-	MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT
-
-at 0x00000168 : */	0x18000000,0x000004c8,
-/*
-	MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT
-
-at 0x0000016a : */	0x18000000,0x000004d0,
-/*
-	MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT
-
-at 0x0000016c : */	0x18000000,0x000004d8,
-/*
-	MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT
-
-at 0x0000016e : */	0x18000000,0x000004e0,
-/*
-	MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT
-
-at 0x00000170 : */	0x18000000,0x000004e8,
-/*
-	MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT
-
-at 0x00000172 : */	0x18000000,0x000004f0,
-/*
-	MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT
-
-at 0x00000174 : */	0x18000000,0x000004f8,
-/*
-	MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT
-
-at 0x00000176 : */	0x18000000,0x00000500,
-/*
-	MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT
-
-at 0x00000178 : */	0x18000000,0x00000508,
-/*
-	MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT
-
-at 0x0000017a : */	0x18000000,0x00000510,
-/*
-	MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT
-
-at 0x0000017c : */	0x18000000,0x00000518,
-/*
-	MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT
-
-at 0x0000017e : */	0x18000000,0x00000520,
-/*
-	MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT
-
-at 0x00000180 : */	0x18000000,0x00000528,
-/*
-	MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT
-
-at 0x00000182 : */	0x18000000,0x00000530,
-/*
-	MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT
-
-at 0x00000184 : */	0x18000000,0x00000538,
-/*
-	MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT
-
-at 0x00000186 : */	0x18000000,0x00000540,
-/*
-	MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT
-
-at 0x00000188 : */	0x18000000,0x00000548,
-/*
-	MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT
-
-at 0x0000018a : */	0x18000000,0x00000550,
-/*
-	MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT
-
-at 0x0000018c : */	0x18000000,0x00000558,
-/*
-	MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT
-
-at 0x0000018e : */	0x18000000,0x00000560,
-/*
-	MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT
-
-at 0x00000190 : */	0x18000000,0x00000568,
-/*
-	MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT
-
-at 0x00000192 : */	0x18000000,0x00000570,
-/*
-	MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT
-
-at 0x00000194 : */	0x18000000,0x00000578,
-/*
-	MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT
-
-at 0x00000196 : */	0x18000000,0x00000580,
-/*
-	MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT
-
-at 0x00000198 : */	0x18000000,0x00000588,
-/*
-	MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT
-
-at 0x0000019a : */	0x18000000,0x00000590,
-/*
-	MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT
-
-at 0x0000019c : */	0x18000000,0x00000598,
-/*
-	MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT
-
-at 0x0000019e : */	0x18000000,0x000005a0,
-/*
-	MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT
-
-at 0x000001a0 : */	0x18000000,0x000005a8,
-/*
-	MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT
-
-at 0x000001a2 : */	0x18000000,0x000005b0,
-/*
-	MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT
-
-at 0x000001a4 : */	0x18000000,0x000005b8,
-/*
-	MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT
-
-at 0x000001a6 : */	0x18000000,0x000005c0,
-/*
-	MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT
-
-at 0x000001a8 : */	0x18000000,0x000005c8,
-/*
-	MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT
-
-at 0x000001aa : */	0x18000000,0x000005d0,
-/*
-	MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT
-
-at 0x000001ac : */	0x18000000,0x000005d8,
-/*
-	MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT
-
-at 0x000001ae : */	0x18000000,0x000005e0,
-/*
-	MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT
-
-at 0x000001b0 : */	0x18000000,0x000005e8,
-/*
-	MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT
-
-at 0x000001b2 : */	0x18000000,0x000005f0,
-/*
-	MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT
-
-at 0x000001b4 : */	0x18000000,0x000005f8,
-/*
-	MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT
-
-at 0x000001b6 : */	0x18000000,0x00000600,
-/*
-	MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT
-
-at 0x000001b8 : */	0x18000000,0x00000608,
-/*
-	MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT
-
-at 0x000001ba : */	0x18000000,0x00000610,
-/*
-	MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT
-
-at 0x000001bc : */	0x18000000,0x00000618,
-/*
-	MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT
-
-at 0x000001be : */	0x18000000,0x00000620,
-/*
-	MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT
-
-at 0x000001c0 : */	0x18000000,0x00000628,
-/*
-	MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT
-
-at 0x000001c2 : */	0x18000000,0x00000630,
-/*
-	MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT
-
-at 0x000001c4 : */	0x18000000,0x00000638,
-/*
-	MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT
-
-at 0x000001c6 : */	0x18000000,0x00000640,
-/*
-	MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT
-
-at 0x000001c8 : */	0x18000000,0x00000648,
-/*
-	MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT
-
-at 0x000001ca : */	0x18000000,0x00000650,
-/*
-	MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT
-
-at 0x000001cc : */	0x18000000,0x00000658,
-/*
-	MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT
-
-at 0x000001ce : */	0x18000000,0x00000660,
-/*
-	MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT
-
-at 0x000001d0 : */	0x18000000,0x00000668,
-/*
-	MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT
-
-at 0x000001d2 : */	0x18000000,0x00000670,
-/*
-	MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT
-
-at 0x000001d4 : */	0x18000000,0x00000678,
-/*
-	MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT
-
-at 0x000001d6 : */	0x18000000,0x00000680,
-/*
-	MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT
-
-at 0x000001d8 : */	0x18000000,0x00000688,
-/*
-	MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT
-
-at 0x000001da : */	0x18000000,0x00000690,
-/*
-	MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT
-
-at 0x000001dc : */	0x18000000,0x00000698,
-/*
-	MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT
-
-at 0x000001de : */	0x18000000,0x000006a0,
-/*
-	MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT
-
-at 0x000001e0 : */	0x18000000,0x000006a8,
-/*
-	MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT
-
-at 0x000001e2 : */	0x18000000,0x000006b0,
-/*
-	MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT
-
-at 0x000001e4 : */	0x18000000,0x000006b8,
-/*
-	MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT
-
-at 0x000001e6 : */	0x18000000,0x000006c0,
-/*
-	MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT
-
-at 0x000001e8 : */	0x18000000,0x000006c8,
-/*
-	MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT
-
-at 0x000001ea : */	0x18000000,0x000006d0,
-/*
-	MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT
-
-at 0x000001ec : */	0x18000000,0x000006d8,
-/*
-	MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT
-
-at 0x000001ee : */	0x18000000,0x000006e0,
-/*
-	MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT
-
-at 0x000001f0 : */	0x18000000,0x000006e8,
-/*
-	MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT
-
-at 0x000001f2 : */	0x18000000,0x000006f0,
-/*
-	MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT
-
-at 0x000001f4 : */	0x18000000,0x000006f8,
-/*
-	MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT
-
-at 0x000001f6 : */	0x18000000,0x00000700,
-/*
-	MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT
-
-at 0x000001f8 : */	0x18000000,0x00000708,
-/*
-	MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT
-
-at 0x000001fa : */	0x18000000,0x00000710,
-/*
-	MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT
-
-at 0x000001fc : */	0x18000000,0x00000718,
-/*
-	MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT
-
-at 0x000001fe : */	0x18000000,0x00000720,
-/*
-	MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT
-
-at 0x00000200 : */	0x18000000,0x00000728,
-/*
-	MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT
-
-at 0x00000202 : */	0x18000000,0x00000730,
-/*
-	MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT
-
-at 0x00000204 : */	0x18000000,0x00000738,
-/*
-	MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT
-
-at 0x00000206 : */	0x18000000,0x00000740,
-/*
-	MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT
-
-at 0x00000208 : */	0x18000000,0x00000748,
-/*
-	MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT
-
-at 0x0000020a : */	0x18000000,0x00000750,
-/*
-	MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT
-
-at 0x0000020c : */	0x18000000,0x00000758,
-/*
-	MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT
-
-at 0x0000020e : */	0x18000000,0x00000760,
-/*
-	MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT
-
-at 0x00000210 : */	0x18000000,0x00000768,
-/*
-	MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT
-
-at 0x00000212 : */	0x18000000,0x00000770,
-/*
-	MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT
-
-at 0x00000214 : */	0x18000000,0x00000778,
-/*
-	MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT
-
-at 0x00000216 : */	0x18000000,0x00000780,
-/*
-	MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT
-
-at 0x00000218 : */	0x18000000,0x00000788,
-/*
-	MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT
-
-at 0x0000021a : */	0x18000000,0x00000790,
-/*
-	MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT
-
-at 0x0000021c : */	0x18000000,0x00000798,
-/*
-	MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT
-
-at 0x0000021e : */	0x18000000,0x000007a0,
-/*
-	MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT
-
-at 0x00000220 : */	0x18000000,0x000007a8,
-/*
-	MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT
-
-at 0x00000222 : */	0x18000000,0x000007b0,
-/*
-	MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT
-
-at 0x00000224 : */	0x18000000,0x000007b8,
-/*
-	MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT
-
-at 0x00000226 : */	0x18000000,0x000007c0,
-/*
-	MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT
-
-at 0x00000228 : */	0x18000000,0x000007c8,
-/*
-	MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT
-
-at 0x0000022a : */	0x18000000,0x000007d0,
-/*
-	MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT
-
-at 0x0000022c : */	0x18000000,0x000007d8,
-/*
-	MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT
-
-at 0x0000022e : */	0x18000000,0x000007e0,
-/*
-	MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT
-
-at 0x00000230 : */	0x18000000,0x000007e8,
-/*
-	MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT
-
-at 0x00000232 : */	0x18000000,0x000007f0,
-/*
-	MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT
-
-at 0x00000234 : */	0x18000000,0x000007f8,
-/*
-	MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT
-
-at 0x00000236 : */	0x18000000,0x00000800,
-/*
-	MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT
-
-at 0x00000238 : */	0x18000000,0x00000808,
-/*
-	MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT
-
-at 0x0000023a : */	0x18000000,0x00000810,
-/*
-	MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT
-
-at 0x0000023c : */	0x18000000,0x00000818,
-/*
-	MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT
-
-at 0x0000023e : */	0x18000000,0x00000820,
-/*
-ENTRY end_data_trans
-end_data_trans:
-redo_msgin3:
-	JUMP get_status, WHEN STATUS
-
-at 0x00000240 : */	0x830b0000,0x00000098,
-/*
-	JUMP get_msgin3, WHEN MSG_IN
-
-at 0x00000242 : */	0x870b0000,0x00000b78,
-/*
-	INT int_data_bad_phase
-
-at 0x00000244 : */	0x98080000,0xab93000b,
-/*
-
-get_msgin1:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-
-at 0x00000246 : */	0x7a344000,0x00000000,
-/*
-	MOVE 1, msgin_buf, WHEN MSG_IN
-
-at 0x00000248 : */	0x0f000001,0x00000000,
-/*
-	JUMP ext_msg1, IF 0x01		; Extended Message
-
-at 0x0000024a : */	0x800c0001,0x00000960,
-/*
-	JUMP ignore_msg1, IF 0x02	; Save Data Pointers
-
-at 0x0000024c : */	0x800c0002,0x00000950,
-/*
-	JUMP ignore_msg1, IF 0x03	; Save Restore Pointers
-
-at 0x0000024e : */	0x800c0003,0x00000950,
-/*
-	JUMP disc1, IF 0x04		; Disconnect
-
-at 0x00000250 : */	0x800c0004,0x000009f0,
-/*
-	INT int_bad_msg1
-
-at 0x00000252 : */	0x98080000,0xab930006,
-/*
-ignore_msg1:
-	CLEAR ACK
-
-at 0x00000254 : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin1
-
-at 0x00000256 : */	0x80080000,0x00000050,
-/*
-ext_msg1:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-
-at 0x00000258 : */	0x7a348000,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x0000025a : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-
-at 0x0000025c : */	0x0f000001,0x00000001,
-/*
-	JUMP reject_msg1, IF NOT 0x03	; Only handle SDTR
-
-at 0x0000025e : */	0x80040003,0x000009b0,
-/*
-	CLEAR ACK
-
-at 0x00000260 : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-
-at 0x00000262 : */	0x0f000001,0x00000002,
-/*
-	JUMP reject_msg1, IF NOT 0x01	; Only handle SDTR
-
-at 0x00000264 : */	0x80040001,0x000009b0,
-/*
-	CLEAR ACK
-
-at 0x00000266 : */	0x60000040,0x00000000,
-/*
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-
-at 0x00000268 : */	0x0f000002,0x00000003,
-/*
-	INT int_msg_sdtr1
-
-at 0x0000026a : */	0x98080000,0xab93000c,
-/*
-reject_msg1:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-
-at 0x0000026c : */	0x7a350100,0x00000000,
-/*
-	SET ATN
-
-at 0x0000026e : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x00000270 : */	0x60000040,0x00000000,
-/*
-	JUMP reject_msg1a, WHEN NOT MSG_IN
-
-at 0x00000272 : */	0x87030000,0x000009e0,
-/*
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-
-at 0x00000274 : */	0x0f000001,0x00000007,
-/*
-	JUMP reject_msg1
-
-at 0x00000276 : */	0x80080000,0x000009b0,
-/*
-reject_msg1a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-
-at 0x00000278 : */	0x0e000001,0x00000000,
-/*
-	JUMP redo_msgin1
-
-at 0x0000027a : */	0x80080000,0x00000050,
-/*
-disc1:
-	CLEAR ACK
-
-at 0x0000027c : */	0x60000040,0x00000000,
-/*
-ENTRY wait_disc1
-wait_disc1:
-	WAIT DISCONNECT
-
-at 0x0000027e : */	0x48000000,0x00000000,
-/*
-	INT int_disc1
-
-at 0x00000280 : */	0x98080000,0xab930019,
-/*
-ENTRY resume_msgin1a
-resume_msgin1a:
-	CLEAR ACK
-
-at 0x00000282 : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin1
-
-at 0x00000284 : */	0x80080000,0x00000050,
-/*
-ENTRY resume_msgin1b
-resume_msgin1b:
-	SET ATN
-
-at 0x00000286 : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x00000288 : */	0x60000040,0x00000000,
-/*
-	INT int_no_msgout1, WHEN NOT MSG_OUT
-
-at 0x0000028a : */	0x9e030000,0xab93000f,
-/*
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-
-at 0x0000028c : */	0x7a340200,0x00000000,
-/*
-	MOVE FROM dsa_msgout, when MSG_OUT
-
-at 0x0000028e : */	0x1e000000,0x00000008,
-/*
-	JUMP redo_msgin1
-
-at 0x00000290 : */	0x80080000,0x00000050,
-/*
-
-get_msgin2:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-
-at 0x00000292 : */	0x7a344000,0x00000000,
-/*
-	MOVE 1, msgin_buf, WHEN MSG_IN
-
-at 0x00000294 : */	0x0f000001,0x00000000,
-/*
-	JUMP ext_msg2, IF 0x01		; Extended Message
-
-at 0x00000296 : */	0x800c0001,0x00000a90,
-/*
-	JUMP ignore_msg2, IF 0x02	; Save Data Pointers
-
-at 0x00000298 : */	0x800c0002,0x00000a80,
-/*
-	JUMP ignore_msg2, IF 0x03	; Save Restore Pointers
-
-at 0x0000029a : */	0x800c0003,0x00000a80,
-/*
-	JUMP disc2, IF 0x04		; Disconnect
-
-at 0x0000029c : */	0x800c0004,0x00000b20,
-/*
-	INT int_bad_msg2
-
-at 0x0000029e : */	0x98080000,0xab930007,
-/*
-ignore_msg2:
-	CLEAR ACK
-
-at 0x000002a0 : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin2
-
-at 0x000002a2 : */	0x80080000,0x00000070,
-/*
-ext_msg2:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-
-at 0x000002a4 : */	0x7a348000,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x000002a6 : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-
-at 0x000002a8 : */	0x0f000001,0x00000001,
-/*
-	JUMP reject_msg2, IF NOT 0x03	; Only handle SDTR
-
-at 0x000002aa : */	0x80040003,0x00000ae0,
-/*
-	CLEAR ACK
-
-at 0x000002ac : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-
-at 0x000002ae : */	0x0f000001,0x00000002,
-/*
-	JUMP reject_msg2, IF NOT 0x01	; Only handle SDTR
-
-at 0x000002b0 : */	0x80040001,0x00000ae0,
-/*
-	CLEAR ACK
-
-at 0x000002b2 : */	0x60000040,0x00000000,
-/*
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-
-at 0x000002b4 : */	0x0f000002,0x00000003,
-/*
-	INT int_msg_sdtr2
-
-at 0x000002b6 : */	0x98080000,0xab93000d,
-/*
-reject_msg2:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-
-at 0x000002b8 : */	0x7a350100,0x00000000,
-/*
-	SET ATN
-
-at 0x000002ba : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x000002bc : */	0x60000040,0x00000000,
-/*
-	JUMP reject_msg2a, WHEN NOT MSG_IN
-
-at 0x000002be : */	0x87030000,0x00000b10,
-/*
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-
-at 0x000002c0 : */	0x0f000001,0x00000007,
-/*
-	JUMP reject_msg2
-
-at 0x000002c2 : */	0x80080000,0x00000ae0,
-/*
-reject_msg2a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-
-at 0x000002c4 : */	0x0e000001,0x00000000,
-/*
-	JUMP redo_msgin2
-
-at 0x000002c6 : */	0x80080000,0x00000070,
-/*
-disc2:
-	CLEAR ACK
-
-at 0x000002c8 : */	0x60000040,0x00000000,
-/*
-ENTRY wait_disc2
-wait_disc2:
-	WAIT DISCONNECT
-
-at 0x000002ca : */	0x48000000,0x00000000,
-/*
-	INT int_disc2
-
-at 0x000002cc : */	0x98080000,0xab93001a,
-/*
-ENTRY resume_msgin2a
-resume_msgin2a:
-	CLEAR ACK
-
-at 0x000002ce : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin2
-
-at 0x000002d0 : */	0x80080000,0x00000070,
-/*
-ENTRY resume_msgin2b
-resume_msgin2b:
-	SET ATN
-
-at 0x000002d2 : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x000002d4 : */	0x60000040,0x00000000,
-/*
-	INT int_no_msgout2, WHEN NOT MSG_OUT
-
-at 0x000002d6 : */	0x9e030000,0xab930010,
-/*
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-
-at 0x000002d8 : */	0x7a340200,0x00000000,
-/*
-	MOVE FROM dsa_msgout, when MSG_OUT
-
-at 0x000002da : */	0x1e000000,0x00000008,
-/*
-	JUMP redo_msgin2
-
-at 0x000002dc : */	0x80080000,0x00000070,
-/*
-
-get_msgin3:
-	MOVE SCRATCH0 | had_msgin TO SCRATCH0
-
-at 0x000002de : */	0x7a344000,0x00000000,
-/*
-	MOVE 1, msgin_buf, WHEN MSG_IN
-
-at 0x000002e0 : */	0x0f000001,0x00000000,
-/*
-	JUMP ext_msg3, IF 0x01		; Extended Message
-
-at 0x000002e2 : */	0x800c0001,0x00000bc0,
-/*
-	JUMP ignore_msg3, IF 0x02	; Save Data Pointers
-
-at 0x000002e4 : */	0x800c0002,0x00000bb0,
-/*
-	JUMP ignore_msg3, IF 0x03	; Save Restore Pointers
-
-at 0x000002e6 : */	0x800c0003,0x00000bb0,
-/*
-	JUMP disc3, IF 0x04		; Disconnect
-
-at 0x000002e8 : */	0x800c0004,0x00000c50,
-/*
-	INT int_bad_msg3
-
-at 0x000002ea : */	0x98080000,0xab930008,
-/*
-ignore_msg3:
-	CLEAR ACK
-
-at 0x000002ec : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin3
-
-at 0x000002ee : */	0x80080000,0x00000900,
-/*
-ext_msg3:
-	MOVE SCRATCH0 | had_extmsg TO SCRATCH0
-
-at 0x000002f0 : */	0x7a348000,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x000002f2 : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 1, WHEN MSG_IN
-
-at 0x000002f4 : */	0x0f000001,0x00000001,
-/*
-	JUMP reject_msg3, IF NOT 0x03	; Only handle SDTR
-
-at 0x000002f6 : */	0x80040003,0x00000c10,
-/*
-	CLEAR ACK
-
-at 0x000002f8 : */	0x60000040,0x00000000,
-/*
-	MOVE 1, msgin_buf + 2, WHEN MSG_IN
-
-at 0x000002fa : */	0x0f000001,0x00000002,
-/*
-	JUMP reject_msg3, IF NOT 0x01	; Only handle  SDTR
-
-at 0x000002fc : */	0x80040001,0x00000c10,
-/*
-	CLEAR ACK
-
-at 0x000002fe : */	0x60000040,0x00000000,
-/*
-	MOVE 2, msgin_buf + 3, WHEN MSG_IN
-
-at 0x00000300 : */	0x0f000002,0x00000003,
-/*
-	INT int_msg_sdtr3
-
-at 0x00000302 : */	0x98080000,0xab93000e,
-/*
-reject_msg3:
-	MOVE SCRATCH1 | did_reject TO SCRATCH1
-
-at 0x00000304 : */	0x7a350100,0x00000000,
-/*
-	SET ATN
-
-at 0x00000306 : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x00000308 : */	0x60000040,0x00000000,
-/*
-	JUMP reject_msg3a, WHEN NOT MSG_IN
-
-at 0x0000030a : */	0x87030000,0x00000c40,
-/*
-	MOVE 1, msgin_buf + 7, WHEN MSG_IN
-
-at 0x0000030c : */	0x0f000001,0x00000007,
-/*
-	JUMP reject_msg3
-
-at 0x0000030e : */	0x80080000,0x00000c10,
-/*
-reject_msg3a:
-	MOVE 1, msg_reject, WHEN MSG_OUT
-
-at 0x00000310 : */	0x0e000001,0x00000000,
-/*
-	JUMP redo_msgin3
-
-at 0x00000312 : */	0x80080000,0x00000900,
-/*
-disc3:
-	CLEAR ACK
-
-at 0x00000314 : */	0x60000040,0x00000000,
-/*
-ENTRY wait_disc3
-wait_disc3:
-	WAIT DISCONNECT
-
-at 0x00000316 : */	0x48000000,0x00000000,
-/*
-	INT int_disc3
-
-at 0x00000318 : */	0x98080000,0xab93001b,
-/*
-ENTRY resume_msgin3a
-resume_msgin3a:
-	CLEAR ACK
-
-at 0x0000031a : */	0x60000040,0x00000000,
-/*
-	JUMP redo_msgin3
-
-at 0x0000031c : */	0x80080000,0x00000900,
-/*
-ENTRY resume_msgin3b
-resume_msgin3b:
-	SET ATN
-
-at 0x0000031e : */	0x58000008,0x00000000,
-/*
-	CLEAR ACK
-
-at 0x00000320 : */	0x60000040,0x00000000,
-/*
-	INT int_no_msgout3, WHEN NOT MSG_OUT
-
-at 0x00000322 : */	0x9e030000,0xab930011,
-/*
-	MOVE SCRATCH0 | had_msgout TO SCRATCH0
-
-at 0x00000324 : */	0x7a340200,0x00000000,
-/*
-	MOVE FROM dsa_msgout, when MSG_OUT
-
-at 0x00000326 : */	0x1e000000,0x00000008,
-/*
-	JUMP redo_msgin3
-
-at 0x00000328 : */	0x80080000,0x00000900,
-/*
-
-ENTRY resume_rej_ident
-resume_rej_ident:
-	CLEAR ATN
-
-at 0x0000032a : */	0x60000008,0x00000000,
-/*
-	MOVE 1, msgin_buf, WHEN MSG_IN
-
-at 0x0000032c : */	0x0f000001,0x00000000,
-/*
-	INT int_not_rej, IF NOT 0x07		; Reject
-
-at 0x0000032e : */	0x98040007,0xab93001c,
-/*
-	CLEAR ACK
-
-at 0x00000330 : */	0x60000040,0x00000000,
-/*
-	JUMP done_ident
-
-at 0x00000332 : */	0x80080000,0x00000048,
-/*
-
-ENTRY reselect
-reselect:
-	; Disable selection timer
-	MOVE CTEST7 | 0x10 TO CTEST7
-
-at 0x00000334 : */	0x7a1b1000,0x00000000,
-/*
-	WAIT RESELECT resel_err
-
-at 0x00000336 : */	0x50000000,0x00000cf8,
-/*
-	INT int_resel_not_msgin, WHEN NOT MSG_IN
-
-at 0x00000338 : */	0x9f030000,0xab930016,
-/*
-	MOVE 1, reselected_identify, WHEN MSG_IN
-
-at 0x0000033a : */	0x0f000001,0x00000000,
-/*
-	INT int_reselected
-
-at 0x0000033c : */	0x98080000,0xab930017,
-/*
-resel_err:
-	MOVE CTEST2 & 0x40 TO SFBR
-
-at 0x0000033e : */	0x74164000,0x00000000,
-/*
-	JUMP selected, IF 0x00
-
-at 0x00000340 : */	0x800c0000,0x00000d38,
-/*
-	MOVE SFBR & 0 TO SFBR
-
-at 0x00000342 : */	0x7c080000,0x00000000,
-/*
-ENTRY patch_new_dsa
-patch_new_dsa:
-	MOVE SFBR | 0x11 TO DSA0
-
-at 0x00000344 : */	0x6a101100,0x00000000,
-/*
-	MOVE SFBR | 0x22 TO DSA1
-
-at 0x00000346 : */	0x6a112200,0x00000000,
-/*
-	MOVE SFBR | 0x33 TO DSA2
-
-at 0x00000348 : */	0x6a123300,0x00000000,
-/*
-	MOVE SFBR | 0x44 TO DSA3
-
-at 0x0000034a : */	0x6a134400,0x00000000,
-/*
-	JUMP do_select
-
-at 0x0000034c : */	0x80080000,0x00000000,
-/*
-
-selected:
-	INT int_selected
-
-at 0x0000034e : */	0x98080000,0xab930018,
-/*
-
-ENTRY test1
-test1:
-	MOVE MEMORY 4, test1_src, test1_dst
-
-at 0x00000350 : */	0xc0000004,0x00000000,0x00000000,
-/*
-	INT int_test1
-
-at 0x00000353 : */	0x98080000,0xab93001d,
-};
-
-#define A_did_reject	0x00000001
-static u32 A_did_reject_used[] __attribute((unused)) = {
-	0x0000026c,
-	0x000002b8,
-	0x00000304,
-};
-
-#define A_dsa_cmnd	0x00000010
-static u32 A_dsa_cmnd_used[] __attribute((unused)) = {
-	0x0000001b,
-};
-
-#define A_dsa_datain	0x00000028
-static u32 A_dsa_datain_used[] __attribute((unused)) = {
-	0x0000003b,
-	0x0000003d,
-	0x0000003f,
-	0x00000041,
-	0x00000043,
-	0x00000045,
-	0x00000047,
-	0x00000049,
-	0x0000004b,
-	0x0000004d,
-	0x0000004f,
-	0x00000051,
-	0x00000053,
-	0x00000055,
-	0x00000057,
-	0x00000059,
-	0x0000005b,
-	0x0000005d,
-	0x0000005f,
-	0x00000061,
-	0x00000063,
-	0x00000065,
-	0x00000067,
-	0x00000069,
-	0x0000006b,
-	0x0000006d,
-	0x0000006f,
-	0x00000071,
-	0x00000073,
-	0x00000075,
-	0x00000077,
-	0x00000079,
-	0x0000007b,
-	0x0000007d,
-	0x0000007f,
-	0x00000081,
-	0x00000083,
-	0x00000085,
-	0x00000087,
-	0x00000089,
-	0x0000008b,
-	0x0000008d,
-	0x0000008f,
-	0x00000091,
-	0x00000093,
-	0x00000095,
-	0x00000097,
-	0x00000099,
-	0x0000009b,
-	0x0000009d,
-	0x0000009f,
-	0x000000a1,
-	0x000000a3,
-	0x000000a5,
-	0x000000a7,
-	0x000000a9,
-	0x000000ab,
-	0x000000ad,
-	0x000000af,
-	0x000000b1,
-	0x000000b3,
-	0x000000b5,
-	0x000000b7,
-	0x000000b9,
-	0x000000bb,
-	0x000000bd,
-	0x000000bf,
-	0x000000c1,
-	0x000000c3,
-	0x000000c5,
-	0x000000c7,
-	0x000000c9,
-	0x000000cb,
-	0x000000cd,
-	0x000000cf,
-	0x000000d1,
-	0x000000d3,
-	0x000000d5,
-	0x000000d7,
-	0x000000d9,
-	0x000000db,
-	0x000000dd,
-	0x000000df,
-	0x000000e1,
-	0x000000e3,
-	0x000000e5,
-	0x000000e7,
-	0x000000e9,
-	0x000000eb,
-	0x000000ed,
-	0x000000ef,
-	0x000000f1,
-	0x000000f3,
-	0x000000f5,
-	0x000000f7,
-	0x000000f9,
-	0x000000fb,
-	0x000000fd,
-	0x000000ff,
-	0x00000101,
-	0x00000103,
-	0x00000105,
-	0x00000107,
-	0x00000109,
-	0x0000010b,
-	0x0000010d,
-	0x0000010f,
-	0x00000111,
-	0x00000113,
-	0x00000115,
-	0x00000117,
-	0x00000119,
-	0x0000011b,
-	0x0000011d,
-	0x0000011f,
-	0x00000121,
-	0x00000123,
-	0x00000125,
-	0x00000127,
-	0x00000129,
-	0x0000012b,
-	0x0000012d,
-	0x0000012f,
-	0x00000131,
-	0x00000133,
-	0x00000135,
-	0x00000137,
-	0x00000139,
-};
-
-#define A_dsa_dataout	0x00000428
-static u32 A_dsa_dataout_used[] __attribute((unused)) = {
-	0x00000141,
-	0x00000143,
-	0x00000145,
-	0x00000147,
-	0x00000149,
-	0x0000014b,
-	0x0000014d,
-	0x0000014f,
-	0x00000151,
-	0x00000153,
-	0x00000155,
-	0x00000157,
-	0x00000159,
-	0x0000015b,
-	0x0000015d,
-	0x0000015f,
-	0x00000161,
-	0x00000163,
-	0x00000165,
-	0x00000167,
-	0x00000169,
-	0x0000016b,
-	0x0000016d,
-	0x0000016f,
-	0x00000171,
-	0x00000173,
-	0x00000175,
-	0x00000177,
-	0x00000179,
-	0x0000017b,
-	0x0000017d,
-	0x0000017f,
-	0x00000181,
-	0x00000183,
-	0x00000185,
-	0x00000187,
-	0x00000189,
-	0x0000018b,
-	0x0000018d,
-	0x0000018f,
-	0x00000191,
-	0x00000193,
-	0x00000195,
-	0x00000197,
-	0x00000199,
-	0x0000019b,
-	0x0000019d,
-	0x0000019f,
-	0x000001a1,
-	0x000001a3,
-	0x000001a5,
-	0x000001a7,
-	0x000001a9,
-	0x000001ab,
-	0x000001ad,
-	0x000001af,
-	0x000001b1,
-	0x000001b3,
-	0x000001b5,
-	0x000001b7,
-	0x000001b9,
-	0x000001bb,
-	0x000001bd,
-	0x000001bf,
-	0x000001c1,
-	0x000001c3,
-	0x000001c5,
-	0x000001c7,
-	0x000001c9,
-	0x000001cb,
-	0x000001cd,
-	0x000001cf,
-	0x000001d1,
-	0x000001d3,
-	0x000001d5,
-	0x000001d7,
-	0x000001d9,
-	0x000001db,
-	0x000001dd,
-	0x000001df,
-	0x000001e1,
-	0x000001e3,
-	0x000001e5,
-	0x000001e7,
-	0x000001e9,
-	0x000001eb,
-	0x000001ed,
-	0x000001ef,
-	0x000001f1,
-	0x000001f3,
-	0x000001f5,
-	0x000001f7,
-	0x000001f9,
-	0x000001fb,
-	0x000001fd,
-	0x000001ff,
-	0x00000201,
-	0x00000203,
-	0x00000205,
-	0x00000207,
-	0x00000209,
-	0x0000020b,
-	0x0000020d,
-	0x0000020f,
-	0x00000211,
-	0x00000213,
-	0x00000215,
-	0x00000217,
-	0x00000219,
-	0x0000021b,
-	0x0000021d,
-	0x0000021f,
-	0x00000221,
-	0x00000223,
-	0x00000225,
-	0x00000227,
-	0x00000229,
-	0x0000022b,
-	0x0000022d,
-	0x0000022f,
-	0x00000231,
-	0x00000233,
-	0x00000235,
-	0x00000237,
-	0x00000239,
-	0x0000023b,
-	0x0000023d,
-	0x0000023f,
-};
-
-#define A_dsa_msgin	0x00000020
-static u32 A_dsa_msgin_used[] __attribute((unused)) = {
-	0x0000002d,
-};
-
-#define A_dsa_msgout	0x00000008
-static u32 A_dsa_msgout_used[] __attribute((unused)) = {
-	0x00000011,
-	0x0000028f,
-	0x000002db,
-	0x00000327,
-};
-
-#define A_dsa_select	0x00000000
-static u32 A_dsa_select_used[] __attribute((unused)) = {
-	0x00000004,
-};
-
-#define A_dsa_size	0x00000828
-static u32 A_dsa_size_used[] __attribute((unused)) = {
-};
-
-#define A_dsa_status	0x00000018
-static u32 A_dsa_status_used[] __attribute((unused)) = {
-	0x00000029,
-};
-
-#define A_had_cmdout	0x00000004
-static u32 A_had_cmdout_used[] __attribute((unused)) = {
-	0x00000018,
-};
-
-#define A_had_datain	0x00000008
-static u32 A_had_datain_used[] __attribute((unused)) = {
-	0x00000036,
-};
-
-#define A_had_dataout	0x00000010
-static u32 A_had_dataout_used[] __attribute((unused)) = {
-	0x0000013c,
-};
-
-#define A_had_extmsg	0x00000080
-static u32 A_had_extmsg_used[] __attribute((unused)) = {
-	0x00000258,
-	0x000002a4,
-	0x000002f0,
-};
-
-#define A_had_msgin	0x00000040
-static u32 A_had_msgin_used[] __attribute((unused)) = {
-	0x00000246,
-	0x00000292,
-	0x000002de,
-};
-
-#define A_had_msgout	0x00000002
-static u32 A_had_msgout_used[] __attribute((unused)) = {
-	0x0000000e,
-	0x0000028c,
-	0x000002d8,
-	0x00000324,
-};
-
-#define A_had_select	0x00000001
-static u32 A_had_select_used[] __attribute((unused)) = {
-	0x0000000a,
-};
-
-#define A_had_status	0x00000020
-static u32 A_had_status_used[] __attribute((unused)) = {
-};
-
-#define A_int_bad_msg1	0xab930006
-static u32 A_int_bad_msg1_used[] __attribute((unused)) = {
-	0x00000253,
-};
-
-#define A_int_bad_msg2	0xab930007
-static u32 A_int_bad_msg2_used[] __attribute((unused)) = {
-	0x0000029f,
-};
-
-#define A_int_bad_msg3	0xab930008
-static u32 A_int_bad_msg3_used[] __attribute((unused)) = {
-	0x000002eb,
-};
-
-#define A_int_cmd_bad_phase	0xab930009
-static u32 A_int_cmd_bad_phase_used[] __attribute((unused)) = {
-	0x00000025,
-};
-
-#define A_int_cmd_complete	0xab93000a
-static u32 A_int_cmd_complete_used[] __attribute((unused)) = {
-	0x00000035,
-};
-
-#define A_int_data_bad_phase	0xab93000b
-static u32 A_int_data_bad_phase_used[] __attribute((unused)) = {
-	0x00000245,
-};
-
-#define A_int_disc1	0xab930019
-static u32 A_int_disc1_used[] __attribute((unused)) = {
-	0x00000281,
-};
-
-#define A_int_disc2	0xab93001a
-static u32 A_int_disc2_used[] __attribute((unused)) = {
-	0x000002cd,
-};
-
-#define A_int_disc3	0xab93001b
-static u32 A_int_disc3_used[] __attribute((unused)) = {
-	0x00000319,
-};
-
-#define A_int_msg_sdtr1	0xab93000c
-static u32 A_int_msg_sdtr1_used[] __attribute((unused)) = {
-	0x0000026b,
-};
-
-#define A_int_msg_sdtr2	0xab93000d
-static u32 A_int_msg_sdtr2_used[] __attribute((unused)) = {
-	0x000002b7,
-};
-
-#define A_int_msg_sdtr3	0xab93000e
-static u32 A_int_msg_sdtr3_used[] __attribute((unused)) = {
-	0x00000303,
-};
-
-#define A_int_no_msgout1	0xab93000f
-static u32 A_int_no_msgout1_used[] __attribute((unused)) = {
-	0x0000028b,
-};
-
-#define A_int_no_msgout2	0xab930010
-static u32 A_int_no_msgout2_used[] __attribute((unused)) = {
-	0x000002d7,
-};
-
-#define A_int_no_msgout3	0xab930011
-static u32 A_int_no_msgout3_used[] __attribute((unused)) = {
-	0x00000323,
-};
-
-#define A_int_not_cmd_complete	0xab930012
-static u32 A_int_not_cmd_complete_used[] __attribute((unused)) = {
-	0x0000002f,
-};
-
-#define A_int_not_rej	0xab93001c
-static u32 A_int_not_rej_used[] __attribute((unused)) = {
-	0x0000032f,
-};
-
-#define A_int_resel_not_msgin	0xab930016
-static u32 A_int_resel_not_msgin_used[] __attribute((unused)) = {
-	0x00000339,
-};
-
-#define A_int_reselected	0xab930017
-static u32 A_int_reselected_used[] __attribute((unused)) = {
-	0x0000033d,
-};
-
-#define A_int_sel_no_ident	0xab930013
-static u32 A_int_sel_no_ident_used[] __attribute((unused)) = {
-	0x0000000d,
-};
-
-#define A_int_sel_not_cmd	0xab930014
-static u32 A_int_sel_not_cmd_used[] __attribute((unused)) = {
-	0x00000017,
-};
-
-#define A_int_selected	0xab930018
-static u32 A_int_selected_used[] __attribute((unused)) = {
-	0x0000034f,
-};
-
-#define A_int_status_not_msgin	0xab930015
-static u32 A_int_status_not_msgin_used[] __attribute((unused)) = {
-	0x0000002b,
-};
-
-#define A_int_test1	0xab93001d
-static u32 A_int_test1_used[] __attribute((unused)) = {
-	0x00000354,
-};
-
-#define A_msg_reject	0x00000000
-static u32 A_msg_reject_used[] __attribute((unused)) = {
-	0x00000279,
-	0x000002c5,
-	0x00000311,
-};
-
-#define A_msgin_buf	0x00000000
-static u32 A_msgin_buf_used[] __attribute((unused)) = {
-	0x00000249,
-	0x0000025d,
-	0x00000263,
-	0x00000269,
-	0x00000275,
-	0x00000295,
-	0x000002a9,
-	0x000002af,
-	0x000002b5,
-	0x000002c1,
-	0x000002e1,
-	0x000002f5,
-	0x000002fb,
-	0x00000301,
-	0x0000030d,
-	0x0000032d,
-};
-
-#define A_reselected_identify	0x00000000
-static u32 A_reselected_identify_used[] __attribute((unused)) = {
-	0x0000033b,
-};
-
-#define A_test1_dst	0x00000000
-static u32 A_test1_dst_used[] __attribute((unused)) = {
-	0x00000352,
-};
-
-#define A_test1_src	0x00000000
-static u32 A_test1_src_used[] __attribute((unused)) = {
-	0x00000351,
-};
-
-#define Ent_do_select	0x00000000
-#define Ent_done_ident	0x00000048
-#define Ent_end_data_trans	0x00000900
-#define Ent_patch_input_data	0x000000e0
-#define Ent_patch_new_dsa	0x00000d10
-#define Ent_patch_output_data	0x000004f8
-#define Ent_reselect	0x00000cd0
-#define Ent_resume_cmd	0x00000060
-#define Ent_resume_msgin1a	0x00000a08
-#define Ent_resume_msgin1b	0x00000a18
-#define Ent_resume_msgin2a	0x00000b38
-#define Ent_resume_msgin2b	0x00000b48
-#define Ent_resume_msgin3a	0x00000c68
-#define Ent_resume_msgin3b	0x00000c78
-#define Ent_resume_pmm	0x00000070
-#define Ent_resume_rej_ident	0x00000ca8
-#define Ent_test1	0x00000d40
-#define Ent_wait_disc1	0x000009f8
-#define Ent_wait_disc2	0x00000b28
-#define Ent_wait_disc3	0x00000c58
-#define Ent_wait_disc_complete	0x000000c8
-static u32 LABELPATCHES[] __attribute((unused)) = {
-	0x00000005,
-	0x00000007,
-	0x00000013,
-	0x00000015,
-	0x0000001d,
-	0x0000001f,
-	0x00000021,
-	0x00000023,
-	0x0000013b,
-	0x00000241,
-	0x00000243,
-	0x0000024b,
-	0x0000024d,
-	0x0000024f,
-	0x00000251,
-	0x00000257,
-	0x0000025f,
-	0x00000265,
-	0x00000273,
-	0x00000277,
-	0x0000027b,
-	0x00000285,
-	0x00000291,
-	0x00000297,
-	0x00000299,
-	0x0000029b,
-	0x0000029d,
-	0x000002a3,
-	0x000002ab,
-	0x000002b1,
-	0x000002bf,
-	0x000002c3,
-	0x000002c7,
-	0x000002d1,
-	0x000002dd,
-	0x000002e3,
-	0x000002e5,
-	0x000002e7,
-	0x000002e9,
-	0x000002ef,
-	0x000002f7,
-	0x000002fd,
-	0x0000030b,
-	0x0000030f,
-	0x00000313,
-	0x0000031d,
-	0x00000329,
-	0x00000333,
-	0x00000337,
-	0x00000341,
-	0x0000034d,
-};
-
-static struct {
-	u32	offset;
-	void		*address;
-} EXTERNAL_PATCHES[] __attribute((unused)) = {
-};
-
-static u32 INSTRUCTIONS __attribute((unused))	= 426;
-static u32 PATCHES __attribute((unused))	= 51;
-static u32 EXTERNAL_PATCHES_LEN __attribute((unused))	= 0;
diff -Nru a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
--- a/drivers/scsi/sr_ioctl.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/sr_ioctl.c	Mon Feb 10 10:39:29 2003
@@ -80,34 +80,20 @@
 	struct scsi_device *SDev;
         struct request *req;
 	int result, err = 0, retries = 0;
-	char *bounce_buffer;
 
 	SDev = cd->device;
 	SRpnt = scsi_allocate_request(SDev);
         if (!SRpnt) {
-                printk("Unable to allocate SCSI request in sr_do_ioctl");
+                printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl");
 		err = -ENOMEM;
 		goto out;
         }
 	SRpnt->sr_data_direction = cgc->data_direction;
 
-	/* use ISA DMA buffer if necessary */
-	SRpnt->sr_request->buffer = cgc->buffer;
-	if (cgc->buffer && SRpnt->sr_host->unchecked_isa_dma &&
-	    (virt_to_phys(cgc->buffer) + cgc->buflen - 1 > ISA_DMA_THRESHOLD)) {
-		bounce_buffer = (char *) kmalloc(cgc->buflen, GFP_DMA);
-		if (bounce_buffer == NULL) {
-			printk("SCSI DMA pool exhausted.");
-			err = -ENOMEM;
-			goto out;
-		}
-		memcpy(bounce_buffer, cgc->buffer, cgc->buflen);
-		cgc->buffer = bounce_buffer;
-	}
       retry:
 	if (!scsi_block_when_processing_errors(SDev)) {
 		err = -ENODEV;
-		goto out;
+		goto out_free;
 	}
 
 	scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen,
@@ -179,6 +165,7 @@
 		memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense));
 
 	/* Wake up a process waiting for device */
+      out_free:
 	scsi_release_request(SRpnt);
 	SRpnt = NULL;
       out:
@@ -275,11 +262,15 @@
 	return 0;
 }
 
+/* primitive to determine whether we need to have GFP_DMA set based on
+ * the status of the unchecked_isa_dma flag in the host structure */
+#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)
+
 int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
 	Scsi_CD *cd = cdi->handle;
 	struct cdrom_generic_command cgc;
-	char buffer[32];
+	char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 	int result;
 
 	memset(&cgc, 0, sizeof(struct cdrom_generic_command));
@@ -296,6 +287,7 @@
 	memcpy(mcn->medium_catalog_number, buffer + 9, 13);
 	mcn->medium_catalog_number[13] = 0;
 
+	kfree(buffer);
 	return result;
 }
 
@@ -337,7 +329,7 @@
 	Scsi_CD *cd = cdi->handle;
 	struct cdrom_generic_command cgc;
 	int result;
-	unsigned char buffer[32];
+	unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 
 	memset(&cgc, 0, sizeof(struct cdrom_generic_command));
 	cgc.timeout = IOCTL_TIMEOUT;
@@ -408,7 +400,7 @@
 	}
 
 	default:
-		return -EINVAL;
+		result = -EINVAL;
 	}
 
 #if 0
@@ -416,6 +408,7 @@
 		printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result);
 #endif
 
+	kfree(buffer);
 	return result;
 }
 
@@ -527,7 +520,7 @@
 	if (!xa_test)
 		return 0;
 
-	raw_sector = (unsigned char *) kmalloc(2048, GFP_DMA | GFP_KERNEL);
+	raw_sector = (unsigned char *) kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
 	if (!raw_sector)
 		return -ENOMEM;
 	if (0 == sr_read_sector(cd, cd->ms_offset + 16,
diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
--- a/drivers/scsi/sym53c8xx.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/scsi/sym53c8xx.c	Mon Feb 10 10:39:29 2003
@@ -4735,8 +4735,8 @@
 
 static void PRINT_ADDR(Scsi_Cmnd *cmd)
 {
-	struct host_data *host_data = (struct host_data *) cmd->host->hostdata;
-	PRINT_LUN(host_data->ncb, cmd->target, cmd->lun);
+	struct host_data *host_data = (struct host_data *) cmd->device->host->hostdata;
+	PRINT_LUN(host_data->ncb, cmd->device->id, cmd->device->lun);
 }
 
 /*==========================================================
@@ -6505,8 +6505,8 @@
 static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
 {
 /*	Scsi_Device        *device    = cmd->device; */
-	tcb_p tp                      = &np->target[cmd->target];
-	lcb_p lp		      = ncr_lp(np, tp, cmd->lun);
+	tcb_p tp                      = &np->target[cmd->device->id];
+	lcb_p lp		      = ncr_lp(np, tp, cmd->device->lun);
 	ccb_p cp;
 
 	u_char	idmsg, *msgptr;
@@ -6520,9 +6520,9 @@
 	**
 	**---------------------------------------------
 	*/
-	if ((cmd->target == np->myaddr	  ) ||
-		(cmd->target >= MAX_TARGET) ||
-		(cmd->lun    >= MAX_LUN   )) {
+	if ((cmd->device->id == np->myaddr	  ) ||
+		(cmd->device->id >= MAX_TARGET) ||
+		(cmd->device->lun    >= MAX_LUN   )) {
 		return(DID_BAD_TARGET);
         }
 
@@ -6562,7 +6562,7 @@
 			np->settle_time = tlimit;
 	}
 
-        if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
+        if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->device->id, cmd->device->lun))) {
 		insert_into_waiting_list(np, cmd);
 		return(DID_OK);
 	}
@@ -13592,7 +13592,7 @@
 
 int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
 {
-     ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+     ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
      unsigned long flags;
      int sts;
 
@@ -13661,9 +13661,9 @@
      if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n");
 
      if (done_list) {
-          NCR_LOCK_SCSI_DONE(done_list->host, flags);
+          NCR_LOCK_SCSI_DONE(done_list->device->host, flags);
           ncr_flush_done_cmds(done_list);
-          NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
+          NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags);
      }
 }
 
@@ -13684,9 +13684,9 @@
      NCR_UNLOCK_NCB(np, flags);
 
      if (done_list) {
-          NCR_LOCK_SCSI_DONE(done_list->host, flags);
+          NCR_LOCK_SCSI_DONE(done_list->device->host, flags);
           ncr_flush_done_cmds(done_list);
-          NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
+          NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags);
      }
 }
 
@@ -13700,7 +13700,7 @@
 int sym53c8xx_reset(Scsi_Cmnd *cmd)
 #endif
 {
-	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+	ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
 	Scsi_Cmnd *done_list;
@@ -13762,7 +13762,7 @@
 
 int sym53c8xx_abort(Scsi_Cmnd *cmd)
 {
-	ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
+	ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
 	Scsi_Cmnd *done_list;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c	Mon Feb 10 10:39:33 2003
@@ -330,7 +330,7 @@
 
 #define SYM_UCMD_PTR(cmd)  ((ucmd_p)(&(cmd)->SCp))
 #define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, Scsi_Cmnd, SCp)
-#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->host->hostdata)->ncb)
+#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb)
 
 /*
  *  Deal with DMA mapping/unmapping.
@@ -467,7 +467,7 @@
 	Scsi_Cmnd *cmd = cp->cam_ccb;
 	if (cmd)
 		printf("%s:%d:%d:", sym_name(SYM_SOFTC_PTR(cmd)),
-		       cmd->target,cmd->lun);
+		       cmd->device->id,cmd->device->lun);
 }
 
 /*
@@ -603,13 +603,13 @@
 		return;
 
 	sync_scsi_data(np, cmd);
-	retv = __sym_sniff_inquiry(np, cmd->target, cmd->lun,
+	retv = __sym_sniff_inquiry(np, cmd->device->id, cmd->device->lun,
 				   (u_char *) cmd->request_buffer,
 				   cmd->request_bufflen - resid);
 	if (retv < 0)
 		return;
 	else if (retv)
-		sym_update_trans_settings(np, &np->target[cmd->target]);
+		sym_update_trans_settings(np, &np->target[cmd->device->id]);
 }
 
 /*
@@ -687,9 +687,9 @@
 	 *  Minimal checkings, so that we will not 
 	 *  go outside our tables.
 	 */
-	if (ccb->target == np->myaddr ||
-	    ccb->target >= SYM_CONF_MAX_TARGET ||
-	    ccb->lun    >= SYM_CONF_MAX_LUN) {
+	if (ccb->device->id == np->myaddr ||
+	    ccb->device->id >= SYM_CONF_MAX_TARGET ||
+	    ccb->device->lun >= SYM_CONF_MAX_LUN) {
 		sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE);
 		return 0;
         }
@@ -697,7 +697,7 @@
 	/*
 	 *  Retreive the target descriptor.
 	 */
-	tp = &np->target[ccb->target];
+	tp = &np->target[ccb->device->id];
 
 	/*
 	 *  Complete the 1st INQUIRY command with error 
@@ -714,7 +714,7 @@
 	if (ccb->cmnd[0] == 0x12 || ccb->cmnd[0] == 0x0) {
 		if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
 		    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && 
-		     ccb->lun != 0)) {
+		     ccb->device->lun != 0)) {
 			tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
 			sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE);
 			return 0;
@@ -724,13 +724,13 @@
 	/*
 	 *  Select tagged/untagged.
 	 */
-	lp = sym_lp(np, tp, ccb->lun);
+	lp = sym_lp(np, tp, ccb->device->lun);
 	order = (lp && lp->s.reqtags) ? M_SIMPLE_TAG : 0;
 
 	/*
 	 *  Queue the SCSI IO.
 	 */
-	cp = sym_get_ccb(np, ccb->target, ccb->lun, order);
+	cp = sym_get_ccb(np, ccb->device->id, ccb->device->lun, order);
 	if (!cp)
 		return 1;	/* Means resource shortage */
 	(void) sym_queue_scsiio(np, ccb, cp);
@@ -1113,7 +1113,7 @@
 	struct sym_eh_wait eh, *ep = &eh;
 	char devname[20];
 
-	sprintf(devname, "%s:%d:%d", sym_name(np), cmd->target, cmd->lun);
+	sprintf(devname, "%s:%d:%d", sym_name(np), cmd->device->id, cmd->device->lun);
 
 	printf_warning("%s: %s operation started.\n", devname, opname);
 
@@ -1167,7 +1167,7 @@
 		sts = sym_abort_scsiio(np, cmd, 1);
 		break;
 	case SYM_EH_DEVICE_RESET:
-		sts = sym_reset_scsi_target(np, cmd->target);
+		sts = sym_reset_scsi_target(np, cmd->device->id);
 		break;
 	case SYM_EH_BUS_RESET:
 		sym_reset_scsi_bus(np, 1);
@@ -1843,7 +1843,7 @@
 		pci_unmap_mem(np->s.ram_va, np->ram_ws);
 #endif
 	/*
-	 *  Free O/S independant resources.
+	 *  Free O/S independent resources.
 	 */
 	sym_hcb_free(np);
 
@@ -2043,7 +2043,7 @@
 	}
 
 	/*
-	 *  Perform O/S independant stuff.
+	 *  Perform O/S independent stuff.
 	 */
 	if (sym_hcb_attach(np, fw, nvram))
 		goto attach_failed;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h	Mon Feb 10 10:39:33 2003
@@ -188,7 +188,7 @@
 typedef struct sym_shcb *shcb_p;
 
 /*
- *  Define a reference to the O/S dependant IO request.
+ *  Define a reference to the O/S dependent IO request.
  */
 typedef Scsi_Cmnd *cam_ccb_p;	/* Generic */
 typedef Scsi_Cmnd *cam_scsiio_p;/* SCSI I/O */
diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/scsi/tmscsim.c	Mon Feb 10 10:39:33 2003
@@ -1184,7 +1184,7 @@
 	if (!pSRB) return;
 	pcmd = dc390_Query_get ( pACB );
 	if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; }; /* should not happen */
-	pDCB = dc390_findDCB (pACB, pcmd->target, pcmd->lun);
+	pDCB = dc390_findDCB (pACB, pcmd->device->id, pcmd->device->lun);
 	if (!pDCB) 
 	{ 
 		dc390_Free_insert (pACB, pSRB);
@@ -1223,12 +1223,12 @@
     PDCB   pDCB;
     PSRB   pSRB;
     DC390_AFLAGS
-    PACB   pACB = (PACB) cmd->host->hostdata;
+    PACB   pACB = (PACB) cmd->device->host->hostdata;
 
 
     DEBUG0(/*  if(pACB->scan_devices) */	\
 	printk(KERN_INFO "DC390: Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",\
-		cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);)
+		cmd->cmnd[0],cmd->device->id,cmd->device->lun,cmd->pid);)
 
     DC390_LOCK_ACB;
     
@@ -1245,11 +1245,11 @@
     else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
 	pACB->scan_devices = 0;
 
-    if ( ( cmd->target >= pACB->pScsiHost->max_id ) || 
-	 (cmd->lun >= pACB->pScsiHost->max_lun) )
+    if ( ( cmd->device->id >= pACB->pScsiHost->max_id ) || 
+	 (cmd->device->lun >= pACB->pScsiHost->max_lun) )
     {
 /*	printk ("DC390: Ignore target %d lun %d\n",
-		cmd->target, cmd->lun); */
+		cmd->device->id, cmd->device->lun); */
 	DC390_UNLOCK_ACB;
 	//return (1);
 	done (cmd);
@@ -1257,15 +1257,15 @@
     }
 
     if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) && 
-       !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
+       !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
     {
         pACB->scan_devices = 1;
 
-	dc390_initDCB( pACB, &pDCB, cmd->target, cmd->lun );
+	dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun );
 	if (!pDCB)
 	  {
 	    printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", 
-		    cmd->target, cmd->lun);
+		    cmd->device->id, cmd->device->lun);
 	    DC390_UNLOCK_ACB;
 	    printk ("DC390: No DCB in queue_command!\n");
 #ifdef USE_NEW_EH
@@ -1277,10 +1277,10 @@
 	  };
             
     }
-    else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
+    else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
     {
 	printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
-		cmd->target, cmd->lun); 
+		cmd->device->id, cmd->device->lun); 
 	DC390_UNLOCK_ACB;
 	//return (1);
 	done (cmd);
@@ -1288,11 +1288,11 @@
     }
     else
     {
-	pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
+	pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
 	if (!pDCB)
 	 {  /* should never happen */
 	    printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n", 
-		    cmd->target, cmd->lun);
+		    cmd->device->id, cmd->device->lun);
 	    DC390_UNLOCK_ACB;
 	    printk ("DC390: No DCB in queuecommand (2)!\n");
 #ifdef USE_NEW_EH
@@ -1547,12 +1547,12 @@
     int   status;
     //ULONG sbac;
     DC390_AFLAGS
-    PACB  pACB = (PACB) cmd->host->hostdata;
+    PACB  pACB = (PACB) cmd->device->host->hostdata;
 
     DC390_LOCK_ACB;
 
     printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
-	    cmd->pid, cmd->target, cmd->lun);
+	    cmd->pid, cmd->device->id, cmd->device->lun);
 
     /* First scan Query list */
     if( pACB->QueryCnt )
@@ -1586,7 +1586,7 @@
 	}
     }
 	
-    pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
+    pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
     if( !pDCB ) goto  NOT_RUN;
 
     /* Added 98/07/02 KG */
@@ -1785,7 +1785,7 @@
 {
     UCHAR   bval;
     DC390_AFLAGS
-    PACB    pACB = (PACB) cmd->host->hostdata;
+    PACB    pACB = (PACB) cmd->device->host->hostdata;
 
     printk(KERN_INFO "DC390: RESET ... ");
 
@@ -2358,11 +2358,11 @@
 static void dc390_inquiry_done (Scsi_Cmnd* cmd)
 {
    printk (KERN_INFO "DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n",
-	   cmd->target, cmd->lun, cmd->result);
+	   cmd->device->id, cmd->device->lun, cmd->result);
    if (cmd->result)
    {
-	PACB pACB = (PACB)cmd->host->hostdata;
-	PDCB pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
+	PACB pACB = (PACB)cmd->device->host->hostdata;
+	PDCB pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
 	printk ("DC390: Unsetting DsCn, Sync and TagQ!\n");
 	if (pDCB)
 	{
@@ -2387,9 +2387,10 @@
    cmd->cmnd[4] = 0xff;
    
    cmd->cmd_len = 6; cmd->old_cmd_len = 6;
-   cmd->host = pACB->pScsiHost;
-   cmd->target = pDCB->TargetID;
-   cmd->lun = pDCB->TargetLUN; 
+/* TODO FIXME */
+/*    cmd->host = pACB->pScsiHost; */
+   cmd->device->id = pDCB->TargetID;
+   cmd->device->lun = pDCB->TargetLUN; 
    cmd->serial_number = 1;
    cmd->pid = 390;
    cmd->bufflen = 128;
@@ -2419,7 +2420,7 @@
 static void dc390_sendstart_done (Scsi_Cmnd* cmd)
 {
    printk (KERN_INFO "DC390: SENDSTART (ID %02x LUN %02x) returned %08x\n",
-	   cmd->target, cmd->lun, cmd->result);
+	   cmd->device->id, cmd->device->lun, cmd->result);
    kfree (cmd);
 };
 
@@ -2437,9 +2438,10 @@
    cmd->cmnd[4] = 0x01; /* START */
    
    cmd->cmd_len = 6; cmd->old_cmd_len = 6;
-   cmd->host = pACB->pScsiHost;
-   cmd->target = pDCB->TargetID;
-   cmd->lun = pDCB->TargetLUN; 
+/* TODO FIXME */
+/*    cmd->host = pACB->pScsiHost; */
+   cmd->device->id = pDCB->TargetID;
+   cmd->device->lun = pDCB->TargetLUN; 
    cmd->serial_number = 1;
    cmd->pid = 310;
    cmd->bufflen = 128;
@@ -2734,7 +2736,9 @@
    
  reset:
      {
-	Scsi_Cmnd cmd; cmd.host = pACB->pScsiHost;
+	Scsi_Cmnd cmd;
+	/* TODO FIXME */
+	/* cmd.host = pACB->pScsiHost; */
 	printk (KERN_WARNING "DC390: Driver reset requested!\n");
 	DC390_UNLOCK_ACB;
 	DC390_reset (&cmd, 0);
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/scsi/u14-34f.c	Mon Feb 10 10:39:24 2003
@@ -671,7 +671,7 @@
       tag_suffix = "";
       }
 
-   if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2)
+   if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
       link_suffix = ", sorted";
    else if (TLDEV(dev->type))
       link_suffix = ", unsorted";
@@ -680,7 +680,7 @@
 
    printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
           BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-          dev->new_queue_depth, link_suffix, tag_suffix);
+          dev->queue_depth, link_suffix, tag_suffix);
 
    return FALSE;
 }
@@ -1213,7 +1213,7 @@
    struct mscp *cpp;
 
    /* j is the board number */
-   j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
 
    if (SCpnt->host_scribble)
       panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
@@ -1247,13 +1247,13 @@
    SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
 
    if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
-                        BN(j), i, SCpnt->channel, SCpnt->target,
-                        SCpnt->lun, SCpnt->pid);
+                        BN(j), i, SCpnt->device->channel, SCpnt->device->id,
+                        SCpnt->device->lun, SCpnt->pid);
 
    cpp->opcode = OP_SCSI;
-   cpp->channel = SCpnt->channel;
-   cpp->target = SCpnt->target;
-   cpp->lun = SCpnt->lun;
+   cpp->channel = SCpnt->device->channel;
+   cpp->target = SCpnt->device->id;
+   cpp->lun = SCpnt->device->lun;
    cpp->SCpnt = SCpnt;
    cpp->cdb_len = SCpnt->cmd_len;
    memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
@@ -1264,7 +1264,7 @@
    /* Map DMA buffers and SG list */
    map_dma(i, j);
 
-   if (linked_comm && SCpnt->device->new_queue_depth > 2
+   if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
       flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
@@ -1275,7 +1275,7 @@
       unmap_dma(i, j);
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
-             BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);
+             BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid);
       return 1;
       }
 
@@ -1292,17 +1292,17 @@
 static int u14_34f_eh_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
       printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+             BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
       return SUCCESS;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
    printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+          BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -1368,9 +1368,9 @@
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
+   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
    printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
+          BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -1669,7 +1669,7 @@
       if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
          printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
                 " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
-                SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k);
+                SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k);
          HD(j)->cp_stat[k] = ABORTING;
          continue;
          }
@@ -1761,7 +1761,7 @@
 
    sync_dma(i, j);
 
-   if (linked_comm && SCpnt->device->new_queue_depth > 2
+   if (linked_comm && SCpnt->device->queue_depth > 2
                                      && TLDEV(SCpnt->device->type))
       flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
 
@@ -1781,7 +1781,7 @@
 
          /* If there was a bus reset, redo operation on each target */
          else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
-                  && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
+                  && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel])
             status = DID_BUS_BUSY << 16;
 
          /* Works around a flaw in scsi.c */
@@ -1794,29 +1794,29 @@
             status = DID_OK << 16;
 
          if (tstatus == GOOD)
-            HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
+            HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE;
 
          if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
              (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
                (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
             printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
                    "target_status 0x%x, sense key 0x%x.\n", BN(j),
-                   SCpnt->channel, SCpnt->target, SCpnt->lun,
+                   SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
                    SCpnt->pid, spp->target_status,
                    SCpnt->sense_buffer[2]);
 
-         HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
+         HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
 
          if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
          break;
       case ASST:     /* Selection Time Out */
 
-         if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
+         if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
             status = DID_ERROR << 16;
          else {
             status = DID_TIME_OUT << 16;
-            HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
+            HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++;
             }
 
          break;
@@ -1875,7 +1875,7 @@
       printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
              " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
              BN(j), i, spp->adapter_status, spp->target_status,
-             SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+             SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid,
              reg, HD(j)->iocount);
 
    unmap_dma(i, j);
diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
--- a/drivers/serial/8250_gsc.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/serial/8250_gsc.c	Mon Feb 10 10:39:30 2003
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 #include <asm/io.h>
 #include <asm/serial.h>
 
@@ -32,6 +33,7 @@
 	serial->type = PORT_16550A;
 
 	serial->line = line;
+	serial->iomap_base = address;
 	serial->iomem_base = ioremap(address, 0x8);
 
 	serial->irq = irq;
@@ -91,11 +93,13 @@
 	{ 0 }
 };
 
-/* Hack.  Dino's serial port will get listed first on some machines.
- * So we register this driver first which knows about Lasi's serial port.
- * This needs to get fixed properly somehow.
+/* Hack.  Some machines have SERIAL_0 attached to Lasi and SERIAL_1
+ * attached to Dino.  Unfortunately, Dino appears before Lasi in the device
+ * tree.  To ensure that ttyS0 == SERIAL_0, we register two drivers; one
+ * which only knows about Lasi and then a second which will find all the
+ * other serial ports.  HPUX ignores this problem.
  */
-static struct parisc_device_id serial1_tbl[] = {
+static struct parisc_device_id lasi_tbl[] = {
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
@@ -111,9 +115,9 @@
 
 MODULE_DEVICE_TABLE(parisc, serial_tbl);
 
-static struct parisc_driver serial1_driver = {
-	.name		= "Serial RS232",
-	.id_table	= serial1_tbl,
+static struct parisc_driver lasi_driver = {
+	.name		= "Lasi RS232",
+	.id_table	= lasi_tbl,
 	.probe		= serial_init_chip,
 };
 
@@ -125,7 +129,7 @@
 
 int __init probe_serial_gsc(void)
 {
-	register_parisc_driver(&serial1_driver);
+	register_parisc_driver(&lasi_driver);
 	register_parisc_driver(&serial_driver);
 	return 0;
 }
diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig	Mon Feb 10 10:39:32 2003
+++ b/drivers/serial/Kconfig	Mon Feb 10 10:39:32 2003
@@ -23,7 +23,7 @@
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  serial.o.
+	  serial.
 	  [WARNING: Do not compile this driver as a module if you are using
 	  non-standard serial ports, since the configuration information will
 	  be lost when the driver is unloaded.  This limitation may be lifted
@@ -73,7 +73,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called serial_cs.o.  If you want to compile it as
+	  The module will be called serial_cs.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/serial/Makefile	Mon Feb 10 10:39:27 2003
@@ -4,8 +4,6 @@
 #  $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
 #
 
-export-objs	:= core.o 8250.o 8250_pci.o suncore.o
-
 serial-8250-y :=
 serial-8250-$(CONFIG_GSC) += 8250_gsc.o
 serial-8250-$(CONFIG_PCI) += 8250_pci.o
diff -Nru a/drivers/serial/mux.c b/drivers/serial/mux.c
--- a/drivers/serial/mux.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/serial/mux.c	Mon Feb 10 10:39:30 2003
@@ -23,7 +23,9 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/console.h>
+#include <linux/slab.h>
 #include <asm/io.h>
+#include <asm/parisc-device.h>
 
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
@@ -32,34 +34,35 @@
 
 #include <linux/serial_core.h>
 
-#define MUX_NR 1
-
 #define MUX_OFFSET 0x800
 #define MUX_LINE_OFFSET 0x80
 
 #define MUX_FIFO_SIZE 255
-#define MUX_MIN_FREE_SIZE 32
-
-#define MUX_FIFO_DRAIN_DELAY 1
-#define MUX_POLL_DELAY (30 * HZ / 1000) 
+#define MUX_POLL_DELAY (30 * HZ / 1000)
 
-#define IO_COMMAND_REG_OFFSET 0x30
-#define IO_STATUS_REG_OFFSET 0x34
 #define IO_DATA_REG_OFFSET 0x3c
 #define IO_DCOUNT_REG_OFFSET 0x40
-#define IO_UCOUNT_REG_OFFSET 0x44
-#define IO_FIFOS_REG_OFFSET 0x48
 
 #define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
 #define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
 #define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
 
+#define UART_NR 8
+struct mux_card {
+	struct uart_port ports[UART_NR];
+	struct uart_driver drv;
+	struct mux_card *next;
+};
+
+static struct mux_card mux_card_head = {
+	.next = NULL,
+};
 
-static struct uart_port mux_ports[MUX_NR];
 static struct timer_list mux_timer;
 
 #define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
 #define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
+#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
 
 /**
  * mux_tx_empty - Check if the transmitter fifo is empty.
@@ -205,8 +208,8 @@
 static void mux_read(struct uart_port *port)
 {
 	int data;
-	__u32 start_count = port->icount.rx;
 	struct tty_struct *tty = port->info->tty;
+	__u32 start_count = port->icount.rx;
 
 	while(1) {
 		data = __raw_readl((unsigned long)port->membase
@@ -294,7 +297,7 @@
 }
 
 /**
- * release_port - Release memory and IO regions.
+ * mux_release_port - Release memory and IO regions.
  * @port: Ptr to the uart_port.
  * 
  * Release any memory and IO region resources currently in use by
@@ -350,17 +353,26 @@
 }
 
 /**
- * mux_drv_poll - Mux poll function.   
+ * mux_drv_poll - Mux poll function.
  * @unused: Unused variable
  *
  * This function periodically polls the Serial MUX to check for new data.
  */
 static void mux_poll(unsigned long unused)
 {  
-	struct uart_port *port = &mux_ports[0];
+	int i;
+	struct mux_card *card = &mux_card_head;
+
+	while(card) {
+		for(i = 0; i < UART_NR; ++i) {
+			if(!card->ports[i].info)
+				continue;
 
-	mux_read(port);
-	mux_write(port);
+			mux_read(&card->ports[i]);
+			mux_write(&card->ports[i]);
+		}
+		card = card->next;
+	}
 	mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
 }
 
@@ -395,20 +407,6 @@
 	.verify_port =		mux_verify_port,
 };
 
-static struct uart_driver mux_reg = {
-	.owner =		THIS_MODULE,
-	.driver_name =		"ttyB",
-#ifdef CONFIG_DEVFS_FS
-	.dev_name =		"ttyB%d",
-#else
-	.dev_name =		"ttyB%d",
-#endif
-	.major =		MUX_MAJOR,
-	.minor =		0,
-	.nr =			MUX_NR, 
-	.cons =			MUX_CONSOLE,
-};
-
 /**
  * mux_probe - Determine if the Serial Mux should claim this device.
  * @dev: The parisc device.
@@ -418,36 +416,77 @@
  */
 static int __init mux_probe(struct parisc_device *dev)
 {
-	int i, ret;
-	struct uart_port *port = &mux_ports[0];
+	int i, j, ret, ports, port_cnt = 0;
+	u8 iodc_data[8];
+	unsigned long bytecnt;
+	struct uart_port *port;
+	struct mux_card *card = &mux_card_head;
+
+	ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8);
+	if(ret != PDC_OK) {
+		printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
+		return 1;
+	}
 
-	init_timer(&mux_timer);
-	mux_timer.function = mux_poll;
+	ports = GET_MUX_PORTS(iodc_data);
+ 	printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n",
+		ports);
+
+	if(!card->drv.nr) {
+		init_timer(&mux_timer);
+		mux_timer.function = mux_poll;
+	} else {
+		port_cnt += UART_NR;
+		while(card->next) {
+			card = card->next;
+			port_cnt += UART_NR;
+		} 
+	}
 
-	printk(KERN_INFO "Serial mux driver Revision: 0.1\n");
+	for(i = 0; i < ports / UART_NR; ++i) {
+		if(card->drv.nr) {
+			card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL);
+			if(!card->next) {
+				printk(KERN_ERR "Serial mux: Unable to allocate memory.\n");
+				return 1;
+			}
+			memset(card->next, '\0', sizeof(struct mux_card));
+			card = card->next;
+		}
 
-	ret = uart_register_driver(&mux_reg);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < MUX_NR; i++) {
-		port = &mux_ports[i];
-
-		port->iobase	= 0;
-		port->mapbase	= dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
-		port->membase	= ioremap(port->mapbase, MUX_LINE_OFFSET);
-		port->iotype	= SERIAL_IO_MEM;
-		port->type	= PORT_MUX;
-		port->irq	= SERIAL_IRQ_NONE;
-		port->uartclk	= 0;
-		port->fifosize	= MUX_FIFO_SIZE;
-		port->ops	= &mux_pops;
-		port->flags	= UPF_BOOT_AUTOCONF;
-		port->line	= 0;
+		card->drv.owner = THIS_MODULE;
+		card->drv.driver_name = "ttyB";
+		card->drv.dev_name = "ttyB%d";
+		card->drv.major = MUX_MAJOR;
+		card->drv.minor = port_cnt;
+		card->drv.nr = UART_NR;
+		card->drv.cons = MUX_CONSOLE;
+
+		ret = uart_register_driver(&card->drv);
+		if(ret) {
+			printk(KERN_ERR "Serial mux: Unable to register driver.\n");
+			return 1;
+		}
 
-		uart_add_one_port(&mux_reg, port);
-	}
+		for(j = 0; j < UART_NR; ++j) {
+			port = &card->ports[j];
 
+			port->iobase	= 0;
+			port->mapbase	= dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET);
+			port->membase	= ioremap(port->mapbase, MUX_LINE_OFFSET);
+			port->iotype	= SERIAL_IO_MEM;
+			port->type	= PORT_MUX;
+			port->irq	= SERIAL_IRQ_NONE;
+			port->uartclk	= 0;
+			port->fifosize	= MUX_FIFO_SIZE;
+			port->ops	= &mux_pops;
+			port->flags	= UPF_BOOT_AUTOCONF;
+			port->line	= j;
+			ret = uart_add_one_port(&card->drv, port);
+			BUG_ON(ret);
+		}
+		port_cnt += UART_NR;
+	}
 	return 0;
 }
 
@@ -459,9 +498,9 @@
 MODULE_DEVICE_TABLE(parisc, mux_tbl);
 
 static struct parisc_driver mux_driver = {
-	.name     = "Serial MUX driver",
-	.id_table = mux_tbl,
-	.probe    = mux_probe,
+	.name =		"Serial MUX",
+	.id_table =	mux_tbl,
+	.probe =	mux_probe,
 };
 
 /**
@@ -482,12 +521,13 @@
 static void __exit mux_exit(void)
 {
 	int i;
+	struct mux_card *card = &mux_card_head;
 
-	for (i = 0; i < MUX_NR; i++) {
-		uart_remove_one_port(&mux_reg, &mux_ports[i]);
+	for (i = 0; i < UART_NR; i++) {
+		uart_remove_one_port(&card->drv, &card->ports[i]);
 	}
 
-	uart_unregister_driver(&mux_reg);
+	uart_unregister_driver(&card->drv);
 }
 
 module_init(mux_init);
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- a/drivers/serial/uart00.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/serial/uart00.c	Mon Feb 10 10:39:25 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/char/uart00.c
+ *  linux/drivers/serial/uart00.c
  *
  *  Driver for UART00 serial ports
  *
@@ -149,7 +149,7 @@
 			goto ignore_char;
 	} else if (rds & UART_RDS_PE_MSK)
 		port->icount.parity++;
-	else if (rds & UART_RDS_PE_MSK)
+	else if (rds & UART_RDS_FE_MSK)
 		port->icount.frame++;
 	if (rds & UART_RDS_OE_MSK)
 		port->icount.overrun++;
@@ -168,7 +168,7 @@
 	else if (rds & UART_RDS_FE_MSK)
 		flg = TTY_FRAME;
 
-	if (status & UART_RDS_OE_MSK) {
+	if (rds & UART_RDS_OE_MSK) {
 		/*
 		 * CHECK: does overrun affect the current character?
 		 * ASSUMPTION: it does not.
diff -Nru a/drivers/sgi/char/Makefile b/drivers/sgi/char/Makefile
--- a/drivers/sgi/char/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/sgi/char/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-export-objs	:= newport.o shmiq.o sgicons.o usema.o rrm.o
 obj-y		:= newport.o shmiq.o sgicons.o usema.o streamable.o
 
 obj-$(CONFIG_SGI_SERIAL)	+= sgiserial.o
diff -Nru a/drivers/tc/Makefile b/drivers/tc/Makefile
--- a/drivers/tc/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/tc/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,11 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs	:= tc.o
-
 # Object file lists.
 
 obj-$(CONFIG_TC) += tc.o
diff -Nru a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig
--- a/drivers/telephony/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/telephony/Kconfig	Mon Feb 10 10:39:24 2003
@@ -16,7 +16,7 @@
 	  This support is also available as a module.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  phonedev.o.
+	  phonedev.
 
 config PHONE_IXJ
 	tristate "QuickNet Internet LineJack/PhoneJack support"
@@ -25,7 +25,7 @@
 	  Say M if you have a telephony card manufactured by Quicknet
 	  Technologies, Inc.  These include the Internet PhoneJACK and
 	  Internet LineJACK Telephony Cards. You will get a module called
-	  ixj.o.
+	  ixj.
 
 	  For the ISA versions of these products, you can configure the
 	  cards using the isapnp tools (pnpdump/isapnp) or you can use the
diff -Nru a/drivers/telephony/Makefile b/drivers/telephony/Makefile
--- a/drivers/telephony/Makefile	Mon Feb 10 10:39:28 2003
+++ b/drivers/telephony/Makefile	Mon Feb 10 10:39:28 2003
@@ -2,8 +2,6 @@
 # Makefile for drivers/telephony
 #
 
-export-objs := phonedev.o ixj.o
-
 obj-$(CONFIG_PHONE) += phonedev.o
 obj-$(CONFIG_PHONE_IXJ) += ixj.o
 obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
diff -Nru a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
--- a/drivers/telephony/ixj_pcmcia.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/telephony/ixj_pcmcia.c	Mon Feb 10 10:39:31 2003
@@ -63,6 +63,7 @@
 	if (!link)
 		return NULL;
 	memset(link, 0, sizeof(struct dev_link_t));
+	init_timer(&link->release);
 	link->release.function = &ixj_cs_release;
 	link->release.data = (u_long) link;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
diff -Nru a/drivers/usb/Kconfig b/drivers/usb/Kconfig
--- a/drivers/usb/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/Kconfig	Mon Feb 10 10:39:24 2003
@@ -35,7 +35,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbcore.o.  If you want to compile it as a
+	  The module will be called usbcore.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/usb/core/Kconfig"
@@ -84,7 +84,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called uss720.o. If you want to compile it as a
+	  The module will be called uss720. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 source "drivers/usb/serial/Kconfig"
diff -Nru a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
--- a/drivers/usb/class/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/class/Kconfig	Mon Feb 10 10:39:23 2003
@@ -13,7 +13,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called audio.o. If you want to compile it as a
+	  The module will be called audio. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem"
@@ -38,7 +38,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called bluetty.o. If you want to compile it as
+	  The module will be called bluetty. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_MIDI
@@ -61,7 +61,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usb-midi.o. If you want to compile it as a
+	  The module will be called usb-midi. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_ACM
@@ -78,7 +78,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called acm.o. If you want to compile it as a
+	  The module will be called acm. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_PRINTER
@@ -90,6 +90,6 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called printer.o. If you want to compile it as a
+	  The module will be called printer. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/usb/class/cdc-acm.c	Mon Feb 10 10:39:29 2003
@@ -257,7 +257,7 @@
 	if (urb->status)
 		dbg("nonzero read bulk status received: %d", urb->status);
 
-	if (!urb->status & !acm->throttle)  {
+	if (!urb->status && !acm->throttle)  {
 		for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
 			/* if we insert more than TTY_FLIPBUF_SIZE characters,
 			 * we drop them. */
@@ -697,6 +697,7 @@
 
 static struct usb_device_id acm_ids[] = {
 	{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
+	{ USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) },
 	{ }
 };
 
diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
--- a/drivers/usb/core/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/core/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for USB Core files and filesystem
 #
 
-export-objs	:= usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o
-
 usbcore-objs	:= usb.o usb-debug.o hub.o hcd.o urb.o message.o \
 			config.o file.o buffer.o driverfs.o
 
diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/core/devices.c	Mon Feb 10 10:39:33 2003
@@ -68,7 +68,7 @@
 
 static char *format_topo =
 /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
-  "T:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
+"\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 =
 /* S:  Manufacturer=xxxx */
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Mon Feb 10 10:39:28 2003
+++ b/drivers/usb/core/hcd.c	Mon Feb 10 10:39:28 2003
@@ -310,9 +310,9 @@
 	} else
 	    return 0;
 
-	data [0] = 2 + ascii2utf (buf, data + 2, len - 2);
+	data [0] = 2 * (strlen (buf) + 1);
 	data [1] = 3;	/* type == string */
-	return data [0];
+	return 2 + ascii2utf (buf, data + 2, len - 2);
 }
 
 
@@ -1029,8 +1029,11 @@
 		return status;
 	}
 
-	/* lower level hcd code should use *_dma exclusively */
-	if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
+	/* lower level hcd code should use *_dma exclusively,
+	 * unless it uses pio or talks to another transport.
+	 */
+	if (!(urb->transfer_flags & URB_NO_DMA_MAP)
+			&& hcd->controller->dma_mask) {
 		if (usb_pipecontrol (urb->pipe))
 			urb->setup_dma = dma_map_single (
 					hcd->controller,
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/core/hcd.h	Mon Feb 10 10:39:24 2003
@@ -111,6 +111,13 @@
 	 */
 };
 
+/* 2.4 does this a bit differently ... */
+static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
+{
+	return &hcd->self;
+}
+
+
 struct hcd_dev {	/* usb_device.hcpriv points to this */
 	struct list_head	dev_list;	/* on this hcd */
 	struct list_head	urb_list;	/* pending on this dev */
@@ -342,6 +349,13 @@
 
 extern int usb_register_root_hub (struct usb_device *usb_dev,
 		struct device *parent_dev);
+
+/* for portability to 2.4, hcds should call this */
+static inline int hcd_register_root (struct usb_hcd *hcd)
+{
+	return usb_register_root_hub (
+		hcd_to_bus (hcd)->root_hub, hcd->controller);
+}
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/core/message.c	Mon Feb 10 10:39:24 2003
@@ -206,7 +206,8 @@
 		kfree (io->urbs);
 		io->urbs = 0;
 	}
-	usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
+	if (io->dev->dev.dma_mask != 0)
+		usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
 	io->dev = 0;
 }
 
@@ -301,6 +302,7 @@
 {
 	int			i;
 	int			urb_flags;
+	int			dma;
 
 	if (!io || !dev || !sg
 			|| usb_pipecontrol (pipe)
@@ -314,8 +316,16 @@
 	io->sg = sg;
 	io->nents = nents;
 
+	/* not all host controllers use DMA (like the mainstream pci ones);
+	 * they can use PIO (sl811) or be software over another transport.
+	 */
+	dma = (dev->dev.dma_mask != 0);
+	if (dma)
+		io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
+	else
+		io->entries = nents;
+
 	/* initialize all the urbs we'll use */
-	io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
 	if (io->entries <= 0)
 		return io->entries;
 
@@ -347,8 +357,17 @@
 		io->urbs [i]->status = -EINPROGRESS;
 		io->urbs [i]->actual_length = 0;
 
-		io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
-		len = sg_dma_len (sg + i);
+		if (dma) {
+			/* hc may use _only_ transfer_dma */
+			io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
+			len = sg_dma_len (sg + i);
+		} else {
+			/* hc may use _only_ transfer_buffer */
+			io->urbs [i]->transfer_buffer =
+				page_address (sg [i].page) + sg [i].offset;
+			len = sg [i].length;
+		}
+
 		if (length) {
 			len = min_t (unsigned, len, length);
 			length -= len;
@@ -434,9 +453,7 @@
 			retval = 0;
 			i--;
 			// FIXME:  should it usb_sg_cancel() on INTERRUPT?
-			// how about imposing a backoff?
-			set_current_state (TASK_UNINTERRUPTIBLE);
-			schedule ();
+			yield ();
 			break;
 
 			/* no error? continue immediately.
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/usb/core/usb.c	Mon Feb 10 10:39:27 2003
@@ -1224,7 +1224,8 @@
  *
  * Return value is either null (indicating no buffer could be mapped), or
  * the parameter.  URB_NO_DMA_MAP is added to urb->transfer_flags if the
- * operation succeeds.
+ * operation succeeds.  If the device is connected to this system through
+ * a non-DMA controller, this operation always succeeds.
  *
  * This call would normally be used for an urb which is reused, perhaps
  * as the target of a large periodic transfer, with usb_buffer_dmasync()
@@ -1245,12 +1246,15 @@
 			|| !(controller = bus->controller))
 		return 0;
 
-	urb->transfer_dma = dma_map_single (controller,
+	if (controller->dma_mask) {
+		urb->transfer_dma = dma_map_single (controller,
 			urb->transfer_buffer, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
 	// FIXME generic api broken like pci, can't report errors
 	// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
+	} else
+		urb->transfer_dma = ~0;
 	urb->transfer_flags |= URB_NO_DMA_MAP;
 	return urb;
 }
@@ -1271,7 +1275,8 @@
 			|| !(controller = bus->controller))
 		return;
 
-	dma_sync_single (controller,
+	if (controller->dma_mask)
+		dma_sync_single (controller,
 			urb->transfer_dma, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
@@ -1295,10 +1300,12 @@
 			|| !(controller = bus->controller))
 		return;
 
-	dma_unmap_single (controller,
+	if (controller->dma_mask)
+		dma_unmap_single (controller,
 			urb->transfer_dma, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	urb->transfer_flags &= ~URB_NO_DMA_MAP;
 }
 
 /**
@@ -1336,7 +1343,8 @@
 	if (!dev
 			|| usb_pipecontrol (pipe)
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->controller)
+			|| !controller->dma_mask)
 		return -1;
 
 	// FIXME generic api broken like pci, can't report errors
@@ -1362,7 +1370,8 @@
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->controller)
+			|| !controller->dma_mask)
 		return;
 
 	dma_sync_sg (controller, sg, n_hw_ents,
@@ -1386,7 +1395,8 @@
 
 	if (!dev
 			|| !(bus = dev->bus)
-			|| !(controller = bus->controller))
+			|| !(controller = bus->controller)
+			|| !controller->dma_mask)
 		return;
 
 	dma_unmap_sg (controller, sg, n_hw_ents,
diff -Nru a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
--- a/drivers/usb/host/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/host/Kconfig	Mon Feb 10 10:39:33 2003
@@ -28,7 +28,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ehci-hcd.o. If you want to compile it as a
+	  The module will be called ehci-hcd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_OHCI_HCD
@@ -46,7 +46,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ohci-hcd.o. If you want to compile it
+	  The module will be called ohci-hcd. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_UHCI_HCD
@@ -64,7 +64,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called uhci-hcd.o. If you want to compile it as a
+	  The module will be called uhci-hcd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SL811HS
@@ -77,6 +77,6 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called hc_sl811.o. If you want to compile it
+	  The module will be called hc_sl811. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/host/ehci-dbg.c	Mon Feb 10 10:39:31 2003
@@ -277,7 +277,26 @@
 		default: tmp = '?'; break; \
 		}; tmp; })
 
-static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
+static inline char token_mark (u32 token)
+{
+	token = le32_to_cpu (token);
+	if (token & QTD_STS_ACTIVE)
+		return '*';
+	if (token & QTD_STS_HALT)
+		return '-';
+	if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */
+			|| QTD_LENGTH (token) == 0)
+		return ' ';
+	/* tries to advance through hw_alt_next */
+	return '/';
+}
+
+static void qh_lines (
+	struct ehci_hcd *ehci,
+	struct ehci_qh *qh,
+	char **nextp,
+	unsigned *sizep
+)
 {
 	u32			scratch;
 	u32			hw_curr;
@@ -286,26 +305,49 @@
 	unsigned		temp;
 	unsigned		size = *sizep;
 	char			*next = *nextp;
+	char			mark;
 
+	mark = token_mark (qh->hw_token);
+	if (mark == '/') {	/* qh_alt_next controls qh advance? */
+		if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
+			mark = '#';	/* blocked */
+		else if (qh->hw_alt_next & cpu_to_le32 (0x01))
+			mark = '.';	/* use hw_qtd_next */
+		/* else alt_next points to some other qtd */
+	}
 	scratch = cpu_to_le32p (&qh->hw_info1);
-	hw_curr = cpu_to_le32p (&qh->hw_current);
+	hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0;
 	temp = snprintf (next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)",
+			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
 			qh, scratch & 0x007f,
 			speed_char (scratch),
 			(scratch >> 8) & 0x000f,
 			scratch, cpu_to_le32p (&qh->hw_info2),
-			hw_curr, cpu_to_le32p (&qh->hw_token));
+			cpu_to_le32p (&qh->hw_token), mark,
+			(cpu_to_le32 (0x8000000) & qh->hw_token)
+				? "data0" : "data1",
+			(cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f);
 	size -= temp;
 	next += temp;
 
+	/* hc may be modifying the list as we read it ... */
 	list_for_each (entry, &qh->qtd_list) {
 		td = list_entry (entry, struct ehci_qtd, qtd_list);
 		scratch = cpu_to_le32p (&td->hw_token);
+		mark = ' ';
+		if (hw_curr == td->qtd_dma)
+			mark = '*';
+		else if (qh->hw_qtd_next == td->qtd_dma)
+			mark = '+';
+		else if (QTD_LENGTH (scratch)) {
+			if (td->hw_alt_next == ehci->async->hw_alt_next)
+				mark = '#';
+			else if (td->hw_alt_next != EHCI_LIST_END)
+				mark = '/';
+		}
 		temp = snprintf (next, size,
-				"\n\t%std/%p %s len=%d %08x urb %p",
-				(hw_curr == td->qtd_dma) ? "*" : "",
-				td, ({ char *tmp;
+				"\n\t%p%c%s len=%d %08x urb %p",
+				td, mark, ({ char *tmp;
 				 switch ((scratch>>8)&0x03) {
 				 case 0: tmp = "out"; break;
 				 case 1: tmp = "in"; break;
@@ -315,13 +357,27 @@
 				(scratch >> 16) & 0x7fff,
 				scratch,
 				td->urb);
+		if (temp < 0)
+			temp = 0;
+		else if (size < temp)
+			temp = size;
 		size -= temp;
 		next += temp;
+		if (temp == size)
+			goto done;
 	}
 
 	temp = snprintf (next, size, "\n");
-	*sizep = size - temp;
-	*nextp = next + temp;
+	if (temp < 0)
+		temp = 0;
+	else if (size < temp)
+		temp = size;
+	size -= temp;
+	next += temp;
+
+done:
+	*sizep = size;
+	*nextp = next;
 }
 
 static ssize_t
@@ -344,14 +400,15 @@
 	 * one QH per line, and TDs we know about
 	 */
 	spin_lock_irqsave (&ehci->lock, flags);
-	for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh)
-		qh_lines (qh, &next, &size);
-	if (ehci->reclaim) {
+	for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
+		qh_lines (ehci, qh, &next, &size);
+	if (ehci->reclaim && size > 0) {
 		temp = snprintf (next, size, "\nreclaim =\n");
 		size -= temp;
 		next += temp;
 
-		qh_lines (ehci->reclaim, &next, &size);
+		for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim)
+			qh_lines (ehci, qh, &next, &size);
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
@@ -421,7 +478,7 @@
 						scratch & 0x007f,
 						(scratch >> 8) & 0x000f,
 						p.qh->usecs, p.qh->c_usecs,
-						scratch >> 16);
+						0x7ff & (scratch >> 16));
 
 					/* FIXME TD info too */
 
@@ -490,7 +547,8 @@
 
 	/* Capability Registers */
 	i = readw (&ehci->caps->hci_version);
-	temp = snprintf (next, size, "EHCI %x.%02x, hcd state %d\n",
+	temp = snprintf (next, size,
+		"EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n",
 		i >> 8, i & 0x0ff, ehci->hcd.state);
 	size -= temp;
 	next += temp;
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/usb/host/ehci-hcd.c	Mon Feb 10 10:39:29 2003
@@ -94,7 +94,7 @@
  * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "2002-Nov-29"
+#define DRIVER_VERSION "2003-Jan-22"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -110,10 +110,11 @@
 
 /* magic numbers that can affect system performance */
 #define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
-#define	EHCI_TUNE_RL_HS		0	/* nak throttle; see 4.9 */
+#define	EHCI_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
 #define	EHCI_TUNE_RL_TT		0
 #define	EHCI_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
 #define	EHCI_TUNE_MULT_TT	1
+#define	EHCI_TUNE_FLS		2	/* (small) 256 frame schedule */
 
 #define EHCI_WATCHDOG_JIFFIES	(HZ/100)	/* arbitrary; ~10 msec */
 #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
@@ -416,13 +417,26 @@
 			ehci_info (ehci, "enabled 64bit PCI DMA\n");
 	}
 
+	/* help hc dma work well with cachelines */
+	pci_set_mwi (ehci->hcd.pdev);
+
 	/* clear interrupt enables, set irq latency */
 	temp = readl (&ehci->regs->command) & 0xff;
 	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
 		log2_irq_thresh = 0;
 	temp |= 1 << (16 + log2_irq_thresh);
 	// if hc can park (ehci >= 0.96), default is 3 packets per async QH 
-	// keeping default periodic framelist size
+	if (HCC_PGM_FRAMELISTLEN (hcc_params)) {
+		/* periodic schedule size can be smaller than default */
+		temp &= ~(3 << 2);
+		temp |= (EHCI_TUNE_FLS << 2);
+		switch (EHCI_TUNE_FLS) {
+		case 0: ehci->periodic_size = 1024; break;
+		case 1: ehci->periodic_size = 512; break;
+		case 2: ehci->periodic_size = 256; break;
+		default:	BUG ();
+		}
+	}
 	temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
 	// Philips, Intel, and maybe others need CMD_RUN before the
 	// root hub will detect new devices (why?); NEC doesn't
@@ -759,7 +773,6 @@
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	struct ehci_qh		*qh;
 	unsigned long		flags;
-	int			maybe_irq = 1;
 
 	spin_lock_irqsave (&ehci->lock, flags);
 	switch (usb_pipetype (urb->pipe)) {
@@ -769,23 +782,23 @@
 		qh = (struct ehci_qh *) urb->hcpriv;
 		if (!qh)
 			break;
-		while (qh->qh_state == QH_STATE_LINKED
+
+		/* if we need to use IAA and it's busy, defer */
+		if (qh->qh_state == QH_STATE_LINKED
 				&& ehci->reclaim
 				&& HCD_IS_RUNNING (ehci->hcd.state)
 				) {
-			spin_unlock_irqrestore (&ehci->lock, flags);
+			struct ehci_qh		*last;
 
-			if (maybe_irq) {
-				if (in_interrupt ())
-					return -EAGAIN;
-				maybe_irq = 0;
-			}
-			/* let pending unlinks complete, so this can start */
-			wait_ms (1);
+			for (last = ehci->reclaim;
+					last->reclaim;
+					last = last->reclaim)
+				continue;
+			qh->qh_state = QH_STATE_UNLINK_WAIT;
+			last->reclaim = qh;
 
-			spin_lock_irqsave (&ehci->lock, flags);
-		}
-		if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
+		/* bypass IAA if the hc can't care */
+		} else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
 			end_unlink_async (ehci, NULL);
 
 		/* something else might have unlinked the qh by now */
diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/usb/host/ehci-mem.c	Mon Feb 10 10:39:32 2003
@@ -75,8 +75,6 @@
 	qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma);
 	if (qtd != 0) {
 		ehci_qtd_init (qtd, dma);
-		if (ehci->async)
-			qtd->hw_alt_next = ehci->async->hw_alt_next;
 	}
 	return qtd;
 }
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/host/ehci-q.c	Mon Feb 10 10:39:31 2003
@@ -43,7 +43,8 @@
 /* fill a qtd, returning how much of the buffer we were able to queue up */
 
 static int
-qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token)
+qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
+		int token, int maxpacket)
 {
 	int	i, count;
 	u64	addr = buf;
@@ -69,6 +70,10 @@
 			else
 				count = len;
 		}
+
+		/* short packets may only terminate transfers */
+		if (count != len)
+			count -= (count % maxpacket);
 	}
 	qtd->hw_token = cpu_to_le32 ((count << 16) | token);
 	qtd->length = count;
@@ -85,7 +90,7 @@
 {
 	qh->hw_current = 0;
 	qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
-	qh->hw_alt_next = ehci->async->hw_alt_next;
+	qh->hw_alt_next = EHCI_LIST_END;
 
 	/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
 	wmb ();
@@ -96,7 +101,7 @@
 
 #define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
 
-static inline void qtd_copy_status (
+static void qtd_copy_status (
 	struct ehci_hcd *ehci,
 	struct urb *urb,
 	size_t length,
@@ -224,12 +229,24 @@
 {
 	struct ehci_qtd		*last = 0, *end = qh->dummy;
 	struct list_head	*entry, *tmp;
-	int			stopped = 0;
+	int			stopped;
 	unsigned		count = 0;
+	int			do_status = 0;
+	u8			state;
 
 	if (unlikely (list_empty (&qh->qtd_list)))
 		return count;
 
+	/* completions (or tasks on other cpus) must never clobber HALT
+	 * till we've gone through and cleaned everything up, even when
+	 * they add urbs to this qh's queue or mark them for unlinking.
+	 *
+	 * NOTE:  unlinking expects to be done in queue order.
+	 */
+	state = qh->qh_state;
+	qh->qh_state = QH_STATE_COMPLETING;
+	stopped = (state == QH_STATE_IDLE);
+
 	/* remove de-activated QTDs from front of queue.
 	 * after faults (including short reads), cleanup this urb
 	 * then let the queue advance.
@@ -261,7 +278,6 @@
 		rmb ();
 		token = le32_to_cpu (qtd->hw_token);
 		stopped = stopped
-			|| (qh->qh_state == QH_STATE_IDLE)
 			|| (HALT_BIT & qh->hw_token) != 0
 			|| (ehci->hcd.state == USB_STATE_HALT);
 
@@ -271,36 +287,53 @@
 			/* magic dummy for short reads; won't advance */
 			if (IS_SHORT_READ (token)
 					&& !(token & QTD_STS_HALT)
-					&& ehci->async->hw_alt_next
-						== qh->hw_alt_next)
+					&& (qh->hw_alt_next & QTD_MASK)
+						== ehci->async->hw_alt_next) {
+				stopped = 1;
 				goto halt;
+			}
 
 		/* stop scanning when we reach qtds the hc is using */
 		} else if (likely (!stopped)) {
-			last = 0;
 			break;
 
 		} else {
-			/* ignore active qtds unless some previous qtd
+			/* ignore active urbs unless some previous qtd
 			 * for the urb faulted (including short read) or
 			 * its urb was canceled.  we may patch qh or qtds.
 			 */
-			if ((token & QTD_STS_ACTIVE)
-					&& urb->status == -EINPROGRESS) {
-				last = 0;
+			if (likely (urb->status == -EINPROGRESS))
+				continue;
+			
+			/* issue status after short control reads */
+			if (unlikely (do_status != 0)
+					&& QTD_PID (token) == 0 /* OUT */) {
+				do_status = 0;
 				continue;
 			}
+
+			/* token in overlay may be most current */
+			if (state == QH_STATE_IDLE
+					&& cpu_to_le32 (qtd->qtd_dma)
+						== qh->hw_current)
+				token = le32_to_cpu (qh->hw_token);
+
+			/* force halt for unlinked or blocked qh, so we'll
+			 * patch the qh later and so that completions can't
+			 * activate it while we "know" it's stopped.
+			 */
 			if ((HALT_BIT & qh->hw_token) == 0) {
 halt:
 				qh->hw_token |= HALT_BIT;
 				wmb ();
-				stopped = 1;
 			}
 		}
  
 		/* remove it from the queue */
 		spin_lock (&urb->lock);
 		qtd_copy_status (ehci, urb, qtd->length, token);
+		do_status = (urb->status == -EREMOTEIO)
+				&& usb_pipecontrol (urb->pipe);
 		spin_unlock (&urb->lock);
 
 		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
@@ -319,6 +352,9 @@
 		ehci_qtd_free (ehci, last);
 	}
 
+	/* restore original state; caller must unlink or relink */
+	qh->qh_state = state;
+
 	/* update qh after fault cleanup */
 	if (unlikely ((HALT_BIT & qh->hw_token) != 0)) {
 		qh_update (ehci, qh,
@@ -367,7 +403,7 @@
 	struct ehci_qtd		*qtd, *qtd_prev;
 	dma_addr_t		buf;
 	int			len, maxpacket;
-	int			is_input, status_patch = 0;
+	int			is_input;
 	u32			token;
 
 	/*
@@ -388,7 +424,7 @@
 	if (usb_pipecontrol (urb->pipe)) {
 		/* SETUP pid */
 		qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
-			token | (2 /* "setup" */ << 8));
+			token | (2 /* "setup" */ << 8), 8);
 
 		/* ... and always at least one more pid */
 		token ^= QTD_TOGGLE;
@@ -399,10 +435,6 @@
 		qtd->urb = urb;
 		qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
 		list_add_tail (&qtd->qtd_list, head);
-
-		if (len > 0 && is_input
-				&& !(urb->transfer_flags & URB_SHORT_NOT_OK))
-			status_patch = 1;
 	} 
 
 	/*
@@ -413,6 +445,7 @@
 	else
 		buf = 0;
 
+	// FIXME this 'buf' check break some zlps...
 	if (!buf || is_input)
 		token |= (1 /* "in" */ << 8);
 	/* else it's already initted to "out" pid (0 << 8) */
@@ -427,9 +460,11 @@
 	for (;;) {
 		int this_qtd_len;
 
-		this_qtd_len = qtd_fill (qtd, buf, len, token);
+		this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket);
 		len -= this_qtd_len;
 		buf += this_qtd_len;
+		if (is_input)
+			qtd->hw_alt_next = ehci->async->hw_alt_next;
 
 		/* qh makes control packets use qtd toggle; maybe switch it */
 		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
@@ -447,6 +482,13 @@
 		list_add_tail (&qtd->qtd_list, head);
 	}
 
+	/* unless the bulk/interrupt caller wants a chance to clean
+	 * up after short reads, hc should advance qh past this urb
+	 */
+	if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
+				|| usb_pipecontrol (urb->pipe)))
+		qtd->hw_alt_next = EHCI_LIST_END;
+
 	/*
 	 * control requests may need a terminating data "status" ack;
 	 * bulk ones may need a terminating short packet (zero length).
@@ -473,23 +515,10 @@
 			list_add_tail (&qtd->qtd_list, head);
 
 			/* never any data in such packets */
-			qtd_fill (qtd, 0, 0, token);
+			qtd_fill (qtd, 0, 0, token, 0);
 		}
 	}
 
-	/* if we're permitting a short control read, we want the hardware to
-	 * just continue after short data and send the status ack.  it can do
-	 * that on the last data packet (typically the only one).  for other
-	 * packets, software fixup is needed (in qh_completions).
-	 */
-	if (status_patch) {
-		struct ehci_qtd		*prev;
-
-		prev = list_entry (qtd->qtd_list.prev,
-				struct ehci_qtd, qtd_list);
-		prev->hw_alt_next = QTD_NEXT (qtd->qtd_dma);
-	}
-
 	/* by default, enable interrupt on urb completion */
 	if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
 		qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC);
@@ -611,7 +640,8 @@
 
 	case USB_SPEED_FULL:
 		/* EPS 0 means "full" */
-		info1 |= (EHCI_TUNE_RL_TT << 28);
+		if (type != PIPE_INTERRUPT)
+			info1 |= (EHCI_TUNE_RL_TT << 28);
 		if (type == PIPE_CONTROL) {
 			info1 |= (1 << 27);	/* for TT */
 			info1 |= 1 << 14;	/* toggle from qtd */
@@ -628,12 +658,13 @@
 
 	case USB_SPEED_HIGH:		/* no TT involved */
 		info1 |= (2 << 12);	/* EPS "high" */
-		info1 |= (EHCI_TUNE_RL_HS << 28);
 		if (type == PIPE_CONTROL) {
+			info1 |= (EHCI_TUNE_RL_HS << 28);
 			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
 			info1 |= 1 << 14;	/* toggle from qtd */
 			info2 |= (EHCI_TUNE_MULT_HS << 30);
 		} else if (type == PIPE_BULK) {
+			info1 |= (EHCI_TUNE_RL_HS << 28);
 			info1 |= 512 << 16;	/* usb2 fixed maxpacket */
 			info2 |= (EHCI_TUNE_MULT_HS << 30);
 		} else {		/* PIPE_INTERRUPT */
@@ -769,8 +800,7 @@
 				&& !usb_pipecontrol (urb->pipe)) {
 			/* "never happens": drivers do stall cleanup right */
 			if (qh->qh_state != QH_STATE_IDLE
-					&& (cpu_to_le32 (QTD_STS_HALT)
-						& qh->hw_token) == 0)
+					&& qh->qh_state != QH_STATE_COMPLETING)
 				ehci_warn (ehci, "clear toggle dev%d "
 						"ep%d%s: not idle\n",
 						usb_pipedevice (urb->pipe),
@@ -809,7 +839,6 @@
 			__list_splice (qtd_list, qh->qtd_list.prev);
 
 			ehci_qtd_init (qtd, qtd->qtd_dma);
-			qtd->hw_alt_next = ehci->async->hw_alt_next;
 			qh->dummy = qtd;
 
 			/* hc must see the new dummy at list end */
@@ -877,9 +906,12 @@
 
 /* the async qh for the qtds being reclaimed are now unlinked from the HC */
 
+static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
+
 static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
 {
 	struct ehci_qh		*qh = ehci->reclaim;
+	struct ehci_qh		*next;
 
 	del_timer (&ehci->watchdog);
 
@@ -890,6 +922,10 @@
 	ehci->reclaim = 0;
 	ehci->reclaim_ready = 0;
 
+	/* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
+	next = qh->reclaim;
+	qh->reclaim = 0;
+
 	qh_completions (ehci, qh, regs);
 
 	if (!list_empty (&qh->qtd_list)
@@ -909,6 +945,9 @@
 					jiffies + EHCI_ASYNC_JIFFIES);
 		}
 	}
+
+	if (next)
+		start_unlink_async (ehci, next);
 }
 
 /* makes sure the async qh will become idle */
@@ -921,7 +960,8 @@
 
 #ifdef DEBUG
 	if (ehci->reclaim
-			|| qh->qh_state != QH_STATE_LINKED
+			|| (qh->qh_state != QH_STATE_LINKED
+				&& qh->qh_state != QH_STATE_UNLINK_WAIT)
 #ifdef CONFIG_SMP
 // this macro lies except on SMP compiles
 			|| !spin_is_locked (&ehci->lock)
@@ -953,6 +993,9 @@
 	wmb ();
 
 	if (unlikely (ehci->hcd.state == USB_STATE_HALT)) {
+		/* if (unlikely (qh->reclaim != 0))
+		 * 	this will recurse, probably not much
+		 */
 		end_unlink_async (ehci, NULL);
 		return;
 	}
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/host/ehci.h	Mon Feb 10 10:39:31 2003
@@ -236,12 +236,12 @@
 	/* the rest is HCD-private */
 	dma_addr_t		qtd_dma;		/* qtd address */
 	struct list_head	qtd_list;		/* sw qtd list */
-
-	/* dma same in urb's qtds, except 1st control qtd (setup buffer) */
 	struct urb		*urb;			/* qtd's urb */
 	size_t			length;			/* length of buffer */
 } __attribute__ ((aligned (32)));
 
+#define QTD_MASK cpu_to_le32 (~0x1f)	/* mask NakCnt+T in qh->hw_alt_next */
+
 /*-------------------------------------------------------------------------*/
 
 /* type tag from {qh,itd,sitd,fstn}->hw_next */
@@ -305,6 +305,7 @@
 	union ehci_shadow	qh_next;	/* ptr to qh; or periodic */
 	struct list_head	qtd_list;	/* sw qtd list */
 	struct ehci_qtd		*dummy;
+	struct ehci_qh		*reclaim;	/* next to reclaim */
 
 	atomic_t		refcount;
 	unsigned		stamp;
@@ -313,6 +314,8 @@
 #define	QH_STATE_LINKED		1		/* HC sees this */
 #define	QH_STATE_UNLINK		2		/* HC may still see this */
 #define	QH_STATE_IDLE		3		/* HC doesn't see this */
+#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on reclaim q */
+#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
 
 	/* periodic schedule info */
 	u8			usecs;		/* intr bandwidth */
@@ -425,16 +428,6 @@
 }
 
 #else	/* LINUX_VERSION_CODE */
-
-// hcd_to_bus() eventually moves to hcd.h on 2.5 too
-static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
-	{ return &hcd->self; }
-// ... as does hcd_register_root()
-static inline int hcd_register_root (struct usb_hcd *hcd)
-{
-	return usb_register_root_hub (
-		hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev);
-}
 
 #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
 
diff -Nru a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c
--- a/drivers/usb/host/hc_simple.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/host/hc_simple.c	Mon Feb 10 10:39:33 2003
@@ -219,7 +219,7 @@
 	if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) {
 		/* URB active? */
 
-		if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) {
+		if (urb->transfer_flags & URB_ASYNC_UNLINK) {
 			/* asynchronous with callback */
 			/* relink the urb to the del list */
 			list_move (&urb->urb_list, &hci->del_list);
@@ -388,7 +388,6 @@
 	struct urb *urb = (struct urb *) lurb;
 
 	DBGFUNC ("enter qu_urb_timeout\n");
-	urb->transfer_flags |= URB_TIMEOUT_KILLED;
 	hci_unlink_urb (urb);
 }
 #endif
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/host/ohci-hcd.c	Mon Feb 10 10:39:23 2003
@@ -203,27 +203,27 @@
 		return -ENOMEM;
 	memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *));
 	
-	spin_lock_irqsave (&ohci->lock, flags);
-
-	/* don't submit to a dead HC */
-	if (ohci->disabled || ohci->sleeping) {
-		retval = -ENODEV;
-		goto fail;
-	}
-
 	/* fill the private part of the URB */
 	urb_priv->length = size;
 	urb_priv->ed = ed;	
 
-	/* allocate the TDs (updating hash chains) */
+	/* allocate the TDs (deferring hash chain updates) */
 	for (i = 0; i < size; i++) {
-		urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC);
+		urb_priv->td [i] = td_alloc (ohci, mem_flags);
 		if (!urb_priv->td [i]) {
 			urb_priv->length = i;
-			retval = -ENOMEM;
-			goto fail;
+			urb_free_priv (ohci, urb_priv);
+			return -ENOMEM;
 		}
 	}	
+
+	spin_lock_irqsave (&ohci->lock, flags);
+
+	/* don't submit to a dead HC */
+	if (ohci->disabled || ohci->sleeping) {
+		retval = -ENODEV;
+		goto fail;
+	}
 
 	/* schedule the ed if needed */
 	if (ed->state == ED_IDLE) {
diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/usb/host/ohci-mem.c	Mon Feb 10 10:39:29 2003
@@ -97,17 +97,11 @@
 
 	td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
 	if (td) {
-		int	hash;
-
 		/* in case hc fetches it, make it look dead */
 		memset (td, 0, sizeof *td);
 		td->hwNextTD = cpu_to_le32 (dma);
 		td->td_dma = dma;
-
-		/* hash it for later reverse mapping */
-		hash = TD_HASH_FUNC (dma);
-		td->td_hash = hc->td_hash [hash];
-		hc->td_hash [hash] = td;
+		/* hashed in td_fill */
 	}
 	return td;
 }
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c	Mon Feb 10 10:39:32 2003
+++ b/drivers/usb/host/ohci-q.c	Mon Feb 10 10:39:32 2003
@@ -463,13 +463,14 @@
 /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
 
 static void
-td_fill (unsigned int info,
+td_fill (struct ohci_hcd *ohci, u32 info,
 	dma_addr_t data, int len,
 	struct urb *urb, int index)
 {
 	struct td		*td, *td_pt;
 	struct urb_priv		*urb_priv = urb->hcpriv;
 	int			is_iso = info & TD_ISO;
+	int			hash;
 
 	// ASSERT (index < urb_priv->length);
 
@@ -516,11 +517,16 @@
 		td->hwBE = 0;
 	td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
 
-	/* HC might read the TD right after we link it ... */
-	wmb ();
-
 	/* append to queue */
 	list_add_tail (&td->td_list, &td->ed->td_list);
+
+	/* hash it for later reverse mapping */
+	hash = TD_HASH_FUNC (td->td_dma);
+	td->td_hash = ohci->td_hash [hash];
+	ohci->td_hash [hash] = td;
+
+	/* HC might read the TD (or cachelines) right away ... */
+	wmb ();
 	td->ed->hwTailP = td->hwNextTD;
 }
 
@@ -578,7 +584,7 @@
 			: TD_T_TOGGLE | TD_CC | TD_DP_IN;
 		/* TDs _could_ transfer up to 8K each */
 		while (data_len > 4096) {
-			td_fill (info, data, 4096, urb, cnt);
+			td_fill (ohci, info, data, 4096, urb, cnt);
 			data += 4096;
 			data_len -= 4096;
 			cnt++;
@@ -586,11 +592,11 @@
 		/* maybe avoid ED halt on final TD short read */
 		if (!(urb->transfer_flags & URB_SHORT_NOT_OK))
 			info |= TD_R;
-		td_fill (info, data, data_len, urb, cnt);
+		td_fill (ohci, info, data, data_len, urb, cnt);
 		cnt++;
 		if ((urb->transfer_flags & URB_ZERO_PACKET)
 				&& cnt < urb_priv->length) {
-			td_fill (info, 0, 0, urb, cnt);
+			td_fill (ohci, info, 0, 0, urb, cnt);
 			cnt++;
 		}
 		/* maybe kickstart bulk list */
@@ -605,17 +611,17 @@
 	 */
 	case PIPE_CONTROL:
 		info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
-		td_fill (info, urb->setup_dma, 8, urb, cnt++);
+		td_fill (ohci, info, urb->setup_dma, 8, urb, cnt++);
 		if (data_len > 0) {
 			info = TD_CC | TD_R | TD_T_DATA1;
 			info |= is_out ? TD_DP_OUT : TD_DP_IN;
 			/* NOTE:  mishandles transfers >8K, some >4K */
-			td_fill (info, data, data_len, urb, cnt++);
+			td_fill (ohci, info, data, data_len, urb, cnt++);
 		}
 		info = is_out
 			? TD_CC | TD_DP_IN | TD_T_DATA1
 			: TD_CC | TD_DP_OUT | TD_T_DATA1;
-		td_fill (info, data, 0, urb, cnt++);
+		td_fill (ohci, info, data, 0, urb, cnt++);
 		/* maybe kickstart control list */
 		wmb ();
 		writel (OHCI_CLF, &ohci->regs->cmdstatus);
@@ -634,7 +640,7 @@
 			// a 2^16 iso range, vs other HCs max of 2^10)
 			frame += cnt * urb->interval;
 			frame &= 0xffff;
-			td_fill (TD_CC | TD_ISO | frame,
+			td_fill (ohci, TD_CC | TD_ISO | frame,
 				data + urb->iso_frame_desc [cnt].offset,
 				urb->iso_frame_desc [cnt].length, urb, cnt);
 		}
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/host/uhci-hcd.c	Mon Feb 10 10:39:31 2003
@@ -1747,7 +1747,6 @@
 
 		tmp = tmp->next;
 
-		u->transfer_flags |= URB_TIMEOUT_KILLED;
 		uhci_urb_dequeue(hcd, u);
 	}
 
diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
--- a/drivers/usb/image/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/image/Kconfig	Mon Feb 10 10:39:23 2003
@@ -16,7 +16,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mdc800.o. If you want to compile it as a
+	  The module will be called mdc800. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SCANNER
@@ -29,7 +29,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called scanner.o. If you want to compile it as
+	  The module will be called scanner. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_MICROTEK
@@ -42,7 +42,7 @@
 	  Please report failures and successes.
 	  The scanner will appear as a scsi generic device to the rest
 	  of the system. Scsi support is required.
-	  This driver can be compiled as a module, called microtek.o.
+	  This driver can be compiled as a module, called microtek.
 
 config USB_HPUSBSCSI
 	tristate "HP53xx USB scanner support (EXPERIMENTAL)"
@@ -51,5 +51,5 @@
 	  Say Y here if you want support for the HP 53xx series of scanners
 	  and the Minolta Scan Dual. This driver is experimental.
 	  The scanner will be accessible as a SCSI device.
-	  This can be compiled as a module, called hpusbscsi.o.
+	  This can be compiled as a module, called hpusbscsi.
 
diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c
--- a/drivers/usb/image/hpusbscsi.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/image/hpusbscsi.c	Mon Feb 10 10:39:33 2003
@@ -274,7 +274,7 @@
 
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback)
 {
-	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
 	usb_complete_t usb_callback;
 	int res;
 
@@ -349,7 +349,7 @@
 
 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb)
 {
-	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
 
 	printk(KERN_DEBUG"SCSI reset requested.\n");
 	//usb_reset_device(hpusbscsi->dev);
@@ -361,7 +361,7 @@
 
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
 {
-	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
+	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]);
 	printk(KERN_DEBUG"Requested is canceled.\n");
 
 	usb_unlink_urb(hpusbscsi->dataurb);
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/image/microtek.c	Mon Feb 10 10:39:33 2003
@@ -398,7 +398,7 @@
 
 static int mts_scsi_abort (Scsi_Cmnd *srb)
 {
-	struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
+	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 
 	MTS_DEBUG_GOT_HERE();
 
@@ -409,7 +409,7 @@
 
 static int mts_scsi_host_reset (Scsi_Cmnd *srb)
 {
-	struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
+	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 
 	MTS_DEBUG_GOT_HERE();
 	mts_debug_dump(desc);
@@ -692,7 +692,7 @@
 static
 int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
 {
-	struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
+	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 	int err = 0;
 	int res;
 
diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
--- a/drivers/usb/image/scanner.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/image/scanner.c	Mon Feb 10 10:39:24 2003
@@ -1,13 +1,16 @@
 /* -*- linux-c -*- */
 
 /* 
- * Driver for USB Scanners (linux-2.5.54)
+ * Driver for USB Scanners (linux-2.5.60)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
+ * Copyright (C) 2002, 2003 Henning Meier-Geinitz
  *
  * Portions may be copyright Brad Keryan and Michael Gee.
  *
- * Brian Beattie <beattie@beattie-home.net>
+ * Previously maintained by Brian Beattie
+ *
+ * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de>
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -300,8 +303,6 @@
  *      Frank Zago <fzago@greshamstorage.com> and
  *      Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing.
  *
- * 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net>
- *
  * 0.4.8  5/30/2002
  *    - Added Mustek BearPaw 2400 TA.  Thanks to Sergey
  *      Vlasov <vsu@mivlgu.murom.ru>.
@@ -332,12 +333,18 @@
  *      <oliver@neukum.name>.
  *
  * 0.4.10  01/07/2003
- *    - Added vendor/product ids for Visioneer scanners.
+ *    - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek 
+ *      and Visioneer scanners. Thanks to William Lam <wklam@triad.rr.com>,
+ *      Till Kamppeter <till.kamppeter@gmx.net> and others for all the ids.
+ *    - Cleaned up list of vendor/product ids.
  *    - Print information about user-supplied ids only once at startup instead
  *      of everytime any USB device is plugged in.
  *    - Removed PV8630 ioctls. Use the standard ioctls instead.
  *    - Made endpoint detection more generic. Basically, only one bulk-in 
  *      endpoint is required, everything else is optional.
+ *    - New maintainer: Henning Meier-Geinitz.
+ *    - Print ids and device number when a device was detected.
+ *    - Don't print errors when the device is busy.
  *      
  * TODO
  *    - Performance
@@ -360,7 +367,7 @@
  *    - All the developers that are working on USB SANE backends or other
  *      applications to use USB scanners.
  *    - Thanks to Greg KH <greg@kroah.com> for setting up Brian Beattie
- *      to be the new USB Scanner maintainer.
+ *      and Henning Meier-Geinitz to be the new USB Scanner maintainer.
  *
  *  Performance:
  *
@@ -369,6 +376,14 @@
  *      24 Bit Color ~ 70 secs - 3.6 Mbit/sec
  *       8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */
 
+/*
+ * For documentation, see Documentation/usb/scanner.txt.
+ * Website: http://www.meier-geinitz.de/kernel/
+ * Please contact the maintainer if your scanner is not detected by this
+ * driver automatically.
+ */
+
+
 #include <asm/byteorder.h>
 
 /* 
@@ -461,7 +476,7 @@
 	}
 
 	if (scn->isopen) {
-		err("open_scanner(%d): Scanner device is already open", scn_minor);
+		dbg("open_scanner(%d): Scanner device is already open", scn_minor);
 		err = -EBUSY;
 		goto out_error;
 	}
@@ -1046,6 +1061,9 @@
 				    S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, NULL);
 	if (scn->devfs == NULL)
 		dbg("scanner%d: device node registration failed", scn_minor);
+
+	info ("USB scanner device (0x%04x/0x%04x) now attached to %s",
+	      dev->descriptor.idVendor, dev->descriptor.idProduct, name);
 
 	up(&scn_mutex);
 
diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h
--- a/drivers/usb/image/scanner.h	Mon Feb 10 10:39:25 2003
+++ b/drivers/usb/image/scanner.h	Mon Feb 10 10:39:25 2003
@@ -1,9 +1,10 @@
 /*
- * Driver for USB Scanners (linux-2.5.54)
+ * Driver for USB Scanners (linux-2.5.60)
  *
  * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson
+ * Previously maintained by Brian Beattie
  *
- * Brian Beattie <beattie@beattie-home.net>
+ * Current maintainer: Henning Meier-Geinitz <henning@meier-geinitz.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -19,11 +20,16 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * 05/21/02 Currently maintained by Brian Beattie <beattie@beattie-home.net>
- *
- *
  */ 
 
+/*
+ * For documentation, see Documentation/usb/scanner.txt.
+ * Website: http://www.meier-geinitz.de/kernel/
+ * Please contact the maintainer if your scanner is not detected by this
+ * driver automatically.
+ */
+
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -45,7 +51,7 @@
 
 static __s32 vendor=-1, product=-1, read_timeout=0;
 
-MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net");
+MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de");
 MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
@@ -65,79 +71,90 @@
 
 static struct usb_device_id scanner_device_ids [] = {
 	/* Acer (now Benq) */
-	{ USB_DEVICE(0x04a5, 0x2060) },	/* 620U & 640U (!)*/
-	{ USB_DEVICE(0x04a5, 0x2040) },	/* 620U (!) */
-	{ USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */
-	{ USB_DEVICE(0x04a5, 0x2022) },	/* 340U */
 	{ USB_DEVICE(0x04a5, 0x1a20) },	/* Unknown - Oliver Schwartz */
 	{ USB_DEVICE(0x04a5, 0x1a2a) },	/* Another 620U */
+	{ USB_DEVICE(0x04a5, 0x2022) },	/* 340U */
+	{ USB_DEVICE(0x04a5, 0x2040) },	/* 620U (!) */
+	{ USB_DEVICE(0x04a5, 0x2060) },	/* 620U & 640U (!)*/
 	{ USB_DEVICE(0x04a5, 0x207e) },	/* 640BU */
+	{ USB_DEVICE(0x04a5, 0x20b0) },	/* Benq 4300 */
 	{ USB_DEVICE(0x04a5, 0x20be) },	/* Unknown - Oliver Schwartz */
+	{ USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */
 	{ USB_DEVICE(0x04a5, 0x20de) },	/* S2W 3300U */
-	{ USB_DEVICE(0x04a5, 0x20b0) },	/* Benq 4300 */
-	{ USB_DEVICE(0x04a5, 0x20fe) },	/* Benq 5300 */
 	{ USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */
+	{ USB_DEVICE(0x04a5, 0x20fe) },	/* Benq 5300 */
 	/* Agfa */
 	{ USB_DEVICE(0x06bd, 0x0001) },	/* SnapScan 1212U */
 	{ USB_DEVICE(0x06bd, 0x0002) },	/* SnapScan 1236U */
-	{ USB_DEVICE(0x06bd, 0x2061) },	/* Another SnapScan 1212U (?)*/
 	{ USB_DEVICE(0x06bd, 0x0100) },	/* SnapScan Touch */
+	{ USB_DEVICE(0x06bd, 0x2061) },	/* Another SnapScan 1212U (?)*/
+	{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
+	{ USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/
 	{ USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */
+	{ USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/
 	{ USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */
 	{ USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */
-	{ USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */
-	{ USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/
-	{ USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/
-	{ USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/
 	{ USB_DEVICE(0x06bd, 0x20fd) }, /* SnapScan e52*/
+	{ USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/
+	/* Artec */
+	{ USB_DEVICE(0x05d8, 0x4001) },	/* Ultima 2000 */
+	{ USB_DEVICE(0x05d8, 0x4002) }, /* Ultima 2000 (GT6801 based) */
 	/* Benq: see Acer */
 	/* Canon */
-	{ USB_DEVICE(0x04a9, 0x2201) }, /* FB320U */
-	{ USB_DEVICE(0x04a9, 0x2205) }, /* FB1210U */
+	{ USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */
 	{ USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */
 	{ USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */
+	{ USB_DEVICE(0x04a9, 0x2205) }, /* CanoScan FB1210U */
 	{ USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */
 	{ USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */
 	{ USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ 
-	{ USB_DEVICE(0x04a9, 0x220b) }, /* D646U */
+	{ USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */
+	{ USB_DEVICE(0x04a9, 0x220c) },	/* CanoScan D1250U2 */
 	{ USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */
 	{ USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */
 	{ USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */
 	/* Colorado -- See Primax/Colorado below */
+	/* Compaq */
+	{ USB_DEVICE(0x049f, 0x0021) },	/* S200 */
 	/* Epson -- See Seiko/Epson below */
 	/* Genius */
-	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage-Vivid Pro */
+	{ USB_DEVICE(0x0458, 0x2001) },	/* ColorPage Vivid Pro */
 	{ USB_DEVICE(0x0458, 0x2007) },	/* ColorPage HR6 V2 */
-	{ USB_DEVICE(0x0458, 0x2008) }, /* ColorPage-HR6 V2 */
-	{ USB_DEVICE(0x0458, 0x2009) }, /* ColorPage-HR6A */
-	{ USB_DEVICE(0x0458, 0x2011) }, /* ColorPage-Vivid3x */
-	{ USB_DEVICE(0x0458, 0x2013) }, /* ColorPage-HR7 */
-	{ USB_DEVICE(0x0458, 0x2015) }, /* ColorPage-HR7LE */
-	{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage-HR6X */
+	{ USB_DEVICE(0x0458, 0x2008) }, /* ColorPage HR6 V2 */
+	{ USB_DEVICE(0x0458, 0x2009) }, /* ColorPage HR6A */
+	{ USB_DEVICE(0x0458, 0x2011) }, /* ColorPage Vivid3x */
+	{ USB_DEVICE(0x0458, 0x2013) }, /* ColorPage HR7 */
+	{ USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */
+	{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */
 	/* Hewlett Packard */
-	{ USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */
-	{ USB_DEVICE(0x03f0, 0x0605) },	/* 2200C */
-	{ USB_DEVICE(0x03f0, 0x0901) }, /* 2300C */
-	{ USB_DEVICE(0x03f0, 0x0205) },	/* 3300C */
-	{ USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */
-	{ USB_DEVICE(0x03f0, 0x0101) },	/* 4100C */
-	{ USB_DEVICE(0x03f0, 0x0105) },	/* 4200C */
-	{ USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */
-	{ USB_DEVICE(0x03f0, 0x0705) }, /* 4400C */
+	{ USB_DEVICE(0x03f0, 0x0101) },	/* ScanJet 4100C */
 	{ USB_DEVICE(0x03f0, 0x0102) },	/* PhotoSmart S20 */
-	{ USB_DEVICE(0x03f0, 0x0401) },	/* 5200C */
-	//	{ USB_DEVICE(0x03f0, 0x0701) },	/* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */
-	{ USB_DEVICE(0x03f0, 0x0201) },	/* 6200C */
-	{ USB_DEVICE(0x03f0, 0x0601) },	/* 6300C */
+	{ USB_DEVICE(0x03f0, 0x0105) },	/* ScanJet 4200C */
+	{ USB_DEVICE(0x03f0, 0x0201) },	/* ScanJet 6200C */
+	{ USB_DEVICE(0x03f0, 0x0205) },	/* ScanJet 3300C */
+	{ USB_DEVICE(0x03f0, 0x0305) }, /* ScanJet 4300C */
+	{ USB_DEVICE(0x03f0, 0x0401) },	/* ScanJet 5200C */
+	{ USB_DEVICE(0x03f0, 0x0405) }, /* ScanJet 3400C */
+	{ USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */
+	{ USB_DEVICE(0x03f0, 0x0601) },	/* ScanJet 6300C */
+	{ USB_DEVICE(0x03f0, 0x0605) },	/* ScanJet 2200C */
+	//	{ USB_DEVICE(0x03f0, 0x0701) },	/* ScanJet 5300C - NOT SUPPORTED - use hpusbscsi driver */
+	{ USB_DEVICE(0x03f0, 0x0705) }, /* ScanJet 4400C */
+	//	{ USB_DEVICE(0x03f0, 0x0801) },	/* ScanJet 7400C - NOT SUPPORTED - use hpusbscsi driver */
+	{ USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */
+	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
+	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
+	{ USB_DEVICE(0x03f0, 0x2205) },	/* ScanJet 3500c */
 	/* iVina */
 	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
 	/* Lexmark */
 	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
-	/* Lifetec */
-	{ USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */
 	/* Memorex */
 	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
-	/* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */
+	/* Microtek */
+	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
+	/* The following SCSI-over-USB Microtek devices are supported by the
+	   microtek driver: Enable SCSI and USB Microtek in kernel config */
 	//	{ USB_DEVICE(0x05da, 0x0099) },	/* ScanMaker X6 - X6U */
 	//	{ USB_DEVICE(0x05da, 0x0094) },	/* Phantom 336CX - C3 */
 	//	{ USB_DEVICE(0x05da, 0x00a0) },	/* Phantom 336CX - C3 #2 */
@@ -146,58 +163,59 @@
 	//	{ USB_DEVICE(0x05da, 0x80a3) },	/* ScanMaker V6USL #2 */
 	//	{ USB_DEVICE(0x05da, 0x80ac) },	/* ScanMaker V6UL - SpicyU */
 	/* Minolta */
-	//	{ USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */
-	//	{ USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */
 	{ USB_DEVICE(0x0686, 0x400d) }, /* Scan Dual III */
+	/* The following SCSI-over-USB Minolta devices are supported by the
+	   hpusbscsi driver: Enable SCSI and USB hpusbscsi in kernel config */
+	//	{ USB_DEVICE(0x0638, 0x026a) }, /* Minolta Dimage Scan Dual II */
+	//	{ USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */
 	/* Mustek */
+	{ USB_DEVICE(0x0400, 0x1000) },	/* BearPaw 1200 (National Semiconductor LM9831) */
+	{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 (National Semiconductor LM9832) */
 	{ USB_DEVICE(0x055f, 0x0001) },	/* ScanExpress 1200 CU */
-	{ USB_DEVICE(0x0400, 0x1000) },	/* BearPaw 1200 */
 	{ USB_DEVICE(0x055f, 0x0002) },	/* ScanExpress 600 CU */
-	{ USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */
 	{ USB_DEVICE(0x055f, 0x0003) },	/* ScanExpress 1200 USB */
 	{ USB_DEVICE(0x055f, 0x0006) },	/* ScanExpress 1200 UB */
 	{ USB_DEVICE(0x055f, 0x0007) },	/* ScanExpress 1200 USB Plus */
-	{ USB_DEVICE(0x055f, 0x0210) },	/* ScanExpress A3 USB */
-	{ USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */
 	{ USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */
 	{ USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */
+	{ USB_DEVICE(0x055f, 0x0210) },	/* ScanExpress A3 USB */
 	{ USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */
-	{ USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus */
 	{ USB_DEVICE(0x055f, 0x0219) }, /* BearPaw 2400 TA Plus */
 	{ USB_DEVICE(0x055f, 0x021c) }, /* BearPaw 1200 CU Plus */
 	{ USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */
 	{ USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */
 	{ USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */
+	{ USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */
 	{ USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */
+	//	{ USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus (see Artec) */
 	/* Nikon */
 	{ USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */
 	/* Plustek */
-	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
-	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */
-	{ USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */
-	{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */
+	{ USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */
 	{ USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */
 	{ USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */
-	{ USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */
+	{ USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */
 	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
-	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
 	{ USB_DEVICE(0x0461, 0x0301) },	/* G2E-300 #1 */
-	{ USB_DEVICE(0x0461, 0x0381) },	/* ReadyScan 636i */
 	{ USB_DEVICE(0x0461, 0x0302) },	/* G2-300 #2 */
-	{ USB_DEVICE(0x0461, 0x0382) },	/* G2-600 #2 */
 	{ USB_DEVICE(0x0461, 0x0303) },	/* G2E-300 #2 */
-	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
 	{ USB_DEVICE(0x0461, 0x0340) },	/* Colorado USB 9600 */
-	// { USB_DEVICE(0x0461, 0x0360) },	/* Colorado USB 19200 - undetected endpoint */
 	{ USB_DEVICE(0x0461, 0x0341) },	/* Colorado 600u */
+	{ USB_DEVICE(0x0461, 0x0360) },	/* Colorado USB 19200 */
 	{ USB_DEVICE(0x0461, 0x0361) },	/* Colorado 1200u */
+	{ USB_DEVICE(0x0461, 0x0380) },	/* G2-600 #1 */
+	{ USB_DEVICE(0x0461, 0x0381) },	/* ReadyScan 636i */
+	{ USB_DEVICE(0x0461, 0x0382) },	/* G2-600 #2 */
+	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
 	/* Relisis */
 	// { USB_DEVICE(0x0475, 0x0103) },	/* Episode - undetected endpoint */
 	/* Seiko/Epson Corp. */
@@ -221,17 +239,18 @@
 	{ USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */
 	{ USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */
 	{ USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */
+	{ USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */
 	{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
 	/* Umax */
 	{ USB_DEVICE(0x1606, 0x0010) },	/* Astra 1220U */
 	{ USB_DEVICE(0x1606, 0x0030) },	/* Astra 2000U */
 	{ USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */
 	{ USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */
-	{ USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */
+	{ USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */  
 	{ USB_DEVICE(0x1606, 0x0230) },	/* Astra 2200U */
 	/* Visioneer */
-	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0211) },	/* OneTouch 7600 USB */
+	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0231) },	/* 6100 USB */
 	{ USB_DEVICE(0x04a7, 0x0311) },	/* 6200 EPP/USB */
 	{ USB_DEVICE(0x04a7, 0x0321) },	/* OneTouch 8100 EPP/USB */
diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/input/Kconfig	Mon Feb 10 10:39:30 2003
@@ -22,7 +22,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called hid.o. If you want to compile it as a
+	  The module will be called hid. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 comment "Input core support is needed for USB HID input layer or HIDBP support"
@@ -98,7 +98,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbkbd.o. If you want to compile it as a
+	  The module will be called usbkbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If even remotely unsure, say N.
@@ -116,7 +116,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbmouse.o. If you want to compile it as
+	  The module will be called usbmouse. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If even remotely unsure, say N.
@@ -134,7 +134,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called aiptek.o. If you want to compile it as a
+	  The module will be called aiptek. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_WACOM
@@ -148,7 +148,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called wacom.o.  If you want to compile it as a
+	  The module will be called wacom.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_POWERMATE
@@ -165,7 +165,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called powermate.o. If you want to compile it as a
+	  The module will be called powermate. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_XPAD
@@ -181,6 +181,6 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called xpad.o.  If you want to compile it as a
+	  The module will be called xpad.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/usb/input/hid-core.c	Mon Feb 10 10:39:29 2003
@@ -1324,6 +1324,9 @@
 #define USB_DEVICE_ID_MGE_UPS          0xffff
 #define USB_DEVICE_ID_MGE_UPS1         0x0001
 
+#define USB_VENDOR_ID_ONTRAK		0x0a07
+#define USB_DEVICE_ID_ONTRAK_ADU100	0x0064
+
 struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1359,6 +1362,12 @@
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV },
 	{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
 	{ 0, 0 }
 };
 
diff -Nru a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
--- a/drivers/usb/input/pid.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/input/pid.c	Mon Feb 10 10:39:31 2003
@@ -176,7 +176,7 @@
 	struct hid_ff_pid* pid_private  = (struct hid_ff_pid*)(dev->private);
 	int ret;
 	int is_update;
-	int flags=0;
+	unsigned long flags = 0;
 
         dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n",effect->type);
 	/* Check this effect type is supported by this device */
@@ -192,7 +192,7 @@
 		int id=0;
 
 		// Spinlock so we don`t get a race condition when choosing IDs
-		spin_lock_irqsave(&pid_private->lock,flags);
+		spin_lock_irqsave(&pid_private->lock, flags);
 
 		while(id < FF_EFFECTS_MAX)
 			if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags)) 
diff -Nru a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig
--- a/drivers/usb/media/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/media/Kconfig	Mon Feb 10 10:39:23 2003
@@ -16,7 +16,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dabusb.o.  If you want to compile it as a
+	  The module will be called dabusb.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 comment "Video4Linux support is needed for USB Multimedia device support"
@@ -35,7 +35,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called vicam.o. If you want to compile it as a
+	  The module will be called vicam. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_DSBR
@@ -55,7 +55,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called dsbr100.o. If you want to compile it as a
+	  The module will be called dsbr100. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_IBMCAM
@@ -74,7 +74,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ibmcam.o.  If you want to compile it as a
+	  The module will be called ibmcam.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>. This
 	  camera has several configuration options which can be specified when
 	  you load the module.  Read <file:Documentation/usb/ibmcam.txt> to
@@ -95,7 +95,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called konicawc.o. If you want to compile it as
+	  The module will be called konicawc. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_OV511
@@ -113,7 +113,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ov511.o. If you want to compile it as a
+	  The module will be called ov511. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_PWC
@@ -154,7 +154,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pwc.o.  If you want to compile it as a
+	  The module will be called pwc.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SE401
@@ -172,7 +172,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called se401.o. If you want to compile it as a
+	  The module will be called se401. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_STV680
@@ -191,6 +191,6 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called stv680.o. If you want to compile it as a
+	  The module will be called stv680. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
--- a/drivers/usb/media/Makefile	Mon Feb 10 10:39:22 2003
+++ b/drivers/usb/media/Makefile	Mon Feb 10 10:39:22 2003
@@ -2,8 +2,6 @@
 # Makefile for USB Media drivers
 #
 
-export-objs	:= ov511.o pwc-uncompress.o usbvideo.o
-
 pwc-objs	:= pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
 
 obj-$(CONFIG_USB_DABUSB)	+= dabusb.o
diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
--- a/drivers/usb/media/usbvideo.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/media/usbvideo.c	Mon Feb 10 10:39:33 2003
@@ -61,7 +61,7 @@
 			      unsigned int cmd, unsigned long arg);
 static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
 static int usbvideo_v4l_open(struct inode *inode, struct file *file);
-static int usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
 			     size_t count, loff_t *ppos);
 static int usbvideo_v4l_close(struct inode *inode, struct file *file);
 
@@ -1641,7 +1641,7 @@
  * 20-Oct-2000 Created.
  * 01-Nov-2000 Added mutex (uvd->lock).
  */
-static int usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
 		      size_t count, loff_t *ppos)
 {
 	struct uvd *uvd = file->private_data;
diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/media/vicam.c	Mon Feb 10 10:39:24 2003
@@ -988,7 +988,7 @@
 	up(&cam->cam_lock);
 }
 
-static int
+static ssize_t
 vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
 {
 	struct vicam_camera *cam = file->private_data;
diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/misc/Kconfig	Mon Feb 10 10:39:33 2003
@@ -16,7 +16,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called audio.o. If you want to compile it as a
+	  The module will be called audio. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_TIGL
@@ -32,7 +32,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tiglusb.o. If you want to compile it as a
+	  The module will be called tiglusb. If you want to compile it as a
 	  module, say M here and read Documentation/modules.txt.
 
 	  If you don't know what the SilverLink cable is or what a Texas
@@ -50,7 +50,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called auerswald.o. If you want to compile it as
+	  The module will be called auerswald. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_RIO500
@@ -63,7 +63,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rio500.o. If you want to compile it as
+	  The module will be called rio500. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_BRLVGER
@@ -76,7 +76,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called brlvger.o. If you want to compile it as
+	  The module will be called brlvger. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_LCD
@@ -90,7 +90,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usblcd.o. If you want to compile it as
+	  The module will be called usblcd. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SPEEDTOUCH
diff -Nru a/drivers/usb/misc/atmsar.c b/drivers/usb/misc/atmsar.c
--- a/drivers/usb/misc/atmsar.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/misc/atmsar.c	Mon Feb 10 10:39:24 2003
@@ -45,7 +45,7 @@
  *		- No more in-buffer rewriting for cloned buffers.
  *		- Removed the PII specific CFLAGS in the Makefile.
  *
- *  0.2.1:	- removed dependancy on alloc_tx. tis presented problems when
+ *  0.2.1:	- removed dependency on alloc_tx. tis presented problems when
  *		using this with the br2684 code.
  *
  *  0.2:	- added AAL0 reassembly
@@ -381,6 +381,83 @@
  **
  ***********************/
 
+/* encapsulate in an AAL5 frame, which is then split into ATM cells */
+unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length)
+{
+	unsigned int num_cells = (pdu_length + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD;
+	unsigned int num_pdu_cells = pdu_length / ATM_CELL_PAYLOAD + 1;
+	unsigned int aal5_length = num_cells * ATM_CELL_PAYLOAD;
+	unsigned int zero_padding = aal5_length - pdu_length - ATM_AAL5_TRAILER;
+	unsigned int final_length = num_cells * ATM_CELL_SIZE;
+	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
+	unsigned char cell_header [ATM_CELL_HEADER];
+	u32 crc;
+	int i;
+
+	PDEBUG ("atmsar_encode entered\n");
+
+	PDEBUG ("pdu_length %d, num_cells %d, num_pdu_cells %d, aal5_length %d, zero_padding %d, final_length %d\n", pdu_length, num_cells, num_pdu_cells, aal5_length, zero_padding, final_length);
+
+	PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
+
+	aal5_trailer [0] = 0; /* UU = 0 */
+	aal5_trailer [1] = 0; /* CPI = 0 */
+	aal5_trailer [2] = pdu_length >> 8;
+	aal5_trailer [3] = pdu_length;
+
+	crc = crc32 (~0, source, pdu_length);
+	for (i = 0; i < zero_padding; i++)
+		crc = CRC32 (0, crc);
+	crc = crc32 (crc, aal5_trailer, 4);
+	crc = ~crc;
+
+	aal5_trailer [4] = crc >> 24;
+	aal5_trailer [5] = crc >> 16;
+	aal5_trailer [6] = crc >> 8;
+	aal5_trailer [7] = crc;
+
+	cell_header [0] = ctx->atmHeader >> 24;
+	cell_header [1] = ctx->atmHeader >> 16;
+	cell_header [2] = ctx->atmHeader >> 8;
+	cell_header [3] = ctx->atmHeader;
+	cell_header [4] = 0xec;
+
+	for (i = 1; i < num_pdu_cells; i++) {
+		memcpy (target, cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		memcpy (target, source, ATM_CELL_PAYLOAD);
+		target += ATM_CELL_PAYLOAD;
+		source += ATM_CELL_PAYLOAD;
+		PDEBUG ("source 0x=%p, target 0x%p\n", source, target);
+	}
+	memcpy (target, cell_header, ATM_CELL_HEADER);
+	target += ATM_CELL_HEADER;
+	memcpy (target, source, pdu_length % ATM_CELL_PAYLOAD);
+	target += pdu_length % ATM_CELL_PAYLOAD;
+	if (num_pdu_cells < num_cells) {
+		memset (target, 0, zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD);
+		target += zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD;
+		memcpy (target, cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		zero_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+	}
+	memset (target, 0, zero_padding);
+	target += zero_padding;
+	memcpy (target, aal5_trailer, ATM_AAL5_TRAILER);
+
+	/* set pti bit in last cell */
+	*(target + ATM_AAL5_TRAILER + 3 - ATM_CELL_SIZE) |= 0x2;
+
+	/* update stats */
+	if (ctx->stats)
+		atomic_inc (&ctx->stats->tx);
+
+	if (ctx->stats && (ctx->type <= ATMSAR_TYPE_AAL1))
+		atomic_add (num_cells, &(ctx->stats->tx));
+
+	return final_length;
+}
+
 struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb)
 {
 	int number_of_cells = (skb->len) / 48;
@@ -624,9 +701,8 @@
 		} else {
 			/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
 			if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
-			    NULL) {
-				skb_trim (skb, 0);
-			}
+			    NULL)
+				return NULL;
 		}
 	}
 
diff -Nru a/drivers/usb/misc/atmsar.h b/drivers/usb/misc/atmsar.h
--- a/drivers/usb/misc/atmsar.h	Mon Feb 10 10:39:26 2003
+++ b/drivers/usb/misc/atmsar.h	Mon Feb 10 10:39:26 2003
@@ -33,6 +33,7 @@
 #define ATMSAR_USE_53BYTE_CELL  0x1L
 #define ATMSAR_SET_PTI          0x2L
 
+#define ATM_CELL_HEADER		(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
 
 /* types */
 #define ATMSAR_TYPE_AAL0        ATM_AAL0
@@ -88,5 +89,7 @@
 struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
 
 struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size);
+
+unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length);
 
 #endif				/* _ATMSAR_H_ */
diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/misc/speedtouch.c	Mon Feb 10 10:39:33 2003
@@ -46,6 +46,7 @@
  *
  */
 
+#include <asm/semaphore.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -58,7 +59,6 @@
 #include <linux/usb.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
-
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include "atmsar.h"
@@ -106,20 +106,21 @@
 #define UDSL_ENDPOINT_DATA_OUT		0x07
 #define UDSL_ENDPOINT_DATA_IN		0x87
 
+#define hex2int(c) ( (c >= '0')&&(c <= '9') ?  (c - '0') : ((c & 0xf)+9) )
+
 /* usb_device_id struct */
 
-static struct usb_device_id udsl_usb_ids[] = {
-	{USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)},
-	{}			/* list terminator */
+static struct usb_device_id udsl_usb_ids [] = {
+	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
+	{ }			/* Terminating entry */
 };
 
-/* not exporting this prevents the depmod from generating the map that causes the modules to be isnserted as driver.
- * we do not want this, we want the script run.
-MODULE_DEVICE_TABLE ( usb, udsl_usb_ids);
-*/
+MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
+
 /* context declarations */
 
-struct udsl_data_ctx {
+struct udsl_receiver {
+	struct list_head list;
 	struct sk_buff *skb;
 	struct urb *urb;
 	struct udsl_instance_data *instance;
@@ -137,25 +138,32 @@
  */
 
 struct udsl_instance_data {
-	struct tasklet_struct recvqueue_tasklet;
+	struct semaphore serialize;
 
 	/* usb device part */
 	struct usb_device *usb_dev;
-	struct udsl_data_ctx *rcvbufs;
 	struct sk_buff_head sndqueue;
-	struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS];
-	int data_started;
+	struct udsl_usb_send_data_context send_ctx [UDSL_NUMBER_SND_URBS];
+	int firmware_loaded;
 
 	/* atm device part */
 	struct atm_dev *atm_dev;
-	struct sk_buff_head recvqueue;
 
 	struct atmsar_vcc_data *atmsar_vcc_list;
-};
 
-static const char udsl_driver_name[] = "Alcatel SpeedTouch USB";
+	/* receiving */
+	struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
+
+	spinlock_t spare_receivers_lock;
+	struct list_head spare_receivers;
+
+	spinlock_t completed_receivers_lock;
+	struct list_head completed_receivers;
+
+	struct tasklet_struct receive_tasklet;
+};
 
-static DECLARE_MUTEX(udsl_usb_ioctl_lock);
+static const char udsl_driver_name [] = "Alcatel SpeedTouch USB";
 
 #ifdef DEBUG_PACKET
 static int udsl_print_packet (const unsigned char *data, int len);
@@ -169,8 +177,7 @@
 static void udsl_atm_close (struct atm_vcc *vcc);
 static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
 static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page);
-static void udsl_atm_processqueue (unsigned long data);
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
 
 static struct atmdev_ops udsl_atm_devops = {
 	.open =		udsl_atm_open,
@@ -203,6 +210,170 @@
 	.id_table =	udsl_usb_ids,
 };
 
+
+/**************
+**  receive  **
+**************/
+
+static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs)
+{
+	struct udsl_instance_data *instance;
+	struct udsl_receiver *rcv;
+	unsigned long flags;
+
+	PDEBUG ("udsl_complete_receive entered\n");
+
+	if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) {
+		PDEBUG ("udsl_complete_receive: bad urb!\n");
+		return;
+	}
+
+	/* may not be in_interrupt() */
+	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	list_add_tail (&rcv->list, &instance->completed_receivers);
+	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+	PDEBUG ("udsl_complete_receive: scheduling tasklet\n");
+	tasklet_schedule (&instance->receive_tasklet);
+}
+
+static void udsl_process_receive (unsigned long data)
+{
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+	struct udsl_receiver *rcv;
+	unsigned long flags;
+	unsigned char *data_start;
+	struct sk_buff *skb;
+	struct urb *urb;
+	struct atmsar_vcc_data *atmsar_vcc = NULL;
+	struct sk_buff *new = NULL, *tmp = NULL;
+
+	PDEBUG ("udsl_process_receive entered\n");
+
+	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	while (!list_empty (&instance->completed_receivers)) {
+		rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list);
+		list_del (&rcv->list);
+		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+
+		urb = rcv->urb;
+		PDEBUG ("udsl_process_receive: got packet %p with length %d and status %d\n", urb, urb->actual_length, urb->status);
+
+		switch (urb->status) {
+		case 0:
+			PDEBUG ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p\n", rcv, urb, rcv->skb);
+
+			/* update the skb structure */
+			skb = rcv->skb;
+			skb_trim (skb, 0);
+			skb_put (skb, urb->actual_length);
+			data_start = skb->data;
+
+			PDEBUG ("skb->len = %d\n", skb->len);
+			PACKETDEBUG (skb->data, skb->len);
+
+			while ((new =
+				atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
+						       &atmsar_vcc)) != NULL) {
+				PDEBUG ("(after cell processing)skb->len = %d\n", new->len);
+
+				switch (atmsar_vcc->type) {
+				case ATMSAR_TYPE_AAL5:
+					tmp = new;
+					new = atmsar_decode_aal5 (atmsar_vcc, new);
+
+					/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
+					if (new) {
+						PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len);
+						if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
+							PACKETDEBUG (new->data, new->len);
+							atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
+						} else {
+							PDEBUG
+							    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n",
+							     atomic_read (&atmsar_vcc->vcc->rx_inuse),
+							     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
+							dev_kfree_skb (new);
+						}
+					} else {
+						PDEBUG ("atmsar_decode_aal5 returned NULL!\n");
+						dev_kfree_skb (tmp);
+					}
+					break;
+				default:
+					/* not supported. we delete the skb. */
+					printk (KERN_INFO
+						"SpeedTouch USB: illegal vcc type. Dropping packet.\n");
+					dev_kfree_skb (new);
+					break;
+				}
+			}
+
+			/* restore skb */
+			skb_push (skb, skb->data - data_start);
+
+			usb_fill_bulk_urb (urb,
+					   instance->usb_dev,
+					   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
+					   (unsigned char *) rcv->skb->data,
+					   UDSL_RECEIVE_BUFFER_SIZE,
+					   udsl_complete_receive,
+					   rcv);
+			if (!usb_submit_urb (urb, GFP_ATOMIC))
+				break;
+			PDEBUG ("udsl_process_receive: submission failed\n");
+			/* fall through */
+		default: /* error or urb unlinked */
+			PDEBUG ("udsl_process_receive: adding to spare_receivers\n");
+			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+			list_add (&rcv->list, &instance->spare_receivers);
+			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+			break;
+		} /* switch */
+
+		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	} /* while */
+	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+	PDEBUG ("udsl_process_receive successful\n");
+}
+
+static void udsl_fire_receivers (struct udsl_instance_data *instance)
+{
+	struct list_head receivers, *pos, *n;
+	unsigned long flags;
+
+	INIT_LIST_HEAD (&receivers);
+
+	down (&instance->serialize);
+
+	spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+	list_splice_init (&instance->spare_receivers, &receivers);
+	spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+
+	list_for_each_safe (pos, n, &receivers) {
+		struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list);
+
+		PDEBUG ("udsl_fire_receivers: firing urb %p\n", rcv->urb);
+
+		usb_fill_bulk_urb (rcv->urb,
+				   instance->usb_dev,
+				   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
+				   (unsigned char *) rcv->skb->data,
+				   UDSL_RECEIVE_BUFFER_SIZE,
+				   udsl_complete_receive,
+				   rcv);
+
+		if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) {
+			PDEBUG ("udsl_fire_receivers: submit failed!\n");
+			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+			list_move (pos, &instance->spare_receivers);
+			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+		}
+	}
+
+	up (&instance->serialize);
+}
+
+
 /************
 **   ATM   **
 ************/
@@ -213,27 +384,9 @@
 *
 ****************************************************************************/
 
-static struct atm_dev *udsl_atm_startdevice (struct udsl_instance_data *instance, struct atmdev_ops *devops)
-{
-	MOD_INC_USE_COUNT;
-	instance->atm_dev = atm_dev_register (udsl_driver_name, devops, -1, 0);
-	instance->atm_dev->dev_data = instance;
-	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
-	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
-	instance->atm_dev->signal = ATM_PHY_SIG_LOST;
-
-	skb_queue_head_init (&instance->recvqueue);
-
-	/* tmp init atm device, set to 128kbit */
-	instance->atm_dev->link_rate = 128 * 1000 / 424;
-
-	return instance->atm_dev;
-}
-
 static void udsl_atm_stopdevice (struct udsl_instance_data *instance)
 {
 	struct atm_vcc *walk;
-	struct sk_buff *skb;
 	struct atm_dev *atm_dev;
 
 	if (!instance->atm_dev)
@@ -241,10 +394,6 @@
 
 	atm_dev = instance->atm_dev;
 
-	/* clean queue */
-	while ((skb = skb_dequeue (&instance->recvqueue)))
-		dev_kfree_skb (skb);
-
 	atm_dev->signal = ATM_PHY_SIG_LOST;
 	walk = atm_dev->vccs;
 	shutdown_atm_dev (atm_dev);
@@ -253,16 +402,8 @@
 		wake_up (&walk->sleep);
 
 	instance->atm_dev = NULL;
-	MOD_DEC_USE_COUNT;
 }
 
-static void udsl_atm_set_mac (struct udsl_instance_data *instance, const char mac[6])
-{
-	if (!instance->atm_dev)
-		return;
-
-	memcpy (instance->atm_dev->esi, mac, 6);
-}
 
 /***************************************************************************
 *
@@ -281,11 +422,16 @@
 	return NULL;
 }
 
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
 {
 	struct udsl_instance_data *instance = atm_dev->dev_data;
 	int left = *pos;
 
+	if (!instance) {
+		PDEBUG ("NULL instance!\n");
+		return -ENODEV;
+	}
+
 	if (!left--)
 		return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
 				instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
@@ -311,6 +457,7 @@
 	return 0;
 }
 
+
 /***************************************************************************
 *
 * ATM DATA functions
@@ -325,8 +472,13 @@
 
 	PDEBUG ("udsl_atm_send called\n");
 
-	if (!dev_data)
+	if (!dev_data || !instance) {
+		PDEBUG ("NULL data!\n");
 		return -EINVAL;
+	}
+
+	if (!instance->firmware_loaded)
+		return -EAGAIN;
 
 	switch (vcc->qos.aal) {
 	case ATM_AAL5:
@@ -350,67 +502,13 @@
 		break;
 	default:
 		return -EINVAL;
-	};
+	}
 
 	PDEBUG ("udsl_atm_send unsuccessfull\n");
 	return 0;
       nomem:
 	vcc->pop (vcc, skb);
 	return -ENOMEM;
-};
-
-
-static void udsl_atm_processqueue (unsigned long data)
-{
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	struct atmsar_vcc_data *atmsar_vcc = NULL;
-	struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL;
-
-	PDEBUG ("udsl_atm_processqueue entered\n");
-
-	while ((skb = skb_dequeue (&instance->recvqueue))) {
-		PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len);
-		PACKETDEBUG (skb->data, skb->len);
-
-		while ((new =
-			atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
-					       &atmsar_vcc)) != NULL) {
-			PDEBUG ("(after cell processing)skb->len = %d\n", new->len);
-			switch (atmsar_vcc->type) {
-			case ATMSAR_TYPE_AAL5:
-				tmp = new;
-				new = atmsar_decode_aal5 (atmsar_vcc, new);
-
-				/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
-				if (new) {
-					PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len);
-					if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
-						PACKETDEBUG (new->data, new->len);
-						atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
-					} else {
-						PDEBUG
-						    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n",
-						     atomic_read (&atmsar_vcc->vcc->rx_inuse),
-						     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
-						dev_kfree_skb (new);
-					}
-				} else {
-					PDEBUG ("atmsar_decode_aal5 returned NULL!\n");
-					dev_kfree_skb (tmp);
-				}
-				break;
-			default:
-				/* not supported. we delete the skb. */
-				printk (KERN_INFO
-					"SpeedTouch USB: illegal vcc type. Dropping packet.\n");
-				dev_kfree_skb (new);
-				break;
-			}
-		};
-		dev_kfree_skb (skb);
-	};
-
-	PDEBUG ("udsl_atm_processqueue successfull\n");
 }
 
 
@@ -419,6 +517,7 @@
 * SAR driver entries
 *
 ****************************************************************************/
+
 static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
 {
 	struct udsl_atm_dev_data *dev_data;
@@ -426,6 +525,11 @@
 
 	PDEBUG ("udsl_atm_open called\n");
 
+	if (!instance) {
+		PDEBUG ("NULL instance!\n");
+		return -ENODEV;
+	}
+
 	/* at the moment only AAL5 support */
 	if (vcc->qos.aal != ATM_AAL5)
 		return -EINVAL;
@@ -453,6 +557,9 @@
 
 	dev_data->atmsar_vcc->mtu = UDSL_MAX_AAL5_MRU;
 
+	if (instance->firmware_loaded)
+		udsl_fire_receivers (instance);
+
 	PDEBUG ("udsl_atm_open successfull\n");
 	return 0;
 }
@@ -464,6 +571,11 @@
 
 	PDEBUG ("udsl_atm_close called\n");
 
+	if (!dev_data || !instance) {
+		PDEBUG ("NULL data!\n");
+		return;
+	}
+
 	/* freeing resources */
 	/* cancel all sends on this vcc */
 	udsl_usb_cancelsends (instance, vcc);
@@ -482,7 +594,7 @@
 
 	PDEBUG ("udsl_atm_close successfull\n");
 	return;
-};
+}
 
 static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
 {
@@ -492,7 +604,7 @@
 	default:
 		return -ENOIOCTLCMD;
 	}
-};
+}
 
 
 /************
@@ -566,9 +678,6 @@
 
 	PDEBUG ("udsl_usb_send_data entered, sending packet %p with length %d\n", skb, skb->len);
 
-	if (!instance->data_started)
-		return -EAGAIN;
-
 	PACKETDEBUG (skb->data, skb->len);
 
 	spin_lock_irqsave (&instance->sndqueue.lock, flags);
@@ -592,7 +701,7 @@
 		spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
 		PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb);
 		return 0;
-	};
+	}
 
 	/* init context */
 	urb = instance->send_ctx[i].urb;
@@ -620,285 +729,264 @@
 	return err;
 }
 
-/********* receive *******/
-static void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
-{
-	struct udsl_data_ctx *ctx;
-	struct udsl_instance_data *instance;
 
-	if (!urb)
-		return;
+/***************************************************************************
+*
+* usb driver entries
+*
+****************************************************************************/
 
-	PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb,
-		urb->actual_length, urb->status);
+static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
+{
+	struct udsl_instance_data *instance = usb_get_intfdata (intf);
 
-	ctx = urb->context;
-	if (!ctx || !ctx->skb)
-		return;
+	PDEBUG ("udsl_usb_ioctl entered\n");
 
-	instance = ctx->instance;
+	if (!instance) {
+		PDEBUG ("NULL instance!\n");
+		return -ENODEV;
+	}
 
-	switch (urb->status) {
-	case 0:
-		PDEBUG ("udsl_usb_data_receive: processing urb with ctx %p, urb %p (%p), skb %p\n",
-			ctx, ctx ? ctx->urb : NULL, urb, ctx ? ctx->skb : NULL);
-		/* update the skb structure */
-		skb_put (ctx->skb, urb->actual_length);
-
-		/* queue the skb for processing and wake the SAR */
-		skb_queue_tail (&instance->recvqueue, ctx->skb);
-		tasklet_schedule (&instance->recvqueue_tasklet);
-		/* get a new skb */
-		ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
-		if (!ctx->skb) {
-			PDEBUG ("No skb, loosing urb.\n");
-			usb_free_urb (ctx->urb);
-			ctx->urb = NULL;
-			return;
+	switch (code) {
+	case UDSL_IOCTL_START:
+		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
+		down (&instance->serialize); /* vs self */
+		if (!instance->firmware_loaded) {
+			usb_set_interface (instance->usb_dev, 1, 2);
+			instance->firmware_loaded = 1;
 		}
-		break;
-	case -ENOENT:		/* buffer was unlinked */
-	case -EILSEQ:		/* unplug or timeout */
-	case -ETIMEDOUT:	/* unplug or timeout */
-		/*
-		 * we don't do anything here and we don't resubmit
-		 */
-		return;
+		up (&instance->serialize);
+		udsl_fire_receivers (instance);
+		return 0;
+	case UDSL_IOCTL_STOP:
+		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
+		return 0;
+	default:
+		return -ENOTTY;
 	}
+}
 
-	usb_fill_bulk_urb (urb,
-		       instance->usb_dev,
-		       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-		       (unsigned char *) ctx->skb->data,
-		       UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx);
-	usb_submit_urb (urb, GFP_ATOMIC);
-	return;
-};
-
-static int udsl_usb_data_init (struct udsl_instance_data *instance)
+static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
 {
-	int i, succes;
+	struct usb_device *dev = interface_to_usbdev(intf);
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	struct udsl_instance_data *instance;
+	unsigned char mac_str [13];
+	unsigned char mac [6];
+	int i, err;
 
-	if (instance->data_started)
-		return 1;
+	PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n",
+		dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
 
-	/* set alternate setting 1 on interface 1 */
-	usb_set_interface (instance->usb_dev, 1, 2);
+	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
+	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
+	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+		return -ENODEV;
 
-	PDEBUG ("max packet size on endpoint %d is %d\n", UDSL_ENDPOINT_DATA_OUT,
-		usb_maxpacket (instance->usb_dev,
-			       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0));
+	PDEBUG ("Device Accepted\n");
 
-	instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL);
-	if (!instance->rcvbufs)
-		return -ENOMEM;
+	/* instance init */
+	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
+		PDEBUG ("No memory for Instance data!\n");
+		err = -ENOMEM;
+		goto fail_instance;
+	}
 
-	memset (instance->rcvbufs, 0, sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS);
+	memset (instance, 0, sizeof (struct udsl_instance_data));
 
-	skb_queue_head_init (&instance->sndqueue);
+	init_MUTEX (&instance->serialize);
 
-	for (i = 0, succes = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]);
+	instance->usb_dev = dev;
 
-		ctx->urb = NULL;
-		ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
-		if (!ctx->skb)
-			continue;
+	spin_lock_init (&instance->spare_receivers_lock);
+	INIT_LIST_HEAD (&instance->spare_receivers);
 
-		ctx->urb = usb_alloc_urb (0, GFP_KERNEL);
-		if (!ctx->urb) {
-			kfree_skb (ctx->skb);
-			ctx->skb = NULL;
-			break;
-		};
+	spin_lock_init (&instance->completed_receivers_lock);
+	INIT_LIST_HEAD (&instance->completed_receivers);
 
-		usb_fill_bulk_urb (ctx->urb,
-			       instance->usb_dev,
-			       usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-			       (unsigned char *) ctx->skb->data,
-			       UDSL_RECEIVE_BUFFER_SIZE,
-			       udsl_usb_data_receive, ctx);
+	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
 
+	skb_queue_head_init (&instance->sndqueue);
 
-		ctx->instance = instance;
+	/* receive urb init */
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
 
-		PDEBUG ("udsl_usb_data_init: usb with skb->truesize = %d (Asked for %d)\n",
-			ctx->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE);
+		if (!(rcv->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE))) {
+			PDEBUG ("No memory for skb %d!\n", i);
+			err = -ENOMEM;
+			goto fail_urbs;
+		}
 
-		if (usb_submit_urb (ctx->urb, GFP_KERNEL) < 0)
-			PDEBUG ("udsl_usb_data_init: Submit failed, loosing urb.\n");
-		else
-			succes++;
-	}
+		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
+			PDEBUG ("No memory for receive urb %d!\n", i);
+			err = -ENOMEM;
+			goto fail_urbs;
+		}
+
+		rcv->instance = instance;
 
-	PDEBUG ("udsl_usb_data_init %d urb%s queued for receive\n", succes,
-		(succes != 1) ? "s" : "");
+		list_add (&rcv->list, &instance->spare_receivers);
 
-	for (i = 0, succes = 0; i < UDSL_NUMBER_SND_URBS; i++) {
-		instance->send_ctx[i].urb = usb_alloc_urb (0, GFP_KERNEL);
-		PDEBUG ("udsl_usb_data_init: send urb allocted address %p\n",
-			instance->send_ctx[i].urb);
-		if (instance->send_ctx[i].urb)
-			succes++;
+		PDEBUG ("skb->truesize = %d (asked for %d)\n", rcv->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE);
 	}
 
-	PDEBUG ("udsl_usb_data_init %d urb%s queued for send\n", succes, (succes != 1) ? "s" : "");
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
+		struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]);
 
-	instance->data_started = 1;
-	instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
+		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
+			PDEBUG ("No memory for send urb %d!\n", i);
+			err = -ENOMEM;
+			goto fail_urbs;
+		}
 
-	return 0;
-}
+		snd->instance = instance;
+	}
 
-static int udsl_usb_data_exit (struct udsl_instance_data *instance)
-{
-	int i;
+	/* atm init */
+	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
+		PDEBUG ("failed to register ATM device!\n");
+		err = -ENOMEM;
+		goto fail_atm;
+	}
 
-	if (!instance->data_started)
-		return 0;
+	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
+	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
+	instance->atm_dev->signal = ATM_PHY_SIG_LOST;
 
-	if (!instance->rcvbufs)
-		return 0;
+	/* tmp init atm device, set to 128kbit */
+	instance->atm_dev->link_rate = 128 * 1000 / 424;
 
-	/* destroy urbs */
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]);
+	/* set MAC address, it is stored in the serial number */
+	usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13);
+	for (i = 0; i < 6; i++)
+		mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
 
-		if ((!ctx->urb) || (!ctx->skb))
-			continue;
+	PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 
-		usb_unlink_urb (ctx->urb);
+	memcpy (instance->atm_dev->esi, mac, 6);
 
-		usb_free_urb (ctx->urb);
-		kfree_skb (ctx->skb);
-		ctx->skb = NULL;
-	}
+	wmb ();
 
-	tasklet_kill (&instance->recvqueue_tasklet);
+	instance->atm_dev->dev_data = instance;
 
+	usb_set_intfdata (intf, instance);
+
+	return 0;
+
+fail_atm:
+fail_urbs:
 	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
-		struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]);
+		struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]);
 
-		usb_unlink_urb (ctx->urb);
+		if (snd->urb)
+			usb_free_urb (snd->urb);
+	}
 
-		if (ctx->skb)
-			ctx->vcc->pop (ctx->vcc, ctx->skb);
-		ctx->skb = NULL;
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
 
-		usb_free_urb (ctx->urb);
+		if (rcv->skb)
+			kfree_skb (rcv->skb);
 
+		if (rcv->urb)
+			usb_free_urb (rcv->urb);
 	}
+	kfree (instance);
+fail_instance:
+	return err;
+}
 
-	/* free receive contexts */
-	kfree (instance->rcvbufs);
-	instance->rcvbufs = NULL;
+static void udsl_usb_disconnect (struct usb_interface *intf)
+{
+	struct udsl_instance_data *instance = usb_get_intfdata (intf);
+	struct list_head *pos;
+	unsigned long flags;
+	unsigned int count = 0;
+	int i;
 
-	instance->data_started = 0;
-	instance->atm_dev->signal = ATM_PHY_SIG_LOST;
+	PDEBUG ("disconnecting\n");
 
-	return 0;
-};
+	usb_set_intfdata (intf, NULL);
 
+	if (!instance) {
+		PDEBUG ("NULL instance!\n");
+		return;
+	}
 
-/***************************************************************************
-*
-* usb driver entries
-*
-****************************************************************************/
-#define hex2int(c) ( (c >= '0')&&(c <= '9') ?  (c - '0') : ((c & 0xf)+9) )
+	tasklet_disable (&instance->receive_tasklet);
 
+	down (&instance->serialize); /* vs udsl_fire_receivers */
+	/* no need to take the spinlock - receive_tasklet is not running */
+	list_for_each (pos, &instance->spare_receivers)
+		if (++count > UDSL_NUMBER_RCV_URBS)
+			panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+	INIT_LIST_HEAD (&instance->spare_receivers);
+	up (&instance->serialize);
 
-static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
-{
-	struct udsl_instance_data *instance = usb_get_intfdata (intf);
-	int retval;
+	PDEBUG ("udsl_usb_disconnect: flushed %u spare receivers\n", count);
 
-	down(&udsl_usb_ioctl_lock);
-	switch (code) {
-	case UDSL_IOCTL_START:
-		retval = udsl_usb_data_init (instance);
-		break;
-	case UDSL_IOCTL_STOP:
-		retval = udsl_usb_data_exit (instance);
-		break;
-	default:
-		retval = -ENOTTY;
-		break;
-	}
-	up(&udsl_usb_ioctl_lock);
-	return retval;
-}
+	count = UDSL_NUMBER_RCV_URBS - count;
 
-static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
-{
-	struct usb_device *dev = interface_to_usbdev(intf);
-	int ifnum = intf->altsetting->desc.bInterfaceNumber;
-	int i;
-	unsigned char mac[6];
-	unsigned char mac_str[13];
-	struct udsl_instance_data *instance = NULL;
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++)
+		usb_unlink_urb (instance->all_receivers[i].urb);
 
-	PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n",
-		dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+	/* wait for completion handlers to finish */
+	do {
+		unsigned int completed = 0;
 
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
-	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
-	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
-		return -ENODEV;
+		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+		list_for_each (pos, &instance->completed_receivers)
+			if (++completed > count)
+				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
 
-	MOD_INC_USE_COUNT;
+		PDEBUG ("udsl_usb_disconnect: found %u completed receivers\n", completed);
 
-	PDEBUG ("Device Accepted\n");
+		if (completed == count)
+			break;
 
-	/* device init */
-	instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL);
-	if (!instance) {
-		PDEBUG ("No memory for Instance data!\n");
-		return -ENOMEM;
-	}
+		/* not all urbs completed */
+		yield ();
+	} while (1);
+
+	PDEBUG ("udsl_usb_disconnect: flushing %u completed receivers\n", count);
+	/* no need to take the spinlock - no completion handlers running */
+	INIT_LIST_HEAD (&instance->completed_receivers);
 
-	/* initialize structure */
-	memset (instance, 0, sizeof (struct udsl_instance_data));
-	instance->usb_dev = dev;
-	instance->rcvbufs = NULL;
-	tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance);
+	tasklet_enable (&instance->receive_tasklet);
+	tasklet_kill (&instance->receive_tasklet);
 
-	udsl_atm_startdevice (instance, &udsl_atm_devops);
+	PDEBUG ("udsl_usb_disconnect: freeing receivers\n");
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
 
-	/* set MAC address, it is stored in the serial number */
-	usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13);
-	for (i = 0; i < 6; i++)
-		mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
+		usb_free_urb (rcv->urb);
+		kfree_skb (rcv->skb);
+	}
 
-	PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4],
-		mac[5]);
-	udsl_atm_set_mac (instance, mac);
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
+		struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]);
 
-	usb_set_intfdata (intf, instance);
-	return 0;
-}
+		usb_unlink_urb (ctx->urb);
 
-static void udsl_usb_disconnect (struct usb_interface *intf)
-{
-	struct udsl_instance_data *instance = usb_get_intfdata (intf);
+		if (ctx->skb)
+			ctx->vcc->pop (ctx->vcc, ctx->skb);
+		ctx->skb = NULL;
 
-	PDEBUG ("disconnecting\n");
+		usb_free_urb (ctx->urb);
 
-	usb_set_intfdata (intf, NULL);
-	if (instance) {
-		/* unlinking receive buffers */
-		udsl_usb_data_exit (instance);
+	}
 
-		/* removing atm device */
-		if (instance->atm_dev)
-			udsl_atm_stopdevice (instance);
 
-		kfree (instance);
+	/* removing atm device */
+	if (instance->atm_dev)
+		udsl_atm_stopdevice (instance);
 
-		MOD_DEC_USE_COUNT;
-	}
+	kfree (instance);
 }
 
+
 /***************************************************************************
 *
 * Driver Init
@@ -907,18 +995,25 @@
 
 static int __init udsl_usb_init (void)
 {
-	PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n");
+	PDEBUG ("udsl_usb_init: driver version " DRIVER_VERSION "\n");
 
 	return usb_register (&udsl_usb_driver);
 }
 
 static void __exit udsl_usb_cleanup (void)
 {
+	PDEBUG ("udsl_usb_cleanup\n");
+
 	usb_deregister (&udsl_usb_driver);
 }
 
-module_init(udsl_usb_init);
-module_exit(udsl_usb_cleanup);
+module_init (udsl_usb_init);
+module_exit (udsl_usb_cleanup);
+
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_LICENSE ("GPL");
+
 
 #ifdef DEBUG_PACKET
 /*******************************************************************************
@@ -929,7 +1024,7 @@
 
 static int udsl_print_packet (const unsigned char *data, int len)
 {
-	unsigned char buffer[256];
+	unsigned char buffer [256];
 	int i = 0, j = 0;
 
 	for (i = 0; i < len;) {
@@ -941,10 +1036,6 @@
 		PDEBUG ("%s\n", buffer);
 	}
 	return i;
-};
+}
 
 #endif				/* PACKETDEBUG */
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
diff -Nru a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
--- a/drivers/usb/net/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/net/Kconfig	Mon Feb 10 10:39:30 2003
@@ -25,7 +25,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called catc.o. If you want to compile it as a
+	  The module will be called catc. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_CDCETHER
@@ -49,7 +49,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cdc-ether.o.  If you want to compile it 
+	  The module will be called cdc-ether.  If you want to compile it 
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_KAWETH
@@ -91,7 +91,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called kaweth.o. If you want to compile it as a
+	  The module will be called kaweth. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_PEGASUS
@@ -107,7 +107,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pegasus.o. If you want to compile it as a
+	  The module will be called pegasus. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_RTL8150
@@ -120,7 +120,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rtl8150.o. If you want to compile it as a
+	  The module will be called rtl8150. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_USBNET
@@ -144,6 +144,6 @@
 
 	  This code is also available as a kernel module (code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbnet.o. If you want to compile it as a
+	  The module will be called usbnet. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
diff -Nru a/drivers/usb/net/Makefile.mii b/drivers/usb/net/Makefile.mii
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/net/Makefile.mii	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,5 @@
+#
+# Makefile for USB Network drivers which require generic MII code.
+#
+
+obj-$(CONFIG_USB_PEGASUS)	+= mii.o
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/serial/Kconfig	Mon Feb 10 10:39:30 2003
@@ -19,7 +19,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usbserial.o. If you want to compile it
+	  The module will be called usbserial. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_DEBUG
@@ -72,7 +72,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called belkin_sa.o.  If you want to compile it as
+	  The module will be called belkin_sa.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_WHITEHEAT
@@ -84,7 +84,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called whiteheat.o.  If you want to compile it as
+	  The module will be called whiteheat.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_DIGI_ACCELEPORT
@@ -101,7 +101,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called digi_acceleport.o.  If you want to compile
+	  The module will be called digi_acceleport.  If you want to compile
 	  it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -116,7 +116,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called empeg.o. If you want to compile it as a
+	  The module will be called empeg. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_FTDI_SIO
@@ -132,7 +132,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ftdi_sio.o.  If you want to compile it as
+	  The module will be called ftdi_sio.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_VISOR
@@ -146,7 +146,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called visor.o. If you want to compile it as a
+	  The module will be called visor. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_IPAQ
@@ -160,7 +160,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ipaq.o. If you want to compile it as a
+	  The module will be called ipaq. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_IR
@@ -173,7 +173,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ir-usb.o. If you want to compile it as a
+	  The module will be called ir-usb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_EDGEPORT
@@ -201,7 +201,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called io_edgeport.o.  If you want to compile it
+	  The module will be called io_edgeport.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_EDGEPORT_TI
@@ -214,7 +214,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called io_ti.o.  If you want to compile it
+	  The module will be called io_ti.  If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_KEYSPAN_PDA
@@ -227,7 +227,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called keyspan_pda.o. If you want to compile it
+	  The module will be called keyspan_pda. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_KEYSPAN
@@ -243,7 +243,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called keyspan.o. If you want to compile it as a
+	  The module will be called keyspan. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_KEYSPAN_USA28
@@ -323,7 +323,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called kl5kusb105.o. If you want to compile it as
+	  The module will be called kl5kusb105. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_KOBIL_SCT
@@ -342,7 +342,7 @@
           Note that you need a current CT-API.
           This code is also available as a module ( = code which can be
           inserted in and removed from the running kernel whenever you want).
-          The module will be called kobil_sct.o. If you want to compile it as
+          The module will be called kobil_sct. If you want to compile it as
           a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_MCT_U232
@@ -357,7 +357,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mct_u232.o.  If you want to compile it as
+	  The module will be called mct_u232.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_PL2303
@@ -369,7 +369,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called pl2303.o.  If you want to compile it as
+	  The module will be called pl2303.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_SAFE
@@ -390,7 +390,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called cyberjack.o. If you want to compile it as
+	  The module will be called cyberjack. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say N.
@@ -405,7 +405,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called keyspan_pda.o. If you want to compile it
+	  The module will be called keyspan_pda. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_SERIAL_OMNINET
@@ -416,7 +416,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called omninet.o. If you want to compile it as a
+	  The module will be called omninet. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_EZUSB
diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
--- a/drivers/usb/serial/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/serial/Makefile	Mon Feb 10 10:39:23 2003
@@ -30,7 +30,4 @@
 obj-$(CONFIG_USB_SERIAL_KLSI)			+= kl5kusb105.o
 obj-$(CONFIG_USB_SERIAL_SAFE)			+= safe_serial.o
 
-# Objects that export symbols.
-export-objs	:= usb-serial.o ezusb.o
-
 usbserial-objs	:= usb-serial.o generic.o bus.o $(usbserial-obj-y)
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/serial/ftdi_sio.c	Mon Feb 10 10:39:30 2003
@@ -135,6 +135,7 @@
    
 static struct usb_device_id id_table_8U232AM [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ }						/* Terminating entry */
 };
@@ -143,6 +144,7 @@
 static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ }						/* Terminating entry */
 };
diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
--- a/drivers/usb/serial/ftdi_sio.h	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/serial/ftdi_sio.h	Mon Feb 10 10:39:31 2003
@@ -17,11 +17,14 @@
  * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the 
  * FTDI_SIO implementation.
  *
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
+ * from Rudolf Gugler
  */
 
 #define FTDI_VID	0x0403	/* Vendor Id */
 #define FTDI_SIO_PID	0x8372	/* Product Id SIO application of 8U100AX  */
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
+#define FTDI_RELAIS_PID	0xFA10  /* Relais device from Rudolf Gugler */
 #define FTDI_NF_RIC_VID	0x0DCD	/* Vendor Id */
 #define FTDI_NF_RIC_PID	0x0001	/* Product Id */
 
diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c	Mon Feb 10 10:39:31 2003
+++ b/drivers/usb/serial/ipaq.c	Mon Feb 10 10:39:31 2003
@@ -106,6 +106,7 @@
 	{ USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) },
 	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
 	{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) },
+	{ USB_DEVICE(DELL_VENDOR_ID, DELL_AXIM_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
 	{ USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) },
@@ -126,6 +127,7 @@
 	{ USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) },
 	{ USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) },
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) },
+	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) },
 	{ USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) },
 	{ USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) },
 	{ }					/* Terminating entry */
diff -Nru a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h
--- a/drivers/usb/serial/ipaq.h	Mon Feb 10 10:39:23 2003
+++ b/drivers/usb/serial/ipaq.h	Mon Feb 10 10:39:23 2003
@@ -30,6 +30,9 @@
 #define COMPAQ_IPAQ_ID		0x0003
 #define COMPAQ_0032_ID		0x0032
 
+#define DELL_VENDOR_ID		0x413c
+#define DELL_AXIM_ID		0x4001
+
 #define HP_VENDOR_ID		0x03f0
 #define HP_JORNADA_548_ID	0x1016
 #define HP_JORNADA_568_ID	0x1116
@@ -63,6 +66,7 @@
 
 #define TOSHIBA_VENDOR_ID	0x0930
 #define TOSHIBA_PRODUCT_ID	0x0700
+#define TOSHIBA_E740_ID		0x0706
 
 #define HTC_VENDOR_ID		0x0bb4
 #define HTC_PRODUCT_ID		0x00ce
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
--- a/drivers/usb/serial/pl2303.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/usb/serial/pl2303.c	Mon Feb 10 10:39:26 2003
@@ -74,6 +74,7 @@
 	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
 	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) },
+	{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
--- a/drivers/usb/serial/pl2303.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/usb/serial/pl2303.h	Mon Feb 10 10:39:27 2003
@@ -28,3 +28,6 @@
 
 #define RATOC_VENDOR_ID		0x0584
 #define RATOC_PRODUCT_ID	0xb000
+
+#define TRIPP_VENDOR_ID		0x2478
+#define TRIPP_PRODUCT_ID	0x2008
diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
--- a/drivers/usb/serial/safe_serial.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/serial/safe_serial.c	Mon Feb 10 10:39:24 2003
@@ -256,7 +256,7 @@
 				}
 				tty_flip_buffer_push (port->tty);
 			} else {
-				err ("%s - inconsistant lengths %d:%d", __FUNCTION__,
+				err ("%s - inconsistent lengths %d:%d", __FUNCTION__,
 				     actual_length, length);
 			}
 		} else {
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Mon Feb 10 10:39:26 2003
+++ b/drivers/usb/serial/usb-serial.c	Mon Feb 10 10:39:26 2003
@@ -214,7 +214,7 @@
  *	Brian Warner has a place to put his code.
  *	Made the ezusb specific functions generic enough that different
  *	devices can use them (whiteheat and keyspan_pda both need them).
- *	Split out a whole bunch of structure and other stuff to a seperate
+ *	Split out a whole bunch of structure and other stuff to a separate
  *	usb-serial.h file.
  *	Made the Visor connection messages a little more understandable, now
  *	that Miles Lott (milos@insync.net) has gotten the Generic channel to
diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
--- a/drivers/usb/storage/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/storage/Kconfig	Mon Feb 10 10:39:33 2003
@@ -16,7 +16,7 @@
 
 	  This code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called usb-storage.o. If you want to compile it
+	  The module will be called usb-storage. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config USB_STORAGE_DEBUG
diff -Nru a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h
--- a/drivers/usb/storage/datafab.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/storage/datafab.h	Mon Feb 10 10:39:30 2003
@@ -27,14 +27,14 @@
 extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us);
 
 struct datafab_info {
-	unsigned long   sectors;     // total sector count
-	unsigned long   ssize;       // sector size in bytes
-	char            lun;         // used for dual-slot readers
-        
-        // the following aren't used yet
+	unsigned long   sectors;	// total sector count
+	unsigned long   ssize;		// sector size in bytes
+	char		lun;		// used for dual-slot readers
+	
+	// the following aren't used yet
 	unsigned char   sense_key;
-	unsigned long   sense_asc;   // additional sense code
-	unsigned long   sense_ascq;  // additional sense code qualifier
+	unsigned long   sense_asc;	// additional sense code
+	unsigned long   sense_ascq;	// additional sense code qualifier
 };
 
 #endif
diff -Nru a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c
--- a/drivers/usb/storage/dpcm.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/storage/dpcm.c	Mon Feb 10 10:39:30 2003
@@ -48,9 +48,9 @@
   if(srb == NULL)
     return USB_STOR_TRANSPORT_ERROR;
 
-  US_DEBUGP("dpcm_transport: LUN=%d\n", srb->lun);
+  US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun);
 
-  switch(srb->lun) {
+  switch(srb->device->lun) {
   case 0:
 
     /*
@@ -68,15 +68,15 @@
     /*
      * Set the LUN to 0 (just in case).
      */
-    srb->lun = 0; us->srb->lun = 0;
+    srb->device->lun = 0; us->srb->device->lun = 0;
     ret = sddr09_transport(srb, us);
-    srb->lun = 1; us->srb->lun = 1;
+    srb->device->lun = 1; us->srb->device->lun = 1;
 
     return ret;
 #endif
 
   default:
-    US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->lun);
+    US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun);
     return USB_STOR_TRANSPORT_ERROR;
   }
 }
diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
--- a/drivers/usb/storage/freecom.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/usb/storage/freecom.c	Mon Feb 10 10:39:33 2003
@@ -45,42 +45,42 @@
 #define DRQ_STAT		0x08
 
 struct freecom_udata {
-        u8    buffer[64];             /* Common command block. */
+	u8    buffer[64];	/* Common command block. */
 };
 typedef struct freecom_udata *freecom_udata_t;
 
 /* All of the outgoing packets are 64 bytes long. */
 struct freecom_cb_wrap {
-        u8    Type;                   /* Command type. */
-        u8    Timeout;                /* Timeout in seconds. */
-        u8    Atapi[12];              /* An ATAPI packet. */
-        u8    Filler[50];             /* Padding Data. */
+	u8    Type;		/* Command type. */
+	u8    Timeout;		/* Timeout in seconds. */
+	u8    Atapi[12];	/* An ATAPI packet. */
+	u8    Filler[50];	/* Padding Data. */
 };
 
 struct freecom_xfer_wrap {
-        u8    Type;                   /* Command type. */
-        u8    Timeout;                /* Timeout in seconds. */
-        u32   Count;                  /* Number of bytes to transfer. */
-        u8    Pad[58];
+	u8    Type;		/* Command type. */
+	u8    Timeout;		/* Timeout in seconds. */
+	u32   Count;		/* Number of bytes to transfer. */
+	u8    Pad[58];
 } __attribute__ ((packed));
 
 struct freecom_ide_out {
-        u8    Type;                   /* Type + IDE register. */
-        u8    Pad;
-        u16   Value;                  /* Value to write. */
-        u8    Pad2[60];
+	u8    Type;		/* Type + IDE register. */
+	u8    Pad;
+	u16   Value;		/* Value to write. */
+	u8    Pad2[60];
 };
 
 struct freecom_ide_in {
-        u8    Type;                   /* Type | IDE register. */
-        u8    Pad[63];
+	u8    Type;		/* Type | IDE register. */
+	u8    Pad[63];
 };
 
 struct freecom_status {
-        u8    Status;
-        u8    Reason;
-        u16   Count;
-        u8    Pad[60];
+	u8    Status;
+	u8    Reason;
+	u16   Count;
+	u8    Pad[60];
 };
 
 /* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide
@@ -110,32 +110,32 @@
 
 static int
 freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
-                unsigned int ipipe, unsigned int opipe, int count)
+		unsigned int ipipe, unsigned int opipe, int count)
 {
-        freecom_udata_t extra = (freecom_udata_t) us->extra;
-        struct freecom_xfer_wrap *fxfr =
-                (struct freecom_xfer_wrap *) extra->buffer;
-        int result;
-
-        fxfr->Type = FCM_PACKET_INPUT | 0x00;
-        fxfr->Timeout = 0;    /* Short timeout for debugging. */
-        fxfr->Count = cpu_to_le32 (count);
-        memset (fxfr->Pad, 0, sizeof (fxfr->Pad));
-
-        US_DEBUGP("Read data Freecom! (c=%d)\n", count);
-
-        /* Issue the transfer command. */
-        result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
-                        FCM_PACKET_LENGTH, NULL);
-        if (result != USB_STOR_XFER_GOOD) {
-                US_DEBUGP ("Freecom readdata transport error\n");
-                return USB_STOR_TRANSPORT_ERROR;
-        }
+	freecom_udata_t extra = (freecom_udata_t) us->extra;
+	struct freecom_xfer_wrap *fxfr =
+		(struct freecom_xfer_wrap *) extra->buffer;
+	int result;
+
+	fxfr->Type = FCM_PACKET_INPUT | 0x00;
+	fxfr->Timeout = 0;    /* Short timeout for debugging. */
+	fxfr->Count = cpu_to_le32 (count);
+	memset (fxfr->Pad, 0, sizeof (fxfr->Pad));
+
+	US_DEBUGP("Read data Freecom! (c=%d)\n", count);
+
+	/* Issue the transfer command. */
+	result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
+			FCM_PACKET_LENGTH, NULL);
+	if (result != USB_STOR_XFER_GOOD) {
+		US_DEBUGP ("Freecom readdata transport error\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
 
-        /* Now transfer all of our blocks. */
+	/* Now transfer all of our blocks. */
 	US_DEBUGP("Start of read\n");
 	result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count);
-        US_DEBUGP("freecom_readdata done!\n");
+	US_DEBUGP("freecom_readdata done!\n");
 
 	if (result > USB_STOR_XFER_SHORT)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -144,33 +144,33 @@
 
 static int
 freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
-                int unsigned ipipe, unsigned int opipe, int count)
+		int unsigned ipipe, unsigned int opipe, int count)
 {
-        freecom_udata_t extra = (freecom_udata_t) us->extra;
-        struct freecom_xfer_wrap *fxfr =
-                (struct freecom_xfer_wrap *) extra->buffer;
-        int result;
-
-        fxfr->Type = FCM_PACKET_OUTPUT | 0x00;
-        fxfr->Timeout = 0;    /* Short timeout for debugging. */
-        fxfr->Count = cpu_to_le32 (count);
-        memset (fxfr->Pad, 0, sizeof (fxfr->Pad));
-
-        US_DEBUGP("Write data Freecom! (c=%d)\n", count);
-
-        /* Issue the transfer command. */
-        result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
-                        FCM_PACKET_LENGTH, NULL);
-        if (result != USB_STOR_XFER_GOOD) {
-                US_DEBUGP ("Freecom writedata transport error\n");
-                return USB_STOR_TRANSPORT_ERROR;
-        }
+	freecom_udata_t extra = (freecom_udata_t) us->extra;
+	struct freecom_xfer_wrap *fxfr =
+		(struct freecom_xfer_wrap *) extra->buffer;
+	int result;
+
+	fxfr->Type = FCM_PACKET_OUTPUT | 0x00;
+	fxfr->Timeout = 0;    /* Short timeout for debugging. */
+	fxfr->Count = cpu_to_le32 (count);
+	memset (fxfr->Pad, 0, sizeof (fxfr->Pad));
+
+	US_DEBUGP("Write data Freecom! (c=%d)\n", count);
+
+	/* Issue the transfer command. */
+	result = usb_stor_bulk_transfer_buf (us, opipe, fxfr,
+			FCM_PACKET_LENGTH, NULL);
+	if (result != USB_STOR_XFER_GOOD) {
+		US_DEBUGP ("Freecom writedata transport error\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
 
-        /* Now transfer all of our blocks. */
+	/* Now transfer all of our blocks. */
 	US_DEBUGP("Start of write\n");
 	result = usb_stor_bulk_transfer_srb(us, opipe, srb, count);
 
-        US_DEBUGP("freecom_writedata done!\n");
+	US_DEBUGP("freecom_writedata done!\n");
 	if (result > USB_STOR_XFER_SHORT)
 		return USB_STOR_TRANSPORT_ERROR;
 	return USB_STOR_TRANSPORT_GOOD;
@@ -182,54 +182,54 @@
  */
 int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
 {
-        struct freecom_cb_wrap *fcb;
-        struct freecom_status  *fst;
-        unsigned int ipipe, opipe;             /* We need both pipes. */
-        int result;
+	struct freecom_cb_wrap *fcb;
+	struct freecom_status  *fst;
+	unsigned int ipipe, opipe;		/* We need both pipes. */
+	int result;
 	unsigned int partial;
-        int length;
-        freecom_udata_t extra;
+	int length;
+	freecom_udata_t extra;
+
+	extra = (freecom_udata_t) us->extra;
 
-        extra = (freecom_udata_t) us->extra;
+	fcb = (struct freecom_cb_wrap *) extra->buffer;
+	fst = (struct freecom_status *) extra->buffer;
 
-        fcb = (struct freecom_cb_wrap *) extra->buffer;
-        fst = (struct freecom_status *) extra->buffer;
+	US_DEBUGP("Freecom TRANSPORT STARTED\n");
 
-        US_DEBUGP("Freecom TRANSPORT STARTED\n");
-
-        /* Get handles for both transports. */
-        opipe = us->send_bulk_pipe;
-        ipipe = us->recv_bulk_pipe;
-
-        /* The ATAPI Command always goes out first. */
-        fcb->Type = FCM_PACKET_ATAPI | 0x00;
-        fcb->Timeout = 0;
-        memcpy (fcb->Atapi, srb->cmnd, 12);
-        memset (fcb->Filler, 0, sizeof (fcb->Filler));
-
-        US_DEBUG(pdump (srb->cmnd, 12));
-
-        /* Send it out. */
-        result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
-                        FCM_PACKET_LENGTH, NULL);
-
-        /* The Freecom device will only fail if there is something wrong in
-         * USB land.  It returns the status in its own registers, which
-         * come back in the bulk pipe. */
-        if (result != USB_STOR_XFER_GOOD) {
-                US_DEBUGP ("freecom transport error\n");
-                return USB_STOR_TRANSPORT_ERROR;
-        }
-
-        /* There are times we can optimize out this status read, but it
-         * doesn't hurt us to always do it now. */
-        result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
-                        FCM_PACKET_LENGTH, &partial);
-        US_DEBUGP("foo Status result %d %u\n", result, partial);
+	/* Get handles for both transports. */
+	opipe = us->send_bulk_pipe;
+	ipipe = us->recv_bulk_pipe;
+
+	/* The ATAPI Command always goes out first. */
+	fcb->Type = FCM_PACKET_ATAPI | 0x00;
+	fcb->Timeout = 0;
+	memcpy (fcb->Atapi, srb->cmnd, 12);
+	memset (fcb->Filler, 0, sizeof (fcb->Filler));
+
+	US_DEBUG(pdump (srb->cmnd, 12));
+
+	/* Send it out. */
+	result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
+			FCM_PACKET_LENGTH, NULL);
+
+	/* The Freecom device will only fail if there is something wrong in
+	 * USB land.  It returns the status in its own registers, which
+	 * come back in the bulk pipe. */
+	if (result != USB_STOR_XFER_GOOD) {
+		US_DEBUGP ("freecom transport error\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* There are times we can optimize out this status read, but it
+	 * doesn't hurt us to always do it now. */
+	result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+			FCM_PACKET_LENGTH, &partial);
+	US_DEBUGP("foo Status result %d %u\n", result, partial);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-        US_DEBUG(pdump ((void *) fst, partial));
+	US_DEBUG(pdump ((void *) fst, partial));
 
 	/* The firmware will time-out commands after 20 seconds. Some commands
 	 * can legitimately take longer than this, so we use a different
@@ -249,7 +249,7 @@
 		memset (fcb->Atapi, 0, sizeof(fcb->Atapi));
 		memset (fcb->Filler, 0, sizeof (fcb->Filler));
 
-        	/* Send it out. */
+		/* Send it out. */
 		result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
 				FCM_PACKET_LENGTH, NULL);
 
@@ -263,31 +263,31 @@
 		}
 
 		/* get the data */
-        	result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+		result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
 				FCM_PACKET_LENGTH, &partial);
 
 		US_DEBUGP("bar Status result %d %u\n", result, partial);
 		if (result > USB_STOR_XFER_SHORT)
-	                return USB_STOR_TRANSPORT_ERROR;
+			return USB_STOR_TRANSPORT_ERROR;
 
 		US_DEBUG(pdump ((void *) fst, partial));
 	}
 
-        if (partial != 4)
-                return USB_STOR_TRANSPORT_ERROR;
-        if ((fst->Status & 1) != 0) {
-                US_DEBUGP("operation failed\n");
-                return USB_STOR_TRANSPORT_FAILED;
-        }
-
-        /* The device might not have as much data available as we
-         * requested.  If you ask for more than the device has, this reads
-         * and such will hang. */
-        US_DEBUGP("Device indicates that it has %d bytes available\n",
-                        le16_to_cpu (fst->Count));
-        US_DEBUGP("SCSI requested %d\n", srb->request_bufflen);
+	if (partial != 4)
+		return USB_STOR_TRANSPORT_ERROR;
+	if ((fst->Status & 1) != 0) {
+		US_DEBUGP("operation failed\n");
+		return USB_STOR_TRANSPORT_FAILED;
+	}
 
-        /* Find the length we desire to read. */
+	/* The device might not have as much data available as we
+	 * requested.  If you ask for more than the device has, this reads
+	 * and such will hang. */
+	US_DEBUGP("Device indicates that it has %d bytes available\n",
+			le16_to_cpu (fst->Count));
+	US_DEBUGP("SCSI requested %d\n", srb->request_bufflen);
+
+	/* Find the length we desire to read. */
 	switch (srb->cmnd[0]) {
 		case INQUIRY:
 		case REQUEST_SENSE:		/* 16 or 18 bytes? spec says 18, lots of devices only have 16 */
@@ -305,97 +305,97 @@
 		US_DEBUGP("Truncating request to match buffer length: %d\n", length);
 	}
 
-        /* What we do now depends on what direction the data is supposed to
-         * move in. */
+	/* What we do now depends on what direction the data is supposed to
+	 * move in. */
+
+	switch (us->srb->sc_data_direction) {
+	case SCSI_DATA_READ:
+		/* Make sure that the status indicates that the device
+		 * wants data as well. */
+		if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
+			US_DEBUGP("SCSI wants data, drive doesn't have any\n");
+			return USB_STOR_TRANSPORT_FAILED;
+		}
+		result = freecom_readdata (srb, us, ipipe, opipe, length);
+		if (result != USB_STOR_TRANSPORT_GOOD)
+			return result;
 
-        switch (us->srb->sc_data_direction) {
-        case SCSI_DATA_READ:
-                /* Make sure that the status indicates that the device
-                 * wants data as well. */
-                if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
-                        US_DEBUGP("SCSI wants data, drive doesn't have any\n");
-                        return USB_STOR_TRANSPORT_FAILED;
-                }
-                result = freecom_readdata (srb, us, ipipe, opipe, length);
-                if (result != USB_STOR_TRANSPORT_GOOD)
-                        return result;
-
-                US_DEBUGP("FCM: Waiting for status\n");
-                result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
-                                FCM_PACKET_LENGTH, &partial);
+		US_DEBUGP("FCM: Waiting for status\n");
+		result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+				FCM_PACKET_LENGTH, &partial);
 		US_DEBUG(pdump ((void *) fst, partial));
 
-                if (partial != 4 || result > USB_STOR_XFER_SHORT)
-                        return USB_STOR_TRANSPORT_ERROR;
-                if ((fst->Status & ERR_STAT) != 0) {
-                        US_DEBUGP("operation failed\n");
-                        return USB_STOR_TRANSPORT_FAILED;
-                }
-                if ((fst->Reason & 3) != 3) {
-                        US_DEBUGP("Drive seems still hungry\n");
-                        return USB_STOR_TRANSPORT_FAILED;
-                }
-                US_DEBUGP("Transfer happy\n");
-                break;
-
-        case SCSI_DATA_WRITE:
-                /* Make sure the status indicates that the device wants to
-                 * send us data. */
-                /* !!IMPLEMENT!! */
-                result = freecom_writedata (srb, us, ipipe, opipe, length);
-                if (result != USB_STOR_TRANSPORT_GOOD)
-                        return result;
-
-                US_DEBUGP("FCM: Waiting for status\n");
-                result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
-                                FCM_PACKET_LENGTH, &partial);
-
-                if (partial != 4 || result > USB_STOR_XFER_SHORT)
-                        return USB_STOR_TRANSPORT_ERROR;
-                if ((fst->Status & ERR_STAT) != 0) {
-                        US_DEBUGP("operation failed\n");
-                        return USB_STOR_TRANSPORT_FAILED;
-                }
-                if ((fst->Reason & 3) != 3) {
-                        US_DEBUGP("Drive seems still hungry\n");
-                        return USB_STOR_TRANSPORT_FAILED;
-                }
-
-                US_DEBUGP("Transfer happy\n");
-                break;
-
-
-        case SCSI_DATA_NONE:
-                /* Easy, do nothing. */
-                break;
-
-        default:
-                US_DEBUGP ("freecom unimplemented direction: %d\n",
-                                us->srb->sc_data_direction);
-                // Return fail, SCSI seems to handle this better.
-                return USB_STOR_TRANSPORT_FAILED;
-                break;
-        }
+		if (partial != 4 || result > USB_STOR_XFER_SHORT)
+			return USB_STOR_TRANSPORT_ERROR;
+		if ((fst->Status & ERR_STAT) != 0) {
+			US_DEBUGP("operation failed\n");
+			return USB_STOR_TRANSPORT_FAILED;
+		}
+		if ((fst->Reason & 3) != 3) {
+			US_DEBUGP("Drive seems still hungry\n");
+			return USB_STOR_TRANSPORT_FAILED;
+		}
+		US_DEBUGP("Transfer happy\n");
+		break;
+
+	case SCSI_DATA_WRITE:
+		/* Make sure the status indicates that the device wants to
+		 * send us data. */
+		/* !!IMPLEMENT!! */
+		result = freecom_writedata (srb, us, ipipe, opipe, length);
+		if (result != USB_STOR_TRANSPORT_GOOD)
+			return result;
+
+		US_DEBUGP("FCM: Waiting for status\n");
+		result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
+				FCM_PACKET_LENGTH, &partial);
+
+		if (partial != 4 || result > USB_STOR_XFER_SHORT)
+			return USB_STOR_TRANSPORT_ERROR;
+		if ((fst->Status & ERR_STAT) != 0) {
+			US_DEBUGP("operation failed\n");
+			return USB_STOR_TRANSPORT_FAILED;
+		}
+		if ((fst->Reason & 3) != 3) {
+			US_DEBUGP("Drive seems still hungry\n");
+			return USB_STOR_TRANSPORT_FAILED;
+		}
 
-        return USB_STOR_TRANSPORT_GOOD;
+		US_DEBUGP("Transfer happy\n");
+		break;
+
+
+	case SCSI_DATA_NONE:
+		/* Easy, do nothing. */
+		break;
+
+	default:
+		US_DEBUGP ("freecom unimplemented direction: %d\n",
+				us->srb->sc_data_direction);
+		// Return fail, SCSI seems to handle this better.
+		return USB_STOR_TRANSPORT_FAILED;
+		break;
+	}
+
+	return USB_STOR_TRANSPORT_GOOD;
 }
 
 int
 freecom_init (struct us_data *us)
 {
-        int result;
+	int result;
 	char buffer[33];
 
-        /* Allocate a buffer for us.  The upper usb transport code will
-         * free this for us when cleaning up. */
-        if (us->extra == NULL) {
-                us->extra = kmalloc (sizeof (struct freecom_udata),
-                                GFP_KERNEL);
-                if (us->extra == NULL) {
-                        US_DEBUGP("Out of memory\n");
-                        return USB_STOR_TRANSPORT_ERROR;
-                }
-        }
+	/* Allocate a buffer for us.  The upper usb transport code will
+	 * free this for us when cleaning up. */
+	if (us->extra == NULL) {
+		us->extra = kmalloc (sizeof (struct freecom_udata),
+				GFP_KERNEL);
+		if (us->extra == NULL) {
+			US_DEBUGP("Out of memory\n");
+			return USB_STOR_TRANSPORT_ERROR;
+		}
+	}
 
 	result = usb_control_msg(us->pusb_dev, us->recv_ctrl_pipe,
 			0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ);
@@ -424,15 +424,15 @@
 	/* wait 3 seconds */
 	mdelay(3 * 1000);
 
-        return USB_STOR_TRANSPORT_GOOD;
+	return USB_STOR_TRANSPORT_GOOD;
 }
 
 int usb_stor_freecom_reset(struct us_data *us)
 {
-        printk (KERN_CRIT "freecom reset called\n");
+	printk (KERN_CRIT "freecom reset called\n");
 
-        /* We don't really have this feature. */
-        return FAILED;
+	/* We don't really have this feature. */
+	return FAILED;
 }
 
 #ifdef CONFIG_USB_STORAGE_DEBUG
diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
--- a/drivers/usb/storage/isd200.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/usb/storage/isd200.c	Mon Feb 10 10:39:27 2003
@@ -34,11 +34,11 @@
  *  2002-10-19: Removed the specialized transfer routines.
  *		(Alan Stern <stern@rowland.harvard.edu>)
  *  2001-02-24: Removed lots of duplicate code and simplified the structure.
- *              (bjorn@haxx.se)
+ *	      (bjorn@haxx.se)
  *  2002-01-16: Fixed endianness bug so it works on the ppc arch.
- *              (Luc Saillard <luc@saillard.org>)
+ *	      (Luc Saillard <luc@saillard.org>)
  *  2002-01-17: All bitfields removed.
- *              (bjorn@haxx.se)
+ *	      (bjorn@haxx.se)
  */
 
 
@@ -59,14 +59,14 @@
 
 /* Timeout defines (in Seconds) */
 
-#define ISD200_ENUM_BSY_TIMEOUT         35
+#define ISD200_ENUM_BSY_TIMEOUT		35
 #define ISD200_ENUM_DETECT_TIMEOUT      30
-#define ISD200_DEFAULT_TIMEOUT          30
+#define ISD200_DEFAULT_TIMEOUT		30
 
 /* device flags */
-#define DF_ATA_DEVICE               0x0001
-#define DF_MEDIA_STATUS_ENABLED     0x0002
-#define DF_REMOVABLE_MEDIA          0x0004
+#define DF_ATA_DEVICE		0x0001
+#define DF_MEDIA_STATUS_ENABLED	0x0002
+#define DF_REMOVABLE_MEDIA	0x0004
 
 /* capability bit definitions */
 #define CAPABILITY_DMA		0x01
@@ -82,46 +82,46 @@
 #define ATA_ADDRESS_DEVHEAD_SLAVE    0x10
 
 /* Action Select bits */
-#define ACTION_SELECT_0             0x01
-#define ACTION_SELECT_1             0x02
-#define ACTION_SELECT_2             0x04
-#define ACTION_SELECT_3             0x08
-#define ACTION_SELECT_4             0x10
-#define ACTION_SELECT_5             0x20
-#define ACTION_SELECT_6             0x40
-#define ACTION_SELECT_7             0x80
+#define ACTION_SELECT_0	     0x01
+#define ACTION_SELECT_1	     0x02
+#define ACTION_SELECT_2	     0x04
+#define ACTION_SELECT_3	     0x08
+#define ACTION_SELECT_4	     0x10
+#define ACTION_SELECT_5	     0x20
+#define ACTION_SELECT_6	     0x40
+#define ACTION_SELECT_7	     0x80
 
 /* Register Select bits */
-#define REG_ALTERNATE_STATUS 0x01
-#define REG_DEVICE_CONTROL   0x01
-#define REG_ERROR            0x02
-#define REG_FEATURES         0x02
-#define REG_SECTOR_COUNT     0x04
-#define REG_SECTOR_NUMBER    0x08
-#define REG_CYLINDER_LOW     0x10
-#define REG_CYLINDER_HIGH    0x20
-#define REG_DEVICE_HEAD      0x40
-#define REG_STATUS           0x80
-#define REG_COMMAND          0x80
+#define REG_ALTERNATE_STATUS	0x01
+#define REG_DEVICE_CONTROL	0x01
+#define REG_ERROR		0x02
+#define REG_FEATURES		0x02
+#define REG_SECTOR_COUNT	0x04
+#define REG_SECTOR_NUMBER	0x08
+#define REG_CYLINDER_LOW	0x10
+#define REG_CYLINDER_HIGH	0x20
+#define REG_DEVICE_HEAD		0x40
+#define REG_STATUS		0x80
+#define REG_COMMAND		0x80
 
 /* ATA error definitions not in <linux/hdreg.h> */
-#define ATA_ERROR_MEDIA_CHANGE       0x20
+#define ATA_ERROR_MEDIA_CHANGE		0x20
 
 /* ATA command definitions not in <linux/hdreg.h> */
-#define ATA_COMMAND_GET_MEDIA_STATUS        0xDA
-#define ATA_COMMAND_MEDIA_EJECT             0xED
+#define ATA_COMMAND_GET_MEDIA_STATUS	0xDA
+#define ATA_COMMAND_MEDIA_EJECT		0xED
 
 /* ATA drive control definitions */
-#define ATA_DC_DISABLE_INTERRUPTS    0x02
-#define ATA_DC_RESET_CONTROLLER      0x04
-#define ATA_DC_REENABLE_CONTROLLER   0x00
+#define ATA_DC_DISABLE_INTERRUPTS	0x02
+#define ATA_DC_RESET_CONTROLLER		0x04
+#define ATA_DC_REENABLE_CONTROLLER	0x00
 
 /*
  *  General purpose return codes
  */ 
 
-#define ISD200_ERROR                -1
-#define ISD200_GOOD                 0
+#define ISD200_ERROR		-1
+#define ISD200_GOOD		 0
 
 /*
  * Transport return codes
@@ -162,7 +162,7 @@
 		unsigned char WriteData1F7;
 		unsigned char Reserved[3];
 	} generic;
-        
+
 	struct {
 		unsigned char SignatureByte0;
 		unsigned char SignatureByte1;
@@ -180,7 +180,7 @@
 		unsigned char Reserved[3];
 	} read;
 
-        struct {
+	struct {
 		unsigned char SignatureByte0;
 		unsigned char SignatureByte1;
 		unsigned char ActionSelect;
@@ -211,8 +211,8 @@
 /*
  * DeviceType field
  */
-#define DIRECT_ACCESS_DEVICE            0x00    /* disks */
-#define DEVICE_REMOVABLE                0x80
+#define DIRECT_ACCESS_DEVICE	    0x00    /* disks */
+#define DEVICE_REMOVABLE		0x80
 
 struct inquiry_data {
    	unsigned char DeviceType;
@@ -240,9 +240,9 @@
  * ISD200 CONFIG data struct
  */
 
-#define ATACFG_TIMING          0x0f
+#define ATACFG_TIMING	  0x0f
 #define ATACFG_ATAPI_RESET     0x10
-#define ATACFG_MASTER          0x20
+#define ATACFG_MASTER	  0x20
 #define ATACFG_BLOCKSIZE       0xa0
 
 #define ATACFGE_LAST_LUN       0x07
@@ -255,12 +255,12 @@
 #define CFG_CAPABILITY_SRST    0x01
 
 struct isd200_config {
-        unsigned char EventNotification;
-        unsigned char ExternalClock;
-        unsigned char ATAInitTimeout;
+	unsigned char EventNotification;
+	unsigned char ExternalClock;
+	unsigned char ATAInitTimeout;
 	unsigned char ATAConfig;
-        unsigned char ATAMajorCommand;
-        unsigned char ATAMinorCommand;
+	unsigned char ATAMajorCommand;
+	unsigned char ATAMinorCommand;
 	unsigned char ATAExtraConfig;
 	unsigned char Capability;
 }__attribute__ ((packed));
@@ -309,7 +309,7 @@
  * Sense Data Format
  */
 
-#define SENSE_ERRCODE           0x7f
+#define SENSE_ERRCODE	   0x7f
 #define SENSE_ERRCODE_VALID     0x80
 #define SENSE_FLAG_SENSE_KEY    0x0f
 #define SENSE_FLAG_BAD_LENGTH   0x20
@@ -319,13 +319,13 @@
 	unsigned char ErrorCode;
 	unsigned char SegmentNumber;
 	unsigned char Flags;
-        unsigned char Information[4];
-        unsigned char AdditionalSenseLength;
-        unsigned char CommandSpecificInformation[4];
-        unsigned char AdditionalSenseCode;
-        unsigned char AdditionalSenseCodeQualifier;
-        unsigned char FieldReplaceableUnitCode;
-        unsigned char SenseKeySpecific[3];
+	unsigned char Information[4];
+	unsigned char AdditionalSenseLength;
+	unsigned char CommandSpecificInformation[4];
+	unsigned char AdditionalSenseCode;
+	unsigned char AdditionalSenseCodeQualifier;
+	unsigned char FieldReplaceableUnitCode;
+	unsigned char SenseKeySpecific[3];
 } __attribute__ ((packed));
 
 /*
@@ -340,18 +340,18 @@
 
 /**************************************************************************
  * isd200_build_sense
- *                                                                         
+ *									 
  *  Builds an artificial sense buffer to report the results of a 
  *  failed command.
- *                                                                       
+ *								       
  * RETURNS:
  *    void
- */                                                                        
+ */
 void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb)
 {
-        struct isd200_info *info = (struct isd200_info *)us->extra;
-        struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0];
-        unsigned char error = info->ATARegs[IDE_ERROR_OFFSET];
+	struct isd200_info *info = (struct isd200_info *)us->extra;
+	struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0];
+	unsigned char error = info->ATARegs[IDE_ERROR_OFFSET];
 
 	if(error & ATA_ERROR_MEDIA_CHANGE) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
@@ -359,31 +359,31 @@
 		buf->Flags = UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-        } else if(error & MCR_ERR) {
+	} else if(error & MCR_ERR) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-        } else if(error & TRK0_ERR) {
+	} else if(error & TRK0_ERR) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  NOT_READY;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-        } else if(error & ECC_ERR) {
+	} else if(error & ECC_ERR) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  DATA_PROTECT;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-        } else {
+	} else {
 		buf->ErrorCode = 0;
 		buf->AdditionalSenseLength = 0;
 		buf->Flags =  0;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-        }
+	}
 }
 
 
@@ -430,8 +430,8 @@
 	case ACTION_ENUM:
 		US_DEBUGP("   isd200_action(ENUM,0x%02x)\n",value);
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
-			                   ACTION_SELECT_3|ACTION_SELECT_4|
-		                           ACTION_SELECT_5;
+					   ACTION_SELECT_3|ACTION_SELECT_4|
+					   ACTION_SELECT_5;
 		ata.generic.RegisterSelect = REG_DEVICE_HEAD;
 		ata.write.DeviceHeadByte = value;
 		srb.sc_data_direction = SCSI_DATA_NONE;
@@ -440,7 +440,7 @@
 	case ACTION_RESET:
 		US_DEBUGP("   isd200_action(RESET)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
-			                   ACTION_SELECT_3|ACTION_SELECT_4;
+					   ACTION_SELECT_3|ACTION_SELECT_4;
 		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
 		ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER;
 		srb.sc_data_direction = SCSI_DATA_NONE;
@@ -449,7 +449,7 @@
 	case ACTION_REENABLE:
 		US_DEBUGP("   isd200_action(REENABLE)\n");
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2|
-			                   ACTION_SELECT_3|ACTION_SELECT_4;
+					   ACTION_SELECT_3|ACTION_SELECT_4;
 		ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
 		ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER;
 		srb.sc_data_direction = SCSI_DATA_NONE;
@@ -493,12 +493,12 @@
 
 /**************************************************************************
  * isd200_read_regs
- *                                                                         
+ *									 
  * Read ATA Registers
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_read_regs( struct us_data *us )
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
@@ -512,10 +512,10 @@
 	if (transferStatus != ISD200_TRANSPORT_GOOD) {
 		US_DEBUGP("   Error reading ATA registers\n");
 		retStatus = ISD200_ERROR;
-        } else {
+	} else {
 		US_DEBUGP("   Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", 
 			  info->ATARegs[IDE_ERROR_OFFSET]);
-        }
+	}
 
 	return retStatus;
 }
@@ -649,12 +649,12 @@
 
 /**************************************************************************
  * isd200_write_config
- *                                                                         
+ *									 
  * Write the ISD200 Configuraton data
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_write_config( struct us_data *us ) 
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
@@ -669,21 +669,21 @@
 
 	/* let's send the command via the control pipe */
 	result = usb_stor_ctrl_transfer(
-                us, 
-                us->send_ctrl_pipe,
-                0x01, 
-                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-                0x0000, 
-                0x0002, 
-                (void *) &info->ConfigData, 
-                sizeof(info->ConfigData));
+		us, 
+		us->send_ctrl_pipe,
+		0x01, 
+		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+		0x0000, 
+		0x0002, 
+		(void *) &info->ConfigData, 
+		sizeof(info->ConfigData));
 
 	if (result >= 0) {
 		US_DEBUGP("   ISD200 Config Data was written successfully\n");
-        } else {
+	} else {
 		US_DEBUGP("   Request to write ISD200 Config Data failed!\n");
 		retStatus = ISD200_ERROR;
-        }
+	}
 
 	US_DEBUGP("Leaving isd200_write_config %08X\n", retStatus);
 	return retStatus;
@@ -692,12 +692,12 @@
 
 /**************************************************************************
  * isd200_read_config
- *                                                                         
+ *									 
  * Reads the ISD200 Configuraton data
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_read_config( struct us_data *us ) 
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
@@ -707,17 +707,17 @@
 	US_DEBUGP("Entering isd200_read_config\n");
 
 	/* read the configuration information from ISD200.  Use this to */
-	/* determine what the special ATA CDB bytes are.                */
+	/* determine what the special ATA CDB bytes are.		*/
 
 	result = usb_stor_ctrl_transfer(
-                us, 
-                us->recv_ctrl_pipe,
-                0x02, 
-                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                0x0000, 
-                0x0002, 
-                (void *) &info->ConfigData, 
-                sizeof(info->ConfigData));
+		us, 
+		us->recv_ctrl_pipe,
+		0x02, 
+		USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+		0x0000, 
+		0x0002, 
+		(void *) &info->ConfigData, 
+		sizeof(info->ConfigData));
 
 
 	if (result >= 0) {
@@ -725,10 +725,10 @@
 #ifdef CONFIG_USB_STORAGE_DEBUG
 		isd200_log_config(info);
 #endif
-        } else {
+	} else {
 		US_DEBUGP("   Request to get ISD200 Config Data failed!\n");
 		retStatus = ISD200_ERROR;
-        }
+	}
 
 	US_DEBUGP("Leaving isd200_read_config %08X\n", retStatus);
 	return retStatus;
@@ -737,12 +737,12 @@
 
 /**************************************************************************
  * isd200_atapi_soft_reset
- *                                                                         
+ *									 
  * Perform an Atapi Soft Reset on the device
  *
  * RETURNS:
  *    NT status code
- */                                                                        
+ */
 int isd200_atapi_soft_reset( struct us_data *us ) 
 {
 	int retStatus = ISD200_GOOD;
@@ -754,7 +754,7 @@
 	if (transferStatus != ISD200_TRANSPORT_GOOD) {
 		US_DEBUGP("   Error issuing Atapi Soft Reset\n");
 		retStatus = ISD200_ERROR;
-        }
+	}
 
 	US_DEBUGP("Leaving isd200_atapi_soft_reset %08X\n", retStatus);
 	return retStatus;
@@ -763,12 +763,12 @@
 
 /**************************************************************************
  * isd200_srst
- *                                                                         
+ *									 
  * Perform an SRST on the device
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_srst( struct us_data *us ) 
 {
 	int retStatus = ISD200_GOOD;
@@ -782,7 +782,7 @@
 	if (transferStatus != ISD200_TRANSPORT_GOOD) {
 		US_DEBUGP("   Error issuing SRST\n");
 		retStatus = ISD200_ERROR;
-        } else {
+	} else {
 		/* delay 10ms to give the drive a chance to see it */
 		wait_ms(10);
 
@@ -794,7 +794,7 @@
 			/* delay 50ms to give the drive a chance to recover after SRST */
 			wait_ms(50);
 		}
-        }
+	}
 
 	US_DEBUGP("Leaving isd200_srst %08X\n", retStatus);
 	return retStatus;
@@ -803,13 +803,13 @@
 
 /**************************************************************************
  * isd200_try_enum
- *                                                                         
+ *									 
  * Helper function for isd200_manual_enum(). Does ENUM and READ_STATUS
  * and tries to analyze the status registers
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 static int isd200_try_enum(struct us_data *us, unsigned char master_slave,
 			   int detect )
 {
@@ -908,13 +908,13 @@
 
 /**************************************************************************
  * isd200_manual_enum
- *                                                                         
+ *									 
  * Determines if the drive attached is an ATA or ATAPI and if it is a
  * master or slave.
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_manual_enum(struct us_data *us)
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
@@ -1078,15 +1078,15 @@
 			us->proto_handler = usb_stor_transparent_scsi_command;
 
 			US_DEBUGP("Protocol changed to: %s\n", us->protocol_name);
-            
-			/* Free driver structure */            
+	    
+			/* Free driver structure */	    
 			if (us->extra != NULL) {
 				kfree(us->extra);
 				us->extra = NULL;
 				us->extra_destructor = NULL;
 			}
 		}
-        }
+	}
 
 	US_DEBUGP("Leaving isd200_get_inquiry_data %08X\n", retStatus);
 
@@ -1096,12 +1096,12 @@
 
 /**************************************************************************
  * isd200_data_copy
- *                                                                         
+ *									 
  * Copy data into the srb request buffer.  Use scatter gather if required.
  *
  * RETURNS:
  *    void
- */                                                                        
+ */
 void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length)
 {
 	unsigned int len = length;
@@ -1150,13 +1150,13 @@
 
 /**************************************************************************
  * isd200_scsi_to_ata
- *                                                                         
+ *									 
  * Translate SCSI commands to ATA commands.
  *
  * RETURNS:
  *    TRUE if the command needs to be sent to the transport layer
  *    FALSE otherwise
- */                                                                        
+ */
 int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, 
 		       union ata_cdb * ataCdb)
 {
@@ -1321,7 +1321,7 @@
 
 		if (info->DeviceFlags & DF_REMOVABLE_MEDIA) {
 			US_DEBUGP("   srb->cmnd[4] = 0x%X\n", srb->cmnd[4]);
-            
+	    
 			ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 			ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
 			ataCdb->generic.TransferBlockSize = 1;
@@ -1378,12 +1378,12 @@
 
 /**************************************************************************
  * isd200_init_info
- *                                                                         
+ *									 
  * Allocates (if necessary) and initializes the driver structure.
  *
  * RETURNS:
  *    ISD status code
- */                                                                        
+ */
 int isd200_init_info(struct us_data *us)
 {
 	int retStatus = ISD200_GOOD;
@@ -1394,11 +1394,11 @@
 			US_DEBUGP("ERROR - kmalloc failure\n");
 			retStatus = ISD200_ERROR;
 		}
-        }
+	}
 
 	if (retStatus == ISD200_GOOD) {
 		memset(us->extra, 0, sizeof(struct isd200_info));
-        }
+	}
 
 	return(retStatus);
 }
@@ -1415,14 +1415,14 @@
 
 	if (isd200_init_info(us) == ISD200_ERROR) {
 		US_DEBUGP("ERROR Initializing ISD200 Info struct\n");
-        } else {
+	} else {
 		/* Get device specific data */
 
 		if (isd200_get_inquiry_data(us) != ISD200_GOOD)
 			US_DEBUGP("ISD200 Initialization Failure\n");
 		else
 			US_DEBUGP("ISD200 Initialization complete\n");
-        }
+	}
 
 	return 0;
 }
diff -Nru a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
--- a/drivers/usb/storage/protocol.h	Mon Feb 10 10:39:26 2003
+++ b/drivers/usb/storage/protocol.h	Mon Feb 10 10:39:26 2003
@@ -53,7 +53,7 @@
 #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_ISD200    0x07		/* ISD200 ATA */
 #define US_SC_MIN	US_SC_RBC
 #define US_SC_MAX	US_SC_ISD200
 
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Mon Feb 10 10:39:27 2003
+++ b/drivers/usb/storage/scsiglue.c	Mon Feb 10 10:39:27 2003
@@ -50,23 +50,25 @@
 #include "transport.h"
 
 #include <linux/slab.h>
+#include <linux/module.h>
 
 
 /***********************************************************************
  * Host functions 
  ***********************************************************************/
 
-static const char* host_info(struct Scsi_Host *host)
+static const char* usb_storage_info(struct Scsi_Host *host)
 {
 	return "SCSI emulation for USB Mass Storage devices";
 }
 
+#if 0
 /* detect a virtual adapter (always works)
  * Synchronization: 2.4: with the io_request_lock
  * 			2.5: no locks.
  * fortunately we don't care.
  * */
-static int detect(struct SHT *sht)
+static int usb_storage_detect(struct SHT *sht)
 {
 	struct us_data *us;
 	char local_name[32];
@@ -109,7 +111,7 @@
  * the driver and we're doing each virtual host in turn, not in parallel
  * Synchronization: BKL, no spinlock.
  */
-static int release(struct Scsi_Host *psh)
+static int usb_storage_release(struct Scsi_Host *psh)
 {
 	struct us_data *us = (struct us_data *)psh->hostdata[0];
 
@@ -132,20 +134,13 @@
 	/* we always have a successful release */
 	return 0;
 }
-
-/* run command */
-static int command( Scsi_Cmnd *srb )
-{
-	US_DEBUGP("Bad use of us_command\n");
-
-	return DID_BAD_TARGET << 16;
-}
+#endif
 
 /* queue a command */
 /* This is always called with scsi_lock(srb->host) held */
-static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
+static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
 {
-	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
 
 	US_DEBUGP("queuecommand() called\n");
 	srb->host_scribble = (unsigned char *)us;
@@ -168,9 +163,9 @@
 
 /* Command abort */
 /* This is always called with scsi_lock(srb->host) held */
-static int command_abort( Scsi_Cmnd *srb )
+static int usb_storage_command_abort( Scsi_Cmnd *srb )
 {
-	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
 
 	US_DEBUGP("command_abort() called\n");
 
@@ -187,9 +182,9 @@
 /* This invokes the transport reset mechanism to reset the state of the
  * device */
 /* This is always called with scsi_lock(srb->host) held */
-static int device_reset( Scsi_Cmnd *srb )
+static int usb_storage_device_reset( Scsi_Cmnd *srb )
 {
-	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
 	int result;
 
 	US_DEBUGP("device_reset() called\n" );
@@ -197,20 +192,19 @@
 
 	/* set the state and release the lock */
 	atomic_set(&us->sm_state, US_STATE_RESETTING);
-	scsi_unlock(srb->host);
+	scsi_unlock(srb->device->host);
 
 	/* lock the device pointers */
 	down(&(us->dev_semaphore));
 
-	/* if the device was removed, then we're already reset */
-	if (!(us->flags & US_FL_DEV_ATTACHED))
-		result = SUCCESS;
-	else
-		result = us->transport_reset(us);
+	/* do the reset */
+	result = us->transport_reset(us);
+
+	/* unlock */
 	up(&(us->dev_semaphore));
 
 	/* lock access to the state and clear it */
-	scsi_lock(srb->host);
+	scsi_lock(srb->device->host);
 	atomic_set(&us->sm_state, US_STATE_IDLE);
 	return result;
 }
@@ -219,43 +213,38 @@
  * disconnect/reconnect for all drivers which have claimed
  * interfaces, including ourself. */
 /* This is always called with scsi_lock(srb->host) held */
-static int bus_reset( Scsi_Cmnd *srb )
+
+/* FIXME: This needs to be re-examined in the face of the new
+ * hotplug system -- this will implicitly cause a detach/reattach of
+ * usb-storage, which is not what we want now.
+ *
+ * Can we just skip over usb-storage in the while loop?
+ */
+static int usb_storage_bus_reset( Scsi_Cmnd *srb )
 {
-	struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+	struct us_data *us;
 	int i;
 	int result;
-	struct usb_device *pusb_dev_save;
 
 	/* we use the usb_reset_device() function to handle this for us */
 	US_DEBUGP("bus_reset() called\n");
-
-	scsi_unlock(srb->host);
-
-	/* if the device has been removed, this worked */
-	down(&us->dev_semaphore);
-	if (!(us->flags & US_FL_DEV_ATTACHED)) {
-		US_DEBUGP("-- device removed already\n");
-		up(&us->dev_semaphore);
-		scsi_lock(srb->host);
-		return SUCCESS;
-	}
-	pusb_dev_save = us->pusb_dev;
-	up(&us->dev_semaphore);
+	scsi_unlock(srb->device->host);
+	us = (struct us_data *)srb->device->host->hostdata[0];
 
 	/* attempt to reset the port */
-	result = usb_reset_device(pusb_dev_save);
+	result = usb_reset_device(us->pusb_dev);
 	US_DEBUGP("usb_reset_device returns %d\n", result);
 	if (result < 0) {
-		scsi_lock(srb->host);
+		scsi_lock(srb->device->host);
 		return FAILED;
 	}
 
 	/* FIXME: This needs to lock out driver probing while it's working
 	 * or we can have race conditions */
 	/* This functionality really should be provided by the khubd thread */
-	for (i = 0; i < pusb_dev_save->actconfig->desc.bNumInterfaces; i++) {
+	for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) {
  		struct usb_interface *intf =
-			&pusb_dev_save->actconfig->interface[i];
+			&us->pusb_dev->actconfig->interface[i];
 
 		/* if this is an unclaimed interface, skip it */
 		if (!intf->driver) {
@@ -270,18 +259,10 @@
 		usb_device_probe (&intf->dev);
 	}
 	US_DEBUGP("bus_reset() complete\n");
-	scsi_lock(srb->host);
+	scsi_lock(srb->device->host);
 	return SUCCESS;
 }
 
-/* FIXME: This doesn't do anything right now */
-static int host_reset( Scsi_Cmnd *srb )
-{
-	printk(KERN_CRIT "usb-storage: host_reset() requested but not implemented\n" );
-	bus_reset(srb);
-	return FAILED;
-}
-
 /***********************************************************************
  * /proc/scsi/ functions
  ***********************************************************************/
@@ -291,29 +272,23 @@
 #define SPRINTF(args...) \
 	do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
 
-static int proc_info (char *buffer, char **start, off_t offset, int length,
-		int hostno, int inout)
+static int usb_storage_proc_info (char *buffer, char **start, off_t offset,
+		int length, int hostno, int inout)
 {
 	struct us_data *us;
 	char *pos = buffer;
+	struct Scsi_Host *hostptr;
 
 	/* if someone is sending us data, just throw it away */
 	if (inout)
 		return length;
 
-	/* lock the data structures */
-	down(&us_list_semaphore);
-
-	/* find our data from hostno */
-	us = us_list;
-	while (us) {
-		if (us->host_no == hostno)
-			break;
-		us = us->next;
+	/* find our data from the given hostno */
+	hostptr = scsi_host_hn_get(hostno);
+	if (!hostptr) {	 /* if we couldn't find it, we return an error */
+		return -ESRCH;
 	}
-
-	/* release our lock on the data structures */
-	up(&us_list_semaphore);
+	us = (struct us_data*)hostptr->hostdata[0];
 
 	/* if we couldn't find it, we return an error */
 	if (!us) {
@@ -332,10 +307,8 @@
 	SPRINTF("     Protocol: %s\n", us->protocol_name);
 	SPRINTF("    Transport: %s\n", us->transport_name);
 
-	/* show the GUID of the device */
-	SPRINTF("         GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
-	SPRINTF("     Attached: %s\n", (us->flags & US_FL_DEV_ATTACHED ?
-			"Yes" : "No"));
+	/* release the reference count on this host */
+	scsi_host_put(hostptr);
 
 	/*
 	 * Calculate start of next buffer, and return value.
@@ -351,33 +324,69 @@
 }
 
 /*
- * this defines our 'host'
+ * this defines our host template, with which we'll allocate hosts
  */
 
-Scsi_Host_Template usb_stor_host_template = {
-	.name =			"usb-storage",
-	.proc_info =		proc_info,
-	.info =			host_info,
-
-	.detect =		detect,
-	.release =		release,
-	.command =		command,
-	.queuecommand =		queuecommand,
-
-	.eh_abort_handler =	command_abort,
-	.eh_device_reset_handler =device_reset,
-	.eh_bus_reset_handler =	bus_reset,
-	.eh_host_reset_handler =host_reset,
-
-	.can_queue =		1,
-	.this_id =		-1,
-
-	.sg_tablesize =		SG_ALL,
-	.cmd_per_lun =		1,
-	.present =		0,
-	.unchecked_isa_dma =	FALSE,
-	.use_clustering =	TRUE,
-	.emulated =		TRUE
+struct SHT usb_stor_host_template = {
+	/* basic userland interface stuff */
+	.name =				"usb-storage",
+	.proc_name =			"usb-storage",
+	.proc_info =			usb_storage_proc_info,
+	.proc_dir =			NULL,
+	.info =				usb_storage_info,
+	.ioctl =			NULL,
+
+	/* old-style detect and release */
+	.detect =			NULL,
+	.release =			NULL,
+
+	/* command interface -- queued only */
+	.command =			NULL,
+	.queuecommand =			usb_storage_queuecommand,
+
+	/* error and abort handlers */
+	.eh_abort_handler =		usb_storage_command_abort,
+	.eh_device_reset_handler =	usb_storage_device_reset,
+	.eh_bus_reset_handler =		usb_storage_bus_reset,
+	.eh_host_reset_handler =	NULL,
+	.eh_strategy_handler =		NULL,
+
+	/* queue commands only, only one command per LUN */
+	.can_queue =			1,
+	.cmd_per_lun =			1,
+
+	/* unknown initiator id */
+	.this_id =			-1,
+
+	/* no limit on commands */
+	.max_sectors =			0,
+	
+	/* pre- and post- device scan functions */
+	.slave_alloc =			NULL,
+	.slave_configure =		NULL,
+	.slave_destroy =		NULL,
+
+	/* lots of sg segments can be handled */
+	.sg_tablesize =			SG_ALL,
+
+	/* use 32-bit address space for DMA */
+	.unchecked_isa_dma =		FALSE,
+	.highmem_io =			FALSE,
+
+	/* merge commands... this seems to help performance, but
+	 * periodically someone should test to see which setting is more
+	 * optimal.
+	 */
+	.use_clustering =		TRUE,
+
+	/* emulated HBA */
+	.emulated =			TRUE,
+
+	/* sorry, no BIOS to help us */
+	.bios_param =			NULL,
+
+	/* module management */
+	.module =			THIS_MODULE
 };
 
 /* For a device that is "Not Ready" */
diff -Nru a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h
--- a/drivers/usb/storage/scsiglue.h	Mon Feb 10 10:39:27 2003
+++ b/drivers/usb/storage/scsiglue.h	Mon Feb 10 10:39:27 2003
@@ -47,7 +47,7 @@
 
 extern unsigned char usb_stor_sense_notready[18];
 extern unsigned char usb_stor_sense_invalidCDB[18];
-extern Scsi_Host_Template usb_stor_host_template;
+extern struct SHT usb_stor_host_template;
 extern int usb_stor_scsiSense10to6(Scsi_Cmnd*);
 extern int usb_stor_scsiSense6to10(Scsi_Cmnd*);
 
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Mon Feb 10 10:39:25 2003
+++ b/drivers/usb/storage/transport.c	Mon Feb 10 10:39:25 2003
@@ -697,7 +697,7 @@
 
 	/* set state to abort and release the lock */
 	atomic_set(&us->sm_state, US_STATE_ABORTING);
-	host = us->srb->host;
+	host = us->srb->device->host;
 	scsi_unlock(host);
 
 	/* If the state machine is blocked waiting for an URB,
@@ -895,7 +895,7 @@
 	bcb.Tag = srb->serial_number;
 	bcb.Lun = srb->cmnd[1] >> 5;
 	if (us->flags & US_FL_SCM_MULT_TARG)
-		bcb.Lun |= srb->target << 4;
+		bcb.Lun |= srb->device->id << 4;
 	bcb.Length = srb->cmd_len;
 
 	/* copy the command payload */
diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h	Mon Feb 10 10:39:25 2003
+++ b/drivers/usb/storage/transport.h	Mon Feb 10 10:39:25 2003
@@ -55,8 +55,7 @@
 #define US_PR_SCM_ATAPI	0x80		/* SCM-ATAPI bridge */
 #endif
 #ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for
-						SDDR-09 */
+#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) */
@@ -64,15 +63,15 @@
 #define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1            /* Freecom */
+#define US_PR_FREECOM   0xf1	    /* Freecom */
 #endif
 
 #ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2            /* Datafab chipsets */
+#define US_PR_DATAFAB   0xf2	    /* Datafab chipsets */
 #endif
 
 #ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3            /* Lexar Jumpshot */
+#define US_PR_JUMPSHOT  0xf3	    /* Lexar Jumpshot */
 #endif
 
 /*
@@ -118,10 +117,10 @@
  * usb_stor_bulk_transfer_xxx() return codes, in order of severity
  */
 
-#define USB_STOR_XFER_GOOD		0  /* good transfer                 */
-#define USB_STOR_XFER_SHORT		1  /* transfered less than expected */
-#define USB_STOR_XFER_STALLED		2  /* endpoint stalled		    */
-#define USB_STOR_XFER_ERROR		3  /* transfer died in the middle   */
+#define USB_STOR_XFER_GOOD	0	/* good transfer                 */
+#define USB_STOR_XFER_SHORT	1	/* transfered less than expected */
+#define USB_STOR_XFER_STALLED	2	/* endpoint stalled              */
+#define USB_STOR_XFER_ERROR	3	/* transfer died in the middle   */
 
 /*
  * Transport return codes
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	Mon Feb 10 10:39:30 2003
+++ b/drivers/usb/storage/unusual_devs.h	Mon Feb 10 10:39:30 2003
@@ -264,7 +264,7 @@
 		
 /* Submitted by Nathan Babb <nathan@lexi.com> */
 UNUSUAL_DEV(  0x054c, 0x006d, 0x0000, 0x9999,
-                "Sony",
+		"Sony",
 		"PEG Mass Storage",
 		US_SC_8070, US_PR_CBI, NULL,
 		US_FL_FIX_INQUIRY ),
@@ -546,10 +546,10 @@
 
 /* aeb */
 UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
-	        "Feiya",
-	        "5-in-1 Card Reader",
-	        US_SC_SCSI, US_PR_BULK, NULL,
-	        US_FL_FIX_CAPACITY ),
+		"Feiya",
+		"5-in-1 Card Reader",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_FIX_CAPACITY ),
 
 UNUSUAL_DEV(  0x097a, 0x0001, 0x0000, 0x0001,
 		"Minds@Work",
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/usb/storage/usb.c	Mon Feb 10 10:39:24 2003
@@ -93,16 +93,6 @@
 MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
 MODULE_LICENSE("GPL");
 
-/*
- * Per device data
- */
-
-static int my_host_number;
-
-/* The list of structures and the protective lock for them */
-struct us_data *us_list;
-struct semaphore us_list_semaphore;
-
 static int storage_probe(struct usb_interface *iface,
 			 const struct usb_device_id *id);
 
@@ -311,15 +301,15 @@
 	daemonize();
 
 	/* avoid getting signals */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	flush_signals(current);
 	current->flags |= PF_IOTHREAD;
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* set our name for identification purposes */
-	sprintf(current->comm, "usb-storage-%d", us->host_number);
+	sprintf(current->comm, "usb-storage");
 
 	unlock_kernel();
 
@@ -342,7 +332,7 @@
 			US_DEBUGP("-- exit command received\n");
 			break;
 		}
-		host = us->srb->host;
+		host = us->srb->device->host;
 
 		/* lock access to the state */
 		scsi_lock(host);
@@ -371,16 +361,16 @@
 		/* reject if target != 0 or if LUN is higher than
 		 * the maximum known LUN
 		 */
-		else if (us->srb->target && 
+		else if (us->srb->device->id && 
 				!(us->flags & US_FL_SCM_MULT_TARG)) {
 			US_DEBUGP("Bad target number (%d/%d)\n",
-				  us->srb->target, us->srb->lun);
+				  us->srb->device->id, us->srb->device->lun);
 			us->srb->result = DID_BAD_TARGET << 16;
 		}
 
-		else if (us->srb->lun > us->max_lun) {
+		else if (us->srb->device->lun > us->max_lun) {
 			US_DEBUGP("Bad LUN (%d/%d)\n",
-				  us->srb->target, us->srb->lun);
+				  us->srb->device->id, us->srb->device->lun);
 			us->srb->result = DID_BAD_TARGET << 16;
 		}
 
@@ -395,35 +385,6 @@
 				us->srb->result = CHECK_CONDITION << 1;
 		}
 
-		/* our device has gone - pretend not ready */
-		else if (!(us->flags & US_FL_DEV_ATTACHED)) {
-			US_DEBUGP("Request is for removed device\n");
-			/* For REQUEST_SENSE, it's the data.  But
-			 * for anything else, it should look like
-			 * we auto-sensed for it.
-			 */
-			if (us->srb->cmnd[0] == REQUEST_SENSE) {
-				memcpy(us->srb->request_buffer, 
-				       usb_stor_sense_notready, 
-				       sizeof(usb_stor_sense_notready));
-				us->srb->result = GOOD << 1;
-			} else if(us->srb->cmnd[0] == INQUIRY) {
-				/* INQUIRY should always work, per spec... */
-				unsigned char data_ptr[36] = {
-				    0x20, 0x80, 0x02, 0x02,
-				    0x1F, 0x00, 0x00, 0x00};
-				US_DEBUGP("Faking INQUIRY command for disconnected device\n");
-				fill_inquiry_response(us, data_ptr, 36);
-				us->srb->result = GOOD << 1;
-			} else {
-				/* not ready */
-				memcpy(us->srb->sense_buffer, 
-				       usb_stor_sense_notready, 
-				       sizeof(usb_stor_sense_notready));
-				us->srb->result = CHECK_CONDITION << 1;
-			}
-		}  /* !(us->flags & US_FL_DEV_ATTACHED) */
-
 		/* Handle those devices which need us to fake 
 		 * their inquiry data */
 		else if ((us->srb->cmnd[0] == INQUIRY) &&
@@ -547,7 +508,6 @@
 	}
 
 	/* mark the device as gone */
-	ss->flags &= ~ US_FL_DEV_ATTACHED;
 	usb_put_dev(ss->pusb_dev);
 	ss->pusb_dev = NULL;
 }
@@ -563,12 +523,10 @@
 	char mf[USB_STOR_STRING_LEN];		     /* manufacturer */
 	char prod[USB_STOR_STRING_LEN];		     /* product */
 	char serial[USB_STOR_STRING_LEN];	     /* serial number */
-	GUID(guid);			   /* Global Unique Identifier */
 	unsigned int flags;
 	struct us_unusual_dev *unusual_dev;
 	struct us_data *ss = NULL;
 	int result;
-	int new_device = 0;
 
 	/* these are temporary copies -- we test on these, then put them
 	 * in the us-data structure 
@@ -676,8 +634,7 @@
 	/* At this point, we've decided to try to use the device */
 	usb_get_dev(dev);
 
-	/* clear the GUID and fetch the strings */
-	GUID_CLEAR(guid);
+	/* fetch the strings */
 	if (dev->descriptor.iManufacturer)
 		usb_string(dev, dev->descriptor.iManufacturer, 
 			   mf, sizeof(mf));
@@ -688,346 +645,277 @@
 		usb_string(dev, dev->descriptor.iSerialNumber, 
 			   serial, sizeof(serial));
 
-	/* Create a GUID for this device */
-	if (dev->descriptor.iSerialNumber && serial[0]) {
-		/* If we have a serial number, and it's a non-NULL string */
-		make_guid(guid, dev->descriptor.idVendor, 
-			  dev->descriptor.idProduct, serial);
-	} else {
-		/* We don't have a serial number, so we use 0 */
-		make_guid(guid, dev->descriptor.idVendor, 
-			  dev->descriptor.idProduct, "0");
+	/* New device -- allocate memory and initialize */
+	if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), 
+					    GFP_KERNEL)) == NULL) {
+		printk(KERN_WARNING USB_STORAGE "Out of memory\n");
+		usb_put_dev(dev);
+		return -ENOMEM;
+	}
+	memset(ss, 0, sizeof(struct us_data));
+
+	/* Initialize the mutexes only when the struct is new */
+	init_completion(&(ss->notify));
+	init_MUTEX_LOCKED(&(ss->dev_semaphore));
+
+	/* copy over the subclass and protocol data */
+	ss->subclass = subclass;
+	ss->protocol = protocol;
+	ss->flags = flags;
+	ss->unusual_dev = unusual_dev;
+
+	/* copy over the endpoint data */
+	ss->ep_in = ep_in->bEndpointAddress & 
+		USB_ENDPOINT_NUMBER_MASK;
+	ss->ep_out = ep_out->bEndpointAddress & 
+		USB_ENDPOINT_NUMBER_MASK;
+	if (ep_int) {
+		ss->ep_int = ep_int->bEndpointAddress & 
+			USB_ENDPOINT_NUMBER_MASK;
+		ss->ep_bInterval = ep_int->bInterval;
 	}
+	else
+		ss->ep_int = ss->ep_bInterval = 0;
 
-	/*
-	 * Now check if we have seen this GUID before
-	 * We're looking for a device with a matching GUID that isn't
-	 * already on the system
-	 */
-	ss = us_list;
-	while ((ss != NULL) && 
-	           ((ss->flags & US_FL_DEV_ATTACHED) ||
-		    !GUID_EQUAL(guid, ss->guid)))
-		ss = ss->next;
-
-	if (ss != NULL) {
-		/* Existing device -- re-connect */
-		US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
-			  GUID_ARGS(guid));
-
-		/* lock the device pointers */
-		down(&(ss->dev_semaphore));
-
-		/* establish the connection to the new device upon reconnect */
-		ss->ifnum = ifnum;
-		ss->pusb_dev = dev;
-		ss->flags |= US_FL_DEV_ATTACHED;
-
-		/* copy over the endpoint data */
-		ss->ep_in = ep_in->bEndpointAddress & 
-			USB_ENDPOINT_NUMBER_MASK;
-		ss->ep_out = ep_out->bEndpointAddress & 
-			USB_ENDPOINT_NUMBER_MASK;
-		if (ep_int) {
-			ss->ep_int = ep_int->bEndpointAddress & 
-				USB_ENDPOINT_NUMBER_MASK;
-			ss->ep_bInterval = ep_int->bInterval;
-		}
+	/* establish the connection to the new device */
+	ss->ifnum = ifnum;
+	ss->pusb_dev = dev;
+
+	/* copy over the identifiying strings */
+	strncpy(ss->vendor, mf, USB_STOR_STRING_LEN);
+	strncpy(ss->product, prod, USB_STOR_STRING_LEN);
+	strncpy(ss->serial, serial, USB_STOR_STRING_LEN);
+	if (strlen(ss->vendor) == 0) {
+		if (unusual_dev->vendorName)
+			strncpy(ss->vendor, unusual_dev->vendorName,
+				USB_STOR_STRING_LEN);
 		else
-			ss->ep_int = ss->ep_bInterval = 0;
-
-		/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
-		if (usb_stor_allocate_urbs(ss))
-			goto BadDevice;
-
-                /* Re-Initialize the device if it needs it */
-		if (unusual_dev && unusual_dev->initFunction)
-			(unusual_dev->initFunction)(ss);
-
-		/* unlock the device pointers */
-		up(&(ss->dev_semaphore));
-
-	} else { 
-		/* New device -- allocate memory and initialize */
-		US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
-
-		if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), 
-						    GFP_KERNEL)) == NULL) {
-			printk(KERN_WARNING USB_STORAGE "Out of memory\n");
-			usb_put_dev(dev);
-			return -ENOMEM;
-		}
-		memset(ss, 0, sizeof(struct us_data));
-		new_device = 1;
-
-		/* Initialize the mutexes only when the struct is new */
-		init_completion(&(ss->notify));
-		init_MUTEX_LOCKED(&(ss->dev_semaphore));
-
-		/* copy over the subclass and protocol data */
-		ss->subclass = subclass;
-		ss->protocol = protocol;
-		ss->flags = flags | US_FL_DEV_ATTACHED;
-		ss->unusual_dev = unusual_dev;
-
-		/* copy over the endpoint data */
-		ss->ep_in = ep_in->bEndpointAddress & 
-			USB_ENDPOINT_NUMBER_MASK;
-		ss->ep_out = ep_out->bEndpointAddress & 
-			USB_ENDPOINT_NUMBER_MASK;
-		if (ep_int) {
-			ss->ep_int = ep_int->bEndpointAddress & 
-				USB_ENDPOINT_NUMBER_MASK;
-			ss->ep_bInterval = ep_int->bInterval;
-		}
+			strncpy(ss->vendor, "Unknown",
+				USB_STOR_STRING_LEN);
+	}
+	if (strlen(ss->product) == 0) {
+		if (unusual_dev->productName)
+			strncpy(ss->product, unusual_dev->productName,
+				USB_STOR_STRING_LEN);
 		else
-			ss->ep_int = ss->ep_bInterval = 0;
-
-		/* establish the connection to the new device */
-		ss->ifnum = ifnum;
-		ss->pusb_dev = dev;
-
-		/* copy over the identifiying strings */
-		strncpy(ss->vendor, mf, USB_STOR_STRING_LEN);
-		strncpy(ss->product, prod, USB_STOR_STRING_LEN);
-		strncpy(ss->serial, serial, USB_STOR_STRING_LEN);
-		if (strlen(ss->vendor) == 0) {
-			if (unusual_dev->vendorName)
-				strncpy(ss->vendor, unusual_dev->vendorName,
-					USB_STOR_STRING_LEN);
-			else
-				strncpy(ss->vendor, "Unknown",
-					USB_STOR_STRING_LEN);
-		}
-		if (strlen(ss->product) == 0) {
-			if (unusual_dev->productName)
-				strncpy(ss->product, unusual_dev->productName,
-					USB_STOR_STRING_LEN);
-			else
-				strncpy(ss->product, "Unknown",
-					USB_STOR_STRING_LEN);
-		}
-		if (strlen(ss->serial) == 0)
-			strncpy(ss->serial, "None", USB_STOR_STRING_LEN);
-
-		/* copy the GUID we created before */
-		memcpy(ss->guid, guid, sizeof(guid));
-
-		/* 
-		 * Set the handler pointers based on the protocol
-		 * Again, this data is persistant across reattachments
-		 */
-		switch (ss->protocol) {
-		case US_PR_CB:
-			ss->transport_name = "Control/Bulk";
-			ss->transport = usb_stor_CB_transport;
-			ss->transport_reset = usb_stor_CB_reset;
-			ss->max_lun = 7;
-			break;
-
-		case US_PR_CBI:
-			ss->transport_name = "Control/Bulk/Interrupt";
-			ss->transport = usb_stor_CBI_transport;
-			ss->transport_reset = usb_stor_CB_reset;
-			ss->max_lun = 7;
-			break;
+			strncpy(ss->product, "Unknown",
+				USB_STOR_STRING_LEN);
+	}
+	if (strlen(ss->serial) == 0)
+		strncpy(ss->serial, "None", USB_STOR_STRING_LEN);
 
-		case US_PR_BULK:
-			ss->transport_name = "Bulk";
-			ss->transport = usb_stor_Bulk_transport;
-			ss->transport_reset = usb_stor_Bulk_reset;
-			ss->max_lun = usb_stor_Bulk_max_lun(ss);
-			break;
+	/* 
+	 * Set the handler pointers based on the protocol
+	 * Again, this data is persistent across reattachments
+	 */
+	switch (ss->protocol) {
+	case US_PR_CB:
+		ss->transport_name = "Control/Bulk";
+		ss->transport = usb_stor_CB_transport;
+		ss->transport_reset = usb_stor_CB_reset;
+		ss->max_lun = 7;
+		break;
+
+	case US_PR_CBI:
+		ss->transport_name = "Control/Bulk/Interrupt";
+		ss->transport = usb_stor_CBI_transport;
+		ss->transport_reset = usb_stor_CB_reset;
+		ss->max_lun = 7;
+		break;
+
+	case US_PR_BULK:
+		ss->transport_name = "Bulk";
+		ss->transport = usb_stor_Bulk_transport;
+		ss->transport_reset = usb_stor_Bulk_reset;
+		ss->max_lun = usb_stor_Bulk_max_lun(ss);
+		break;
 
 #ifdef CONFIG_USB_STORAGE_HP8200e
-		case US_PR_SCM_ATAPI:
-			ss->transport_name = "SCM/ATAPI";
-			ss->transport = hp8200e_transport;
-			ss->transport_reset = usb_stor_CB_reset;
-			ss->max_lun = 1;
-			break;
+	case US_PR_SCM_ATAPI:
+		ss->transport_name = "SCM/ATAPI";
+		ss->transport = hp8200e_transport;
+		ss->transport_reset = usb_stor_CB_reset;
+		ss->max_lun = 1;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
-		case US_PR_EUSB_SDDR09:
-			ss->transport_name = "EUSB/SDDR09";
-			ss->transport = sddr09_transport;
-			ss->transport_reset = usb_stor_CB_reset;
-			ss->max_lun = 0;
-			break;
+	case US_PR_EUSB_SDDR09:
+		ss->transport_name = "EUSB/SDDR09";
+		ss->transport = sddr09_transport;
+		ss->transport_reset = usb_stor_CB_reset;
+		ss->max_lun = 0;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_SDDR55
-		case US_PR_SDDR55:
-			ss->transport_name = "SDDR55";
-			ss->transport = sddr55_transport;
-			ss->transport_reset = sddr55_reset;
-			ss->max_lun = 0;
-			break;
+	case US_PR_SDDR55:
+		ss->transport_name = "SDDR55";
+		ss->transport = sddr55_transport;
+		ss->transport_reset = sddr55_reset;
+		ss->max_lun = 0;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_DPCM
-		case US_PR_DPCM_USB:
-			ss->transport_name = "Control/Bulk-EUSB/SDDR09";
-			ss->transport = dpcm_transport;
-			ss->transport_reset = usb_stor_CB_reset;
-			ss->max_lun = 1;
-			break;
+	case US_PR_DPCM_USB:
+		ss->transport_name = "Control/Bulk-EUSB/SDDR09";
+		ss->transport = dpcm_transport;
+		ss->transport_reset = usb_stor_CB_reset;
+		ss->max_lun = 1;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
-                case US_PR_FREECOM:
-                        ss->transport_name = "Freecom";
-                        ss->transport = freecom_transport;
-                        ss->transport_reset = usb_stor_freecom_reset;
-                        ss->max_lun = 0;
-                        break;
+	case US_PR_FREECOM:
+		ss->transport_name = "Freecom";
+		ss->transport = freecom_transport;
+		ss->transport_reset = usb_stor_freecom_reset;
+		ss->max_lun = 0;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_DATAFAB
-                case US_PR_DATAFAB:
-                        ss->transport_name  = "Datafab Bulk-Only";
-                        ss->transport = datafab_transport;
-                        ss->transport_reset = usb_stor_Bulk_reset;
-                        ss->max_lun = 1;
-                        break;
+	case US_PR_DATAFAB:
+		ss->transport_name  = "Datafab Bulk-Only";
+		ss->transport = datafab_transport;
+		ss->transport_reset = usb_stor_Bulk_reset;
+		ss->max_lun = 1;
+		break;
 #endif
 
 #ifdef CONFIG_USB_STORAGE_JUMPSHOT
-                case US_PR_JUMPSHOT:
-                        ss->transport_name  = "Lexar Jumpshot Control/Bulk";
-                        ss->transport = jumpshot_transport;
-                        ss->transport_reset = usb_stor_Bulk_reset;
-                        ss->max_lun = 1;
-                        break;
+	case US_PR_JUMPSHOT:
+		ss->transport_name  = "Lexar Jumpshot Control/Bulk";
+		ss->transport = jumpshot_transport;
+		ss->transport_reset = usb_stor_Bulk_reset;
+		ss->max_lun = 1;
+		break;
 #endif
 
-		default:
-			/* ss->transport_name = "Unknown"; */
-			goto BadDevice;
-		}
-		US_DEBUGP("Transport: %s\n", ss->transport_name);
-
-		/* fix for single-lun devices */
-		if (ss->flags & US_FL_SINGLE_LUN)
-			ss->max_lun = 0;
-
-		switch (ss->subclass) {
-		case US_SC_RBC:
-			ss->protocol_name = "Reduced Block Commands (RBC)";
-			ss->proto_handler = usb_stor_transparent_scsi_command;
-			break;
-
-		case US_SC_8020:
-			ss->protocol_name = "8020i";
-			ss->proto_handler = usb_stor_ATAPI_command;
-			ss->max_lun = 0;
-			break;
-
-		case US_SC_QIC:
-			ss->protocol_name = "QIC-157";
-			ss->proto_handler = usb_stor_qic157_command;
-			ss->max_lun = 0;
-			break;
-
-		case US_SC_8070:
-			ss->protocol_name = "8070i";
-			ss->proto_handler = usb_stor_ATAPI_command;
-			ss->max_lun = 0;
-			break;
-
-		case US_SC_SCSI:
-			ss->protocol_name = "Transparent SCSI";
-			ss->proto_handler = usb_stor_transparent_scsi_command;
-			break;
-
-		case US_SC_UFI:
-			ss->protocol_name = "Uniform Floppy Interface (UFI)";
-			ss->proto_handler = usb_stor_ufi_command;
-			break;
+	default:
+		/* ss->transport_name = "Unknown"; */
+		goto BadDevice;
+	}
+	US_DEBUGP("Transport: %s\n", ss->transport_name);
+
+	/* fix for single-lun devices */
+	if (ss->flags & US_FL_SINGLE_LUN)
+		ss->max_lun = 0;
+
+	switch (ss->subclass) {
+	case US_SC_RBC:
+		ss->protocol_name = "Reduced Block Commands (RBC)";
+		ss->proto_handler = usb_stor_transparent_scsi_command;
+		break;
+
+	case US_SC_8020:
+		ss->protocol_name = "8020i";
+		ss->proto_handler = usb_stor_ATAPI_command;
+		ss->max_lun = 0;
+		break;
+
+	case US_SC_QIC:
+		ss->protocol_name = "QIC-157";
+		ss->proto_handler = usb_stor_qic157_command;
+		ss->max_lun = 0;
+		break;
+
+	case US_SC_8070:
+		ss->protocol_name = "8070i";
+		ss->proto_handler = usb_stor_ATAPI_command;
+		ss->max_lun = 0;
+		break;
+
+	case US_SC_SCSI:
+		ss->protocol_name = "Transparent SCSI";
+		ss->proto_handler = usb_stor_transparent_scsi_command;
+		break;
+
+	case US_SC_UFI:
+		ss->protocol_name = "Uniform Floppy Interface (UFI)";
+		ss->proto_handler = usb_stor_ufi_command;
+		break;
 
 #ifdef CONFIG_USB_STORAGE_ISD200
-                case US_SC_ISD200:
-                        ss->protocol_name = "ISD200 ATA/ATAPI";
-                        ss->proto_handler = isd200_ata_command;
-                        break;
+	case US_SC_ISD200:
+		ss->protocol_name = "ISD200 ATA/ATAPI";
+		ss->proto_handler = isd200_ata_command;
+		break;
 #endif
 
-		default:
-			/* ss->protocol_name = "Unknown"; */
-			goto BadDevice;
-		}
-		US_DEBUGP("Protocol: %s\n", ss->protocol_name);
-
-		/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
-		if (usb_stor_allocate_urbs(ss))
-			goto BadDevice;
-
-		/*
-		 * Since this is a new device, we need to generate a scsi 
-		 * host definition, and register with the higher SCSI layers
-		 */
-
-		/* Initialize the host template based on the default one */
-		memcpy(&(ss->htmplt), &usb_stor_host_template, 
-		       sizeof(usb_stor_host_template));
-
-		/* Grab the next host number */
-		ss->host_number = my_host_number++;
-
-		/* We abuse this pointer so we can pass the ss pointer to 
-		 * the host controller thread in us_detect.  But how else are
-		 * we to do it?
-		 */
-		(struct us_data *)ss->htmplt.proc_dir = ss; 
-
-		/* Just before we start our control thread, initialize
-		 * the device if it needs initialization */
-		if (unusual_dev && unusual_dev->initFunction)
-			unusual_dev->initFunction(ss);
-
-		/* start up our control thread */
-		atomic_set(&ss->sm_state, US_STATE_IDLE);
-		ss->pid = kernel_thread(usb_stor_control_thread, ss,
-					CLONE_VM);
-		if (ss->pid < 0) {
-			printk(KERN_WARNING USB_STORAGE 
-			       "Unable to start control thread\n");
-			goto BadDevice;
-		}
-
-		/* wait for the thread to start */
-		wait_for_completion(&(ss->notify));
+	default:
+		/* ss->protocol_name = "Unknown"; */
+		goto BadDevice;
+	}
+	US_DEBUGP("Protocol: %s\n", ss->protocol_name);
+
+	/* allocate the URB, the usb_ctrlrequest, and the IRQ URB */
+	if (usb_stor_allocate_urbs(ss))
+		goto BadDevice;
 
-		/* unlock the device pointers */
-		up(&(ss->dev_semaphore));
+	/*
+	 * Since this is a new device, we need to generate a scsi 
+	 * host definition, and register with the higher SCSI layers
+	 */
 
-		/* now register	 - our detect function will be called */
-		ss->htmplt.module = THIS_MODULE;
-		result = scsi_register_host(&(ss->htmplt));
-		if (result) {
-			printk(KERN_WARNING USB_STORAGE
-				"Unable to register the scsi host\n");
-
-			/* tell the control thread to exit */
-			ss->srb = NULL;
-			up(&ss->sema);
-			wait_for_completion(&ss->notify);
-
-			/* re-lock the device pointers */
-			down(&ss->dev_semaphore);
-			goto BadDevice;
-		}
+	/* Just before we start our control thread, initialize
+	 * the device if it needs initialization */
+	if (unusual_dev && unusual_dev->initFunction)
+		unusual_dev->initFunction(ss);
+
+	/* start up our control thread */
+	atomic_set(&ss->sm_state, US_STATE_IDLE);
+	ss->pid = kernel_thread(usb_stor_control_thread, ss,
+				CLONE_VM);
+	if (ss->pid < 0) {
+		printk(KERN_WARNING USB_STORAGE 
+		       "Unable to start control thread\n");
+		goto BadDevice;
+	}
 
-		/* lock access to the data structures */
-		down(&us_list_semaphore);
+	/* wait for the thread to start */
+	wait_for_completion(&(ss->notify));
 
-		/* put us in the list */
-		ss->next = us_list;
-		us_list = ss;
+	/* unlock the device pointers */
+	up(&(ss->dev_semaphore));
 
-		/* release the data structure lock */
-		up(&us_list_semaphore);
+	/* now register	*/
+	ss->host = scsi_register(&usb_stor_host_template, sizeof(ss));
+	if (!ss->host) {
+		printk(KERN_WARNING USB_STORAGE
+			"Unable to register the scsi host\n");
+
+		/* tell the control thread to exit */
+		ss->srb = NULL;
+		up(&ss->sema);
+		wait_for_completion(&ss->notify);
+
+		/* re-lock the device pointers */
+		down(&ss->dev_semaphore);
+		goto BadDevice;
+	}
+
+	/* set the hostdata to prepare for scanning */
+	ss->host->hostdata[0] = (unsigned long)ss;
+
+	/* associate this host with our interface */
+	scsi_set_device(ss->host, &intf->dev);
+
+	/* now add the host */
+	result = scsi_add_host(ss->host, NULL);
+	if (result) {
+		printk(KERN_WARNING USB_STORAGE
+			"Unable to add the scsi host\n");
+
+		/* tell the control thread to exit */
+		ss->srb = NULL;
+		up(&ss->sema);
+		wait_for_completion(&ss->notify);
+
+		/* re-lock the device pointers */
+		down(&ss->dev_semaphore);
+		goto BadDevice;
 	}
 
 	printk(KERN_DEBUG 
@@ -1041,33 +929,96 @@
 
 	/* we come here if there are any problems */
 	/* ss->dev_semaphore must be locked */
-	BadDevice:
+BadDevice:
 	US_DEBUGP("storage_probe() failed\n");
 	usb_stor_deallocate_urbs(ss);
 	up(&ss->dev_semaphore);
-	if (new_device)
-		kfree(ss);
+	kfree(ss);
 	return -EIO;
 }
 
 /* Handle a disconnect event from the USB core */
 static void storage_disconnect(struct usb_interface *intf)
 {
-	struct us_data *ss = usb_get_intfdata(intf);
+	struct us_data *ss;
+	struct scsi_device *sdev;
 
 	US_DEBUGP("storage_disconnect() called\n");
 
+	ss = usb_get_intfdata(intf);
 	usb_set_intfdata(intf, NULL);
 
-	/* this is the odd case -- we disconnected but weren't using it */
-	if (!ss) {
-		US_DEBUGP("-- device was not in use\n");
-		return;
-	}
+	/* serious error -- we're attempting to disconnect an interface but
+	 * cannot locate the local data structure
+	 */
+	BUG_ON(ss == NULL);
 
+	/* set devices offline -- need host lock for this */
+	scsi_lock(ss->host);
+	list_for_each_entry(sdev, &ss->host->my_devices, siblings)
+		sdev->online = 0;
+	scsi_unlock(ss->host);
+
+	/* lock device access -- no need to unlock, as we're going away */
 	down(&(ss->dev_semaphore));
+
+	/* Complete all pending commands with * cmd->result = DID_ERROR << 16.
+	 * Since we only queue one command at a time, this is pretty easy. */
+	if (ss->srb) {
+		ss->srb->result = DID_ERROR << 16;
+		ss->srb->scsi_done(ss->srb);
+	}
+
+	/* TODO: somehow, wait for the device to
+	 * be 'idle' (tasklet completion) */
+
+	/* remove the pointer to the data structure we were using */
+	(struct us_data*)ss->host->hostdata[0] = NULL;
+
+	/* begin SCSI host removal sequence */
+	if(scsi_remove_host(ss->host)) {
+		US_DEBUGP("-- SCSI refused to unregister\n");
+		BUG();
+		return;
+	};
+
+	/* finish SCSI host removal sequence */
+	scsi_unregister(ss->host);
+
+	/* Kill the control threads
+	 *
+	 * Enqueue the command, wake up the thread, and wait for 
+	 * notification that it has exited.
+	 */
+	US_DEBUGP("-- sending exit command to thread\n");
+	BUG_ON(atomic_read(&ss->sm_state) != US_STATE_IDLE);
+	ss->srb = NULL;
+	up(&(ss->sema));
+	wait_for_completion(&(ss->notify));
+
+	/* free allocated urbs */
 	usb_stor_deallocate_urbs(ss);
+
+	/* If there's extra data in the us_data structure then
+	 * free that first */
+	if (ss->extra) {
+		/* call the destructor routine, if it exists */
+		if (ss->extra_destructor) {
+			US_DEBUGP("-- calling extra_destructor()\n");
+			ss->extra_destructor(ss->extra);
+		}
+
+		/* destroy the extra data */
+		US_DEBUGP("-- freeing the data structure\n");
+		kfree(ss->extra);
+	}
+
+	/* up the semaphore so auto-code-checkers won't complain about
+	 * the down/up imbalance */
 	up(&(ss->dev_semaphore));
+
+	/* free the structure itself */
+	kfree (ss);
 }
 
 /***********************************************************************
@@ -1078,11 +1029,6 @@
 {
 	printk(KERN_INFO "Initializing USB Mass Storage driver...\n");
 
-	/* initialize internal global data elements */
-	us_list = NULL;
-	init_MUTEX(&us_list_semaphore);
-	my_host_number = 0;
-
 	/* register the driver, return -1 if error */
 	if (usb_register(&usb_storage_driver) < 0)
 		return -1;
@@ -1094,16 +1040,16 @@
 
 void __exit usb_stor_exit(void)
 {
-	struct us_data *next;
-
 	US_DEBUGP("usb_stor_exit() called\n");
 
 	/* Deregister the driver
-	 * This eliminates races with probes and disconnects 
+	 * This will cause disconnect() to be called for each
+	 * attached unit
 	 */
 	US_DEBUGP("-- calling usb_deregister()\n");
 	usb_deregister(&usb_storage_driver) ;
 
+#if 0
 	/* While there are still virtual hosts, unregister them
 	 * Note that it's important to do this completely before removing
 	 * the structures because of possible races with the /proc
@@ -1111,7 +1057,7 @@
 	 */
 	for (next = us_list; next; next = next->next) {
 		US_DEBUGP("-- calling scsi_unregister_host()\n");
-		scsi_unregister_host(&(next->htmplt));
+		scsi_unregister_host(&usb_stor_host_template);
 	}
 
 	/* While there are still structures, free them.  Note that we are
@@ -1137,11 +1083,12 @@
 		}
 
 		/* free the structure itself */
-                kfree (us_list);
+		kfree (us_list);
 
 		/* advance the list pointer */
 		us_list = next;
 	}
+#endif
 }
 
 module_init(usb_stor_init);
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h	Mon Feb 10 10:39:29 2003
+++ b/drivers/usb/storage/usb.h	Mon Feb 10 10:39:29 2003
@@ -52,33 +52,6 @@
 #include "scsi.h"
 #include "hosts.h"
 
-/* 
- * GUID definitions
- */
-
-#define GUID(x) __u32 x[3]
-#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2])
-#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0;
-#define GUID_NONE(x) (!x[0] && !x[1] && !x[2])
-#define GUID_FORMAT "%08x%08x%08x"
-#define GUID_ARGS(x) x[0], x[1], x[2]
-
-static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial)
-{
-	pg[0] = (vendor << 16) | product;
-	pg[1] = pg[2] = 0;
-	while (*serial) {
-		pg[1] <<= 4;
-		pg[1] |= pg[2] >> 28;
-		pg[2] <<= 4;
-		if (*serial >= 'a')
-			*serial -= 'a' - 'A';
-		pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0'
-			: *serial - 'A' + 10;
-		serial++;
-	}
-}
-
 struct us_data;
 
 /*
@@ -104,7 +77,6 @@
 #define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs fixing   */
 #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
 
-#define US_FL_DEV_ATTACHED    0x00010000 /* is the device attached?	    */
 #define US_FLIDX_CAN_CANCEL  18  /* 0x00040000  okay to cancel current_urb? */
 #define US_FLIDX_CANCEL_SG   19  /* 0x00080000	okay to cancel current_sg?  */
 
@@ -124,12 +96,9 @@
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
-	struct us_data		*next;		 /* next device */
-
 	/* The device we're working with
 	 * It's important to note:
 	 *    (o) you must hold dev_semaphore to change pusb_dev
-	 *    (o) DEV_ATTACHED in flags should change whenever pusb_dev does
 	 */
 	struct semaphore	dev_semaphore;	 /* protect pusb_dev */
 	struct usb_device	*pusb_dev;	 /* this usb_device */
@@ -163,11 +132,7 @@
 	proto_cmnd		proto_handler;	 /* protocol handler	   */
 
 	/* SCSI interfaces */
-	GUID(guid);				 /* unique dev id	*/
 	struct Scsi_Host	*host;		 /* our dummy host data */
-	Scsi_Host_Template	htmplt;		 /* own host template	*/
-	int			host_number;	 /* to find us		*/
-	int			host_no;	 /* allocated by scsi	*/
 	Scsi_Cmnd		*srb;		 /* current srb		*/
 
 	/* thread information */
@@ -191,10 +156,6 @@
 	void			*extra;		 /* Any extra data          */
 	extra_data_destructor	extra_destructor;/* extra data destructor   */
 };
-
-/* The list of structures and the protective lock for them */
-extern struct us_data *us_list;
-extern struct semaphore us_list_semaphore;
 
 /* The structure which defines our driver */
 extern struct usb_driver usb_storage_driver;
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/drivers/video/Kconfig	Mon Feb 10 10:39:23 2003
@@ -160,7 +160,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called amifb.o. If you want to compile it as a
+	  module will be called amifb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_AMIGA_OCS
@@ -292,7 +292,7 @@
 	  as a module ( = code which can be inserted in and removed from the
 	  running kernel whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
-	  vga16fb.o.
+	  vga16fb.
 
 config FB_STI
 	tristate "HP STI frame buffer device support"
@@ -350,7 +350,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want).
-	  The module will be called hgafb.o. If you want to compile it as
+	  The module will be called hgafb. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  As this card technology is 15 years old, most people will answer N
@@ -406,7 +406,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want).
-	  The module will be called pvr2fb.o.  If you want to compile it as
+	  The module will be called pvr2fb.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  You can pass several parameters to the driver at boot time or at
@@ -462,7 +462,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called rivafb.o. If you want to compile it as a
+	  module will be called rivafb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_I810
@@ -474,7 +474,7 @@
 
           The driver is also available as a module ( = code which can be
           inserted and removed from the running kernel whenever you want). 
-          The module will be called i810fb.o. If you want to compile it as a
+          The module will be called i810fb. If you want to compile it as a
           module, say M here and read <file:Documentation/modules.txt>.
 
           For more information, please read 
@@ -514,7 +514,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want).
-	  The module will be called matroxfb.o. If you want to compile it as
+	  The module will be called matroxfb. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  You can pass several parameters to the driver at boot time or at
@@ -606,7 +606,7 @@
 	  second head of G400 or MGA-TVO on G200 or G400.
 
 	  If you compile it as module, it will create a module named
-	  i2c-matroxfb.o.
+	  i2c-matroxfb.
 
 config FB_MATROX_MAVEN
 	tristate "G400 second head support"
@@ -622,7 +622,7 @@
 	  the fbdev driver on first head and the fbdev driver on second head.
 
 	  If you compile it as module, two modules are created,
-	  matroxfb_crtc2.o and matroxfb_maven.o. Matroxfb_maven is needed for
+	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
 	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
 	  also load i2c-matroxfb to get it to run.
 
@@ -651,7 +651,7 @@
 
 	  If you said M to "Matrox unified accelerated driver" and N here, you
 	  will still be able to use several Matrox devices simultaneously:
-	  insert several instances of the module matroxfb.o into the kernel
+	  insert several instances of the module matroxfb into the kernel
 	  with insmod, supplying the parameter "dev=N" where N is 0, 1, etc.
 	  for the different Matrox devices. This method is slightly faster but
 	  uses 40 KB of kernel memory per Matrox card.
@@ -679,7 +679,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called aty128fb.o. If you want to compile it as a
+	  module will be called aty128fb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_ATY
@@ -691,7 +691,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called atyfb.o. If you want to compile it as a
+	  module will be called atyfb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_ATY_CT
@@ -746,7 +746,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called neofb.o. If you want to compile it as a
+	  module will be called neofb. If you want to compile it as a
 	  module, say M here and read Documentation/modules.txt.
 
 config FB_3DFX
@@ -758,7 +758,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called tdfxfb.o. If you want to compile it as a
+	  module will be called tdfxfb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_VOODOO1
@@ -770,7 +770,7 @@
 
 	  This driver is also available as a module ( = code which can be 
 	  inserted and removed from the running kernel whenever you want).
-	  The module will be called sstfb.o. If you want to compile it as
+	  The module will be called sstfb. If you want to compile it as
 	  a module, say M here and read Documentation/modules.txt.
 
 	  WARNING: Do not use any application that uses the 3D engine
@@ -791,7 +791,7 @@
 
 	  The driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called tridentfb.o. If you want to compile it as a
+	  module will be called tridentfb. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config FB_PM3
@@ -917,7 +917,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want). The
-	  module will be called vfb.o. If you want to compile it as a module,
+	  module will be called vfb. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say N.
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Mon Feb 10 10:39:23 2003
+++ b/drivers/video/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,12 +2,6 @@
 # 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
 # Rewritten to use lists instead of if-statements.
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs    	:= fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \
-		   cfbcopyarea.o cfbimgblt.o cyber2000fb.o vgastate.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_VT)		  += console/
diff -Nru a/drivers/video/acornfb.c b/drivers/video/acornfb.c
--- a/drivers/video/acornfb.c	Mon Feb 10 10:39:33 2003
+++ b/drivers/video/acornfb.c	Mon Feb 10 10:39:33 2003
@@ -896,6 +896,7 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_mmap	= acornfb_mmap,
+	.fb_cursor	= soft_cursor,
 };
 
 /*
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	Mon Feb 10 10:39:29 2003
+++ b/drivers/video/aty/atyfb_base.c	Mon Feb 10 10:39:29 2003
@@ -2587,12 +2587,12 @@
 	if (info->screen_base)
 		iounmap((void *) info->screen_base);
 #ifdef __BIG_ENDIAN
-	if (info->cursor && par->cursor->ram)
+	if (par->cursor && par->cursor->ram)
 		iounmap(par->cursor->ram);
 #endif
 #endif
-	if (info->cursor)
-		kfree(info->cursor);
+	if (par->cursor)
+		kfree(par->cursor);
 #ifdef __sparc__
 	if (par->mmap_map)
 		kfree(par->mmap_map);
diff -Nru a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
--- a/drivers/video/console/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/drivers/video/console/Kconfig	Mon Feb 10 10:39:24 2003
@@ -52,7 +52,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted and removed from the running kernel whenever you want).
-	  The module will be called mdacon.o. If you want to compile it as
+	  The module will be called mdacon. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say N.
@@ -131,7 +131,7 @@
 
 	  Low level frame buffer console drivers can be modules ( = code which
 	  can be inserted and removed from the running kernel whenever you
-	  want). The modules will be called fbcon-*.o. If you want to compile
+	  want). The modules will be called fbcon-*. If you want to compile
 	  (some of) them as modules, read <file:Documentation/modules.txt>.
 
 	  If unsure, say N.
diff -Nru a/drivers/video/console/Makefile b/drivers/video/console/Makefile
--- a/drivers/video/console/Makefile	Mon Feb 10 10:39:27 2003
+++ b/drivers/video/console/Makefile	Mon Feb 10 10:39:27 2003
@@ -2,11 +2,6 @@
 # 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
 # Rewritten to use lists instead of if-statements.
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs    	:= fbcon.o fonts.o
-
 # Font handling
 font-objs := fonts.o
 
diff -Nru a/drivers/video/matrox/Makefile b/drivers/video/matrox/Makefile
--- a/drivers/video/matrox/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/video/matrox/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,11 +2,6 @@
 # 5 Aug 1999, James Simmons, <mailto:jsimmons@edgeglobal.com>
 # Rewritten to use lists instead of if-statements.
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs    :=  matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o matroxfb_g450.o
-
 # Each configuration option enables a list of files.
 
 my-obj-$(CONFIG_FB_MATROX_G100)	  += g450_pll.o
diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c	Mon Feb 10 10:39:30 2003
+++ b/drivers/video/riva/fbdev.c	Mon Feb 10 10:39:30 2003
@@ -1759,7 +1759,7 @@
 	case NV_ARCH_03:
 		/* Riva128's PRAMIN is in the "framebuffer" space
 		 * Since these cards were never made with more than 8 megabytes
-		 * we can safely allocate this seperately.
+		 * we can safely allocate this separately.
 		 */
 		if (!request_mem_region(rivafb_fix.smem_start + 0x00C00000,
 					 0x00008000, "rivafb")) {
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/video/sa1100fb.c	Mon Feb 10 10:39:24 2003
@@ -1122,6 +1122,7 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_blank	= sa1100fb_blank,
+	.fb_cursor	= soft_cursor,
 };
 
 /*
diff -Nru a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile
--- a/drivers/video/sis/Makefile	Mon Feb 10 10:39:33 2003
+++ b/drivers/video/sis/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for the SiS framebuffer device driver
 #
 
-export-objs := sis_main.o
-
 obj-$(CONFIG_FB_SIS) += sisfb.o
 
 sisfb-objs := sis_main.o sis_accel.o init.o init301.o
diff -Nru a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
--- a/drivers/video/skeletonfb.c	Mon Feb 10 10:39:24 2003
+++ b/drivers/video/skeletonfb.c	Mon Feb 10 10:39:24 2003
@@ -19,7 +19,7 @@
  *  struct vc_data to data in a device independent way in struct fb_info. Then
  *  various functions in struct fb_ops will be called to store the device 
  *  dependent state in the par field in struct fb_info and to change the 
- *  hardware to that state. This allows a very clean seperation of the fbdev
+ *  hardware to that state. This allows a very clean separation of the fbdev
  *  layer from the console layer. It also allows one to use fbdev on its own
  *  which is a bounus for embedded devices. The reason this approach works is  
  *  for each framebuffer device when used as a tty/console device is allocated
@@ -93,7 +93,7 @@
      * 	Modern graphical hardware not only supports pipelines but some 
      *  also support multiple monitors where each display can have its  
      *  its own unique data. In this case each display could be  
-     *  represented by a seperate framebuffer device thus a seperate 
+     *  represented by a separate framebuffer device thus a separate 
      *  struct fb_info. Now the struct xxx_par represents the graphics
      *  hardware state thus only one exist per card. In this case the 
      *  struct xxx_par for each graphics card would be shared between 
@@ -513,7 +513,7 @@
  *		     for a graphics card take a specific amount of time.
  *		     Often we have to wait for the accelerator to finish
  *		     its operation before we can write to the framebuffer
- *		     so we can have consistant display output. 
+ *		     so we can have consistent display output. 
  *
  *      @info: frame buffer structure that represents a single frame buffer
  */
diff -Nru a/drivers/video/vesafb.c b/drivers/video/vesafb.c
--- a/drivers/video/vesafb.c	Mon Feb 10 10:39:23 2003
+++ b/drivers/video/vesafb.c	Mon Feb 10 10:39:23 2003
@@ -62,6 +62,7 @@
 static int vesafb_pan_display(struct fb_var_screeninfo *var,
                               struct fb_info *info)
 {
+#ifdef __i386__
 	int offset;
 
 	if (!ypan)
@@ -83,11 +84,13 @@
                   "c" (offset),         /* ECX */
                   "d" (offset >> 16),   /* EDX */
                   "D" (&pmi_start));    /* EDI */
+#endif
 	return 0;
 }
 
 static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
 {
+#ifdef __i386__
 	struct { u_char blue, green, red, pad; } entry;
 
 	if (pmi_setpal) {
@@ -111,6 +114,7 @@
 		outb_p(green >> 10, dac_val);
 		outb_p(blue  >> 10, dac_val);
 	}
+#endif
 }
 
 static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -224,6 +228,10 @@
 	vesafb_fix.smem_len = screen_info.lfb_size * 65536;
 	vesafb_fix.visual   = (vesafb_defined.bits_per_pixel == 8) ?
 		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+
+#ifndef __i386__
+	screen_info.vesapm_seg = 0;
+#endif
 
 	if (!request_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len, "vesafb")) {
 		printk(KERN_WARNING
diff -Nru a/drivers/zorro/Makefile b/drivers/zorro/Makefile
--- a/drivers/zorro/Makefile	Mon Feb 10 10:39:24 2003
+++ b/drivers/zorro/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the Zorro bus specific drivers.
 #
 
-export-objs		:= zorro.o
-
 obj-$(CONFIG_ZORRO)	+= zorro.o names.o
 obj-$(CONFIG_PROC_FS)	+= proc.o
 
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	Mon Feb 10 10:39:28 2003
+++ b/fs/Kconfig	Mon Feb 10 10:39:28 2003
@@ -56,7 +56,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called autofs.o.
+	  will be called autofs.
 
 	  If you are not a part of a fairly large, distributed network, you
 	  probably do not need an automounter, and can say N here.
@@ -76,7 +76,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called autofs4.o.  You will need to add "alias autofs
+	  will be called autofs4.  You will need to add "alias autofs
 	  autofs4" to your modules configuration file.
 
 	  If you are not a part of a fairly large, distributed network or
@@ -150,7 +150,7 @@
 	  /dev/[hs]d?1) on each of your drives. Please read the file
 	  <file:Documentation/filesystems/adfs.txt> for further details.
 
-	  This code is also available as a module called adfs.o ( = code which
+	  This code is also available as a module called adfs ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want). If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
@@ -186,7 +186,7 @@
 
 	  This file system is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called affs.o.  If you want to compile it as a module,
+	  The module is called affs.  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.  If unsure,
 	  say N.
 
@@ -201,7 +201,7 @@
 
 	  This file system support is also available as a module ( = code
 	  which can be inserted in and removed from the running kernel
-	  whenever you want). The module is called hfs.o.  If you want to
+	  whenever you want). The module is called hfs.  If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -224,7 +224,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read Documentation/modules.txt. The module will be
-	  called befs.o.
+	  called befs.
 
 config BEFS_DEBUG
 	bool "Debug BeFS"
@@ -252,7 +252,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called bfs.o.  Note that the file system of your root
+	  will be called bfs.  Note that the file system of your root
 	  partition (the one containing the directory /) cannot be compiled as
 	  a module.
 
@@ -285,7 +285,7 @@
 	  If you want to compile this file system as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called ext3.o.  Be aware however that the file system
+	  module will be called ext3.  Be aware however that the file system
 	  of your root partition (the one containing the directory /) cannot
 	  be compiled as a module, and so this may be dangerous.
 
@@ -332,7 +332,7 @@
 	  If you want to compile this device as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called jbd.o.  If you are compiling ext3 into the kernel,
+	  will be called jbd.  If you are compiling ext3 into the kernel,
 	  you cannot compile this code as a module.
 
 config JBD_DEBUG
@@ -388,7 +388,7 @@
 	  If you want to compile this as a module however ( = code which can
 	  be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called fat.o.  Note that if you compile the FAT
+	  module will be called fat.  Note that if you compile the FAT
 	  support as a module, you cannot compile any of the FAT-based file
 	  systems into the kernel -- they will have to be modules as well.
 	  The file system of your root partition (the one containing the
@@ -425,7 +425,7 @@
 	  which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
 	  <file:Documentation/modules.txt>.
-	  The module will be called msdos.o.
+	  The module will be called msdos.
 
 #dep_tristate '    UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
 # UMSDOS is temprory broken
@@ -454,7 +454,7 @@
 	  above.  If you want to compile this as a module ( = code which can
 	  be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called umsdos.o.  Note that the file system of your
+	  module will be called umsdos.  Note that the file system of your
 	  root partition (the one containing the directory /) cannot be a
 	  module, so saying M could be dangerous.  If unsure, say N.
 
@@ -480,7 +480,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called vfat.o.
+	  will be called vfat.
 
 config EFS_FS
 	tristate "EFS file system support (read only) (EXPERIMENTAL)"
@@ -497,7 +497,7 @@
 	  If you want to compile the EFS file system support as a module ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
-	  <file:Documentation/modules.txt>. The module will be called efs.o.
+	  <file:Documentation/modules.txt>. The module will be called efs.
 
 config JFFS_FS
 	tristate "Journalling Flash File System (JFFS) support"
@@ -583,7 +583,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called cramfs.o.  Note that the root file system (the one
+	  will be called cramfs.  Note that the root file system (the one
 	  containing the directory /) cannot be compiled as a module.
 
 	  If unsure, say N.
@@ -614,7 +614,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ramfs.o.
+	  will be called ramfs.
 
 config HUGETLBFS
 	bool "HugeTLB file system support"
@@ -636,7 +636,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called isofs.o.
+	  will be called isofs.
 
 config JOLIET
 	bool "Microsoft Joliet CDROM extensions"
@@ -711,7 +711,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>. The module
-	  will be called minix.o.  Note that the file system of your root
+	  will be called minix.  Note that the file system of your root
 	  partition (the one containing the directory /) cannot be compiled as
 	  a module.
 
@@ -730,7 +730,7 @@
 
 	  This file system is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called freevxfs.o.  If you want to compile it as a
+	  The module is called freevxfs.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  If
 	  unsure, say N.
 
@@ -743,7 +743,7 @@
 
 	  This file system is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ntfs.o. If you want to compile it as a
+	  The module will be called ntfs. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 	  If you are not using Windows NT/2000/XP in addition to Linux on your
@@ -796,7 +796,7 @@
 
 	  This file system is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called hpfs.o.  If you want to compile it as a module,
+	  The module is called hpfs.  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.  If unsure,
 	  say N.
 
@@ -907,7 +907,7 @@
 
 	  This file system support is also available as a module ( = code
 	  which can be inserted in and removed from the running kernel
-	  whenever you want). The module is called qnx4.o. If you want to
+	  whenever you want). The module is called qnx4. If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -933,7 +933,7 @@
 
 	  This file system support is also available as a module ( = code
 	  which can be inserted in and removed from the running kernel
-	  whenever you want). The module is called romfs.o.  If you want to
+	  whenever you want). The module is called romfs.  If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  Note that the file system of your
 	  root partition (the one containing the directory /) cannot be a
@@ -984,7 +984,7 @@
 	  If you want to compile this file system as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called ext2.o.  Be aware however that the file system
+	  module will be called ext2.  Be aware however that the file system
 	  of your root partition (the one containing the directory /) cannot
 	  be compiled as a module, and so this could be dangerous.  Most
 	  everyone wants to say Y here.
@@ -1045,7 +1045,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called sysv.o.
+	  will be called sysv.
 
 	  If you haven't heard about all of this before, it's safe to say N.
 
@@ -1059,7 +1059,7 @@
 
 	  This file system support is also available as a module ( = code
 	  which can be inserted in and removed from the running kernel
-	  whenever you want). The module is called udf.o. If you want to
+	  whenever you want). The module is called udf. If you want to
 	  compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
@@ -1092,7 +1092,7 @@
 	  If you want to compile the UFS file system support as a module ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
-	  <file:Documentation/modules.txt>. The module will be called ufs.o.
+	  <file:Documentation/modules.txt>. The module will be called ufs.
 
 	  If you haven't heard about all of this before, it's safe to say N.
 
@@ -1120,7 +1120,7 @@
 	  If you want to compile this file system as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>. The
-	  module will be called xfs.o.  Be aware, however, that if the file
+	  module will be called xfs.  Be aware, however, that if the file
 	  system of your root partition is compiled as a module, you'll need
 	  to use an initial ramdisk (initrd) to boot.
 
@@ -1196,7 +1196,7 @@
 	  If you want to compile the coda client support as a module ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want), say M here and read
-	  <file:Documentation/modules.txt>.  The module will be called coda.o.
+	  <file:Documentation/modules.txt>.  The module will be called coda.
 
 config INTERMEZZO_FS
 	tristate "InterMezzo file system support (replicating fs) (EXPERIMENTAL)"
@@ -1235,7 +1235,7 @@
 
 	  This file system is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called nfs.o. If you want to compile it as a module,
+	  The module is called nfs. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
 
 	  If you are configuring a diskless machine which will mount its root
@@ -1307,7 +1307,7 @@
 
 	  The NFS server is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called nfsd.o.  If you want to compile it as a module,
+	  The module is called nfsd.  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.  If unsure,
 	  say N.
 
@@ -1425,7 +1425,7 @@
 	  If you want to compile the SMB support as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called smbfs.o.  Most people say N, however.
+	  module will be called smbfs.  Most people say N, however.
 
 config SMB_NLS_DEFAULT
 	bool "Use a default NLS"
@@ -1477,7 +1477,7 @@
 	  If you want to compile this as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called ncpfs.o.  Say N unless you are connected to a Novell
+	  will be called ncpfs.  Say N unless you are connected to a Novell
 	  network.
 
 source "fs/ncpfs/Kconfig"
diff -Nru a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile	Mon Feb 10 10:39:28 2003
+++ b/fs/Makefile	Mon Feb 10 10:39:28 2003
@@ -5,9 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 # 
 
-export-objs :=	open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \
-                fcntl.o read_write.o dcookies.o mbcache.o posix_acl.o xattr_acl.o
-
 obj-y :=	open.o read_write.o file_table.o buffer.o \
 		bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \
 		namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
diff -Nru a/fs/afs/cmservice.c b/fs/afs/cmservice.c
--- a/fs/afs/cmservice.c	Mon Feb 10 10:39:27 2003
+++ b/fs/afs/cmservice.c	Mon Feb 10 10:39:27 2003
@@ -127,10 +127,10 @@
 	complete(&kafscmd_alive);
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
 	do {
diff -Nru a/fs/afs/internal.h b/fs/afs/internal.h
--- a/fs/afs/internal.h	Mon Feb 10 10:39:25 2003
+++ b/fs/afs/internal.h	Mon Feb 10 10:39:25 2003
@@ -46,9 +46,9 @@
 	while (signal_pending(current)) {
 		siginfo_t sinfo;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		dequeue_signal(&current->blocked,&sinfo);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
--- a/fs/afs/kafsasyncd.c	Mon Feb 10 10:39:33 2003
+++ b/fs/afs/kafsasyncd.c	Mon Feb 10 10:39:33 2003
@@ -101,10 +101,10 @@
 	complete(&kafsasyncd_alive);
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
 	do {
diff -Nru a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
--- a/fs/afs/kafstimod.c	Mon Feb 10 10:39:29 2003
+++ b/fs/afs/kafstimod.c	Mon Feb 10 10:39:29 2003
@@ -78,10 +78,10 @@
 	complete(&kafstimod_alive);
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
  loop:
diff -Nru a/fs/autofs/waitq.c b/fs/autofs/waitq.c
--- a/fs/autofs/waitq.c	Mon Feb 10 10:39:24 2003
+++ b/fs/autofs/waitq.c	Mon Feb 10 10:39:24 2003
@@ -70,10 +70,10 @@
 	/* Keep the currently executing process from receiving a
 	   SIGPIPE unless it was already supposed to get one */
 	if (wr == -EPIPE && !sigpipe) {
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		sigdelset(&current->pending.signal, SIGPIPE);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 	}
 
 	return (bytes > 0);
@@ -158,21 +158,14 @@
 
 	if ( wq->name ) {
 		/* Block all but "shutdown" signals while waiting */
-		sigset_t oldset;
-		unsigned long irqflags;
+		sigset_t sigmask;
 
-		spin_lock_irqsave(&current->sig->siglock, irqflags);
-		oldset = current->blocked;
-		siginitsetinv(&current->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]);
-		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+		siginitsetinv(&sigmask, SHUTDOWN_SIGS);
+		sigprocmask(SIG_BLOCK, &sigmask, &sigmask);
 
 		interruptible_sleep_on(&wq->queue);
 
-		spin_lock_irqsave(&current->sig->siglock, irqflags);
-		current->blocked = oldset;
-		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+		sigprocmask(SIG_SETMASK, &sigmask, NULL);
 	} else {
 		DPRINTK(("autofs_wait: skipped sleeping\n"));
 	}
diff -Nru a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
--- a/fs/autofs4/waitq.c	Mon Feb 10 10:39:32 2003
+++ b/fs/autofs4/waitq.c	Mon Feb 10 10:39:32 2003
@@ -74,10 +74,10 @@
 	/* Keep the currently executing process from receiving a
 	   SIGPIPE unless it was already supposed to get one */
 	if (wr == -EPIPE && !sigpipe) {
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		sigdelset(&current->pending.signal, SIGPIPE);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 	}
 
 	return (bytes > 0);
@@ -198,18 +198,18 @@
 		sigset_t oldset;
 		unsigned long irqflags;
 
-		spin_lock_irqsave(&current->sig->siglock, irqflags);
+		spin_lock_irqsave(&current->sighand->siglock, irqflags);
 		oldset = current->blocked;
 		siginitsetinv(&current->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+		spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
 
 		interruptible_sleep_on(&wq->queue);
 
-		spin_lock_irqsave(&current->sig->siglock, irqflags);
+		spin_lock_irqsave(&current->sighand->siglock, irqflags);
 		current->blocked = oldset;
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+		spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
 	} else {
 		DPRINTK(("autofs_wait: skipped sleeping\n"));
 	}
diff -Nru a/fs/befs/ChangeLog b/fs/befs/ChangeLog
--- a/fs/befs/ChangeLog	Mon Feb 10 10:39:23 2003
+++ b/fs/befs/ChangeLog	Mon Feb 10 10:39:23 2003
@@ -60,7 +60,7 @@
 
 * Documentation improvements in source. [WD]
 
-* Makefile fix for independant module when CONFIG_MODVERSION is set in 
+* Makefile fix for independent module when CONFIG_MODVERSION is set in 
 	kernel config [Pavel Roskin <proski@gnu.org>]
 
 * Compile warning fix for namei.c. [Sergey S. Kostyliov <rathamahata@php4.ru>]
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	Mon Feb 10 10:39:26 2003
+++ b/fs/binfmt_elf.c	Mon Feb 10 10:39:26 2003
@@ -236,7 +236,7 @@
 			return;
 		p += len;
 	}
-	__put_user(NULL, argv);
+	__put_user(0, argv);
 	current->mm->arg_end = current->mm->env_start = p;
 	while (envc-- > 0) {
 		size_t len;
@@ -246,7 +246,7 @@
 			return;
 		p += len;
 	}
-	__put_user(NULL, envp);
+	__put_user(0, envp);
 	current->mm->env_end = p;
 
 	/* Put the elf_info on the stack in the right place.  */
@@ -362,8 +362,6 @@
 	  }
 	}
 
-	/* Now use mmap to map the library into memory. */
-
 	/*
 	 * Now fill out the bss section.  First pad the last page up
 	 * to the page boundary, and then perform a mmap to make sure
@@ -536,6 +534,25 @@
 			    strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
 				ibcs2_interpreter = 1;
 
+			/*
+			 * The early SET_PERSONALITY here is so that the lookup
+			 * for the interpreter happens in the namespace of the 
+			 * to-be-execed image.  SET_PERSONALITY can select an
+			 * alternate root.
+			 *
+			 * However, SET_PERSONALITY is NOT allowed to switch
+			 * this task into the new images's memory mapping
+			 * policy - that is, TASK_SIZE must still evaluate to
+			 * that which is appropriate to the execing application.
+			 * This is because exit_mmap() needs to have TASK_SIZE
+			 * evaluate to the size of the old image.
+			 *
+			 * So if (say) a 64-bit application is execing a 32-bit
+			 * application it is the architecture's responsibility
+			 * to defer changing the value of TASK_SIZE until the
+			 * switch really is going to happen - do this in
+			 * flush_thread().	- akpm
+			 */
 			SET_PERSONALITY(elf_ex, ibcs2_interpreter);
 
 			interpreter = open_exec(elf_interpreter);
@@ -1041,7 +1058,7 @@
 
 /*
  * fill up all the fields in prstatus from the given task struct, except registers
- * which need to be filled up seperately.
+ * which need to be filled up separately.
  */
 static inline void fill_prstatus(struct elf_prstatus *prstatus, struct task_struct *p, long signr) 
 {
diff -Nru a/fs/binfmt_flat.c b/fs/binfmt_flat.c
--- a/fs/binfmt_flat.c	Mon Feb 10 10:39:22 2003
+++ b/fs/binfmt_flat.c	Mon Feb 10 10:39:22 2003
@@ -403,7 +403,7 @@
 	set_personality(PER_LINUX);
 
 	/*
-	 * there are a couple of cases here,  the seperate code/data
+	 * there are a couple of cases here,  the separate code/data
 	 * case,  and then the fully copied to RAM case which lumps
 	 * it all together.
 	 */
diff -Nru a/fs/binfmt_som.c b/fs/binfmt_som.c
--- a/fs/binfmt_som.c	Mon Feb 10 10:39:25 2003
+++ b/fs/binfmt_som.c	Mon Feb 10 10:39:25 2003
@@ -56,7 +56,7 @@
 static struct linux_binfmt som_format = {
 	.module		= THIS_MODULE,
 	.load_binary	= load_som_binary,
-	.load_library	= load_som_library,
+	.load_shlib	= load_som_library,
 	.core_dump	= som_core_dump,
 	.min_coredump	= SOM_PAGESIZE
 };
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Mon Feb 10 10:39:28 2003
+++ b/fs/buffer.c	Mon Feb 10 10:39:28 2003
@@ -81,21 +81,11 @@
  * Return the address of the waitqueue_head to be used for this
  * buffer_head
  */
-static wait_queue_head_t *bh_waitq_head(struct buffer_head *bh)
+wait_queue_head_t *bh_waitq_head(struct buffer_head *bh)
 {
 	return &bh_wait_queue_heads[hash_ptr(bh, BH_WAIT_TABLE_ORDER)].wqh;
 }
-
-/*
- * Wait on a buffer until someone does a wakeup on it.  Needs
- * lots of external locking.  ext3 uses this.  Fix it.
- */
-void sleep_on_buffer(struct buffer_head *bh)
-{
-	wait_queue_head_t *wq = bh_waitq_head(bh);
-	sleep_on(wq);
-}
-EXPORT_SYMBOL(sleep_on_buffer);
+EXPORT_SYMBOL(bh_waitq_head);
 
 void wake_up_buffer(struct buffer_head *bh)
 {
@@ -137,9 +127,10 @@
 	get_bh(bh);
 	do {
 		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-		blk_run_queues();
-		if (buffer_locked(bh))
-			schedule();
+		if (buffer_locked(bh)) {
+			blk_run_queues();
+			io_schedule();
+		}
 	} while (buffer_locked(bh));
 	put_bh(bh);
 	finish_wait(wqh, &wait);
@@ -969,8 +960,6 @@
 	 * the reserve list is empty, we're sure there are 
 	 * async buffer heads in use.
 	 */
-	blk_run_queues();
-
 	free_more_memory();
 	goto try_again;
 }
diff -Nru a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c	Mon Feb 10 10:39:24 2003
+++ b/fs/char_dev.c	Mon Feb 10 10:39:24 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/block_dev.c
+ *  linux/fs/char_dev.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
@@ -38,16 +38,13 @@
 	 ((struct char_device *) kmem_cache_alloc(cdev_cachep, SLAB_KERNEL))
 #define destroy_cdev(cdev) kmem_cache_free(cdev_cachep, (cdev))
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
 {
-	struct char_device * cdev = (struct char_device *) foo;
+	struct char_device *cdev = (struct char_device *) foo;
 
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR)
-	{
 		memset(cdev, 0, sizeof(*cdev));
-		sema_init(&cdev->sem, 1);
-	}
 }
 
 void __init cdev_cache_init(void)
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	Mon Feb 10 10:39:23 2003
+++ b/fs/dcache.c	Mon Feb 10 10:39:23 2003
@@ -1147,21 +1147,24 @@
 		namelen = dentry->d_name.len;
 		buflen -= namelen + 1;
 		if (buflen < 0)
-			break;
+			return ERR_PTR(-ENAMETOOLONG);
 		end -= namelen;
 		memcpy(end, dentry->d_name.name, namelen);
 		*--end = '/';
 		retval = end;
 		dentry = parent;
 	}
+
 	return retval;
+
 global_root:
 	namelen = dentry->d_name.len;
 	buflen -= namelen;
 	if (buflen >= 0) {
 		retval -= namelen-1;	/* hit the slash */
 		memcpy(retval, dentry->d_name.name, namelen);
-	}
+	} else
+		retval = ERR_PTR(-ENAMETOOLONG);
 	return retval;
 }
 
@@ -1229,6 +1232,10 @@
 		cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
 		spin_unlock(&dcache_lock);
 
+		error = PTR_ERR(cwd);
+		if (IS_ERR(cwd))
+			goto out;
+
 		error = -ERANGE;
 		len = PAGE_SIZE + page - cwd;
 		if (len <= size) {
@@ -1238,6 +1245,8 @@
 		}
 	} else
 		spin_unlock(&dcache_lock);
+
+out:
 	dput(pwd);
 	mntput(pwdmnt);
 	dput(root);
diff -Nru a/fs/devfs/Makefile b/fs/devfs/Makefile
--- a/fs/devfs/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/devfs/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux devfs-filesystem routines.
 #
 
-export-objs := base.o util.o
-
 obj-$(CONFIG_DEVFS_FS) += devfs.o
 
 devfs-objs := base.o util.o
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Mon Feb 10 10:39:28 2003
+++ b/fs/direct-io.c	Mon Feb 10 10:39:28 2003
@@ -892,15 +892,14 @@
 	
 		ret = do_direct_IO(dio);
 
-		if (ret) {
-			dio_cleanup(dio);
-			break;
-		}
-
 		dio->result += iov[seg].iov_len -
 			((dio->final_block_in_request - dio->block_in_file) <<
 					blkbits);
 
+		if (ret) {
+			dio_cleanup(dio);
+			break;
+		}
 	} /* end iovec loop */
 
 	/*
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	Mon Feb 10 10:39:29 2003
+++ b/fs/dquot.c	Mon Feb 10 10:39:29 2003
@@ -159,7 +159,7 @@
  * Note that any operation which operates on dquot data (ie. dq_dqb) must
  * hold dq_data_lock.
  *
- * Any operation working with dquots must hold dqoff_sem. If operation is
+ * Any operation working with dquots must hold dqptr_sem. If operation is
  * just reading pointers from inodes than read lock is enough. If pointers
  * are altered function must hold write lock.
  *
@@ -270,7 +270,7 @@
 }
 
 /* Invalidate all dquots on the list. Note that this function is called after
- * quota is disabled so no new quota might be created. Because we hold dqoff_sem
+ * quota is disabled so no new quota might be created. Because we hold dqptr_sem
  * for writing and pointers were already removed from inodes we actually know that
  * no quota for this sb+type should be held. */
 static void invalidate_dquots(struct super_block *sb, int type)
@@ -287,7 +287,7 @@
 		if (dquot->dq_type != type)
 			continue;
 #ifdef __DQUOT_PARANOIA	
-		/* There should be no users of quota - we hold dqoff_sem for writing */
+		/* There should be no users of quota - we hold dqptr_sem for writing */
 		if (atomic_read(&dquot->dq_count))
 			BUG();
 #endif
@@ -307,7 +307,7 @@
 	struct quota_info *dqopt = sb_dqopt(sb);
 	int cnt;
 
-	down_read(&dqopt->dqoff_sem);
+	down_read(&dqopt->dqptr_sem);
 restart:
 	/* At this point any dirty dquot will definitely be written so we can clear
 	   dirty flag from info */
@@ -340,7 +340,7 @@
 	spin_lock(&dq_list_lock);
 	dqstats.syncs++;
 	spin_unlock(&dq_list_lock);
-	up_read(&dqopt->dqoff_sem);
+	up_read(&dqopt->dqptr_sem);
 
 	return 0;
 }
@@ -427,7 +427,7 @@
 /*
  * Put reference to dquot
  * NOTE: If you change this function please check whether dqput_blocks() works right...
- * MUST be called with dqoff_sem held
+ * MUST be called with dqptr_sem held
  */
 static void dqput(struct dquot *dquot)
 {
@@ -492,7 +492,7 @@
 
 /*
  * Get reference to dquot
- * MUST be called with dqoff_sem held
+ * MUST be called with dqptr_sem held
  */
 static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
 {
@@ -553,7 +553,7 @@
 	return 0;
 }
 
-/* This routine is guarded by dqoff_sem semaphore */
+/* This routine is guarded by dqptr_sem semaphore */
 static void add_dquot_ref(struct super_block *sb, int type)
 {
 	struct list_head *p;
@@ -586,7 +586,7 @@
 }
 
 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
-/* We can't race with anybody because we hold dqoff_sem for writing... */
+/* We can't race with anybody because we hold dqptr_sem for writing... */
 int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
 {
 	struct dquot *dquot = inode->i_dquot[type];
@@ -829,10 +829,10 @@
 	unsigned int id = 0;
 	int cnt;
 
-	down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
-	/* Having dqoff lock we know NOQUOTA flags can't be altered... */
+	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	/* Having dqptr_sem we know NOQUOTA flags can't be altered... */
 	if (IS_NOQUOTA(inode)) {
-		up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+		up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 		return;
 	}
 	/* Build list of quotas to initialize... */
@@ -853,7 +853,7 @@
 				inode->i_flags |= S_QUOTA;
 		}
 	}
-	up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 }
 
 /*
@@ -876,9 +876,9 @@
 
 void dquot_drop(struct inode *inode)
 {
-	down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	dquot_drop_nolock(inode);
-	up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 }
 
 /*
@@ -892,7 +892,7 @@
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warntype[cnt] = NOWARN;
 
-	down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -910,7 +910,7 @@
 warn_put_all:
 	spin_unlock(&dq_data_lock);
 	flush_warnings(inode->i_dquot, warntype);
-	up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return ret;
 }
 
@@ -924,7 +924,7 @@
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warntype[cnt] = NOWARN;
-	down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -942,7 +942,7 @@
 warn_put_all:
 	spin_unlock(&dq_data_lock);
 	flush_warnings((struct dquot **)inode->i_dquot, warntype);
-	up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return ret;
 }
 
@@ -953,7 +953,7 @@
 {
 	unsigned int cnt;
 
-	down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -962,7 +962,7 @@
 	}
 	inode_sub_bytes(inode, number);
 	spin_unlock(&dq_data_lock);
-	up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 }
 
 /*
@@ -972,7 +972,7 @@
 {
 	unsigned int cnt;
 
-	down_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -980,7 +980,7 @@
 		dquot_decr_inodes(inode->i_dquot[cnt], number);
 	}
 	spin_unlock(&dq_data_lock);
-	up_read(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 }
 
 /*
@@ -1002,7 +1002,7 @@
 		transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
 		warntype[cnt] = NOWARN;
 	}
-	down_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	if (IS_NOQUOTA(inode))	/* File without quota accounting? */
 		goto warn_put_all;
 	/* First build the transfer_to list - here we can block on reading of dquots... */
@@ -1058,7 +1058,7 @@
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		if (transfer_from[cnt] != NODQUOT)
 			dqput(transfer_from[cnt]);
-	up_write(&sb_dqopt(inode->i_sb)->dqoff_sem);
+	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return ret;
 }
 
@@ -1114,7 +1114,8 @@
 		goto out;
 
 	/* We need to serialize quota_off() for device */
-	down_write(&dqopt->dqoff_sem);
+	down(&dqopt->dqonoff_sem);
+	down_write(&dqopt->dqptr_sem);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (type != -1 && cnt != type)
 			continue;
@@ -1145,7 +1146,8 @@
 		dqopt->info[cnt].dqi_bgrace = 0;
 		dqopt->ops[cnt] = NULL;
 	}
-	up_write(&dqopt->dqoff_sem);
+	up_write(&dqopt->dqptr_sem);
+	up(&dqopt->dqonoff_sem);
 out:
 	return 0;
 }
@@ -1157,6 +1159,7 @@
 	struct quota_info *dqopt = sb_dqopt(sb);
 	struct quota_format_type *fmt = find_quota_format(format_id);
 	int error;
+	unsigned int oldflags;
 
 	if (!fmt)
 		return -ESRCH;
@@ -1176,15 +1179,17 @@
 	if (!S_ISREG(inode->i_mode))
 		goto out_f;
 
-	down_write(&dqopt->dqoff_sem);
+	down(&dqopt->dqonoff_sem);
+	down_write(&dqopt->dqptr_sem);
 	if (sb_has_quota_enabled(sb, type)) {
 		error = -EBUSY;
 		goto out_lock;
 	}
+	oldflags = inode->i_flags;
 	dqopt->files[type] = f;
 	error = -EINVAL;
 	if (!fmt->qf_ops->check_quota_file(sb, type))
-		goto out_lock;
+		goto out_file_init;
 	/* We don't want quota on quota files */
 	dquot_drop_nolock(inode);
 	inode->i_flags |= S_NOQUOTA;
@@ -1194,20 +1199,23 @@
 	down(&dqopt->dqio_sem);
 	if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
 		up(&dqopt->dqio_sem);
-		goto out_lock;
+		goto out_file_init;
 	}
 	up(&dqopt->dqio_sem);
 	set_enable_flags(dqopt, type);
+	up_write(&dqopt->dqptr_sem);
 
 	add_dquot_ref(sb, type);
+	up(&dqopt->dqonoff_sem);
 
-	up_write(&dqopt->dqoff_sem);
 	return 0;
 
-out_lock:
-	inode->i_flags &= ~S_NOQUOTA;
+out_file_init:
+	inode->i_flags = oldflags;
 	dqopt->files[type] = NULL;
-	up_write(&dqopt->dqoff_sem);
+out_lock:
+	up_write(&dqopt->dqptr_sem);
+	up(&dqopt->dqonoff_sem);
 out_f:
 	filp_close(f, NULL);
 out_fmt:
@@ -1238,14 +1246,14 @@
 {
 	struct dquot *dquot;
 
-	down_read(&sb_dqopt(sb)->dqoff_sem);
+	down_read(&sb_dqopt(sb)->dqptr_sem);
 	if (!(dquot = dqget(sb, id, type))) {
-		up_read(&sb_dqopt(sb)->dqoff_sem);
+		up_read(&sb_dqopt(sb)->dqptr_sem);
 		return -ESRCH;
 	}
 	do_get_dqblk(dquot, di);
 	dqput(dquot);
-	up_read(&sb_dqopt(sb)->dqoff_sem);
+	up_read(&sb_dqopt(sb)->dqptr_sem);
 	return 0;
 }
 
@@ -1307,14 +1315,14 @@
 {
 	struct dquot *dquot;
 
-	down_read(&sb_dqopt(sb)->dqoff_sem);
+	down_read(&sb_dqopt(sb)->dqptr_sem);
 	if (!(dquot = dqget(sb, id, type))) {
-		up_read(&sb_dqopt(sb)->dqoff_sem);
+		up_read(&sb_dqopt(sb)->dqptr_sem);
 		return -ESRCH;
 	}
 	do_set_dqblk(dquot, di);
 	dqput(dquot);
-	up_read(&sb_dqopt(sb)->dqoff_sem);
+	up_read(&sb_dqopt(sb)->dqptr_sem);
 	return 0;
 }
 
@@ -1323,9 +1331,9 @@
 {
 	struct mem_dqinfo *mi;
   
-	down_read(&sb_dqopt(sb)->dqoff_sem);
+	down_read(&sb_dqopt(sb)->dqptr_sem);
 	if (!sb_has_quota_enabled(sb, type)) {
-		up_read(&sb_dqopt(sb)->dqoff_sem);
+		up_read(&sb_dqopt(sb)->dqptr_sem);
 		return -ESRCH;
 	}
 	mi = sb_dqopt(sb)->info + type;
@@ -1335,7 +1343,7 @@
 	ii->dqi_flags = mi->dqi_flags & DQF_MASK;
 	ii->dqi_valid = IIF_ALL;
 	spin_unlock(&dq_data_lock);
-	up_read(&sb_dqopt(sb)->dqoff_sem);
+	up_read(&sb_dqopt(sb)->dqptr_sem);
 	return 0;
 }
 
@@ -1344,9 +1352,9 @@
 {
 	struct mem_dqinfo *mi;
 
-	down_read(&sb_dqopt(sb)->dqoff_sem);
+	down_read(&sb_dqopt(sb)->dqptr_sem);
 	if (!sb_has_quota_enabled(sb, type)) {
-		up_read(&sb_dqopt(sb)->dqoff_sem);
+		up_read(&sb_dqopt(sb)->dqptr_sem);
 		return -ESRCH;
 	}
 	mi = sb_dqopt(sb)->info + type;
@@ -1359,7 +1367,7 @@
 		mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
 	mark_info_dirty(mi);
 	spin_unlock(&dq_data_lock);
-	up_read(&sb_dqopt(sb)->dqoff_sem);
+	up_read(&sb_dqopt(sb)->dqptr_sem);
 	return 0;
 }
 
diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c
--- a/fs/eventpoll.c	Mon Feb 10 10:39:25 2003
+++ b/fs/eventpoll.c	Mon Feb 10 10:39:25 2003
@@ -1543,7 +1543,7 @@
 
 	/* Allocates slab cache used to allocate "struct epitem" items */
 	error = -ENOMEM;
-	epi_cache = kmem_cache_create("eventpoll epi",
+	epi_cache = kmem_cache_create("eventpoll_epi",
 				      sizeof(struct epitem),
 				      0,
 				      SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL);
@@ -1552,7 +1552,7 @@
 
 	/* Allocates slab cache used to allocate "struct eppoll_entry" */
 	error = -ENOMEM;
-	pwq_cache = kmem_cache_create("eventpoll pwq",
+	pwq_cache = kmem_cache_create("eventpoll_pwq",
 				      sizeof(struct eppoll_entry),
 				      0,
 				      EPI_SLAB_DEBUG, NULL, NULL);
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Mon Feb 10 10:39:25 2003
+++ b/fs/exec.c	Mon Feb 10 10:39:25 2003
@@ -300,6 +300,8 @@
 
 	pgd = pgd_offset(tsk->mm, address);
 	pte_chain = pte_chain_alloc(GFP_KERNEL);
+	if (!pte_chain)
+		goto out_sig;
 	spin_lock(&tsk->mm->page_table_lock);
 	pmd = pmd_alloc(tsk->mm, pgd, address);
 	if (!pmd)
@@ -325,6 +327,7 @@
 	return;
 out:
 	spin_unlock(&tsk->mm->page_table_lock);
+out_sig:
 	__free_page(page);
 	force_sig(SIGKILL, tsk);
 	pte_chain_free(pte_chain);
@@ -556,35 +559,70 @@
  * disturbing other processes.  (Other processes might share the signal
  * table via the CLONE_SIGHAND option to clone().)
  */
-static inline int de_thread(struct signal_struct *oldsig)
+static inline int de_thread(struct task_struct *tsk)
 {
-	struct signal_struct *newsig;
+	struct signal_struct *newsig, *oldsig = tsk->signal;
+	struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
+	spinlock_t *lock = &oldsighand->siglock;
 	int count;
 
-	if (atomic_read(&current->sig->count) <= 1)
+	/*
+	 * If we don't share sighandlers, then we aren't sharing anything
+	 * and we can just re-use it all.
+	 */
+	if (atomic_read(&oldsighand->count) <= 1)
 		return 0;
 
-	newsig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL);
-	if (!newsig)
+	newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
+	if (!newsighand)
 		return -ENOMEM;
 
+	spin_lock_init(&newsighand->siglock);
+	atomic_set(&newsighand->count, 1);
+	memcpy(newsighand->action, oldsighand->action, sizeof(newsighand->action));
+
+	/*
+	 * See if we need to allocate a new signal structure
+	 */
+	newsig = NULL;
+	if (atomic_read(&oldsig->count) > 1) {
+		newsig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
+		if (!newsig) {
+			kmem_cache_free(sighand_cachep, newsighand);
+			return -ENOMEM;
+		}
+		atomic_set(&newsig->count, 1);
+		newsig->group_exit = 0;
+		newsig->group_exit_code = 0;
+		newsig->group_exit_task = NULL;
+		newsig->group_stop_count = 0;
+		init_sigpending(&newsig->shared_pending);
+	}
+
 	if (thread_group_empty(current))
-		goto out;
+		goto no_thread_group;
+
 	/*
-	 * Kill all other threads in the thread group:
+	 * Kill all other threads in the thread group.
+	 * We must hold tasklist_lock to call zap_other_threads.
 	 */
-	spin_lock_irq(&oldsig->siglock);
+	read_lock(&tasklist_lock);
+	spin_lock_irq(lock);
 	if (oldsig->group_exit) {
 		/*
 		 * Another group action in progress, just
 		 * return so that the signal is processed.
 		 */
-		spin_unlock_irq(&oldsig->siglock);
-		kmem_cache_free(sigact_cachep, newsig);
+		spin_unlock_irq(lock);
+		read_unlock(&tasklist_lock);
+		kmem_cache_free(sighand_cachep, newsighand);
+		if (newsig)
+			kmem_cache_free(signal_cachep, newsig);
 		return -EAGAIN;
 	}
 	oldsig->group_exit = 1;
-	__broadcast_thread_group(current, SIGKILL);
+	zap_other_threads(current);
+	read_unlock(&tasklist_lock);
 
 	/*
 	 * Account for the thread group leader hanging around:
@@ -595,13 +633,13 @@
 	while (atomic_read(&oldsig->count) > count) {
 		oldsig->group_exit_task = current;
 		current->state = TASK_UNINTERRUPTIBLE;
-		spin_unlock_irq(&oldsig->siglock);
+		spin_unlock_irq(lock);
 		schedule();
-		spin_lock_irq(&oldsig->siglock);
+		spin_lock_irq(lock);
 		if (oldsig->group_exit_task)
 			BUG();
 	}
-	spin_unlock_irq(&oldsig->siglock);
+	spin_unlock_irq(lock);
 
 	/*
 	 * At this point all other threads have exited, all we have to
@@ -656,7 +694,8 @@
 			current->ptrace = ptrace;
 			__ptrace_link(current, parent);
 		}
-		
+
+		list_del(&current->tasks);
 		list_add_tail(&current->tasks, &init_task.tasks);
 		current->exit_signal = SIGCHLD;
 		state = leader->state;
@@ -671,31 +710,29 @@
 		release_task(leader);
         }
 
-out:
-	spin_lock_init(&newsig->siglock);
-	atomic_set(&newsig->count, 1);
-	newsig->group_exit = 0;
-	newsig->group_exit_code = 0;
-	newsig->group_exit_task = NULL;
-	memcpy(newsig->action, current->sig->action, sizeof(newsig->action));
-	init_sigpending(&newsig->shared_pending);
+no_thread_group:
 
 	write_lock_irq(&tasklist_lock);
-	spin_lock(&oldsig->siglock);
-	spin_lock(&newsig->siglock);
+	spin_lock(&oldsighand->siglock);
+	spin_lock(&newsighand->siglock);
 
 	if (current == oldsig->curr_target)
 		oldsig->curr_target = next_thread(current);
-	current->sig = newsig;
+	if (newsig)
+		current->signal = newsig;
+	current->sighand = newsighand;
 	init_sigpending(&current->pending);
 	recalc_sigpending();
 
-	spin_unlock(&newsig->siglock);
-	spin_unlock(&oldsig->siglock);
+	spin_unlock(&newsighand->siglock);
+	spin_unlock(&oldsighand->siglock);
 	write_unlock_irq(&tasklist_lock);
 
-	if (atomic_dec_and_test(&oldsig->count))
-		kmem_cache_free(sigact_cachep, oldsig);
+	if (newsig && atomic_dec_and_test(&oldsig->count))
+		kmem_cache_free(signal_cachep, oldsig);
+
+	if (atomic_dec_and_test(&oldsighand->count))
+		kmem_cache_free(sighand_cachep, oldsighand);
 
 	if (!thread_group_empty(current))
 		BUG();
@@ -741,21 +778,20 @@
 {
 	char * name;
 	int i, ch, retval;
-	struct signal_struct * oldsig = current->sig;
 
 	/* 
 	 * Release all of the old mmap stuff
 	 */
 	retval = exec_mmap(bprm->mm);
 	if (retval)
-		goto mmap_failed;
+		goto out;
 	/*
 	 * Make sure we have a private signal table and that
 	 * we are unassociated from the previous thread group.
 	 */
-	retval = de_thread(oldsig);
+	retval = de_thread(current);
 	if (retval)
-		goto flush_failed;
+		goto out;
 
 	/* This is the point of no return */
 
@@ -789,14 +825,7 @@
 
 	return 0;
 
-mmap_failed:
-flush_failed:
-	spin_lock_irq(&current->sig->siglock);
-	if (current->sig != oldsig) {
-		kmem_cache_free(sigact_cachep, current->sig);
-		current->sig = oldsig;
-	}
-	spin_unlock_irq(&current->sig->siglock);
+out:
 	return retval;
 }
 
@@ -873,29 +902,25 @@
 
 void compute_creds(struct linux_binprm *bprm) 
 {
-	int do_unlock = 0;
-
+	task_lock(current);
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
                 current->mm->dumpable = 0;
 		
-		lock_kernel();
 		if (must_not_trace_exec(current)
 		    || atomic_read(&current->fs->count) > 1
 		    || atomic_read(&current->files->count) > 1
-		    || atomic_read(&current->sig->count) > 1) {
+		    || atomic_read(&current->sighand->count) > 1) {
 			if(!capable(CAP_SETUID)) {
 				bprm->e_uid = current->uid;
 				bprm->e_gid = current->gid;
 			}
 		}
-		do_unlock = 1;
 	}
 
         current->suid = current->euid = current->fsuid = bprm->e_uid;
         current->sgid = current->egid = current->fsgid = bprm->e_gid;
 
-	if(do_unlock)
-		unlock_kernel();
+	task_unlock(current);
 
 	security_bprm_compute_creds(bprm);
 }
@@ -1166,7 +1191,7 @@
 			case 'p':
 				pid_in_pattern = 1;
 				rc = snprintf(out_ptr, out_end - out_ptr,
-					      "%d", current->pid);
+					      "%d", current->tgid);
 				if (rc > out_end - out_ptr)
 					goto out;
 				out_ptr += rc;
@@ -1238,7 +1263,7 @@
 	if (!pid_in_pattern
             && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
 		rc = snprintf(out_ptr, out_end - out_ptr,
-			      ".%d", current->pid);
+			      ".%d", current->tgid);
 		if (rc > out_end - out_ptr)
 			goto out;
 		out_ptr += rc;
@@ -1301,8 +1326,8 @@
 	}
 	mm->dumpable = 0;
 	init_completion(&mm->core_done);
-	current->sig->group_exit = 1;
-	current->sig->group_exit_code = exit_code;
+	current->signal->group_exit = 1;
+	current->signal->group_exit_code = exit_code;
 	coredump_wait(mm);
 
 	if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
@@ -1329,7 +1354,7 @@
 
 	retval = binfmt->core_dump(signr, regs, file);
 
-	current->sig->group_exit_code |= 0x80;
+	current->signal->group_exit_code |= 0x80;
 close_fail:
 	filp_close(file, NULL);
 fail_unlock:
diff -Nru a/fs/exportfs/Makefile b/fs/exportfs/Makefile
--- a/fs/exportfs/Makefile	Mon Feb 10 10:39:24 2003
+++ b/fs/exportfs/Makefile	Mon Feb 10 10:39:24 2003
@@ -1,8 +1,6 @@
 #
 # Makefile for the filesystem export support routines.
 
-export-objs := expfs.o
-
 obj-$(CONFIG_EXPORTFS) += exportfs.o
 
 exportfs-objs := expfs.o
diff -Nru a/fs/ext2/Makefile b/fs/ext2/Makefile
--- a/fs/ext2/Makefile	Mon Feb 10 10:39:30 2003
+++ b/fs/ext2/Makefile	Mon Feb 10 10:39:30 2003
@@ -7,8 +7,6 @@
 ext2-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 	     ioctl.o namei.o super.o symlink.o
 
-export-objs += xattr.o
-
 ifeq ($(CONFIG_EXT2_FS_XATTR),y)
 ext2-objs += xattr.o xattr_user.o
 endif
diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c
--- a/fs/ext2/balloc.c	Mon Feb 10 10:39:25 2003
+++ b/fs/ext2/balloc.c	Mon Feb 10 10:39:25 2003
@@ -334,22 +334,23 @@
 	if (!prealloc_count || *prealloc_count)
 		prealloc_goal = 0;
 
-	*err = -EDQUOT;
-	if (DQUOT_ALLOC_BLOCK(inode, 1))
+	if (DQUOT_ALLOC_BLOCK(inode, 1)) {
+		*err = -EDQUOT;
 		goto out;
+	}
 
 	while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal))
 		prealloc_goal--;
 
 	dq_alloc = prealloc_goal + 1;
 
-	*err = -ENOSPC;
-
 	lock_super (sb);
 
 	es_alloc = reserve_blocks(sb, dq_alloc);
-	if (!es_alloc)
+	if (!es_alloc) {
+		*err = -ENOSPC;
 		goto out_unlock;
+	}
 
 	ext2_debug ("goal=%lu.\n", goal);
 
@@ -396,8 +397,10 @@
 			goto io_error;
 		group_alloc = group_reserve_blocks(desc, gdp_bh, es_alloc);
 	}
-	if (bit >= sbi->s_groups_count)
+	if (bit >= sbi->s_groups_count) {
+		*err = -ENOSPC;
 		goto out_release;
+	}
 	brelse(bitmap_bh);
 	bitmap_bh = read_block_bitmap(sb, group_no);
 	if (!bitmap_bh)
@@ -409,7 +412,7 @@
 			"Free blocks count corrupted for block group %d",
 				group_no);
 		group_alloc = 0;
-		goto out_release;
+		goto io_error;
 	}
 
 got_block:
@@ -432,7 +435,7 @@
 			    "block(%d) >= blocks count(%d) - "
 			    "block_group = %d, es == %p ", ret_block,
 			le32_to_cpu(es->s_blocks_count), group_no, es);
-		goto out_release;
+		goto io_error;
 	}
 	block = target_block;
 
@@ -470,10 +473,10 @@
 
 	ext2_debug ("allocating block %d. ", block);
 
+	*err = 0;
 out_release:
 	group_release_blocks(desc, gdp_bh, group_alloc);
 	release_blocks(sb, es_alloc);
-	*err = 0;
 out_unlock:
 	unlock_super (sb);
 	DQUOT_FREE_BLOCK(inode, dq_alloc);
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c	Mon Feb 10 10:39:23 2003
+++ b/fs/ext2/inode.c	Mon Feb 10 10:39:23 2003
@@ -1239,6 +1239,12 @@
 	error = inode_change_ok(inode, iattr);
 	if (error)
 		return error;
+	if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
+	    (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
+		error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
+		if (error)
+			return error;
+	}
 	inode_setattr(inode, iattr);
 	if (iattr->ia_valid & ATTR_MODE)
 		error = ext2_acl_chmod(inode);
diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c	Mon Feb 10 10:39:29 2003
+++ b/fs/ext2/super.c	Mon Feb 10 10:39:29 2003
@@ -673,7 +673,7 @@
 		if(!bh) {
 			printk("EXT2-fs: Couldn't read superblock on "
 			       "2nd try.\n");
-			goto failed_mount;
+			goto failed_sbi;
 		}
 		es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 		sbi->s_es = es;
diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile
--- a/fs/ext3/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/ext3/Makefile	Mon Feb 10 10:39:23 2003
@@ -7,8 +7,6 @@
 ext3-objs    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
 		ioctl.o namei.o super.o symlink.o hash.o
 
-export-objs += xattr.o
-
 ifeq ($(CONFIG_EXT3_FS_XATTR),y)
 ext3-objs += xattr.o xattr_user.o
 endif
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Mon Feb 10 10:39:29 2003
+++ b/fs/ext3/inode.c	Mon Feb 10 10:39:29 2003
@@ -99,6 +99,34 @@
 	return err;
 }
 
+/*
+ * Work out how many blocks we need to progress with the next chunk of a
+ * truncate transaction.
+ */
+
+static unsigned long blocks_for_truncate(struct inode *inode) 
+{
+	unsigned long needed;
+	
+	needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
+
+	/* Give ourselves just enough room to cope with inodes in which
+	 * i_blocks is corrupt: we've seen disk corruptions in the past
+	 * which resulted in random data in an inode which looked enough
+	 * like a regular file for ext3 to try to delete it.  Things
+	 * will go a bit crazy if that happens, but at least we should
+	 * try not to panic the whole kernel. */
+	if (needed < 2)
+		needed = 2;
+
+	/* But we need to bound the transaction so we don't overflow the
+	 * journal. */
+	if (needed > EXT3_MAX_TRANS_DATA) 
+		needed = EXT3_MAX_TRANS_DATA;
+
+	return EXT3_DATA_TRANS_BLOCKS + needed;
+}
+	
 /* 
  * Truncate transactions can be complex and absolutely huge.  So we need to
  * be able to restart the transaction at a conventient checkpoint to make
@@ -112,14 +140,9 @@
 
 static handle_t *start_transaction(struct inode *inode) 
 {
-	long needed;
 	handle_t *result;
 	
-	needed = inode->i_blocks;
-	if (needed > EXT3_MAX_TRANS_DATA) 
-		needed = EXT3_MAX_TRANS_DATA;
-	
-	result = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS + needed);
+	result = ext3_journal_start(inode, blocks_for_truncate(inode));
 	if (!IS_ERR(result))
 		return result;
 	
@@ -135,14 +158,9 @@
  */
 static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
 {
-	long needed;
-	
 	if (handle->h_buffer_credits > EXT3_RESERVE_TRANS_BLOCKS)
 		return 0;
-	needed = inode->i_blocks;
-	if (needed > EXT3_MAX_TRANS_DATA) 
-		needed = EXT3_MAX_TRANS_DATA;
-	if (!ext3_journal_extend(handle, EXT3_RESERVE_TRANS_BLOCKS + needed))
+	if (!ext3_journal_extend(handle, blocks_for_truncate(inode)))
 		return 0;
 	return 1;
 }
@@ -154,11 +172,8 @@
  */
 static int ext3_journal_test_restart(handle_t *handle, struct inode *inode)
 {
-	long needed = inode->i_blocks;
-	if (needed > EXT3_MAX_TRANS_DATA) 
-		needed = EXT3_MAX_TRANS_DATA;
 	jbd_debug(2, "restarting handle %p\n", handle);
-	return ext3_journal_restart(handle, EXT3_DATA_TRANS_BLOCKS + needed);
+	return ext3_journal_restart(handle, blocks_for_truncate(inode));
 }
 
 /*
diff -Nru a/fs/fat/Makefile b/fs/fat/Makefile
--- a/fs/fat/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/fat/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux fat filesystem support.
 #
 
-export-objs := fatfs_syms.o
-
 obj-$(CONFIG_FAT_FS) += fat.o
 
 fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o
diff -Nru a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
--- a/fs/freevxfs/vxfs_fshead.c	Mon Feb 10 10:39:23 2003
+++ b/fs/freevxfs/vxfs_fshead.c	Mon Feb 10 10:39:23 2003
@@ -111,13 +111,15 @@
 	struct vxfs_fsh			*pfp, *sfp;
 	struct vxfs_inode_info		*vip, *tip;
 
-	if (!(vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino))) {
+	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
+	if (!vip) {
 		printk(KERN_ERR "vxfs: unabled to read fsh inode\n");
 		return -EINVAL;
-	} else if (!VXFS_ISFSH(vip)) {
+	}
+	if (!VXFS_ISFSH(vip)) {
 		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
 				vip->vii_mode & VXFS_TYPE_MASK); 
-		return -EINVAL;
+		goto out_free_fship;
 	}
 
 
@@ -126,23 +128,26 @@
 	vxfs_dumpi(vip, infp->vsi_fshino);
 #endif
 
-	if (!(infp->vsi_fship = vxfs_get_fake_inode(sbp, vip))) {
+	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
+	if (!infp->vsi_fship) {
 		printk(KERN_ERR "vxfs: unabled to get fsh inode\n");
-		return -EINVAL;
+		goto out_free_fship;
 	}
 
-	if (!(sfp = vxfs_getfsh(infp->vsi_fship, 0))) {
+	sfp = vxfs_getfsh(infp->vsi_fship, 0);
+	if (!sfp) {
 		printk(KERN_ERR "vxfs: unabled to get structural fsh\n");
-		return -EINVAL;
+		goto out_iput_fship;
 	} 
 
 #ifdef DIAGNOSTIC
 	vxfs_dumpfsh(sfp);
 #endif
 
-	if (!(pfp = vxfs_getfsh(infp->vsi_fship, 1))) {
+	pfp = vxfs_getfsh(infp->vsi_fship, 1);
+	if (!pfp) {
 		printk(KERN_ERR "vxfs: unabled to get primary fsh\n");
-		return -EINVAL;
+		goto out_free_sfp;
 	}
 
 #ifdef DIAGNOSTIC
@@ -150,24 +155,50 @@
 #endif
 
 	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
-	if (!tip || ((infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) {
+	if (!tip)
+		goto out_free_pfp;
+
+	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
+	if (!infp->vsi_stilist) {
 		printk(KERN_ERR "vxfs: unabled to get structual list inode\n");
-		return -EINVAL;
-	} else if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
+		kfree(tip);
+		goto out_free_pfp;
+	}
+	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
 		printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
-		return -EINVAL;
+		goto out_iput_stilist;
 	}
 
 	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
-	if (!tip || ((infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) {
+	if (!tip)
+		goto out_iput_stilist;
+	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
+	if (!infp->vsi_ilist) {
 		printk(KERN_ERR "vxfs: unabled to get inode list inode\n");
-		return -EINVAL;
-	} else if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
+		kfree(tip);
+		goto out_iput_stilist;
+	}
+	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
 		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
-		return -EINVAL;
+		goto out_iput_ilist;
 	}
 
 	return 0;
+
+ out_iput_ilist:
+ 	iput(infp->vsi_ilist);
+ out_iput_stilist:
+ 	iput(infp->vsi_stilist);
+ out_free_pfp:
+	kfree(pfp);
+ out_free_sfp:
+ 	kfree(sfp);
+ out_iput_fship:
+	iput(infp->vsi_fship);
+	return -EINVAL;
+ out_free_fship:
+ 	kfree(vip);
+	return -EINVAL;
 }
diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c	Mon Feb 10 10:39:33 2003
+++ b/fs/fs-writeback.c	Mon Feb 10 10:39:33 2003
@@ -61,12 +61,19 @@
 			sb->s_op->dirty_inode(inode);
 	}
 
+	/*
+	 * make sure that changes are seen by all cpus before we test i_state
+	 * -- mikulas
+	 */
+	smp_mb();
+
 	/* avoid the locking if we can */
 	if ((inode->i_state & flags) == flags)
 		return;
 
 	spin_lock(&inode_lock);
 	if ((inode->i_state & flags) != flags) {
+		const int was_dirty = inode->i_state & I_DIRTY;
 		struct address_space *mapping = inode->i_mapping;
 
 		inode->i_state |= flags;
@@ -90,7 +97,7 @@
 		 * If the inode was already on s_dirty or s_io, don't
 		 * reposition it (that would break s_dirty time-ordering).
 		 */
-		if (!mapping->dirtied_when) {
+		if (!was_dirty) {
 			mapping->dirtied_when = jiffies|1; /* 0 is special */
 			list_move(&inode->i_list, &sb->s_dirty);
 		}
@@ -122,12 +129,12 @@
  * Called under inode_lock.
  */
 static void
-__sync_single_inode(struct inode *inode, int wait,
-			struct writeback_control *wbc)
+__sync_single_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	unsigned dirty;
 	struct address_space *mapping = inode->i_mapping;
 	struct super_block *sb = inode->i_sb;
+	int wait = wbc->sync_mode == WB_SYNC_ALL;
 
 	BUG_ON(inode->i_state & I_LOCK);
 
@@ -136,6 +143,12 @@
 	inode->i_state |= I_LOCK;
 	inode->i_state &= ~I_DIRTY;
 
+	/*
+	 * smp_rmb(); note: if you remove write_lock below, you must add this.
+	 * mark_inode_dirty doesn't take spinlock, make sure that inode is not
+	 * read speculatively by this cpu before &= ~I_DIRTY  -- mikulas
+	 */
+
 	write_lock(&mapping->page_lock);
 	if (wait || !wbc->for_kupdate || list_empty(&mapping->io_pages))
 		list_splice_init(&mapping->dirty_pages, &mapping->io_pages);
@@ -181,14 +194,17 @@
  * Write out an inode's dirty pages.  Called under inode_lock.
  */
 static void
-__writeback_single_inode(struct inode *inode, int sync,
+__writeback_single_inode(struct inode *inode,
 			struct writeback_control *wbc)
 {
-	if (current_is_pdflush() && (inode->i_state & I_LOCK)) {
+	if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
 		list_move(&inode->i_list, &inode->i_sb->s_dirty);
 		return;
 	}
 
+	/*
+	 * It's a data-integrity sync.  We must wait.
+	 */
 	while (inode->i_state & I_LOCK) {
 		__iget(inode);
 		spin_unlock(&inode_lock);
@@ -196,7 +212,7 @@
 		iput(inode);
 		spin_lock(&inode_lock);
 	}
-	__sync_single_inode(inode, sync, wbc);
+	__sync_single_inode(inode, wbc);
 }
 
 /*
@@ -242,7 +258,6 @@
 						struct inode, i_list);
 		struct address_space *mapping = inode->i_mapping;
 		struct backing_dev_info *bdi = mapping->backing_dev_info;
-		int really_sync;
 
 		if (bdi->memory_backed)
 			break;
@@ -275,12 +290,11 @@
 		if (current_is_pdflush() && !writeback_acquire(bdi))
 			break;
 
-		really_sync = (wbc->sync_mode == WB_SYNC_ALL);
 		BUG_ON(inode->i_state & I_FREEING);
 		__iget(inode);
-		__writeback_single_inode(inode, really_sync, wbc);
+		__writeback_single_inode(inode, wbc);
 		if (wbc->sync_mode == WB_SYNC_HOLD) {
-			mapping->dirtied_when = jiffies;
+			mapping->dirtied_when = jiffies|1;
 			list_move(&inode->i_list, &sb->s_dirty);
 		}
 		if (current_is_pdflush())
@@ -332,7 +346,6 @@
 	}
 	spin_unlock(&sb_lock);
 	spin_unlock(&inode_lock);
-	blk_run_queues();
 }
 
 /*
@@ -451,10 +464,11 @@
 {
 	struct writeback_control wbc = {
 		.nr_to_write = LONG_MAX,
+		.sync_mode = WB_SYNC_ALL,
 	};
 
 	spin_lock(&inode_lock);
-	__writeback_single_inode(inode, sync, &wbc);
+	__writeback_single_inode(inode, &wbc);
 	spin_unlock(&inode_lock);
 	if (sync)
 		wait_on_inode(inode);
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	Mon Feb 10 10:39:32 2003
+++ b/fs/hugetlbfs/inode.c	Mon Feb 10 10:39:32 2003
@@ -34,6 +34,7 @@
 static struct address_space_operations hugetlbfs_aops;
 struct file_operations hugetlbfs_file_operations;
 static struct inode_operations hugetlbfs_dir_inode_operations;
+static struct inode_operations hugetlbfs_inode_operations;
 
 static struct backing_dev_info hugetlbfs_backing_dev_info = {
 	.ra_pages	= 0,	/* No readahead */
@@ -44,7 +45,6 @@
 {
 	struct inode *inode =file->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
-	size_t len;
 	int ret;
 
 	if (!capable(CAP_IPC_LOCK))
@@ -65,15 +65,52 @@
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
-	len = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
-	if (inode->i_size < len)
-		inode->i_size = len;
-
 	up(&inode->i_sem);
 	return ret;
 }
 
 /*
+ * Called under down_write(mmap_sem), page_table_lock is not held
+ */
+
+#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags);
+#else
+static unsigned long
+hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	if (addr) {
+		addr = ALIGN(addr, HPAGE_SIZE);
+		vma = find_vma(mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vma || addr + len <= vma->vm_start))
+			return addr;
+	}
+
+	addr = ALIGN(mm->free_area_cache, HPAGE_SIZE);
+
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vma || addr + len <= vma->vm_start)
+			return addr;
+		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
+	}
+}
+#endif
+
+/*
  * Read a page. Again trivial. If it didn't already exist
  * in the page cache, it is zero-filled.
  */
@@ -83,12 +120,14 @@
 	return -EINVAL;
 }
 
-static int hugetlbfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int hugetlbfs_prepare_write(struct file *file,
+			struct page *page, unsigned offset, unsigned to)
 {
 	return -EINVAL;
 }
 
-static int hugetlbfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int hugetlbfs_commit_write(struct file *file,
+			struct page *page, unsigned offset, unsigned to)
 {
 	return -EINVAL;
 }
@@ -103,28 +142,8 @@
 	pagevec_reinit(pvec);
 }
 
-void truncate_partial_hugepage(struct page *page, unsigned partial)
+void truncate_huge_page(struct page *page)
 {
-	int i;
-	const unsigned piece = partial & (PAGE_SIZE - 1);
-	const unsigned tailstart = PAGE_SIZE - piece;
-	const unsigned whole_pages = partial / PAGE_SIZE;
-	const unsigned last_page_offset = HPAGE_SIZE/PAGE_SIZE - whole_pages;
-
-	for (i = HPAGE_SIZE/PAGE_SIZE - 1; i >= last_page_offset; ++i)
-		memclear_highpage_flush(&page[i], 0, PAGE_SIZE);
-
-	if (!piece)
-		return;
-
-	memclear_highpage_flush(&page[last_page_offset - 1], tailstart, piece);
-}
-
-void truncate_huge_page(struct address_space *mapping, struct page *page)
-{
-	if (page->mapping != mapping)
-		return;
-
 	clear_page_dirty(page);
 	ClearPageUptodate(page);
 	remove_from_page_cache(page);
@@ -133,52 +152,13 @@
 
 void truncate_hugepages(struct address_space *mapping, loff_t lstart)
 {
-	const pgoff_t start = (lstart + HPAGE_SIZE - 1) >> HPAGE_SHIFT;
-	const unsigned partial = lstart & (HPAGE_SIZE - 1);
+	const pgoff_t start = lstart >> HPAGE_SHIFT;
 	struct pagevec pvec;
 	pgoff_t next;
 	int i;
 
 	pagevec_init(&pvec, 0);
 	next = start;
-
-	while (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 > next)
-				next = page_index;
-
-			++next;
-
-			if (TestSetPageLocked(page))
-				continue;
-
-			if (PageWriteback(page)) {
-				unlock_page(page);
-				continue;
-			}
-
-			truncate_huge_page(mapping, page);
-			unlock_page(page);
-		}
-		huge_pagevec_release(&pvec);
-		cond_resched();
-	}
-
-	if (partial) {
-		struct page *page = find_lock_page(mapping, start - 1);
-		if (page) {
-			wait_on_page_writeback(page);
-			truncate_partial_hugepage(page, partial);
-			unlock_page(page);
-			huge_page_release(page);
-		}
-	}
-
-	next = start;
-
 	while (1) {
 		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
 			if (next == start)
@@ -191,11 +171,10 @@
 			struct page *page = pvec.pages[i];
 
 			lock_page(page);
-			wait_on_page_writeback(page);
 			if (page->index > next)
 				next = page->index;
 			++next;
-			truncate_huge_page(mapping, page);
+			truncate_huge_page(page);
 			unlock_page(page);
 		}
 		huge_pagevec_release(&pvec);
@@ -259,70 +238,73 @@
 		hugetlbfs_forget_inode(inode);
 }
 
-static void hugetlb_vmtruncate_list(struct list_head *list, unsigned long pgoff)
+/*
+ * h_pgoff is in HPAGE_SIZE units.
+ * vma->vm_pgoff is in PAGE_SIZE units.
+ */
+static void
+hugetlb_vmtruncate_list(struct list_head *list, unsigned long h_pgoff)
 {
-	unsigned long start, end, length, delta;
 	struct vm_area_struct *vma;
 
 	list_for_each_entry(vma, list, shared) {
-		start = vma->vm_start;
-		end = vma->vm_end;
-		length = end - start;
-
-		if (vma->vm_pgoff >= pgoff) {
-			zap_hugepage_range(vma, start, length);
+		unsigned long h_vm_pgoff;
+		unsigned long v_length;
+		unsigned long h_length;
+		unsigned long v_offset;
+
+		h_vm_pgoff = vma->vm_pgoff << (HPAGE_SHIFT - PAGE_SHIFT);
+		v_length = vma->vm_end - vma->vm_start;
+		h_length = v_length >> HPAGE_SHIFT;
+		v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT;
+
+		/*
+		 * Is this VMA fully outside the truncation point?
+		 */
+		if (h_vm_pgoff >= h_pgoff) {
+			zap_hugepage_range(vma, vma->vm_start, v_length);
 			continue;
 		}
 
-		length >>= PAGE_SHIFT;
-		delta = pgoff = vma->vm_pgoff;
-		if (delta >= length)
+		/*
+		 * Is this VMA fully inside the truncaton point?
+		 */
+		if (h_vm_pgoff + (v_length >> HPAGE_SHIFT) <= h_pgoff)
 			continue;
 
-		start += delta << PAGE_SHIFT;
-		length = (length - delta) << PAGE_SHIFT;
-		zap_hugepage_range(vma, start, length);
+		/*
+		 * The VMA straddles the truncation point.  v_offset is the
+		 * offset (in bytes) into the VMA where the point lies.
+		 */
+		zap_hugepage_range(vma,
+				vma->vm_start + v_offset,
+				v_length - v_offset);
 	}
 }
 
+/*
+ * Expanding truncates are not allowed.
+ */
 static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
 {
 	unsigned long pgoff;
 	struct address_space *mapping = inode->i_mapping;
-	unsigned long limit;
 
-	pgoff = (offset + HPAGE_SIZE - 1) >> HPAGE_SHIFT;
+	if (offset > inode->i_size)
+		return -EINVAL;
 
-	if (inode->i_size < offset)
-		goto do_expand;
+	BUG_ON(offset & ~HPAGE_MASK);
+	pgoff = offset >> HPAGE_SHIFT;
 
 	inode->i_size = offset;
 	down(&mapping->i_shared_sem);
-	if (list_empty(&mapping->i_mmap) && list_empty(&mapping->i_mmap_shared))
-		goto out_unlock;
 	if (!list_empty(&mapping->i_mmap))
 		hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
 	if (!list_empty(&mapping->i_mmap_shared))
 		hugetlb_vmtruncate_list(&mapping->i_mmap_shared, pgoff);
-
-out_unlock:
 	up(&mapping->i_shared_sem);
 	truncate_hugepages(mapping, offset);
 	return 0;
-
-do_expand:
-	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-	if (limit != RLIM_INFINITY && offset > limit)
-		goto out_sig;
-	if (offset > inode->i_sb->s_maxbytes)
-		goto out;
-	inode->i_size = offset;
-	return 0;
-
-out_sig:
-	send_sig(SIGXFSZ, current, 0);
-out:
-	return -EFBIG;
 }
 
 static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
@@ -341,15 +323,10 @@
 	error = security_inode_setattr(dentry, attr);
 	if (error)
 		goto out;
-
-	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
-		error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
-	if (error)
-		goto out;
-
 	if (ia_valid & ATTR_SIZE) {
-		error = hugetlb_vmtruncate(inode, attr->ia_size);
+		error = -EINVAL;
+		if (!(attr->ia_size & ~HPAGE_MASK))
+			error = hugetlb_vmtruncate(inode, attr->ia_size);
 		if (error)
 			goto out;
 		attr->ia_valid &= ~ATTR_SIZE;
@@ -364,8 +341,8 @@
 	return error;
 }
 
-static struct inode *
-hugetlbfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+static struct inode *hugetlbfs_get_inode(struct super_block *sb,
+					int mode, dev_t dev)
 {
 	struct inode * inode = new_inode(sb);
 
@@ -377,13 +354,14 @@
 		inode->i_blocks = 0;
 		inode->i_rdev = NODEV;
 		inode->i_mapping->a_ops = &hugetlbfs_aops;
-		inode->i_mapping->backing_dev_info = &hugetlbfs_backing_dev_info;
+		inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		switch (mode & S_IFMT) {
 		default:
 			init_special_inode(inode, mode, dev);
 			break;
 		case S_IFREG:
+			inode->i_op = &hugetlbfs_inode_operations;
 			inode->i_fop = &hugetlbfs_file_operations;
 			break;
 		case S_IFDIR:
@@ -405,8 +383,8 @@
  * File creation. Allocate an inode, and we're done..
  */
 /* SMP-safe */
-static int
-hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+static int hugetlbfs_mknod(struct inode *dir,
+			struct dentry *dentry, int mode, dev_t dev)
 {
 	struct inode * inode = hugetlbfs_get_inode(dir->i_sb, mode, dev);
 	int error = -ENOSPC;
@@ -419,7 +397,7 @@
 	return error;
 }
 
-static int hugetlbfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 {
 	int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0);
 	if (!retval)
@@ -432,7 +410,8 @@
 	return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0);
 }
 
-static int hugetlbfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+static int hugetlbfs_symlink(struct inode *dir,
+			struct dentry *dentry, const char *symname)
 {
 	struct inode *inode;
 	int error = -ENOSPC;
@@ -450,15 +429,25 @@
 	return error;
 }
 
+/*
+ * For direct-IO reads into hugetlb pages
+ */
+int hugetlbfs_set_page_dirty(struct page *page)
+{
+	return 0;
+}
+
 static struct address_space_operations hugetlbfs_aops = {
 	.readpage	= hugetlbfs_readpage,
 	.prepare_write	= hugetlbfs_prepare_write,
-	.commit_write	= hugetlbfs_commit_write
+	.commit_write	= hugetlbfs_commit_write,
+	.set_page_dirty	= hugetlbfs_set_page_dirty,
 };
 
 struct file_operations hugetlbfs_file_operations = {
-	.mmap		= hugetlbfs_file_mmap,
-	.fsync		= simple_sync_file,
+	.mmap			= hugetlbfs_file_mmap,
+	.fsync			= simple_sync_file,
+	.get_unmapped_area	= hugetlb_get_unmapped_area,
 };
 
 static struct inode_operations hugetlbfs_dir_inode_operations = {
@@ -474,12 +463,17 @@
 	.setattr	= hugetlbfs_setattr,
 };
 
+static struct inode_operations hugetlbfs_inode_operations = {
+	.setattr	= hugetlbfs_setattr,
+};
+
 static struct super_operations hugetlbfs_ops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= hugetlbfs_drop_inode,
 };
 
-static int hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
+static int
+hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
 {
 	struct inode * inode;
 	struct dentry * root;
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Mon Feb 10 10:39:33 2003
+++ b/fs/inode.c	Mon Feb 10 10:39:33 2003
@@ -16,6 +16,7 @@
 #include <linux/backing-dev.h>
 #include <linux/wait.h>
 #include <linux/hash.h>
+#include <linux/swap.h>
 #include <linux/security.h>
 
 /*
@@ -176,6 +177,7 @@
 	spin_lock_init(&inode->i_data.private_lock);
 	INIT_LIST_HEAD(&inode->i_data.i_mmap);
 	INIT_LIST_HEAD(&inode->i_data.i_mmap_shared);
+	spin_lock_init(&inode->i_lock);
 }
 
 static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
@@ -391,6 +393,7 @@
 	LIST_HEAD(freeable);
 	int nr_pruned = 0;
 	int nr_scanned;
+	unsigned long reap = 0;
 
 	spin_lock(&inode_lock);
 	for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
@@ -409,7 +412,7 @@
 			__iget(inode);
 			spin_unlock(&inode_lock);
 			if (remove_inode_buffers(inode))
-				invalidate_inode_pages(&inode->i_data);
+				reap += invalidate_inode_pages(&inode->i_data);
 			iput(inode);
 			spin_lock(&inode_lock);
 
@@ -427,6 +430,10 @@
 	inodes_stat.nr_unused -= nr_pruned;
 	spin_unlock(&inode_lock);
 	dispose_list(&freeable);
+	if (current_is_kswapd)
+		mod_page_state(kswapd_inodesteal, reap);
+	else
+		mod_page_state(pginodesteal, reap);
 }
 
 /*
diff -Nru a/fs/ioctl.c b/fs/ioctl.c
--- a/fs/ioctl.c	Mon Feb 10 10:39:24 2003
+++ b/fs/ioctl.c	Mon Feb 10 10:39:24 2003
@@ -57,7 +57,6 @@
 	filp = fget(fd);
 	if (!filp)
 		goto out;
-	error = 0;
 
 	error = security_file_ioctl(filp, cmd, arg);
 	if (error) {
diff -Nru a/fs/jbd/Makefile b/fs/jbd/Makefile
--- a/fs/jbd/Makefile	Mon Feb 10 10:39:26 2003
+++ b/fs/jbd/Makefile	Mon Feb 10 10:39:26 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux journaling routines.
 #
 
-export-objs := journal.o
-
 obj-$(CONFIG_JBD) += jbd.o
 
 jbd-objs := transaction.o commit.o recovery.o checkpoint.o revoke.o journal.o
diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c	Mon Feb 10 10:39:24 2003
+++ b/fs/jbd/journal.c	Mon Feb 10 10:39:24 2003
@@ -205,10 +205,10 @@
 
 	lock_kernel();
 	daemonize();
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	sprintf(current->comm, "kjournald");
 
@@ -732,14 +732,21 @@
  * need to set up all of the mapping information to tell the journaling
  * system where the journal blocks are.
  *
- * journal_init_dev creates a journal which maps a fixed contiguous
- * range of blocks on an arbitrary block device.
- *
- * journal_init_inode creates a journal which maps an on-disk inode as
- * the journal.  The inode must exist already, must support bmap() and
- * must have all data blocks preallocated.
  */
 
+/**
+ *  journal_t * journal_init_dev() - creates an initialises a journal structure
+ *  @bdev: Block device on which to create the journal
+ *  @fs_dev: Device which hold journalled filesystem for this journal.
+ *  @start: Block nr Start of journal.
+ *  @len:  Lenght of the journal in blocks.
+ *  @blocksize: blocksize of journalling device
+ *  @returns: a newly created journal_t *
+ *  
+ *  journal_init_dev creates a journal which maps a fixed contiguous
+ *  range of blocks on an arbitrary block device.
+ * 
+ */
 journal_t * journal_init_dev(struct block_device *bdev,
 			struct block_device *fs_dev,
 			int start, int len, int blocksize)
@@ -763,7 +770,15 @@
 
 	return journal;
 }
-
+ 
+/** 
+ *  journal_t * journal_init_inode () - creates a journal which maps to a inode.
+ *  @inode: An inode to create the journal in
+ *  
+ * journal_init_inode creates a journal which maps an on-disk inode as
+ * the journal.  The inode must exist already, must support bmap() and
+ * must have all data blocks preallocated.
+ */
 journal_t * journal_init_inode (struct inode *inode)
 {
 	struct buffer_head *bh;
@@ -852,12 +867,15 @@
 	return 0;
 }
 
-/*
+/** 
+ * int journal_create() - Initialise the new journal file
+ * @journal: Journal to create. This structure must have been initialised
+ * 
  * Given a journal_t structure which tells us which disk blocks we can
  * use, create a new journal superblock and initialise all of the
- * journal fields from scratch.  */
-
-int journal_create (journal_t *journal)
+ * journal fields from scratch.  
+ **/
+int journal_create(journal_t *journal)
 {
 	unsigned long blocknr;
 	struct buffer_head *bh;
@@ -920,11 +938,14 @@
 	return journal_reset(journal);
 }
 
-/*
+/** 
+ * void journal_update_superblock() - Update journal sb on disk.
+ * @journal: The journal to update.
+ * @wait: Set to '0' if you don't want to wait for IO completion.
+ *
  * Update a journal's dynamic superblock fields and write it to disk,
  * optionally waiting for the IO to complete.
-*/
-
+ */
 void journal_update_superblock(journal_t *journal, int wait)
 {
 	journal_superblock_t *sb = journal->j_superblock;
@@ -1040,12 +1061,14 @@
 }
 
 
-/*
+/**
+ * int journal_load() - Read journal from disk.
+ * @journal: Journal to act on.
+ * 
  * Given a journal_t structure which tells us which disk blocks contain
  * a journal, read the journal from disk to initialise the in-memory
  * structures.
  */
-
 int journal_load(journal_t *journal)
 {
 	int err;
@@ -1090,11 +1113,13 @@
 	return -EIO;
 }
 
-/*
+/**
+ * void journal_destroy() - Release a journal_t structure.
+ * @journal: Journal to act on.
+* 
  * Release a journal_t structure once it is no longer in use by the
  * journaled object.
  */
-
 void journal_destroy (journal_t *journal)
 {
 	/* Wait for the commit thread to wake up and die. */
@@ -1131,8 +1156,12 @@
 }
 
 
-/* Published API: Check whether the journal uses all of a given set of
- * features.  Return true (non-zero) if it does. */
+/**
+ *int journal_check_used_features () - Check if features specified are used.
+ * 
+ * Check whether the journal uses all of a given set of
+ * features.  Return true (non-zero) if it does. 
+ **/
 
 int journal_check_used_features (journal_t *journal, unsigned long compat,
 				 unsigned long ro, unsigned long incompat)
@@ -1154,7 +1183,10 @@
 	return 0;
 }
 
-/* Published API: Check whether the journaling code supports the use of
+/**
+ * int journal_check_available_features() - Check feature set in journalling layer
+ * 
+ * Check whether the journaling code supports the use of
  * all of a given set of features on this journal.  Return true
  * (non-zero) if it can. */
 
@@ -1183,8 +1215,13 @@
 	return 0;
 }
 
-/* Published API: Mark a given journal feature as present on the
- * superblock.  Returns true if the requested features could be set. */
+/**
+ * int journal_set_features () - Mark a given journal feature in the superblock
+ *
+ * Mark a given journal feature as present on the
+ * superblock.  Returns true if the requested features could be set. 
+ *
+ */
 
 int journal_set_features (journal_t *journal, unsigned long compat,
 			  unsigned long ro, unsigned long incompat)
@@ -1210,12 +1247,12 @@
 }
 
 
-/*
- * Published API:
+/**
+ * int journal_update_format () - Update on-disk journal structure.
+ *
  * Given an initialised but unloaded journal struct, poke about in the
  * on-disk structure to update it to the most recent supported version.
  */
-
 int journal_update_format (journal_t *journal)
 {
 	journal_superblock_t *sb;
@@ -1265,7 +1302,10 @@
 }
 
 
-/*
+/**
+ * int journal_flush () - Flush journal
+ * @journal: Journal to act on.
+ * 
  * Flush all data for a given journal to disk and empty the journal.
  * Filesystems can use this when remounting readonly to ensure that
  * recovery does not need to happen on remount.
@@ -1319,12 +1359,16 @@
 	return err;
 }
 
-/*
+/**
+ * int journal_wipe() - Wipe journal contents
+ * @journal: Journal to act on.
+ * @write: flag (see below)
+ * 
  * Wipe out all of the contents of a journal, safely.  This will produce
  * a warning if the journal contains any valid recovery information.
  * Must be called between journal_init_*() and journal_load().
  *
- * If (write) is non-zero, then we wipe out the journal on disk; otherwise
+ * If 'write' is non-zero, then we wipe out the journal on disk; otherwise
  * we merely suppress recovery.
  */
 
@@ -1373,43 +1417,11 @@
 }
 
 /*
- * journal_abort: perform a complete, immediate shutdown of the ENTIRE
- * journal (not of a single transaction).  This operation cannot be
- * undone without closing and reopening the journal.
- *
- * The journal_abort function is intended to support higher level error
- * recovery mechanisms such as the ext2/ext3 remount-readonly error
- * mode.
- *
- * Journal abort has very specific semantics.  Any existing dirty,
- * unjournaled buffers in the main filesystem will still be written to
- * disk by bdflush, but the journaling mechanism will be suspended
- * immediately and no further transaction commits will be honoured.
- *
- * Any dirty, journaled buffers will be written back to disk without
- * hitting the journal.  Atomicity cannot be guaranteed on an aborted
- * filesystem, but we _do_ attempt to leave as much data as possible
- * behind for fsck to use for cleanup.
- *
- * Any attempt to get a new transaction handle on a journal which is in
- * ABORT state will just result in an -EROFS error return.  A
- * journal_stop on an existing handle will return -EIO if we have
- * entered abort state during the update.
- *
- * Recursive transactions are not disturbed by journal abort until the
- * final journal_stop, which will receive the -EIO error.
- *
- * Finally, the journal_abort call allows the caller to supply an errno
- * which will be recored (if possible) in the journal superblock.  This
- * allows a client to record failure conditions in the middle of a
- * transaction without having to complete the transaction to record the
- * failure to disk.  ext3_error, for example, now uses this
- * functionality.
+ * Journal abort has very specific semantics, which we describe
+ * for journal abort. 
  *
- * Errors which originate from within the journaling layer will NOT
- * supply an errno; a null errno implies that absolutely no further
- * writes are done to the journal (unless there are any already in
- * progress).
+ * Two internal function, which provide abort to te jbd layer
+ * itself are here.
  */
 
 /* Quick version for internal journal use (doesn't lock the journal).
@@ -1447,7 +1459,52 @@
 		journal_update_superblock(journal, 1);
 }
 
-/* Full version for external use */
+/**
+ * void journal_abort () - Shutdown the journal immediately.
+ * @journal: the journal to shutdown.
+ * @errno:   an error number to record in the journal indicating
+ *           the reason for the shutdown.
+ *
+ * Perform a complete, immediate shutdown of the ENTIRE
+ * journal (not of a single transaction).  This operation cannot be
+ * undone without closing and reopening the journal.
+ *           
+ * The journal_abort function is intended to support higher level error
+ * recovery mechanisms such as the ext2/ext3 remount-readonly error
+ * mode.
+ *
+ * Journal abort has very specific semantics.  Any existing dirty,
+ * unjournaled buffers in the main filesystem will still be written to
+ * disk by bdflush, but the journaling mechanism will be suspended
+ * immediately and no further transaction commits will be honoured.
+ *
+ * Any dirty, journaled buffers will be written back to disk without
+ * hitting the journal.  Atomicity cannot be guaranteed on an aborted
+ * filesystem, but we _do_ attempt to leave as much data as possible
+ * behind for fsck to use for cleanup.
+ *
+ * Any attempt to get a new transaction handle on a journal which is in
+ * ABORT state will just result in an -EROFS error return.  A
+ * journal_stop on an existing handle will return -EIO if we have
+ * entered abort state during the update.
+ *
+ * Recursive transactions are not disturbed by journal abort until the
+ * final journal_stop, which will receive the -EIO error.
+ *
+ * Finally, the journal_abort call allows the caller to supply an errno
+ * which will be recorded (if possible) in the journal superblock.  This
+ * allows a client to record failure conditions in the middle of a
+ * transaction without having to complete the transaction to record the
+ * failure to disk.  ext3_error, for example, now uses this
+ * functionality.
+ *
+ * Errors which originate from within the journaling layer will NOT
+ * supply an errno; a null errno implies that absolutely no further
+ * writes are done to the journal (unless there are any already in
+ * progress).
+ * 
+ */
+
 void journal_abort (journal_t *journal, int errno)
 {
 	lock_journal(journal);
@@ -1455,6 +1512,17 @@
 	unlock_journal(journal);
 }
 
+/** 
+ * int journal_errno () - returns the journal's error state.
+ * @journal: journal to examine.
+ *
+ * This is the errno numbet set with journal_abort(), the last
+ * time the journal was mounted - if the journal was stopped
+ * without calling abort this will be 0.
+ *
+ * If the journal has been aborted on this mount time -EROFS will
+ * be returned.
+ */
 int journal_errno (journal_t *journal)
 {
 	int err;
@@ -1468,6 +1536,14 @@
 	return err;
 }
 
+
+
+/** 
+ * int journal_clear_err () - clears the journal's error state
+ *
+ * An error must be cleared or Acked to take a FS out of readonly
+ * mode.
+ */
 int journal_clear_err (journal_t *journal)
 {
 	int err = 0;
@@ -1481,6 +1557,13 @@
 	return err;
 }
 
+
+/** 
+ * void journal_ack_err() - Ack journal err.
+ *
+ * An error must be cleared or Acked to take a FS out of readonly
+ * mode.
+ */
 void journal_ack_err (journal_t *journal)
 {
 	lock_journal(journal);
diff -Nru a/fs/jbd/recovery.c b/fs/jbd/recovery.c
--- a/fs/jbd/recovery.c	Mon Feb 10 10:39:30 2003
+++ b/fs/jbd/recovery.c	Mon Feb 10 10:39:30 2003
@@ -206,20 +206,22 @@
 		var -= ((journal)->j_last - (journal)->j_first);	\
 } while (0)
 
-/*
- * journal_recover
- *
+/**
+ * int journal_recover(journal_t *journal) - recovers a on-disk journal
+ * @journal: the journal to recover
+ * 
  * The primary function for recovering the log contents when mounting a
  * journaled device.  
- * 
+ */
+int journal_recover(journal_t *journal)
+{
+/*
  * Recovery is done in three passes.  In the first pass, we look for the
  * end of the log.  In the second, we assemble the list of revoke
  * blocks.  In the third and final pass, we replay any un-revoked blocks
  * in the log.  
  */
 
-int journal_recover(journal_t *journal)
-{
 	int			err;
 	journal_superblock_t *	sb;
 
@@ -263,20 +265,23 @@
 	return err;
 }
 
-/*
- * journal_skip_recovery
- *
+/**
+ * int journal_skip_recovery() - Start journal and wipe exiting records 
+ * @journal: journal to startup
+ * 
  * Locate any valid recovery information from the journal and set up the
  * journal structures in memory to ignore it (presumably because the
  * caller has evidence that it is out of date).  
- *
+ * This function does'nt appear to be exorted..
+ */
+int journal_skip_recovery(journal_t *journal)
+{
+/*
  * We perform one pass over the journal to allow us to tell the user how
  * much recovery information is being erased, and to let us initialise
  * the journal transaction sequence numbers to the next unused ID. 
  */
 
-int journal_skip_recovery(journal_t *journal)
-{
 	int			err;
 	journal_superblock_t *	sb;
 
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Mon Feb 10 10:39:24 2003
+++ b/fs/jbd/transaction.c	Mon Feb 10 10:39:24 2003
@@ -222,19 +222,20 @@
 	return handle;
 }
 
-/*
- * Obtain a new handle.  
+/**
+ * handle_t *journal_start() - Obtain a new handle.  
+ * @journal: Journal to start transaction on.
+ * @nblocks: number of block buffer we might modify
  *
  * We make sure that the transaction can guarantee at least nblocks of
  * modified buffers in the log.  We block until the log can guarantee
  * that much space.  
  *
- * This function is visible to journal users (like ext2fs), so is not
+ * This function is visible to journal users (like ext3fs), so is not
  * called with the journal already locked.
  *
  * Return a pointer to a newly allocated handle, or NULL on failure
  */
-
 handle_t *journal_start(journal_t *journal, int nblocks)
 {
 	handle_t *handle = journal_current_handle();
@@ -324,7 +325,11 @@
 	return ret;
 }
 
-/*
+/**
+ * handle_t *journal_try_start() - Don't block, but try and get a handle
+ * @journal: Journal to start transaction on.
+ * @nblocks: number of block buffer we might modify
+ * 
  * Try to start a handle, but non-blockingly.  If we weren't able
  * to, return an ERR_PTR value.
  */
@@ -368,16 +373,18 @@
 	return handle;
 }
 
-/*
- * journal_extend: extend buffer credits.
- *
+/**
+ * int journal_extend() - extend buffer credits.
+ * @handle:  handle to 'extend'
+ * @nblocks: nr blocks to try to extend by.
+ * 
  * Some transactions, such as large extends and truncates, can be done
  * atomically all at once or in several stages.  The operation requests
  * a credit for a number of buffer modications in advance, but can
  * extend its credit if it needs more.  
  *
  * journal_extend tries to give the running handle more buffer credits.
- * It does not guarantee that allocation: this is a best-effort only.
+ * It does not guarantee that allocation - this is a best-effort only.
  * The calling process MUST be able to deal cleanly with a failure to
  * extend here.
  *
@@ -386,7 +393,6 @@
  * return code < 0 implies an error
  * return code > 0 implies normal transaction-full status.
  */
-
 int journal_extend (handle_t *handle, int nblocks)
 {
 	transaction_t *transaction = handle->h_transaction;
@@ -435,8 +441,12 @@
 }
 
 
-/*
- * journal_restart: restart a handle for a multi-transaction filesystem
+/**
+ * int journal_restart() - restart a handle .
+ * @handle:  handle to restart
+ * @nblocks: nr credits requested
+ * 
+ * Restart a handle for a multi-transaction filesystem
  * operation.
  *
  * If the journal_extend() call above fails to grant new buffer credits
@@ -478,8 +488,9 @@
 }
 
 
-/* 
- * Barrier operation: establish a transaction barrier. 
+/**
+ * void journal_lock_updates () - establish a transaction barrier.
+ * @journal:  Journal to establish a barrier on.
  *
  * This locks out any further updates from being started, and blocks
  * until all existing updates have completed, returning only once the
@@ -487,7 +498,6 @@
  *
  * The journal lock should not be held on entry.
  */
-
 void journal_lock_updates (journal_t *journal)
 {
 	lock_journal(journal);
@@ -515,12 +525,14 @@
 	down(&journal->j_barrier);
 }
 
-/*
+/**
+ * void journal_unlock_updates (journal_t* journal) - release barrier
+ * @journal:  Journal to release the barrier on.
+ * 
  * Release a transaction barrier obtained with journal_lock_updates().
  *
  * Should be called without the journal lock held.
  */
-
 void journal_unlock_updates (journal_t *journal)
 {
 	lock_journal(journal);
@@ -566,9 +578,6 @@
 }
 
 /*
- * journal_get_write_access: notify intent to modify a buffer for metadata
- * (not data) update.
- *
  * If the buffer is already part of the current transaction, then there
  * is nothing we need to do.  If it is already part of a prior
  * transaction which we are still committing to disk, then we need to
@@ -577,7 +586,6 @@
  * the handle's metadata buffer credits (unless the buffer is already
  * part of the transaction, that is).
  *
- * Returns an error code or 0 on success.
  */
 
 static int
@@ -689,11 +697,14 @@
 		 * disk then we cannot do copy-out here. */
 
 		if (jh->b_jlist == BJ_Shadow) {
+			wait_queue_head_t *wqh;
+
 			JBUFFER_TRACE(jh, "on shadow: sleep");
 			spin_unlock(&journal_datalist_lock);
 			unlock_journal(journal);
 			/* commit wakes up all shadow buffers after IO */
-			sleep_on_buffer(jh2bh(jh));
+			wqh = bh_waitq_head(jh2bh(jh));
+			wait_event(*wqh, (jh->b_jlist != BJ_Shadow));
 			lock_journal(journal);
 			goto repeat;
 		}
@@ -783,6 +794,17 @@
 	return error;
 }
 
+/**
+ * int journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update.
+ * @handle: transaction to add buffer modifications to
+ * @bh:     bh to be used for metadata writes
+ *
+ * Returns an error code or 0 on success.
+ *
+ * In full data journalling mode the buffer may be of type BJ_AsyncData,
+ * because we're write()ing a buffer which is also part of a shared mapping.
+ */
+
 int journal_get_write_access (handle_t *handle, struct buffer_head *bh) 
 {
 	transaction_t *transaction = handle->h_transaction;
@@ -813,6 +835,13 @@
  * There is no lock ranking violation: it was a newly created,
  * unlocked buffer beforehand. */
 
+/**
+ * int journal_get_create_access () - notify intent to use newly created bh
+ * @handle: transaction to new buffer to
+ * @bh: new buffer.
+ *
+ * Call this if you create a new bh.
+ */
 int journal_get_create_access (handle_t *handle, struct buffer_head *bh) 
 {
 	transaction_t *transaction = handle->h_transaction;
@@ -872,13 +901,14 @@
 
 
 
-/*
- * journal_get_undo_access: Notify intent to modify metadata with non-
- * rewindable consequences
- *
+/**
+ * int journal_get_undo_access() -  Notify intent to modify metadata with non-rewindable consequences
+ * @handle: transaction
+ * @bh: buffer to undo
+ * 
  * Sometimes there is a need to distinguish between metadata which has
  * been committed to disk and that which has not.  The ext3fs code uses
- * this for freeing and allocating space: we have to make sure that we
+ * this for freeing and allocating space, we have to make sure that we
  * do not reuse freed space until the deallocation has been committed,
  * since if we overwrote that space we would make the delete
  * un-rewindable in case of a crash.
@@ -890,13 +920,12 @@
  * as we know that the buffer has definitely been committed to disk.
  * 
  * We never need to know which transaction the committed data is part
- * of: buffers touched here are guaranteed to be dirtied later and so
+ * of, buffers touched here are guaranteed to be dirtied later and so
  * will be committed to a new transaction in due course, at which point
  * we can discard the old committed data pointer.
  *
  * Returns error number or 0 on success.  
  */
-
 int journal_get_undo_access (handle_t *handle, struct buffer_head *bh)
 {
 	journal_t *journal = handle->h_transaction->t_journal;
@@ -939,21 +968,23 @@
 	return err;
 }
 
-/* 
- * journal_dirty_data: mark a buffer as containing dirty data which
- * needs to be flushed before we can commit the current transaction.  
- *
+/** 
+ * int journal_dirty_data() -  mark a buffer as containing dirty data which needs to be flushed before we can commit the current transaction.  
+ * @handle: transaction
+ * @bh: bufferhead to mark
+ * 
  * The buffer is placed on the transaction's data list and is marked as
  * belonging to the transaction.
  *
  * Returns error number or 0 on success.  
- *
+ */
+int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
+{
+/*
  * journal_dirty_data() can be called via page_launder->ext3_writepage
  * by kswapd.  So it cannot block.  Happily, there's nothing here
  * which needs lock_journal if `async' is set.
  */
-int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
-{
 	journal_t *journal = handle->h_transaction->t_journal;
 	int need_brelse = 0;
 	struct journal_head *jh;
@@ -1094,24 +1125,28 @@
 	return 0;
 }
 
-/* 
- * journal_dirty_metadata: mark a buffer as containing dirty metadata
- * which needs to be journaled as part of the current transaction.
+/** 
+ * int journal_dirty_metadata() -  mark a buffer as containing dirty metadata
+ * @handle: transaction to add buffer to.
+ * @bh: buffer to mark 
+ * 
+ * mark dirty metadata which needs to be journaled as part of the current transaction.
  *
  * The buffer is placed on the transaction's metadata list and is marked
  * as belonging to the transaction.  
  *
+ * Returns error number or 0 on success.  
+ */
+int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
+{
+/*
  * Special care needs to be taken if the buffer already belongs to the
  * current committing transaction (in which case we should have frozen
  * data present for that commit).  In that case, we don't relink the
  * buffer: that only gets done when the old transaction finally
  * completes its commit.
  * 
- * Returns error number or 0 on success.  
  */
-
-int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
-{
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	struct journal_head *jh = bh2jh(bh);
@@ -1196,9 +1231,12 @@
 }
 #endif
 
-/* 
- * journal_forget: bforget() for potentially-journaled buffers.  We can
- * only do the bforget if there are no commits pending against the
+/** 
+ * void journal_forget() - bforget() for potentially-journaled buffers.
+ * @handle: transaction handle
+ * @bh:     bh to 'forget'
+ *
+ * We can only do the bforget if there are no commits pending against the
  * buffer.  If the buffer is dirty in the current running transaction we
  * can safely unlink it. 
  *
@@ -1210,7 +1248,6 @@
  * Allow this call even if the handle has aborted --- it may be part of
  * the caller's cleanup after an abort.
  */
-
 void journal_forget (handle_t *handle, struct buffer_head *bh)
 {
 	transaction_t *transaction = handle->h_transaction;
@@ -1349,8 +1386,14 @@
 }
 #endif
 
-/*
- * Register a callback function for this handle.  The function will be
+/**
+ * void journal_callback_set() -  Register a callback function for this handle.
+ * @handle: handle to attach the callback to.
+ * @func: function to callback.
+ * @jcb:  structure with additional information required by func() , and
+ *        some space for jbd internal information.
+ * 
+ * The function will be
  * called when the transaction that this handle is part of has been
  * committed to disk with the original callback data struct and the
  * error status of the journal as parameters.  There is no guarantee of
@@ -1371,7 +1414,11 @@
 	jcb->jcb_func = func;
 }
 
-/*
+
+/**
+ * int journal_stop() - complete a transaction
+ * @handle: tranaction to complete.
+ * 
  * All done for a particular handle.
  *
  * There is not much action needed here.  We just return any remaining
@@ -1384,7 +1431,6 @@
  * return -EIO if a journal_abort has been executed since the
  * transaction began.
  */
-
 int journal_stop(handle_t *handle)
 {
 	transaction_t *transaction = handle->h_transaction;
@@ -1470,8 +1516,10 @@
 	return err;
 }
 
-/*
- * For synchronous operations: force any uncommitted trasnactions
+/**int journal_force_commit() - force any uncommitted transactions
+ * @journal: journal to force
+ *
+ * For synchronous operations: force any uncommitted transactions
  * to disk.  May seem kludgy, but it reuses all the handle batching
  * code in a very simple manner.
  */
@@ -1664,6 +1712,26 @@
 	return 0;
 }
 
+
+/** 
+ * int journal_try_to_free_buffers() - try to free page buffers.
+ * @journal: journal for operation
+ * @page: to try and free
+ * @gfp_mask: 'IO' mode for try_to_free_buffers()
+ *
+ * 
+ * For all the buffers on this page,
+ * if they are fully written out ordered data, move them onto BUF_CLEAN
+ * so try_to_free_buffers() can reap them.
+ * 
+ * This function returns non-zero if we wish try_to_free_buffers()
+ * to be called. We do this if the page is releasable by try_to_free_buffers().
+ * We also do it if the page has locked or dirty buffers and the caller wants
+ * us to perform sync or async writeout.
+ */
+int journal_try_to_free_buffers(journal_t *journal, 
+				struct page *page, int unused_gfp_mask)
+{
 /*
  * journal_try_to_free_buffers().  Try to remove all this page's buffers
  * from the journal.
@@ -1686,9 +1754,6 @@
  * cannot happen because we never reallocate freed data as metadata
  * while the data is part of a transaction.  Yes?
  */
-int journal_try_to_free_buffers(journal_t *journal, 
-				struct page *page, int unused_gfp_mask)
-{
 	struct buffer_head *head;
 	struct buffer_head *bh;
 	int ret = 0;
@@ -1883,8 +1948,15 @@
 	return may_free;
 }
 
-/*
- * Return non-zero if the page's buffers were successfully reaped
+/** 
+ * int journal_invalidatepage() 
+ * @journal: journal to use for flush... 
+ * @page:    page to flush
+ * @offset:  length of page to invalidate.
+ *
+ * Reap page buffers containing data after offset in page.
+ *
+ * Return non-zero if the page's buffers were successfully reaped.
  */
 int journal_invalidatepage(journal_t *journal, 
 		      struct page *page, 
diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c
--- a/fs/jffs/intrep.c	Mon Feb 10 10:39:29 2003
+++ b/fs/jffs/intrep.c	Mon Feb 10 10:39:29 2003
@@ -3344,13 +3344,12 @@
 	lock_kernel();
 	exit_mm(c->gc_task);
 
-	current->session = 1;
-	current->pgrp = 1;
+	set_special_pids(1, 1);
 	init_completion(&c->gc_thread_comp); /* barrier */ 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	strcpy(current->comm, "jffs_gcd");
 
 	D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n"));
@@ -3378,9 +3377,9 @@
 			siginfo_t info;
 			unsigned long signr = 0;
 
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			signr = dequeue_signal(&current->blocked, &info);
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 
 			switch(signr) {
 			case SIGSTOP:
diff -Nru a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
--- a/fs/jffs2/os-linux.h	Mon Feb 10 10:39:23 2003
+++ b/fs/jffs2/os-linux.h	Mon Feb 10 10:39:23 2003
@@ -54,7 +54,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40)
 #define current_sig_lock current->sigmask_lock
 #else
-#define current_sig_lock current->sig->siglock
+#define current_sig_lock current->sighand->siglock
 #endif
 
 static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
diff -Nru a/fs/jfs/inode.c b/fs/jfs/inode.c
--- a/fs/jfs/inode.c	Mon Feb 10 10:39:22 2003
+++ b/fs/jfs/inode.c	Mon Feb 10 10:39:22 2003
@@ -85,7 +85,7 @@
 	tid_t tid;
 	static int noisy = 5;
 
-	jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode));
+	jfs_info("In jfs_commit_inode, inode = 0x%p", inode);
 
 	/*
 	 * Don't commit if inode has been committed since last being
@@ -100,9 +100,9 @@
 		 * partitions and may think inode is dirty
 		 */
 		if (!special_file(inode->i_mode) && noisy) {
-			jERROR(1, ("jfs_commit_inode(0x%p) called on "
-				   "read-only volume\n", inode));
-			jERROR(1, ("Is remount racy?\n"));
+			jfs_err("jfs_commit_inode(0x%p) called on "
+				   "read-only volume", inode);
+			jfs_err("Is remount racy?");
 			noisy--;
 		}
 		return 0;
@@ -128,13 +128,13 @@
 		return;
 
 	if (jfs_commit_inode(inode, wait)) {
-		jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n"));
+		jfs_err("jfs_write_inode: jfs_commit_inode failed!");
 	}
 }
 
 void jfs_delete_inode(struct inode *inode)
 {
-	jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode));
+	jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
 
 	if (test_cflag(COMMIT_Freewmap, inode))
 		freeZeroLink(inode);
@@ -153,9 +153,8 @@
 			/* kernel allows writes to devices on read-only
 			 * partitions and may try to mark inode dirty
 			 */
-			jERROR(1, ("jfs_dirty_inode called on "
-				   "read-only volume\n"));
-			jERROR(1, ("Is remount racy?\n"));
+			jfs_err("jfs_dirty_inode called on read-only volume");
+			jfs_err("Is remount racy?");
 			noisy--;
 		}
 		return;
@@ -302,7 +301,7 @@
 static int jfs_prepare_write(struct file *file,
 			     struct page *page, unsigned from, unsigned to)
 {
-	return block_prepare_write(page, from, to, jfs_get_block);
+	return nobh_prepare_write(page, from, to, jfs_get_block);
 }
 
 static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
@@ -327,7 +326,7 @@
 	.writepages	= jfs_writepages,
 	.sync_page	= block_sync_page,
 	.prepare_write	= jfs_prepare_write,
-	.commit_write	= generic_commit_write,
+	.commit_write	= nobh_commit_write,
 	.bmap		= jfs_bmap,
 	.direct_IO	= jfs_direct_IO,
 };
@@ -378,9 +377,9 @@
 
 void jfs_truncate(struct inode *ip)
 {
-	jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size));
+	jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
 
-	block_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block);
+	nobh_truncate_page(ip->i_mapping, ip->i_size);
 
 	IWRITE_LOCK(ip);
 	jfs_truncate_nolock(ip, ip->i_size);
diff -Nru a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h
--- a/fs/jfs/jfs_btree.h	Mon Feb 10 10:39:23 2003
+++ b/fs/jfs/jfs_btree.h	Mon Feb 10 10:39:23 2003
@@ -71,19 +71,16 @@
 		MP = (struct metapage *)&JFS_IP(IP)->bxflag;\
 		P = (TYPE *)&JFS_IP(IP)->ROOT;\
 		RC = 0;\
-		jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\
 	}\
 	else\
 	{\
-		jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\
-			 (int)BN));\
 		MP = read_metapage((IP), BN, SIZE, 1);\
 		if (MP) {\
 			RC = 0;\
 			P = (MP)->data;\
 		} else {\
 			P = NULL;\
-			jERROR(1,("bread failed!\n"));\
+			jfs_err("bread failed!");\
 			RC = EIO;\
 		}\
 	}\
diff -Nru a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
--- a/fs/jfs/jfs_debug.h	Mon Feb 10 10:39:24 2003
+++ b/fs/jfs/jfs_debug.h	Mon Feb 10 10:39:24 2003
@@ -41,13 +41,13 @@
 /* kgdb stuff */
 #define assert(p) KERNEL_ASSERT(#p, p)
 #else
-#define assert(p) {\
-if (!(p))\
-	{\
-		printk("assert(%s)\n",#p);\
-		BUG();\
-	}\
-}
+#define assert(p) do {	\
+	if (!(p)) {	\
+		printk(KERN_CRIT "BUG at %s:%d assert(%s)\n",	\
+		       __FILE__, __LINE__, #p);			\
+		BUG();	\
+	}		\
+} while (0)
 #endif
 
 /*
@@ -57,33 +57,53 @@
 #ifdef CONFIG_JFS_DEBUG
 #define ASSERT(p) assert(p)
 
+/* printk verbosity */
+#define JFS_LOGLEVEL_ERR 1
+#define JFS_LOGLEVEL_WARN 2
+#define JFS_LOGLEVEL_DEBUG 3
+#define JFS_LOGLEVEL_INFO 4
+
+extern int jfsloglevel;
+
 /* dump memory contents */
 extern void dump_mem(char *label, void *data, int length);
-extern int jfsloglevel;
 
 /* information message: e.g., configuration, major event */
-#define jFYI(button, prspec) \
-	do { if (button && jfsloglevel > 1) printk prspec; } while (0)
+#define jfs_info(fmt, arg...) do {			\
+	if (jfsloglevel >= JFS_LOGLEVEL_INFO)		\
+		printk(KERN_INFO fmt "\n", ## arg);	\
+} while (0)
+
+/* debug message: ad hoc */
+#define jfs_debug(fmt, arg...) do {			\
+	if (jfsloglevel >= JFS_LOGLEVEL_DEBUG)		\
+		printk(KERN_DEBUG fmt "\n", ## arg);	\
+} while (0)
+
+/* warn message: */
+#define jfs_warn(fmt, arg...) do {			\
+	if (jfsloglevel >= JFS_LOGLEVEL_WARN)		\
+		printk(KERN_WARNING fmt "\n", ## arg);	\
+} while (0)
 
 /* error event message: e.g., i/o error */
-extern int jfsERROR;
-#define jERROR(button, prspec) \
-	do { if (button && jfsloglevel > 0) { printk prspec; } } while (0)
-
-/* debug event message: */
-#define jEVENT(button,prspec) \
-	do { if (button) printk prspec; } while (0)
+#define jfs_err(fmt, arg...) do {			\
+	if (jfsloglevel >= JFS_LOGLEVEL_ERR)		\
+		printk(KERN_ERR "%s:%d " fmt "\n",	\
+		       __FILE__, __LINE__, ## arg);	\
+} while (0)
 
 /*
  *	debug OFF
  *	---------
  */
 #else				/* CONFIG_JFS_DEBUG */
-#define dump_mem(label,data,length)
-#define ASSERT(p)
-#define jEVENT(button,prspec)
-#define jERROR(button,prspec)
-#define jFYI(button,prspec)
+#define dump_mem(label,data,length) do {} while (0)
+#define ASSERT(p) do {} while (0)
+#define jfs_info(fmt, arg...) do {} while (0)
+#define jfs_debug(fmt, arg...) do {} while (0)
+#define jfs_warn(fmt, arg...) do {} while (0)
+#define jfs_err(fmt, arg...) do {} while (0)
 #endif				/* CONFIG_JFS_DEBUG */
 
 /*
diff -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
--- a/fs/jfs/jfs_dmap.c	Mon Feb 10 10:39:31 2003
+++ b/fs/jfs/jfs_dmap.c	Mon Feb 10 10:39:31 2003
@@ -314,7 +314,7 @@
 			   BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
 			   PSIZE, 0);
 	if (mp == NULL) {
-		jERROR(1,("dbSync: read_metapage failed!\n"));
+		jfs_err("dbSync: read_metapage failed!");
 		return (EIO);
 	}
 	/* copy the in-memory version of the bmap to the on-disk version */
@@ -1444,10 +1444,10 @@
 		/* assert(!(rc == ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */
 		if ((rc == ENOSPC) &&
 		    (bmp->db_agfree[agno] == bmp->db_agsize)) {
-			jERROR(1,
-			       ("dbAllocAG: removed assert, but still need to debug here\nblkno = 0x%Lx, nblocks = 0x%Lx\n",
+			jfs_err("dbAllocAG: removed assert, but still need to "
+				"debug here\nblkno = 0x%Lx, nblocks = 0x%Lx",
 				(unsigned long long) blkno,
-				(unsigned long long) nblocks));
+				(unsigned long long) nblocks);
 		}
 		return (rc);
 	}
@@ -1829,8 +1829,7 @@
 			 * to indicate that we have leaked blocks.
 			 */
 			fsDirty();	/* !!! */
-			jERROR(1,
-			       ("dbAllocCtl: I/O Error: Block Leakage.\n"));
+			jfs_err("dbAllocCtl: I/O Error: Block Leakage.");
 			continue;
 		}
 		dp = (struct dmap *) mp->data;
@@ -1843,7 +1842,7 @@
 			 */
 			release_metapage(mp);
 			fsDirty();	/* !!! */
-			jERROR(1, ("dbAllocCtl: Block Leakage.\n"));
+			jfs_err("dbAllocCtl: Block Leakage.");
 			continue;
 		}
 
@@ -3276,9 +3275,8 @@
 
 	newsize = blkno + nblocks;
 
-	jEVENT(0, ("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld\n",
-		   (long long) blkno, (long long) nblocks,
-		   (long long) newsize));
+	jfs_info("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld",
+		 (long long) blkno, (long long) nblocks, (long long) newsize);
 
 	/*
 	 *      initialize bmap control page.
diff -Nru a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
--- a/fs/jfs/jfs_dtree.c	Mon Feb 10 10:39:30 2003
+++ b/fs/jfs/jfs_dtree.c	Mon Feb 10 10:39:30 2003
@@ -130,7 +130,7 @@
 		if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\
 		    ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\
 		{\
-			jERROR(1,("DT_GETPAGE: dtree page corrupt\n"));\
+			jfs_err("DT_GETPAGE: dtree page corrupt");\
 			BT_PUTPAGE(MP);\
 			updateSuper((IP)->i_sb, FM_DIRTY);\
 			MP = NULL;\
@@ -222,6 +222,25 @@
 }
 
 /*
+ *	get_index_page()
+ *
+ *	Same as get_index_page(), but get's a new page without reading
+ */
+static struct metapage *get_index_page(struct inode *inode, s64 blkno)
+{
+	int rc;
+	s64 xaddr;
+	int xflag;
+	s32 xlen;
+
+	rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
+	if (rc || (xlen == 0))
+		return NULL;
+
+	return get_metapage(inode, xaddr, PSIZE, 1);
+}
+
+/*
  *	find_index()
  *
  *	Returns dtree page containing directory table entry for specified
@@ -241,15 +260,14 @@
 
 	if (index < 2) {
 		if (maxWarnings) {
-			jERROR(1, ("find_entry called with index = %d\n",
-				   index));
+			jfs_warn("find_entry called with index = %d", index);
 			maxWarnings--;
 		}
 		return 0;
 	}
 
 	if (index >= jfs_ip->next_index) {
-		jFYI(1, ("find_entry called with index >= next_index\n"));
+		jfs_warn("find_entry called with index >= next_index");
 		return 0;
 	}
 
@@ -274,8 +292,7 @@
 			*mp = read_index_page(ip, blkno);
 		}
 		if (*mp == 0) {
-			jERROR(1,
-			       ("free_index: error reading directory table\n"));
+			jfs_err("free_index: error reading directory table");
 			return 0;
 		}
 
@@ -336,8 +353,8 @@
 	ASSERT(DO_INDEX(ip));
 
 	if (jfs_ip->next_index < 2) {
-		jERROR(1, ("next_index = %d.  Please fix this!\n",
-			   jfs_ip->next_index));
+		jfs_warn("add_index: next_index = %d.  Resetting!",
+			   jfs_ip->next_index);
 		jfs_ip->next_index = 2;
 	}
 
@@ -386,14 +403,14 @@
 		if ((rc =
 		     xtInsert(tid, ip, 0, 0, sbi->nbperpage,
 			      &xaddr, 0))) {
-			jFYI(1, ("add_index: xtInsert failed!\n"));
+			jfs_warn("add_index: xtInsert failed!");
 			return -1;
 		}
 		ip->i_size = PSIZE;
 		ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
 
-		if ((mp = read_index_page(ip, 0)) == 0) {
-			jERROR(1, ("add_index: get_metapage failed!\n"));
+		if ((mp = get_index_page(ip, 0)) == 0) {
+			jfs_err("add_index: get_metapage failed!");
 			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
 			return -1;
 		}
@@ -428,14 +445,14 @@
 		if ((rc =
 		     xtInsert(tid, ip, 0, blkno, sbi->nbperpage,
 			      &xaddr, 0))) {
-			jFYI(1, ("add_index: xtInsert failed!\n"));
+			jfs_warn("add_index: xtInsert failed!");
 			jfs_ip->next_index--;
 			return -1;
 		}
 		ip->i_size += PSIZE;
 		ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
 
-		if ((mp = read_index_page(ip, blkno)))
+		if ((mp = get_index_page(ip, blkno)))
 			memset(mp->data, 0, PSIZE);	/* Just looks better */
 		else
 			xtTruncate(tid, ip, offset, COMMIT_PWMAP);
@@ -443,7 +460,7 @@
 		mp = read_index_page(ip, blkno);
 
 	if (mp == 0) {
-		jERROR(1, ("add_index: get/read_metapage failed!\n"));
+		jfs_err("add_index: get/read_metapage failed!");
 		return -1;
 	}
 
@@ -751,7 +768,7 @@
 			/* Something's corrupted, mark filesytem dirty so
 			 * chkdsk will fix it.
 			 */
-			jERROR(1, ("stack overrun in dtSearch!\n"));
+			jfs_err("stack overrun in dtSearch!");
 			updateSuper(sb, FM_DIRTY);
 			rc = EIO;
 			goto out;
@@ -1162,7 +1179,7 @@
 			break;
 
 		default:
-			jERROR(2, ("dtSplitUp(): UFO!\n"));
+			jfs_err("dtSplitUp(): UFO!");
 			break;
 		}
 
@@ -1313,8 +1330,7 @@
 	if (rmp == NULL)
 		return EIO;
 
-	jEVENT(0,
-	       ("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp));
+	jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
 
 	BT_MARK_DIRTY(rmp, ip);
 	/*
@@ -1420,9 +1436,8 @@
 		 * acquire a transaction lock on the next page
 		 */
 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
-		jEVENT(0,
-		       ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
-			tlck, ip, mp));
+		jfs_info("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p",
+			tlck, ip, mp);
 		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header of previous right sibling page */
@@ -1564,7 +1579,6 @@
 
 	ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd));
 
-	jEVENT(0, ("dtSplitPage: ip:0x%p sp:0x%p rp:0x%p\n", ip, sp, rp));
 	return 0;
 }
 
@@ -1665,8 +1679,7 @@
 	 */
 	sp->header.self = *pxd;
 
-	jEVENT(0,
-	       ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp));
+	jfs_info("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p", ip, smp, sp);
 
 	BT_MARK_DIRTY(smp, ip);
 	/*
@@ -1804,10 +1817,6 @@
 				 ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ?
 				  lengthDXD(&JFS_IP(ip)->acl) : 0));
 
-	jEVENT(0,
-	       ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp));
-
-
 	DT_PUTPAGE(pmp);
 	return 0;
 }
@@ -2401,9 +2410,9 @@
 	oxaddr = addressPXD(opxd);
 	xlen = lengthPXD(opxd);
 
-	jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n",
+	jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d",
 		   (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr,
-		   xlen));
+		   xlen);
 
 	/*
 	 *      1. get the internal parent dtpage covering
@@ -2415,7 +2424,7 @@
 
 	/* retrieve search result */
 	DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
-	jEVENT(0, ("dtRelocate: parent router entry validated.\n"));
+	jfs_info("dtRelocate: parent router entry validated.");
 
 	/*
 	 *      2. relocate the target dtpage
@@ -2521,7 +2530,7 @@
 #endif /* _STILL_TO_PORT */
 	/* unpin the relocated page */
 	DT_PUTPAGE(mp);
-	jEVENT(0, ("dtRelocate: target dtpage relocated.\n"));
+	jfs_info("dtRelocate: target dtpage relocated.");
 
 	/* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec
 	 * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec
@@ -2549,7 +2558,7 @@
 	 * acquire tlck for the parent entry covering the target dtpage;
 	 * write LOG_REDOPAGE to apply after image only;
 	 */
-	jEVENT(0, ("dtRelocate: update parent router entry.\n"));
+	jfs_info("dtRelocate: update parent router entry.");
 	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
 	dtlck = (struct dt_lock *) & tlck->lock;
 	lv = & dtlck->lv[dtlck->index];
@@ -2708,9 +2717,8 @@
 		 * action: update prev pointer;
 		 */
 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
-		jEVENT(0,
-		       ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
-			tlck, ip, mp));
+		jfs_info("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p",
+			tlck, ip, mp);
 		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header */
@@ -2738,9 +2746,8 @@
 		 * action: update next pointer;
 		 */
 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
-		jEVENT(0,
-		       ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
-			tlck, ip, mp));
+		jfs_info("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p",
+			tlck, ip, mp);
 		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header */
@@ -3012,8 +3019,8 @@
 			}
 			if (dirtab_slot.flag == DIR_INDEX_FREE) {
 				if (loop_count++ > JFS_IP(ip)->next_index) {
-					jERROR(1, ("jfs_readdir detected "
-						   "infinite loop!\n"));
+					jfs_err("jfs_readdir detected "
+						   "infinite loop!");
 					filp->f_pos = DIREND;
 					return 0;
 				}
@@ -3032,7 +3039,7 @@
 				return 0;
 			}
 			if (p->header.flag & BT_INTERNAL) {
-				jERROR(1,("jfs_readdir: bad index table\n"));
+				jfs_err("jfs_readdir: bad index table");
 				DT_PUTPAGE(mp);
 				filp->f_pos = -1;
 				return 0;
@@ -3097,8 +3104,8 @@
 					    PARENT(ip), DT_DIR))
 					return 0;
 			} else {
-				jERROR(1,
-				       ("jfs_readdir called with invalid offset!\n"));
+				jfs_err("jfs_readdir called with "
+					"invalid offset!");
 			}
 			dtoffset->pn = 1;
 			dtoffset->index = 0;
@@ -3111,9 +3118,8 @@
 		}
 
 		if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) {
-			jERROR(1,
-			       ("jfs_readdir: unexpected rc = %d from dtReadNext\n",
-				rc));
+			jfs_err("jfs_readdir: unexpected rc = %d "
+				"from dtReadNext", rc);
 			filp->f_pos = DIREND;
 			return 0;
 		}
@@ -3130,7 +3136,7 @@
 	dirent_buf = __get_free_page(GFP_KERNEL);
 	if (dirent_buf == 0) {
 		DT_PUTPAGE(mp);
-		jERROR(1, ("jfs_readdir: __get_free_page failed!\n"));
+		jfs_warn("jfs_readdir: __get_free_page failed!");
 		filp->f_pos = DIREND;
 		return -ENOMEM;
 	}
@@ -3202,9 +3208,10 @@
 				d_namleft -= len;
 				/* Sanity Check */
 				if (d_namleft == 0) {
-					jERROR(1,("JFS:Dtree error: "
-					  "ino = %ld, bn=%Ld, index = %d\n",
-						  (long)ip->i_ino, (long long)bn, i));
+					jfs_err("JFS:Dtree error: ino = "
+						"%ld, bn=%Ld, index = %d",
+						(long)ip->i_ino,(long long)bn,
+						i);
 					updateSuper(ip->i_sb, FM_DIRTY);
 					goto skip_one;
 				}
diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c	Mon Feb 10 10:39:24 2003
+++ b/fs/jfs/jfs_imap.c	Mon Feb 10 10:39:24 2003
@@ -137,7 +137,7 @@
 	/* allocate the in-memory inode map control structure. */
 	imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
 	if (imap == NULL) {
-		jERROR(1, ("diMount: kmalloc returned NULL!\n"));
+		jfs_err("diMount: kmalloc returned NULL!");
 		return (ENOMEM);
 	}
 
@@ -253,7 +253,7 @@
 			  IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
 			  PSIZE, 0);
 	if (mp == NULL) {
-		jERROR(1,("diSync: get_metapage failed!\n"));
+		jfs_err("diSync: get_metapage failed!");
 		return EIO;
 	}
 
@@ -339,7 +339,7 @@
 	uint pageno;
 	int rel_inode;
 
-	jFYI(1, ("diRead: ino = %ld\n", ip->i_ino));
+	jfs_info("diRead: ino = %ld", ip->i_ino);
 
 	ipimap = sbi->ipimap;
 	JFS_IP(ip)->ipimap = ipimap;
@@ -353,7 +353,7 @@
 	rc = diIAGRead(imap, iagno, &mp);
 	IREAD_UNLOCK(ipimap);
 	if (rc) {
-		jERROR(1, ("diRead: diIAGRead returned %d\n", rc));
+		jfs_err("diRead: diIAGRead returned %d", rc);
 		return (rc);
 	}
 
@@ -400,7 +400,7 @@
 	/* read the page of disk inode */
 	mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
 	if (mp == 0) {
-		jERROR(1, ("diRead: read_metapage failed\n"));
+		jfs_err("diRead: read_metapage failed");
 		return EIO;
 	}
 
@@ -409,7 +409,7 @@
 	dp += rel_inode;
 
 	if (ip->i_ino != le32_to_cpu(dp->di_number)) {
-		jERROR(1, ("diRead: i_ino != di_number\n"));
+		jfs_err("diRead: i_ino != di_number");
 		updateSuper(ip->i_sb, FM_DIRTY);
 		rc = EIO;
 	} else if (le32_to_cpu(dp->di_nlink) == 0)
@@ -460,8 +460,7 @@
 
 	ip = new_inode(sb);
 	if (ip == NULL) {
-		jERROR(1,
-		       ("diReadSpecial: new_inode returned NULL!\n"));
+		jfs_err("diReadSpecial: new_inode returned NULL!");
 		return ip;
 	}
 
@@ -480,9 +479,6 @@
 	address += inum >> 3;	/* 8 inodes per 4K page */
 
 	/* read the page of fixed disk inode (AIT) in raw mode */
-	jEVENT(0,
-	       ("Reading aggregate inode %d from block %d\n", (uint) inum,
-		address));
 	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
 	if (mp == NULL) {
 		ip->i_sb = NULL;
@@ -553,13 +549,10 @@
 	address += inum >> 3;	/* 8 inodes per 4K page */
 
 	/* read the page of fixed disk inode (AIT) in raw mode */
-	jEVENT(0,
-	       ("Reading aggregate inode %d from block %d\n", (uint) inum,
-		address));
 	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
 	if (mp == NULL) {
-		jERROR(1,
-		       ("diWriteSpecial: failed to read aggregate inode extent!\n"));
+		jfs_err("diWriteSpecial: failed to read aggregate inode "
+			"extent!");
 		return;
 	}
 
@@ -586,7 +579,7 @@
 void diFreeSpecial(struct inode *ip)
 {
 	if (ip == NULL) {
-		jERROR(1, ("diFreeSpecial called with NULL ip!\n"));
+		jfs_err("diFreeSpecial called with NULL ip!");
 		return;
 	}
 	filemap_fdatawrite(ip->i_mapping);
@@ -794,7 +787,7 @@
 			       lv->length << L2DTSLOTSIZE);
 		}
 	} else {
-		jERROR(1, ("diWrite: UFO tlock\n"));
+		jfs_err("diWrite: UFO tlock");
 	}
 
       inlineData:
@@ -926,8 +919,8 @@
 	 */
 	//assert(iagno < imap->im_nextiag);
 	if (iagno >= imap->im_nextiag) {
-		jERROR(1, ("diFree: inum = %d, iagno = %d, nextiag = %d\n",
-			   (uint) inum, iagno, imap->im_nextiag));
+		jfs_err("diFree: inum = %d, iagno = %d, nextiag = %d",
+			(uint) inum, iagno, imap->im_nextiag);
 		dump_mem("imap", imap, 32);
 		updateSuper(ip->i_sb, FM_DIRTY);
 		return EIO;
@@ -974,7 +967,7 @@
 	bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
 
 	if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
-		jERROR(1,("diFree: numfree > numinos\n"));
+		jfs_err("diFree: numfree > numinos");
 		release_metapage(mp);
 		IREAD_UNLOCK(ipimap);
 		AG_UNLOCK(imap, agno);
@@ -1684,7 +1677,7 @@
 	numinos = imap->im_agctl[agno].numinos;
 
 	if (numfree > numinos) {
-		jERROR(1,("diAllocAG: numfree > numinos\n"));
+		jfs_err("diAllocAG: numfree > numinos");
 		updateSuper(ip->i_sb, FM_DIRTY);
 		return EIO;
 	}
@@ -1835,9 +1828,8 @@
 	 */
 	//assert(iagp->nfreeinos);
 	if (!iagp->nfreeinos) {
-		jERROR(1,
-		       ("diAllocIno: nfreeinos = 0, but iag on freelist\n"));
-		jERROR(1, ("  agno = %d, iagno = %d\n", agno, iagno));
+		jfs_err("diAllocIno: nfreeinos = 0, but iag on freelist");
+		jfs_err("  agno = %d, iagno = %d", agno, iagno);
 		dump_mem("iag", iagp, 64);
 		updateSuper(ip->i_sb, FM_DIRTY);
 		return EIO;
@@ -2764,18 +2756,14 @@
 		 * the inode will be freed from working map at the release
 		 * of last reference release;
 		 */
-//              assert(le32_to_cpu(iagp->wmap[extno]) & mask);
 		if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
-			jERROR(1,
-			       ("diUpdatePMap: inode %ld not marked as allocated in wmap!\n",
-				inum));
+			jfs_err("diUpdatePMap: inode %ld not marked as "
+				"allocated in wmap!", inum);
 			updateSuper(ipimap->i_sb, FM_DIRTY);
 		}
-//              assert(le32_to_cpu(iagp->pmap[extno]) & mask);
 		if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
-			jERROR(1,
-			       ("diUpdatePMap: inode %ld not marked as allocated in pmap!\n",
-				inum));
+			jfs_err("diUpdatePMap: inode %ld not marked as "
+				"allocated in pmap!", inum);
 			updateSuper(ipimap->i_sb, FM_DIRTY);
 		}
 		/* update the bitmap for the extent of the freed inode */
@@ -2851,9 +2839,9 @@
 	int numinos, xnuminos = 0, xnumfree = 0;
 	s64 agstart;
 
-	jEVENT(0, ("diExtendFS: nextiag:%d numinos:%d numfree:%d\n",
+	jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d",
 		   imap->im_nextiag, atomic_read(&imap->im_numinos),
-		   atomic_read(&imap->im_numfree)));
+		   atomic_read(&imap->im_numfree));
 
 	/*
 	 *      reconstruct imap 
diff -Nru a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
--- a/fs/jfs/jfs_inode.c	Mon Feb 10 10:39:23 2003
+++ b/fs/jfs/jfs_inode.c	Mon Feb 10 10:39:23 2003
@@ -38,7 +38,7 @@
 
 	inode = new_inode(sb);
 	if (!inode) {
-		jERROR(1, ("ialloc: new_inode returned NULL!\n"));
+		jfs_warn("ialloc: new_inode returned NULL!");
 		return inode;
 	}
 
@@ -46,7 +46,7 @@
 
 	rc = diAlloc(parent, S_ISDIR(mode), inode);
 	if (rc) {
-		jERROR(1, ("ialloc: diAlloc returned %d!\n", rc));
+		jfs_warn("ialloc: diAlloc returned %d!", rc);
 		make_bad_inode(inode);
 		iput(inode);
 		return NULL;
@@ -87,7 +87,7 @@
 	jfs_inode->atltail = 0;
 	jfs_inode->xtlid = 0;
 
-	jFYI(1, ("ialloc returns inode = 0x%p\n", inode));
+	jfs_info("ialloc returns inode = 0x%p\n", inode);
 
 	return inode;
 }
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	Mon Feb 10 10:39:27 2003
+++ b/fs/jfs/jfs_logmgr.c	Mon Feb 10 10:39:27 2003
@@ -222,8 +222,8 @@
 	int diffp, difft;
 	struct metapage *mp = NULL;
 
-	jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n",
-		 log, tblk, lrd, tlck));
+	jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p",
+		 log, tblk, lrd, tlck);
 
 	LOG_LOCK(log);
 
@@ -390,7 +390,7 @@
 	}
 #endif				/* _JFS_WIP */
 	else {
-		jERROR(2, ("lmWriteRecord: UFO tlck:0x%p\n", tlck));
+		jfs_err("lmWriteRecord: UFO tlck:0x%p", tlck);
 		return 0;	/* Probably should trap */
 	}
 	l2linesize = linelock->l2linesize;
@@ -449,9 +449,8 @@
 		lvd->offset = cpu_to_le16(lv->offset);
 		lvd->length = cpu_to_le16(lv->length);
 		dstoffset += 4;
-		jFYI(1,
-		     ("lmWriteRecord: lv offset:%d length:%d\n",
-		      lv->offset, lv->length));
+		jfs_info("lmWriteRecord: lv offset:%d length:%d",
+			 lv->offset, lv->length);
 	}
 
 	if ((i = linelock->next)) {
@@ -492,9 +491,8 @@
 
 		if (lrd->type & cpu_to_le16(LOG_COMMIT)) {
 			tblk->clsn = lsn;
-			jFYI(1,
-			     ("wr: tclsn:0x%x, beor:0x%x\n", tblk->clsn,
-			      bp->l_eor));
+			jfs_info("wr: tclsn:0x%x, beor:0x%x", tblk->clsn,
+				 bp->l_eor);
 
 			INCREMENT(lmStat.commit);	/* # of commit */
 
@@ -526,10 +524,8 @@
 			LOGGC_UNLOCK(log);
 		}
 
-		jFYI(1,
-		     ("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x\n",
-		      le16_to_cpu(lrd->type), log->bp, log->page,
-		      dstoffset));
+		jfs_info("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x",
+			le16_to_cpu(lrd->type), log->bp, log->page, dstoffset);
 
 		/* page not full ? */
 		if (dstoffset < LOGPSIZE - LOGPTLRSIZE)
@@ -569,8 +565,6 @@
 	struct lbuf *nextbp;
 	struct tblock *tblk;
 
-	jFYI(1, ("lmNextPage\n"));
-
 	/* get current log page number and log sequence page number */
 	pn = log->page;
 	bp = log->bp;
@@ -646,7 +640,6 @@
 	lp->h.page = lp->t.page = cpu_to_le32(lspn + 1);
 	lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
 
-	jFYI(1, ("lmNextPage done\n"));
 	return 0;
 }
 
@@ -680,8 +673,7 @@
 		LOGGC_UNLOCK(log);
 		return rc;
 	}
-	jFYI(1, ("lmGroup Commit: tblk = 0x%p, gcrtc = %d\n", tblk,
-		 log->gcrtc));
+	jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc);
 
 	if (tblk->xflag & COMMIT_LAZY) {
 		/*
@@ -783,9 +775,6 @@
 		tblk->flag |= tblkGC_FREE;
 		bp->l_ceor = bp->l_eor;
 		lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
-		jEVENT(0,
-		       ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn,
-			bp->l_ceor));
 		lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC,
 			 cant_write);
 		INCREMENT(lmStat.full_page);
@@ -794,9 +783,6 @@
 	else {
 		bp->l_ceor = tblk->eor;	/* ? bp->l_ceor = bp->l_eor; */
 		lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
-		jEVENT(0,
-		       ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn,
-			bp->l_ceor));
 		lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write);
 		INCREMENT(lmStat.partial_page);
 	}
@@ -845,9 +831,8 @@
 		tblk->flag &= ~tblkGC_QUEUE;
 		tblk->cqnext = 0;
 
-		jEVENT(0,
-		       ("lmPostGC: tblk = 0x%p, flag = 0x%x\n", tblk,
-			tblk->flag));
+		jfs_info("lmPostGC: tblk = 0x%p, flag = 0x%x", tblk,
+			 tblk->flag);
 
 		if (!(tblk->xflag & COMMIT_FORCE))
 			/*
@@ -877,7 +862,7 @@
 			lp = (struct logpage *) bp->l_ldata;
 			bp->l_ceor = bp->l_eor;
 			lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
-			jEVENT(0, ("lmPostGC: calling lbmWrite\n"));
+			jfs_info("lmPostGC: calling lbmWrite");
 			lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE,
 				 1);
 		}
@@ -1008,8 +993,7 @@
 	delta = LOGSYNC_DELTA(logsize);
 	more = min(free / 2, delta);
 	if (more < 2 * LOGPSIZE) {
-		jEVENT(1,
-		       ("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n\n"));
+		jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n");
 		/*
 		 *      log wrapping
 		 *
@@ -1048,8 +1032,8 @@
 	 */
 	if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) {
 		set_bit(log_SYNCBARRIER, &log->flag);
-		jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn,
-			 log->syncpt));
+		jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn,
+			 log->syncpt);
 		/*
 		 * We may have to initiate group commit
 		 */
@@ -1148,7 +1132,6 @@
 		goto shutdown;
 
       out:
-	jFYI(1, ("lmLogOpen: exit(0)\n"));
 	*logptr = log;
 	return 0;
 
@@ -1167,7 +1150,7 @@
       free:		/* free log descriptor */
 	kfree(log);
 
-	jFYI(1, ("lmLogOpen: exit(%d)\n", rc));
+	jfs_warn("lmLogOpen: exit(%d)", rc);
 	return rc;
 }
 
@@ -1200,7 +1183,7 @@
 	struct logpage *lp;
 	int lsn;
 
-	jFYI(1, ("lmLogInit: log:0x%p\n", log));
+	jfs_info("lmLogInit: log:0x%p", log);
 
 	/*
 	 * log inode is overlaid on generic inode where
@@ -1224,14 +1207,14 @@
 	logsuper = (struct logsuper *) bpsuper->l_ldata;
 
 	if (logsuper->magic != cpu_to_le32(LOGMAGIC)) {
-		jERROR(1, ("*** Log Format Error ! ***\n"));
+		jfs_warn("*** Log Format Error ! ***");
 		rc = EINVAL;
 		goto errout20;
 	}
 
 	/* logredo() should have been run successfully. */
 	if (logsuper->state != cpu_to_le32(LOGREDONE)) {
-		jERROR(1, ("*** Log Is Dirty ! ***\n"));
+		jfs_warn("*** Log Is Dirty ! ***");
 		rc = EINVAL;
 		goto errout20;
 	}
@@ -1242,19 +1225,17 @@
 			rc = EINVAL;
 			goto errout20;
 		}
-		jFYI(0,
-		     ("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x\n",
-		      log, (unsigned long long) log->base, log->size));
+		jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x",
+			log, (unsigned long long) log->base, log->size);
 	} else {
 		if (memcmp(logsuper->uuid, log->uuid, 16)) {
-			jERROR(1,("wrong uuid on JFS log device\n"));
+			jfs_warn("wrong uuid on JFS log device");
 			goto errout20;
 		}
 		log->size = le32_to_cpu(logsuper->size);
 		log->l2bsize = le32_to_cpu(logsuper->l2bsize);
-		jFYI(0,
-		     ("lmLogInit: external log:0x%p base:0x%Lx size:0x%x\n",
-		      log, (unsigned long long) log->base, log->size));
+		jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x",
+			log, (unsigned long long) log->base, log->size);
 	}
 
 	log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
@@ -1269,9 +1250,9 @@
 
 	lp = (struct logpage *) bp->l_ldata;
 
-	jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n",
+	jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d",
 		 le32_to_cpu(logsuper->end), log->page, log->eor,
-		 le16_to_cpu(lp->h.eor)));
+		 le16_to_cpu(lp->h.eor));
 
 //      ASSERT(log->eor == lp->h.eor);
 
@@ -1319,8 +1300,8 @@
 	log->sync = log->syncpt;
 	log->nextsync = LOGSYNC_DELTA(log->logsize);
 
-	jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n",
-		 log->lsn, log->syncpt, log->sync));
+	jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x",
+		 log->lsn, log->syncpt, log->sync);
 
 	LOGSYNC_LOCK_INIT(log);
 
@@ -1345,7 +1326,6 @@
 	if ((rc = lbmIOWait(bpsuper, lbmFREE)))
 		goto errout30;
 
-	jFYI(1, ("lmLogInit: exit(%d)\n", rc));
 	return 0;
 
 	/*
@@ -1360,7 +1340,7 @@
       errout10:		/* unwind lbmLogInit() */
 	lbmLogShutdown(log);
 
-	jFYI(1, ("lmLogInit: exit(%d)\n", rc));
+	jfs_warn("lmLogInit: exit(%d)", rc);
 	return rc;
 }
 
@@ -1383,7 +1363,7 @@
 	struct block_device *bdev = log->bdev;
 	int rc;
 
-	jFYI(1, ("lmLogClose: log:0x%p\n", log));
+	jfs_info("lmLogClose: log:0x%p", log);
 
 	if (!test_bit(log_INLINELOG, &log->flag))
 		goto externalLog;
@@ -1405,7 +1385,7 @@
 	blkdev_put(bdev, BDEV_FS);
 
       out:
-	jFYI(0, ("lmLogClose: exit(%d)\n", rc));
+	jfs_info("lmLogClose: exit(%d)", rc);
 	return rc;
 }
 
@@ -1420,7 +1400,7 @@
 {
 	int i;
 
-	jFYI(1, ("jfs_flush_journal: log:0x%p wait=%d\n", log, wait));
+	jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait);
 
 	/*
 	 * This ensures that we will keep writing to the journal as long
@@ -1485,7 +1465,7 @@
 	struct lbuf *bp;
 	struct logpage *lp;
 
-	jFYI(1, ("lmLogShutdown: log:0x%p\n", log));
+	jfs_info("lmLogShutdown: log:0x%p", log);
 
 	jfs_flush_journal(log, 1);
 
@@ -1525,8 +1505,8 @@
 	lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
 	rc = lbmIOWait(bpsuper, lbmFREE);
 
-	jFYI(1, ("lmLogShutdown: lsn:0x%x page:%d eor:%d\n",
-		 lsn, log->page, log->eor));
+	jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d",
+		 lsn, log->page, log->eor);
 
       out:    
 	/*
@@ -1535,7 +1515,7 @@
 	lbmLogShutdown(log);
 
 	if (rc) {
-		jFYI(1, ("lmLogShutdown: exit(%d)\n", rc));
+		jfs_warn("lmLogShutdown: exit(%d)", rc);
 	}
 	return rc;
 }
@@ -1576,7 +1556,7 @@
 				break;
 			}
 		if (i == MAX_ACTIVE) {
-			jERROR(1,("Too many file systems sharing journal!\n"));
+			jfs_warn("Too many file systems sharing journal!");
 			lbmFree(bpsuper);
 			return EMFILE;	/* Is there a better rc? */
 		}
@@ -1587,7 +1567,7 @@
 				break;
 			}
 		if (i == MAX_ACTIVE) {
-			jERROR(1,("Somebody stomped on the journal!\n"));
+			jfs_warn("Somebody stomped on the journal!");
 			lbmFree(bpsuper);
 			return EIO;
 		}
@@ -1636,7 +1616,7 @@
 	int i;
 	struct lbuf *lbuf;
 
-	jFYI(1, ("lbmLogInit: log:0x%p\n", log));
+	jfs_info("lbmLogInit: log:0x%p", log);
 
 	/* initialize current buffer cursor */
 	log->bp = NULL;
@@ -1690,7 +1670,7 @@
 {
 	struct lbuf *lbuf;
 
-	jFYI(1, ("lbmLogShutdown: log:0x%p\n", log));
+	jfs_info("lbmLogShutdown: log:0x%p", log);
 
 	lbuf = log->lbuf_free;
 	while (lbuf) {
@@ -1804,7 +1784,7 @@
 	 * allocate a log buffer
 	 */
 	*bpp = bp = lbmAllocate(log, pn);
-	jFYI(1, ("lbmRead: bp:0x%p pn:0x%x\n", bp, pn));
+	jfs_info("lbmRead: bp:0x%p pn:0x%x", bp, pn);
 
 	bp->l_flag |= lbmREAD;
 
@@ -1852,8 +1832,7 @@
 	struct lbuf *tail;
 	unsigned long flags;
 
-	jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n",
-		 bp, flag, bp->l_pn));
+	jfs_info("lbmWrite: bp:0x%p flag:0x%x pn:0x%x", bp, flag, bp->l_pn);
 
 	/* map the logical block address to physical block address */
 	bp->l_blkno =
@@ -1917,8 +1896,8 @@
  */
 static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
 {
-	jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n",
-		   bp, flag, bp->l_pn));
+	jfs_info("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x",
+		 bp, flag, bp->l_pn);
 
 	/*
 	 * initialize buffer for device driver
@@ -1950,7 +1929,7 @@
 	struct bio *bio;
 	struct jfs_log *log = bp->l_log;
 
-	jFYI(1, ("lbmStartIO\n"));
+	jfs_info("lbmStartIO\n");
 
 	bio = bio_alloc(GFP_NOFS, 1);
 	bio->bi_sector = bp->l_blkno << (log->l2bsize - 9);
@@ -1970,8 +1949,6 @@
 
 	INCREMENT(lmStat.submitted);
 	blk_run_queues();
-
-	jFYI(1, ("lbmStartIO done\n"));
 }
 
 
@@ -1983,9 +1960,7 @@
 	unsigned long flags;
 	int rc = 0;
 
-	jFYI(1,
-	     ("lbmIOWait1: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag,
-	      flag));
+	jfs_info("lbmIOWait1: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag);
 
 	LCACHE_LOCK(flags);		/* disable+lock */
 
@@ -1998,9 +1973,7 @@
 
 	LCACHE_UNLOCK(flags);	/* unlock+enable */
 
-	jFYI(1,
-	     ("lbmIOWait2: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag,
-	      flag));
+	jfs_info("lbmIOWait2: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag);
 	return rc;
 }
 
@@ -2022,7 +1995,7 @@
 	/*
 	 * get back jfs buffer bound to the i/o buffer
 	 */
-	jEVENT(0, ("lbmIODone: bp:0x%p flag:0x%x\n", bp, bp->l_flag));
+	jfs_info("lbmIODone: bp:0x%p flag:0x%x", bp, bp->l_flag);
 
 	LCACHE_LOCK(flags);		/* disable+lock */
 
@@ -2031,7 +2004,7 @@
 	if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
 		bp->l_flag |= lbmERROR;
 
-		jERROR(1, ("lbmIODone: I/O error in JFS log\n"));
+		jfs_err("lbmIODone: I/O error in JFS log");
 	}
 
 	bio_put(bio);
@@ -2159,8 +2132,6 @@
 {
 	struct lbuf *bp;
 
-	jFYI(1, ("jfsIOWait is here!\n"));
-
 	lock_kernel();
 
 	daemonize();
@@ -2168,10 +2139,10 @@
 
 	unlock_kernel();
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	complete(&jfsIOwait);
 
@@ -2199,7 +2170,7 @@
 		}
 	} while (!jfs_stop_threads);
 
-	jFYI(1,("jfsIOWait being killed!\n"));
+	jfs_info("jfsIOWait being killed!");
 	complete(&jfsIOwait);
 	return 0;
 }
@@ -2231,8 +2202,8 @@
 	int npages = 0;
 	struct lbuf *bp;
 
-	jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n",
-		 (long long)logAddress, logSize));
+	jfs_info("lmLogFormat: logAddress:%Ld logSize:%d",
+		 (long long)logAddress, logSize);
 
 	/* allocate a log buffer */
 	bp = lbmAllocate(log, 1);
diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c	Mon Feb 10 10:39:24 2003
+++ b/fs/jfs/jfs_metapage.c	Mon Feb 10 10:39:24 2003
@@ -229,8 +229,7 @@
 	unsigned long page_index;
 	unsigned long page_offset;
 
-	jFYI(1, ("__get_metapage: inode = 0x%p, lblock = 0x%lx\n",
-		 inode, lblock));
+	jfs_info("__get_metapage: inode = 0x%p, lblock = 0x%lx", inode, lblock);
 
 	if (absolute)
 		mapping = inode->i_sb->s_bdev->bd_inode->i_mapping;
@@ -249,7 +248,7 @@
 			clear_bit(META_discard, &mp->flag);
 		}
 		mp->count++;
-		jFYI(1, ("__get_metapage: found 0x%p, in hash\n", mp));
+		jfs_info("__get_metapage: found 0x%p, in hash", mp);
 		assert(mp->logical_size == size);
 		lock_metapage(mp);
 		spin_unlock(&meta_lock);
@@ -261,7 +260,7 @@
 		    l2bsize;
 		if ((page_offset + size) > PAGE_CACHE_SIZE) {
 			spin_unlock(&meta_lock);
-			jERROR(1, ("MetaData crosses page boundary!!\n"));
+			jfs_err("MetaData crosses page boundary!!");
 			return NULL;
 		}
 		
@@ -320,30 +319,28 @@
 		spin_unlock(&meta_lock);
 
 		if (new) {
-			jFYI(1,
-			     ("__get_metapage: Calling grab_cache_page\n"));
+			jfs_info("__get_metapage: Calling grab_cache_page");
 			mp->page = grab_cache_page(mapping, page_index);
 			if (!mp->page) {
-				jERROR(1, ("grab_cache_page failed!\n"));
+				jfs_err("grab_cache_page failed!");
 				goto freeit;
 			} else {
 				INCREMENT(mpStat.pagealloc);
 				unlock_page(mp->page);
 			}
 		} else {
-			jFYI(1,
-			     ("__get_metapage: Calling read_cache_page\n"));
+			jfs_info("__get_metapage: Calling read_cache_page");
 			mp->page = read_cache_page(mapping, lblock,
 				    (filler_t *)mapping->a_ops->readpage, NULL);
 			if (IS_ERR(mp->page)) {
-				jERROR(1, ("read_cache_page failed!\n"));
+				jfs_err("read_cache_page failed!");
 				goto freeit;
 			} else
 				INCREMENT(mpStat.pagealloc);
 		}
 		mp->data = kmap(mp->page) + page_offset;
 	}
-	jFYI(1, ("__get_metapage: returning = 0x%p\n", mp));
+	jfs_info("__get_metapage: returning = 0x%p", mp);
 	return mp;
 
 freeit:
@@ -378,7 +375,7 @@
 	unsigned long page_offset;
 	int rc;
 
-	jFYI(1, ("__write_metapage: mp = 0x%p\n", mp));
+	jfs_info("__write_metapage: mp = 0x%p", mp);
 
 	if (test_bit(META_discard, &mp->flag)) {
 		/*
@@ -397,7 +394,7 @@
 					       page_offset +
 					       mp->logical_size);
 	if (rc) {
-		jERROR(1, ("prepare_write return %d!\n", rc));
+		jfs_err("prepare_write return %d!", rc);
 		ClearPageUptodate(mp->page);
 		unlock_page(mp->page);
 		clear_bit(META_dirty, &mp->flag);
@@ -407,13 +404,13 @@
 					      page_offset +
 					      mp->logical_size);
 	if (rc) {
-		jERROR(1, ("commit_write returned %d\n", rc));
+		jfs_err("commit_write returned %d", rc);
 	}
 
 	unlock_page(mp->page);
 	clear_bit(META_dirty, &mp->flag);
 
-	jFYI(1, ("__write_metapage done\n"));
+	jfs_info("__write_metapage done");
 }
 
 static inline void sync_metapage(struct metapage *mp)
@@ -435,9 +432,7 @@
 {
 	struct jfs_log *log;
 
-	jFYI(1,
-	     ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp,
-	      mp->flag));
+	jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag);
 
 	spin_lock(&meta_lock);
 	if (test_bit(META_forced, &mp->flag)) {
@@ -491,7 +486,6 @@
 
 		free_metapage(mp);
 	}
-	jFYI(1, ("release_metapage: done\n"));
 }
 
 void __invalidate_metapages(struct inode *ip, s64 addr, int len)
diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
--- a/fs/jfs/jfs_mount.c	Mon Feb 10 10:39:24 2003
+++ b/fs/jfs/jfs_mount.c	Mon Feb 10 10:39:24 2003
@@ -87,8 +87,6 @@
 	struct inode *ipimap = NULL;
 	struct inode *ipbmap = NULL;
 
-	jFYI(1, ("\nMount JFS\n"));
-
 	/*
 	 * read/validate superblock 
 	 * (initialize mount inode from the superblock)
@@ -99,21 +97,19 @@
 
 	ipaimap = diReadSpecial(sb, AGGREGATE_I, 0);
 	if (ipaimap == NULL) {
-		jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n"));
+		jfs_err("jfs_mount: Faild to read AGGREGATE_I");
 		rc = EIO;
 		goto errout20;
 	}
 	sbi->ipaimap = ipaimap;
 
-	jFYI(1, ("jfs_mount: ipaimap:0x%p\n", ipaimap));
+	jfs_info("jfs_mount: ipaimap:0x%p", ipaimap);
 
 	/*
 	 * initialize aggregate inode allocation map
 	 */
 	if ((rc = diMount(ipaimap))) {
-		jERROR(1,
-		       ("jfs_mount: diMount(ipaimap) failed w/rc = %d\n",
-			rc));
+		jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc);
 		goto errout21;
 	}
 
@@ -126,7 +122,7 @@
 		goto errout22;
 	}
 
-	jFYI(1, ("jfs_mount: ipbmap:0x%p\n", ipbmap));
+	jfs_info("jfs_mount: ipbmap:0x%p", ipbmap);
 
 	sbi->ipbmap = ipbmap;
 
@@ -134,7 +130,7 @@
 	 * initialize aggregate block allocation map
 	 */
 	if ((rc = dbMount(ipbmap))) {
-		jERROR(1, ("jfs_mount: dbMount failed w/rc = %d\n", rc));
+		jfs_err("jfs_mount: dbMount failed w/rc = %d", rc);
 		goto errout22;
 	}
 
@@ -152,22 +148,20 @@
 	if ((sbi->mntflag & JFS_BAD_SAIT) == 0) {
 		ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1);
 		if (ipaimap2 == 0) {
-			jERROR(1,
-			       ("jfs_mount: Faild to read AGGREGATE_I\n"));
+			jfs_err("jfs_mount: Faild to read AGGREGATE_I");
 			rc = EIO;
 			goto errout35;
 		}
 		sbi->ipaimap2 = ipaimap2;
 
-		jFYI(1, ("jfs_mount: ipaimap2:0x%p\n", ipaimap2));
+		jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2);
 
 		/*
 		 * initialize secondary aggregate inode allocation map
 		 */
 		if ((rc = diMount(ipaimap2))) {
-			jERROR(1,
-			       ("jfs_mount: diMount(ipaimap2) failed, rc = %d\n",
-				rc));
+			jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d",
+				rc);
 			goto errout35;
 		}
 	} else
@@ -182,23 +176,22 @@
 	 */
 	ipimap = diReadSpecial(sb, FILESYSTEM_I, 0);
 	if (ipimap == NULL) {
-		jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n"));
+		jfs_err("jfs_mount: Failed to read FILESYSTEM_I");
 		/* open fileset secondary inode allocation map */
 		rc = EIO;
 		goto errout40;
 	}
-	jFYI(1, ("jfs_mount: ipimap:0x%p\n", ipimap));
+	jfs_info("jfs_mount: ipimap:0x%p", ipimap);
 
 	/* map further access of per fileset inodes by the fileset inode */
 	sbi->ipimap = ipimap;
 
 	/* initialize fileset inode allocation map */
 	if ((rc = diMount(ipimap))) {
-		jERROR(1, ("jfs_mount: diMount failed w/rc = %d\n", rc));
+		jfs_err("jfs_mount: diMount failed w/rc = %d", rc);
 		goto errout41;
 	}
 
-	jFYI(1, ("Mount JFS Complete.\n"));
 	goto out;
 
 	/*
@@ -234,9 +227,9 @@
 
       out:
 
-	if (rc) {
-		jERROR(1, ("Mount JFS Failure: %d\n", rc));
-	}
+	if (rc)
+		jfs_err("Mount JFS Failure: %d", rc);
+
 	return rc;
 }
 
@@ -265,13 +258,13 @@
 		truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
 		diUnmount(sbi->ipimap, 1);
 		if ((rc = diMount(sbi->ipimap))) {
-			jERROR(1,("jfs_mount_rw: diMount failed!\n"));
+			jfs_err("jfs_mount_rw: diMount failed!");
 			return rc;
 		}
 
 		dbUnmount(sbi->ipbmap, 1);
 		if ((rc = dbMount(sbi->ipbmap))) {
-			jERROR(1,("jfs_mount_rw: dbMount failed!\n"));
+			jfs_err("jfs_mount_rw: dbMount failed!");
 			return rc;
 		}
 	}
@@ -288,8 +281,7 @@
 	 * update file system superblock;
 	 */
 	if ((rc = updateSuper(sb, FM_MOUNT))) {
-		jERROR(1,
-		       ("jfs_mount: updateSuper failed w/rc = %d\n", rc));
+		jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc);
 		lmLogClose(sb, log);
 		JFS_SBI(sb)->log = 0;
 		return rc;
@@ -343,15 +335,15 @@
 	bsize = le32_to_cpu(j_sb->s_bsize);
 #ifdef _JFS_4K
 	if (bsize != PSIZE) {
-		jERROR(1, ("Currently only 4K block size supported!\n"));
+		jfs_err("Currently only 4K block size supported!");
 		rc = EINVAL;
 		goto out;
 	}
 #endif				/* _JFS_4K */
 
-	jFYI(1, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n",
+	jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx",
 		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
-		 (unsigned long long) le64_to_cpu(j_sb->s_size)));
+		 (unsigned long long) le64_to_cpu(j_sb->s_size));
 
 	/* validate the descriptors for Secondary AIM and AIT */
 	if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
@@ -375,15 +367,11 @@
 	if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
 	    cpu_to_le32(JFS_GROUPCOMMIT))
 		j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);
-	jFYI(0, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n",
-		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
-		 (unsigned long long) le64_to_cpu(j_sb->s_size)));
 
 	/* validate fs state */
 	if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
 	    !(sb->s_flags & MS_RDONLY)) {
-		jERROR(1,
-		       ("jfs_mount: Mount Failure: File System Dirty.\n"));
+		jfs_err("jfs_mount: Mount Failure: File System Dirty.");
 		rc = EINVAL;
 		goto out;
 	}
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Mon Feb 10 10:39:29 2003
+++ b/fs/jfs/jfs_txnmgr.c	Mon Feb 10 10:39:29 2003
@@ -214,7 +214,7 @@
 	TxAnchor.freelock = TxLock[lid].next;
 	HIGHWATERMARK(stattx.maxlid, lid);
 	if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TxAnchor.TlocksLow == 0)) {
-		jEVENT(0,("txLockAlloc TlocksLow\n"));
+		jfs_info("txLockAlloc TlocksLow");
 		TxAnchor.TlocksLow = 1;
 		wake_up(&jfs_sync_thread_wait);
 	}
@@ -228,7 +228,7 @@
 	TxAnchor.freelock = lid;
 	TxAnchor.tlocksInUse--;
 	if (TxAnchor.TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) {
-		jEVENT(0,("txLockFree TlocksLow no more\n"));
+		jfs_info("txLockFree TlocksLow no more");
 		TxAnchor.TlocksLow = 0;
 		TXN_WAKEUP(&TxAnchor.lowlockwait);
 	}
@@ -336,7 +336,7 @@
 	struct tblock *tblk;
 	struct jfs_log *log;
 
-	jFYI(1, ("txBegin: flag = 0x%x\n", flag));
+	jfs_info("txBegin: flag = 0x%x", flag);
 	log = JFS_SBI(sb)->log;
 
 	TXN_LOCK();
@@ -372,7 +372,7 @@
 	 * allocate transaction id/block
 	 */
 	if ((t = TxAnchor.freetid) == 0) {
-		jFYI(1, ("txBegin: waiting for free tid\n"));
+		jfs_info("txBegin: waiting for free tid");
 		INCREMENT(TxStat.txBegin_freetid);
 		TXN_SLEEP(&TxAnchor.freewait);
 		goto retry;
@@ -382,7 +382,7 @@
 
 	if ((tblk->next == 0) && (current != jfsCommitTask)) {
 		/* Save one tblk for jfsCommit thread */
-		jFYI(1, ("txBegin: waiting for free tid\n"));
+		jfs_info("txBegin: waiting for free tid");
 		INCREMENT(TxStat.txBegin_freetid);
 		TXN_SLEEP(&TxAnchor.freewait);
 		goto retry;
@@ -413,7 +413,7 @@
 
 	TXN_UNLOCK();
 
-	jFYI(1, ("txBegin: returning tid = %d\n", t));
+	jfs_info("txBegin: returning tid = %d", t);
 
 	return t;
 }
@@ -476,7 +476,7 @@
 	struct tblock *tblk = tid_to_tblock(tid);
 	struct jfs_log *log;
 
-	jFYI(1, ("txEnd: tid = %d\n", tid));
+	jfs_info("txEnd: tid = %d", tid);
 	TXN_LOCK();
 
 	/*
@@ -496,9 +496,7 @@
 	 * routine.
 	 */
 	if (tblk->flag & tblkGC_LAZY) {
-		jFYI(1,
-		     ("txEnd called w/lazy tid: %d, tblk = 0x%p\n",
-		      tid, tblk));
+		jfs_info("txEnd called w/lazy tid: %d, tblk = 0x%p", tid, tblk);
 		TXN_UNLOCK();
 
 		spin_lock_irq(&log->gclock);	// LOGGC_LOCK
@@ -507,7 +505,7 @@
 		return;
 	}
 
-	jFYI(1, ("txEnd: tid: %d, tblk = 0x%p\n", tid, tblk));
+	jfs_info("txEnd: tid: %d, tblk = 0x%p", tid, tblk);
 
 	assert(tblk->next == 0);
 
@@ -529,7 +527,7 @@
 		/* forward log syncpt */
 		/* lmSync(log); */
 
-		jFYI(1, ("     log barrier off: 0x%x\n", log->lsn));
+		jfs_info("     log barrier off: 0x%x", log->lsn);
 
 		/* enable new transactions start */
 		clear_bit(log_SYNCBARRIER, &log->flag);
@@ -544,7 +542,6 @@
 	TXN_WAKEUP(&TxAnchor.freewait);
 
 	TXN_UNLOCK();
-	jFYI(1, ("txEnd: exitting\n"));
 }
 
 
@@ -589,8 +586,7 @@
 	if (lid == 0)
 		goto allocateLock;
 
-	jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%d\n",
-		 tid, ip, mp, lid));
+	jfs_info("txLock: tid:%d ip:0x%p mp:0x%p lid:%d", tid, ip, mp, lid);
 
 	/* is page locked by the requester transaction ? */
 	tlck = lid_to_tlock(lid);
@@ -676,9 +672,8 @@
 		mark_metapage_dirty(mp);
 		atomic_inc(&mp->nohomeok);
 
-		jFYI(1,
-		     ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p\n",
-		      mp, atomic_read(&mp->nohomeok), tid, tlck));
+		jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p",
+			 mp, atomic_read(&mp->nohomeok), tid, tlck);
 
 		/* if anonymous transaction, and buffer is on the group
 		 * commit synclist, mark inode to show this.  This will
@@ -774,7 +769,7 @@
 		break;
 
 	default:
-		jERROR(1, ("UFO tlock:0x%p\n", tlck));
+		jfs_err("UFO tlock:0x%p", tlck);
 	}
 
 	/*
@@ -794,7 +789,7 @@
 	/* Only locks on ipimap or ipaimap should reach here */
 	/* assert(jfs_ip->fileset == AGGREGATE_I); */
 	if (jfs_ip->fileset != AGGREGATE_I) {
-		jERROR(1, ("txLock: trying to lock locked page!\n"));
+		jfs_err("txLock: trying to lock locked page!");
 		dump_mem("ip", ip, sizeof(struct inode));
 		dump_mem("mp", mp, sizeof(struct metapage));
 		dump_mem("Locker's tblk", tid_to_tblock(tid),
@@ -805,10 +800,10 @@
 	INCREMENT(stattx.waitlock);	/* statistics */
 	release_metapage(mp);
 
-	jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %d\n",
-		   tid, xtid, lid));
+	jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",
+		 tid, xtid, lid);
 	TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);
-	jEVENT(0, ("txLock: awakened     tid = %d, lid = %d\n", tid, lid));
+	jfs_info("txLock: awakened     tid = %d, lid = %d", tid, lid);
 
 	return NULL;
 }
@@ -869,7 +864,7 @@
 	struct jfs_log *log;
 	int difft, diffp;
 
-	jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk));
+	jfs_info("txUnlock: tblk = 0x%p", tblk);
 	log = JFS_SBI(tblk->sb)->log;
 
 	/*
@@ -879,7 +874,7 @@
 		tlck = lid_to_tlock(lid);
 		next = tlck->next;
 
-		jFYI(1, ("unlocking lid = %d, tlck = 0x%p\n", lid, tlck));
+		jfs_info("unlocking lid = %d, tlck = 0x%p", lid, tlck);
 
 		/* unbind page from tlock */
 		if ((mp = tlck->mp) != NULL &&
@@ -1113,7 +1108,7 @@
 	ino_t top;
 	struct super_block *sb;
 
-	jFYI(1, ("txCommit, tid = %d, flag = %d\n", tid, flag));
+	jfs_info("txCommit, tid = %d, flag = %d", tid, flag);
 	/* is read-only file system ? */
 	if (isReadOnly(iplist[0])) {
 		rc = EROFS;
@@ -1312,7 +1307,7 @@
 		rc = rc1;
 
       TheEnd:
-	jFYI(1, ("txCommit: tid = %d, returning %d\n", tid, rc));
+	jfs_info("txCommit: tid = %d, returning %d", tid, rc);
 	return rc;
 }
 
@@ -1376,7 +1371,7 @@
 			break;
 
 		default:
-			jERROR(1, ("UFO tlock:0x%p\n", tlck));
+			jfs_err("UFO tlock:0x%p", tlck);
 		}
 		if (tlck->mp)
 			release_metapage(tlck->mp);
@@ -1462,9 +1457,8 @@
 
 		/* mark page as homeward bound */
 		tlck->flag |= tlckWRITEPAGE;
-	} else {
-		jERROR(2, ("diLog: UFO type tlck:0x%p\n", tlck));
-	}
+	} else
+		jfs_err("diLog: UFO type tlck:0x%p", tlck);
 #ifdef  _JFS_WIP
 	/*
 	 *      alloc/free external EA extent
@@ -1754,9 +1748,8 @@
 			xadlock->xdlist = &p->xad[lwm];
 			tblk->xflag &= ~COMMIT_LAZY;
 		}
-		jFYI(1,
-		     ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%d\n",
-		      tlck->ip, mp, tlck, lwm, xadlock->count));
+		jfs_info("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d "
+			 "count:%d", tlck->ip, mp, tlck, lwm, xadlock->count);
 
 		maplock->index = 1;
 
@@ -1848,9 +1841,8 @@
 			xadlock->xdlist = &p->xad[XTENTRYSTART];
 			tblk->xflag &= ~COMMIT_LAZY;
 		}
-		jFYI(1,
-		     ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2\n",
-		      tlck->ip, mp, xadlock->count));
+		jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2",
+			 tlck->ip, mp, xadlock->count);
 
 		maplock->index = 1;
 
@@ -1978,9 +1970,9 @@
 			xadlock->count = next - lwm;
 			xadlock->xdlist = &p->xad[lwm];
 
-			jFYI(1,
-			     ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%d\n",
-			      tlck->ip, mp, xadlock->count, lwm, next));
+			jfs_info("xtLog: alloc ip:0x%p mp:0x%p count:%d "
+				 "lwm:%d next:%d",
+				 tlck->ip, mp, xadlock->count, lwm, next);
 			maplock->index++;
 			xadlock++;
 		}
@@ -2002,9 +1994,8 @@
 			pxdlock->count = 1;
 			pxdlock->pxd = tpxd;
 
-			jFYI(1,
-			     ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%d\n",
-			      ip, mp, pxdlock->count, hwm));
+			jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d "
+				 "hwm:%d", ip, mp, pxdlock->count, hwm);
 			maplock->index++;
 			xadlock++;
 		}
@@ -2022,9 +2013,9 @@
 			xadlock->count = hwm - next + 1;
 			xadlock->xdlist = &p->xad[next];
 
-			jFYI(1,
-			     ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%d\n",
-			      tlck->ip, mp, xadlock->count, next, hwm));
+			jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d "
+				 "next:%d hwm:%d",
+				 tlck->ip, mp, xadlock->count, next, hwm);
 			maplock->index++;
 		}
 
@@ -2111,9 +2102,9 @@
 			lrd->log.updatemap.pxd = pxdlock->pxd;
 			lrd->backchain =
 			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));
-			jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%x\n",
+			jfs_info("mapLog: xaddr:0x%lx xlen:0x%x",
 				 (ulong) addressPXD(&pxdlock->pxd),
-				 lengthPXD(&pxdlock->pxd)));
+				 lengthPXD(&pxdlock->pxd));
 		}
 
 		/* update bmap */
@@ -2429,9 +2420,8 @@
 				dbUpdatePMap(ipbmap, FALSE, xaddr,
 					     (s64) xlen, tblk);
 				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
-				jFYI(1,
-				     ("allocPMap: xaddr:0x%lx xlen:%d\n",
-				      (ulong) xaddr, xlen));
+				jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
+					 (ulong) xaddr, xlen);
 			}
 		}
 	} else if (maplock->flag & mlckALLOCPXD) {
@@ -2439,9 +2429,7 @@
 		xaddr = addressPXD(&pxdlock->pxd);
 		xlen = lengthPXD(&pxdlock->pxd);
 		dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
-		jFYI(1,
-		     ("allocPMap: xaddr:0x%lx xlen:%d\n", (ulong) xaddr,
-		      xlen));
+		jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen);
 	} else {		/* (maplock->flag & mlckALLOCPXDLIST) */
 
 		pxdlistlock = (struct xdlistlock *) maplock;
@@ -2451,9 +2439,8 @@
 			xlen = lengthPXD(pxd);
 			dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen,
 				     tblk);
-			jFYI(1,
-			     ("allocPMap: xaddr:0x%lx xlen:%d\n",
-			      (ulong) xaddr, xlen));
+			jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
+				 (ulong) xaddr, xlen);
 		}
 	}
 }
@@ -2479,9 +2466,8 @@
 	pxd_t *pxd;
 	int n;
 
-	jFYI(1,
-	     ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x\n",
-	      tblk, maplock, maptype));
+	jfs_info("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x",
+		 tblk, maplock, maptype);
 
 	/*
 	 * free from persistent map;
@@ -2496,9 +2482,9 @@
 					xlen = lengthXAD(xad);
 					dbUpdatePMap(ipbmap, TRUE, xaddr,
 						     (s64) xlen, tblk);
-					jFYI(1,
-					     ("freePMap: xaddr:0x%lx xlen:%d\n",
-					      (ulong) xaddr, xlen));
+					jfs_info("freePMap: xaddr:0x%lx "
+						 "xlen:%d",
+						 (ulong) xaddr, xlen);
 				}
 			}
 		} else if (maplock->flag & mlckFREEPXD) {
@@ -2507,9 +2493,8 @@
 			xlen = lengthPXD(&pxdlock->pxd);
 			dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
 				     tblk);
-			jFYI(1,
-			     ("freePMap: xaddr:0x%lx xlen:%d\n",
-			      (ulong) xaddr, xlen));
+			jfs_info("freePMap: xaddr:0x%lx xlen:%d",
+				 (ulong) xaddr, xlen);
 		} else {	/* (maplock->flag & mlckALLOCPXDLIST) */
 
 			pxdlistlock = (struct xdlistlock *) maplock;
@@ -2519,9 +2504,8 @@
 				xlen = lengthPXD(pxd);
 				dbUpdatePMap(ipbmap, TRUE, xaddr,
 					     (s64) xlen, tblk);
-				jFYI(1,
-				     ("freePMap: xaddr:0x%lx xlen:%d\n",
-				      (ulong) xaddr, xlen));
+				jfs_info("freePMap: xaddr:0x%lx xlen:%d",
+					 (ulong) xaddr, xlen);
 			}
 		}
 	}
@@ -2538,18 +2522,16 @@
 				xlen = lengthXAD(xad);
 				dbFree(ip, xaddr, (s64) xlen);
 				xad->flag = 0;
-				jFYI(1,
-				     ("freeWMap: xaddr:0x%lx xlen:%d\n",
-				      (ulong) xaddr, xlen));
+				jfs_info("freeWMap: xaddr:0x%lx xlen:%d",
+					 (ulong) xaddr, xlen);
 			}
 		} else if (maplock->flag & mlckFREEPXD) {
 			pxdlock = (struct pxd_lock *) maplock;
 			xaddr = addressPXD(&pxdlock->pxd);
 			xlen = lengthPXD(&pxdlock->pxd);
 			dbFree(ip, xaddr, (s64) xlen);
-			jFYI(1,
-			     ("freeWMap: xaddr:0x%lx xlen:%d\n",
-			      (ulong) xaddr, xlen));
+			jfs_info("freeWMap: xaddr:0x%lx xlen:%d",
+				 (ulong) xaddr, xlen);
 		} else {	/* (maplock->flag & mlckFREEPXDLIST) */
 
 			pxdlistlock = (struct xdlistlock *) maplock;
@@ -2558,9 +2540,8 @@
 				xaddr = addressPXD(pxd);
 				xlen = lengthPXD(pxd);
 				dbFree(ip, xaddr, (s64) xlen);
-				jFYI(1,
-				     ("freeWMap: xaddr:0x%lx xlen:%d\n",
-				      (ulong) xaddr, xlen));
+				jfs_info("freeWMap: xaddr:0x%lx xlen:%d",
+					 (ulong) xaddr, xlen);
 			}
 		}
 	}
@@ -2625,7 +2606,7 @@
 	struct metapage *mp;
 	struct tblock *tblk = tid_to_tblock(tid);
 
-	jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty));
+	jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty);
 
 	/*
 	 * free tlocks of the transaction
@@ -2688,7 +2669,7 @@
 	struct metapage *mp;
 
 	assert(exval == EIO || exval == ENOMEM);
-	jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd));
+	jfs_warn("txAbortCommit: cd:0x%p", cd);
 
 	/*
 	 * free tlocks of the transaction
@@ -2743,12 +2724,11 @@
 	       ((tblk->flag & tblkGC_UNLOCKED) == 0)) {
 		/* We must have gotten ahead of the user thread
 		 */
-		jFYI(1,
-		     ("jfs_lazycommit: tblk 0x%p not unlocked\n", tblk));
+		jfs_info("jfs_lazycommit: tblk 0x%p not unlocked", tblk);
 		schedule();
 	}
 
-	jFYI(1, ("txLazyCommit: processing tblk 0x%p\n", tblk));
+	jfs_info("txLazyCommit: processing tblk 0x%p", tblk);
 
 	txUpdateMap(tblk);
 
@@ -2775,7 +2755,7 @@
 	} else
 		spin_unlock_irq(&log->gclock);	// LOGGC_UNLOCK
 
-	jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk));
+	jfs_info("txLazyCommit: done: tblk = 0x%p", tblk);
 }
 
 /*
@@ -2800,10 +2780,10 @@
 
 	jfsCommitTask = current;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	LAZY_LOCK_INIT();
 	TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0;
@@ -2835,7 +2815,7 @@
 			txLazyCommit(tblk);
 
 			/*
-			 * We can be running indefinately if other processors
+			 * We can be running indefinitely if other processors
 			 * are adding transactions to this list
 			 */
 			cond_resched();
@@ -2861,9 +2841,9 @@
 	} while (!jfs_stop_threads);
 
 	if (TxAnchor.unlock_queue)
-		jERROR(1, ("jfs_lazycommit being killed with pending transactions!\n"));
+		jfs_err("jfs_lazycommit being killed w/pending transactions!");
 	else
-		jFYI(1, ("jfs_lazycommit being killed\n"));
+		jfs_info("jfs_lazycommit being killed\n");
 	complete(&jfsIOwait);
 	return 0;
 }
@@ -3005,10 +2985,10 @@
 
 	unlock_kernel();
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	complete(&jfsIOwait);
 
@@ -3077,7 +3057,7 @@
 		}
 	} while (!jfs_stop_threads);
 
-	jFYI(1, ("jfs_sync being killed\n"));
+	jfs_info("jfs_sync being killed");
 	complete(&jfsIOwait);
 	return 0;
 }
diff -Nru a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
--- a/fs/jfs/jfs_umount.c	Mon Feb 10 10:39:27 2003
+++ b/fs/jfs/jfs_umount.c	Mon Feb 10 10:39:27 2003
@@ -58,7 +58,7 @@
 	struct jfs_log *log;
 	int rc = 0;
 
-	jFYI(1, ("\n	UnMount JFS: sb:0x%p\n", sb));
+	jfs_info("UnMount JFS: sb:0x%p", sb);
 
 	/*
 	 *      update superblock and close log 
@@ -74,7 +74,6 @@
 	/*
 	 * close fileset inode allocation map (aka fileset inode)
 	 */
-	jEVENT(0, ("jfs_umount: close ipimap:0x%p\n", ipimap));
 	diUnmount(ipimap, 0);
 
 	diFreeSpecial(ipimap);
@@ -85,7 +84,6 @@
 	 */
 	ipaimap2 = sbi->ipaimap2;
 	if (ipaimap2) {
-		jEVENT(0, ("jfs_umount: close ipaimap2:0x%p\n", ipaimap2));
 		diUnmount(ipaimap2, 0);
 		diFreeSpecial(ipaimap2);
 		sbi->ipaimap2 = NULL;
@@ -95,7 +93,6 @@
 	 * close aggregate inode allocation map
 	 */
 	ipaimap = sbi->ipaimap;
-	jEVENT(0, ("jfs_umount: close ipaimap:0x%p\n", ipaimap));
 	diUnmount(ipaimap, 0);
 	diFreeSpecial(ipaimap);
 	sbi->ipaimap = NULL;
@@ -103,7 +100,6 @@
 	/*
 	 * close aggregate block allocation map
 	 */
-	jEVENT(0, ("jfs_umount: close ipbmap:%p\n", ipbmap));
 	dbUnmount(ipbmap, 0);
 
 	diFreeSpecial(ipbmap);
@@ -134,7 +130,7 @@
 		 */
 		rc = lmLogClose(sb, log);
 	}
-	jFYI(0, ("	UnMount JFS Complete: %d\n", rc));
+	jfs_info("UnMount JFS Complete: rc = %d", rc);
 	return rc;
 }
 
diff -Nru a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
--- a/fs/jfs/jfs_unicode.c	Mon Feb 10 10:39:31 2003
+++ b/fs/jfs/jfs_unicode.c	Mon Feb 10 10:39:31 2003
@@ -47,7 +47,6 @@
 		}
 	}
 	to[outlen] = 0;
-	jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to));
 	return outlen;
 }
 
@@ -63,21 +62,16 @@
 	int charlen;
 	int i;
 
-	jEVENT(0, ("jfs_strtoUCS - '%s'\n", from));
-
 	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 		charlen = codepage->char2uni(from, len, &to[i]);
 		if (charlen < 1) {
-			jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n",
-				   charlen));
-			jERROR(1, ("charset = %s, char = 0x%x\n",
-				   codepage->charset, (unsigned char) *from));
+			jfs_err("jfs_strtoUCS: char2uni returned %d.", charlen);
+			jfs_err("charset = %s, char = 0x%x",
+				codepage->charset, (unsigned char) *from);
 			to[i] = 0x003f;	/* a question mark */
 			charlen = 1;
 		}
 	}
-
-	jEVENT(0, (" returning %d\n", i));
 
 	to[i] = 0;
 	return i;
diff -Nru a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
--- a/fs/jfs/jfs_xtree.c	Mon Feb 10 10:39:27 2003
+++ b/fs/jfs/jfs_xtree.c	Mon Feb 10 10:39:27 2003
@@ -69,7 +69,7 @@
                     (le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\
                     (le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\
                 {\
-                        jERROR(1,("XT_GETPAGE: xtree page corrupt\n"));\
+                        jfs_err("XT_GETPAGE: xtree page corrupt");\
 			BT_PUTPAGE(MP);\
 			updateSuper((IP)->i_sb, FM_DIRTY);\
 			MP = NULL;\
@@ -169,9 +169,8 @@
 		size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
 		    JFS_SBI(ip->i_sb)->l2bsize;
 		if (lstart >= size) {
-			jERROR(1,
-			       ("xtLookup: lstart (0x%lx) >= size (0x%lx)\n",
-				(ulong) lstart, (ulong) size));
+			jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)",
+				(ulong) lstart, (ulong) size);
 			return 0;
 		}
 	}
@@ -181,7 +180,7 @@
 	 */
 //search:
 	if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) {
-		jERROR(1, ("xtLookup: xtSearch returned %d\n", rc));
+		jfs_err("xtLookup: xtSearch returned %d", rc);
 		return rc;
 	}
 
@@ -198,10 +197,8 @@
 	 * lstart is a page start address,
 	 * i.e., lstart cannot start in a hole;
 	 */
-	if (cmp) {
-		jFYI(1, ("xtLookup: cmp = %d\n", cmp));
+	if (cmp)
 		goto out;
-	}
 
 	/*
 	 * lxd covered by xad
@@ -212,10 +209,6 @@
 	xend = xoff + xlen;
 	xaddr = addressXAD(xad);
 
-	jEVENT(0,
-	       ("index = %d, xoff = 0x%lx, xlen = 0x%x, xaddr = 0x%lx\n",
-		index, (ulong) xoff, xlen, (ulong) xaddr));
-
 	/* initialize new pxd */
 	*pflag = xad->flag;
 	*paddr = xaddr + (lstart - xoff);
@@ -802,8 +795,7 @@
 	struct tlock *tlck;
 	struct xtlock *xtlck;
 
-	jFYI(1,
-	     ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen));
+	jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
 
 	/*
 	 *      search for the entry location at which to insert:
@@ -1248,8 +1240,7 @@
 	if (rmp == NULL)
 		return EIO;
 
-	jEVENT(0,
-	       ("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp));
+	jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
 
 	BT_MARK_DIRTY(rmp, ip);
 	/*
@@ -1324,7 +1315,7 @@
 
 		ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
 
-		jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp));
+		jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
 		return 0;
 	}
 
@@ -1440,7 +1431,7 @@
 
 	ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
 
-	jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp));
+	jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
 	return rc;
 }
 
@@ -1496,7 +1487,7 @@
 	if (rmp == NULL)
 		return EIO;
 
-	jEVENT(0, ("xtSplitRoot: ip:0x%p rmp:0x%p\n", ip, rmp));
+	jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
 
 	/*
 	 * acquire a transaction lock on the new right page;
@@ -1581,7 +1572,7 @@
 
 	ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
 
-	jEVENT(0, ("xtSplitRoot: sp:0x%p rp:0x%p\n", sp, rp));
+	jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp);
 	return 0;
 }
 
@@ -1615,8 +1606,7 @@
 	struct xtlock *xtlck = 0;
 	int rootsplit = 0;
 
-	jFYI(1,
-	     ("xtExtend: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen));
+	jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
 
 	/* there must exist extent to be extended */
 	if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT)))
@@ -1628,9 +1618,6 @@
 
 	/* extension must be contiguous */
 	xad = &p->xad[index];
-	jFYI(0, ("xtExtend: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
-		 (ulong) offsetXAD(xad), lengthXAD(xad),
-		 (ulong) addressXAD(xad)));
 	assert((offsetXAD(xad) + lengthXAD(xad)) == xoff);
 
 	/*
@@ -1893,10 +1880,6 @@
 			PXDlength(&pxdlock->pxd, rlen);
 			pxdlock->index = 1;
 		}
-		jEVENT(0,
-		       ("xtTailgate: free extent xaddr:0x%lx xlen:0x%x\n",
-			(ulong) addressPXD(&pxdlock->pxd),
-			lengthPXD(&pxdlock->pxd)));
 	} else
 		/* free from WMAP */
 		dbFree(ip, addressXAD(xad) + llen, (s64) rlen);
@@ -2408,9 +2391,8 @@
 
 	xaddr = *xaddrp;
 	xlen = *xlenp;
-	jEVENT(0,
-	       ("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx\n",
-		(ulong) xoff, maxblocks, xlen, (ulong) xaddr));
+	jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx",
+		 (ulong) xoff, maxblocks, xlen, (ulong) xaddr);
 
 	/*
 	 *      search for the entry location at which to insert:
@@ -2747,9 +2729,8 @@
 			p->header.nextindex =
 			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
 					1);
-			jEVENT(0,
-			       ("xtDeleteUp(entry): 0x%lx[%d]\n",
-				(ulong) parent->bn, index));
+			jfs_info("xtDeleteUp(entry): 0x%lx[%d]",
+				 (ulong) parent->bn, index);
 		}
 
 		/* unpin the parent page */
@@ -2809,10 +2790,8 @@
 	if (offset >= ip->i_size)
 		return ESTALE;	/* stale extent */
 
-	jEVENT(0,
-	       ("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx\n",
-		xtype, (ulong) xoff, xlen, (ulong) oxaddr,
-		(ulong) nxaddr));
+	jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx",
+		 xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr);
 
 	/*
 	 *      1. get and validate the parent xtpage/xad entry
@@ -2855,7 +2834,7 @@
 		 */
 		xad = &pp->xad[index];
 	}
-	jEVENT(0, ("xtRelocate: parent xad entry validated.\n"));
+	jfs_info("xtRelocate: parent xad entry validated.");
 
 	/*
 	 *      2. relocate the extent
@@ -2926,7 +2905,7 @@
 		/* get back parent page */
 		rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
 		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
-		jEVENT(0, ("xtRelocate: target data extent relocated.\n"));
+		jfs_info("xtRelocate: target data extent relocated.");
 	} else {		/* (xtype  == XTPAGE) */
 
 		/*
@@ -3026,7 +3005,7 @@
 
 		/* unpin the target page to new homeward bound */
 		XT_PUTPAGE(mp);
-		jEVENT(0, ("xtRelocate: target xtpage relocated.\n"));
+		jfs_info("xtRelocate: target xtpage relocated.");
 	}
 
 	/*
@@ -3067,7 +3046,7 @@
 	 * update which will write LOG_REDOPAGE and update bmap for
 	 * allocation of XAD_NEW destination extent;
 	 */
-	jEVENT(0, ("xtRelocate: update parent xad entry.\n"));
+	jfs_info("xtRelocate: update parent xad entry.");
 	BT_MARK_DIRTY(pmp, ip);
 	tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW);
 	xtlck = (struct xtlock *) & tlck->lock;
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Mon Feb 10 10:39:30 2003
+++ b/fs/jfs/namei.c	Mon Feb 10 10:39:30 2003
@@ -70,7 +70,7 @@
 	struct inode *iplist[2];
 	struct tblock *tblk;
 
-	jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+	jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name);
 
 	/*
 	 * search parent directory for entry/freespace
@@ -96,7 +96,7 @@
 	down(&JFS_IP(ip)->commit_sem);
 
 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
-		jERROR(1, ("jfs_create: dtSearch returned %d\n", rc));
+		jfs_err("jfs_create: dtSearch returned %d", rc);
 		goto out3;
 	}
 
@@ -118,7 +118,7 @@
 	 */
 	ino = ip->i_ino;
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
-		jERROR(1, ("jfs_create: dtInsert returned %d\n", rc));
+		jfs_err("jfs_create: dtInsert returned %d", rc);
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks Filesystem dirty */
 		else
@@ -159,7 +159,7 @@
 
       out1:
 
-	jFYI(1, ("jfs_create: rc:%d\n", -rc));
+	jfs_info("jfs_create: rc:%d", -rc);
 	return -rc;
 }
 
@@ -190,7 +190,7 @@
 	struct inode *iplist[2];
 	struct tblock *tblk;
 
-	jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+	jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name);
 
 	/* link count overflow on parent directory ? */
 	if (dip->i_nlink == JFS_LINK_MAX) {
@@ -222,7 +222,7 @@
 	down(&JFS_IP(ip)->commit_sem);
 
 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
-		jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc));
+		jfs_err("jfs_mkdir: dtSearch returned %d", rc);
 		goto out3;
 	}
 
@@ -244,7 +244,7 @@
 	 */
 	ino = ip->i_ino;
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
-		jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc));
+		jfs_err("jfs_mkdir: dtInsert returned %d", rc);
 
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks Filesystem dirty */
@@ -289,7 +289,7 @@
 
       out1:
 
-	jFYI(1, ("jfs_mkdir: rc:%d\n", -rc));
+	jfs_info("jfs_mkdir: rc:%d", -rc);
 	return -rc;
 }
 
@@ -322,7 +322,7 @@
 	struct inode *iplist[2];
 	struct tblock *tblk;
 
-	jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+	jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
 
 	/* directory must be empty to be removed */
 	if (!dtEmpty(ip)) {
@@ -351,7 +351,7 @@
 	 */
 	ino = ip->i_ino;
 	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
-		jERROR(1, ("jfs_rmdir: dtDelete returned %d\n", rc));
+		jfs_err("jfs_rmdir: dtDelete returned %d", rc);
 		if (rc == EIO)
 			txAbort(tid, 1);
 		txEnd(tid);
@@ -411,7 +411,7 @@
 	free_UCSname(&dname);
 
       out:
-	jFYI(1, ("jfs_rmdir: rc:%d\n", rc));
+	jfs_info("jfs_rmdir: rc:%d", rc);
 	return -rc;
 }
 
@@ -447,7 +447,7 @@
 	s64 new_size = 0;
 	int commit_flag;
 
-	jFYI(1, ("jfs_unlink: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+	jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name);
 
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
 		goto out;
@@ -467,7 +467,7 @@
 	 */
 	ino = ip->i_ino;
 	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
-		jERROR(1, ("jfs_unlink: dtDelete returned %d\n", rc));
+		jfs_err("jfs_unlink: dtDelete returned %d", rc);
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks FS Dirty */
 		txEnd(tid);
@@ -560,7 +560,7 @@
       out1:
 	free_UCSname(&dname);
       out:
-	jFYI(1, ("jfs_unlink: rc:%d\n", -rc));
+	jfs_info("jfs_unlink: rc:%d", -rc);
 	return -rc;
 }
 
@@ -593,7 +593,7 @@
 	int filetype;
 	struct tblock *tblk;
 
-	jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip));
+	jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip);
 
 	filetype = ip->i_mode & S_IFMT;
 	switch (filetype) {
@@ -661,7 +661,7 @@
 	int rc = 0;
 	int type;
 
-	jFYI(1, ("freeZeroLink: ip = 0x%p\n", ip));
+	jfs_info("freeZeroLink: ip = 0x%p", ip);
 
 	/* return if not reg or symbolic link or if size is
 	 * already ok.
@@ -767,9 +767,8 @@
 	struct btstack btstack;
 	struct inode *iplist[2];
 
-	jFYI(1,
-	     ("jfs_link: %s %s\n", old_dentry->d_name.name,
-	      dentry->d_name.name));
+	jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
+		 dentry->d_name.name);
 
 	tid = txBegin(ip->i_sb, 0);
 
@@ -814,7 +813,7 @@
 	up(&JFS_IP(dir)->commit_sem);
 	up(&JFS_IP(ip)->commit_sem);
 
-	jFYI(1, ("jfs_link: rc:%d\n", rc));
+	jfs_info("jfs_link: rc:%d", rc);
 	return -rc;
 }
 
@@ -855,7 +854,7 @@
 
 	struct inode *iplist[2];
 
-	jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name));
+	jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
 
 	ssize = strlen(name) + 1;
 
@@ -898,7 +897,7 @@
 
 
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
-		jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc));
+		jfs_err("jfs_symlink: dtInsert returned %d", rc);
 		/* discard ne inode */
 		goto out3;
 
@@ -933,15 +932,14 @@
 		if (ssize > sizeof (JFS_IP(ip)->i_inline))
 			JFS_IP(ip)->mode2 &= ~INLINEEA;
 
-		jFYI(1,
-		     ("jfs_symlink: fast symlink added  ssize:%d name:%s \n",
-		      ssize, name));
+		jfs_info("jfs_symlink: fast symlink added  ssize:%d name:%s ",
+			 ssize, name);
 	}
 	/*
 	 * write source path name in a single extent
 	 */
 	else {
-		jFYI(1, ("jfs_symlink: allocate extent ip:0x%p\n", ip));
+		jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
 
 		ip->i_op = &page_symlink_inode_operations;
 		ip->i_mapping->a_ops = &jfs_aops;
@@ -1033,7 +1031,7 @@
 #endif
 
       out1:
-	jFYI(1, ("jfs_symlink: rc:%d\n", -rc));
+	jfs_info("jfs_symlink: rc:%d", -rc);
 	return -rc;
 }
 
@@ -1064,9 +1062,8 @@
 	int commit_flag;
 
 
-	jFYI(1,
-	     ("jfs_rename: %s %s\n", old_dentry->d_name.name,
-	      new_dentry->d_name.name));
+	jfs_info("jfs_rename: %s %s", old_dentry->d_name.name,
+		 new_dentry->d_name.name);
 
 	old_ip = old_dentry->d_inode;
 	new_ip = new_dentry->d_inode;
@@ -1168,18 +1165,16 @@
 		rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
 			      JFS_CREATE);
 		if (rc) {
-			jERROR(1,
-			       ("jfs_rename didn't expect dtSearch to fail w/rc = %d\n",
-				rc));
+			jfs_err("jfs_rename didn't expect dtSearch to fail "
+				"w/rc = %d", rc);
 			goto out4;
 		}
 
 		ino = old_ip->i_ino;
 		rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
 		if (rc) {
-			jERROR(1,
-			       ("jfs_rename: dtInsert failed w/rc = %d\n",
-				rc));
+			jfs_err("jfs_rename: dtInsert failed w/rc = %d",
+				rc);
 			goto out4;
 		}
 		if (S_ISDIR(old_ip->i_mode))
@@ -1192,9 +1187,8 @@
 	ino = old_ip->i_ino;
 	rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
 	if (rc) {
-		jERROR(1,
-		       ("jfs_rename did not expect dtDelete to return rc = %d\n",
-			rc));
+		jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
+			rc);
 		txAbort(tid, 1);	/* Marks Filesystem dirty */
 		goto out4;
 	}
@@ -1297,7 +1291,7 @@
 		clear_cflag(COMMIT_Stale, old_dir);
 	}
 
-	jFYI(1, ("jfs_rename: returning %d\n", rc));
+	jfs_info("jfs_rename: returning %d", rc);
 	return -rc;
 }
 
@@ -1318,7 +1312,7 @@
 	tid_t tid;
 	struct tblock *tblk;
 
-	jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name));
+	jfs_info("jfs_mknod: %s", dentry->d_name.name);
 
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
 		goto out;
@@ -1378,7 +1372,7 @@
 #endif
 
       out:
-	jFYI(1, ("jfs_mknod: returning %d\n", rc));
+	jfs_info("jfs_mknod: returning %d", rc);
 	return -rc;
 }
 
@@ -1392,7 +1386,7 @@
 	int len = dentry->d_name.len;
 	int rc;
 
-	jFYI(1, ("jfs_lookup: name = %s\n", name));
+	jfs_info("jfs_lookup: name = %s", name);
 
 
 	if ((name[0] == '.') && (len == 1))
@@ -1409,17 +1403,14 @@
 			d_add(dentry, NULL);
 			return ERR_PTR(0);
 		} else if (rc) {
-			jERROR(1,
-			       ("jfs_lookup: dtSearch returned %d\n", rc));
+			jfs_err("jfs_lookup: dtSearch returned %d", rc);
 			return ERR_PTR(-rc);
 		}
 	}
 
 	ip = jfs_iget(dip->i_sb, inum);
 	if (ip == NULL) {
-		jERROR(1,
-		       ("jfs_lookup: iget failed on inum %d\n",
-			(uint) inum));
+		jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum);
 		return ERR_PTR(-EACCES);
 	}
 
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c	Mon Feb 10 10:39:26 2003
+++ b/fs/jfs/super.c	Mon Feb 10 10:39:26 2003
@@ -50,7 +50,7 @@
 DECLARE_COMPLETION(jfsIOwait);
 
 #ifdef CONFIG_JFS_DEBUG
-int jfsloglevel = 1;
+int jfsloglevel = JFS_LOGLEVEL_WARN;
 MODULE_PARM(jfsloglevel, "i");
 MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
 #endif
@@ -120,7 +120,7 @@
 	s64 maxinodes;
 	struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap;
 
-	jFYI(1, ("In jfs_statfs\n"));
+	jfs_info("In jfs_statfs");
 	buf->f_type = JFS_SUPER_MAGIC;
 	buf->f_bsize = sbi->bsize;
 	buf->f_blocks = sbi->bmap->db_mapsize;
@@ -151,11 +151,10 @@
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	int rc;
 
-	jFYI(1, ("In jfs_put_super\n"));
+	jfs_info("In jfs_put_super");
 	rc = jfs_umount(sb);
-	if (rc) {
-		jERROR(1, ("jfs_umount failed with return code %d\n", rc));
-	}
+	if (rc)
+		jfs_err("jfs_umount failed with return code %d", rc);
 	unload_nls(sbi->nls_tab);
 	sbi->nls_tab = NULL;
 
@@ -259,7 +258,7 @@
 	int rc;
 	s64 newLVSize = 0;
 
-	jFYI(1, ("In jfs_read_super: s_flags=0x%lx\n", sb->s_flags));
+	jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
 
 	sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
 	if (!sbi)
@@ -291,8 +290,7 @@
 	rc = jfs_mount(sb);
 	if (rc) {
 		if (!silent) {
-			jERROR(1,
-			       ("jfs_mount failed w/return code = %d\n", rc));
+			jfs_err("jfs_mount failed w/return code = %d", rc);
 		}
 		goto out_kfree;
 	}
@@ -302,9 +300,8 @@
 		rc = jfs_mount_rw(sb, 0);
 		if (rc) {
 			if (!silent) {
-				jERROR(1,
-				       ("jfs_mount_rw failed w/return code = %d\n",
-					rc));
+				jfs_err("jfs_mount_rw failed, return code = %d",
+					rc);
 			}
 			goto out_no_rw;
 		}
@@ -335,14 +332,14 @@
 	return 0;
 
 out_no_root:
-	jEVENT(1, ("jfs_read_super: get root inode failed\n"));
+	jfs_err("jfs_read_super: get root inode failed");
 	if (inode)
 		iput(inode);
 
 out_no_rw:
 	rc = jfs_umount(sb);
 	if (rc) {
-		jERROR(1, ("jfs_umount failed with return code %d\n", rc));
+		jfs_err("jfs_umount failed with return code %d", rc);
 	}
 out_kfree:
 	if (sbi->nls_tab)
@@ -370,8 +367,7 @@
 
 	if (!(sb->s_flags & MS_RDONLY)) {
 		if ((rc = lmLogInit(log)))
-			jERROR(1,
-			       ("jfs_unlock failed with return code %d\n", rc));
+			jfs_err("jfs_unlock failed with return code %d", rc);
 		else
 			txResume(sb);
 	}
@@ -458,7 +454,7 @@
 	 */
 	rc = metapage_init();
 	if (rc) {
-		jERROR(1, ("metapage_init failed w/rc = %d\n", rc));
+		jfs_err("metapage_init failed w/rc = %d", rc);
 		goto free_slab;
 	}
 
@@ -467,7 +463,7 @@
 	 */
 	rc = txInit();
 	if (rc) {
-		jERROR(1, ("txInit failed w/rc = %d\n", rc));
+		jfs_err("txInit failed w/rc = %d", rc);
 		goto free_metapage;
 	}
 
@@ -477,8 +473,7 @@
 	jfsIOthread = kernel_thread(jfsIOWait, 0,
 				    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsIOthread < 0) {
-		jERROR(1,
-		       ("init_jfs_fs: fork failed w/rc = %d\n", jfsIOthread));
+		jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
 		goto end_txmngr;
 	}
 	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
@@ -486,9 +481,7 @@
 	jfsCommitThread = kernel_thread(jfs_lazycommit, 0,
 					CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsCommitThread < 0) {
-		jERROR(1,
-		       ("init_jfs_fs: fork failed w/rc = %d\n",
-			jfsCommitThread));
+		jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread);
 		goto kill_iotask;
 	}
 	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
@@ -496,8 +489,7 @@
 	jfsSyncThread = kernel_thread(jfs_sync, 0,
 				      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsSyncThread < 0) {
-		jERROR(1,
-		       ("init_jfs_fs: fork failed w/rc = %d\n", jfsSyncThread));
+		jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
 		goto kill_committask;
 	}
 	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
@@ -527,7 +519,7 @@
 
 static void __exit exit_jfs_fs(void)
 {
-	jFYI(1, ("exit_jfs_fs called\n"));
+	jfs_info("exit_jfs_fs called");
 
 	jfs_stop_threads = 1;
 	txExit();
diff -Nru a/fs/lockd/Makefile b/fs/lockd/Makefile
--- a/fs/lockd/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/lockd/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux lock manager stuff
 #
 
-export-objs := lockd_syms.o
-
 obj-$(CONFIG_LOCKD) += lockd.o
 
 lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \
diff -Nru a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
--- a/fs/lockd/clntproc.c	Mon Feb 10 10:39:23 2003
+++ b/fs/lockd/clntproc.c	Mon Feb 10 10:39:23 2003
@@ -139,7 +139,7 @@
 	}
 
 	/* Keep the old signal mask */
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	oldset = current->blocked;
 
 	/* If we're cleaning up locks because the process is exiting,
@@ -149,7 +149,7 @@
 	    && (current->flags & PF_EXITING)) {
 		sigfillset(&current->blocked);	/* Mask all signals */
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 		call = nlmclnt_alloc_call();
 		if (!call) {
@@ -158,7 +158,7 @@
 		}
 		call->a_flags = RPC_TASK_ASYNC;
 	} else {
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 		memset(call, 0, sizeof(*call));
 		locks_init_lock(&call->a_args.lock.fl);
 		locks_init_lock(&call->a_res.lock.fl);
@@ -183,10 +183,10 @@
 		kfree(call);
 
  out_restore:
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	current->blocked = oldset;
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 done:
 	dprintk("lockd: clnt proc returns %d\n", status);
@@ -588,11 +588,11 @@
 	int		status;
 
 	/* Block all signals while setting up call */
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	oldset = current->blocked;
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 	req = nlmclnt_alloc_call();
 	if (!req)
@@ -607,10 +607,10 @@
 	if (status < 0)
 		kfree(req);
 
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	current->blocked = oldset;
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
 	return status;
 }
diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c
--- a/fs/lockd/svc.c	Mon Feb 10 10:39:29 2003
+++ b/fs/lockd/svc.c	Mon Feb 10 10:39:29 2003
@@ -101,10 +101,10 @@
 	sprintf(current->comm, "lockd");
 
 	/* Process request with signals blocked.  */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked, sigmask(SIGKILL));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* kick rpciod */
 	rpciod_up();
@@ -126,9 +126,9 @@
 	{
 		long timeout = MAX_SCHEDULE_TIMEOUT;
 		if (signalled()) {
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 			if (nlmsvc_ops) {
 				nlmsvc_invalidate_all();
 				grace_period_expire = set_grace_period();
@@ -297,9 +297,9 @@
 			"lockd_down: lockd failed to exit, clearing pid\n");
 		nlmsvc_pid = 0;
 	}
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 out:
 	up(&nlmsvc_sema);
 }
diff -Nru a/fs/mpage.c b/fs/mpage.c
--- a/fs/mpage.c	Mon Feb 10 10:39:24 2003
+++ b/fs/mpage.c	Mon Feb 10 10:39:24 2003
@@ -116,6 +116,49 @@
 	return bio;
 }
 
+/*
+ * support function for mpage_readpages.  The fs supplied get_block might
+ * return an up to date buffer.  This is used to map that buffer into
+ * the page, which allows readpage to avoid triggering a duplicate call
+ * to get_block.
+ *
+ * The idea is to avoid adding buffers to pages that don't already have
+ * them.  So when the buffer is up to date and the page size == block size,
+ * this marks the page up to date instead of adding new buffers.
+ */
+static void 
+map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block) 
+{
+	struct inode *inode = page->mapping->host;
+	struct buffer_head *page_bh, *head;
+	int block = 0;
+
+	if (!page_has_buffers(page)) {
+		/*
+		 * don't make any buffers if there is only one buffer on
+		 * the page and the page just needs to be set up to date
+		 */
+		if (inode->i_blkbits == PAGE_CACHE_SHIFT && 
+		    buffer_uptodate(bh)) {
+			SetPageUptodate(page);    
+			return;
+		}
+		create_empty_buffers(page, 1 << inode->i_blkbits, 0);
+	}
+	head = page_buffers(page);
+	page_bh = head;
+	do {
+		if (block == page_block) {
+			page_bh->b_state = bh->b_state;
+			page_bh->b_bdev = bh->b_bdev;
+			page_bh->b_blocknr = bh->b_blocknr;
+			break;
+		}
+		page_bh = page_bh->b_this_page;
+		block++;
+	} while (page_bh != head);
+}
+
 /**
  * mpage_readpages - populate an address space with some pages, and
  *                       start reads against them.
@@ -186,6 +229,7 @@
 	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
 	last_block = (inode->i_size + blocksize - 1) >> blkbits;
 
+	bh.b_page = page;
 	for (page_block = 0; page_block < blocks_per_page;
 				page_block++, block_in_file++) {
 		bh.b_state = 0;
@@ -200,6 +244,17 @@
 				first_hole = page_block;
 			continue;
 		}
+
+		/* some filesystems will copy data into the page during
+		 * the get_block call, in which case we don't want to
+		 * read it again.  map_buffer_to_page copies the data
+		 * we just collected from get_block into the page's buffers
+		 * so readpage doesn't have to repeat the get_block call
+		 */
+		if (buffer_uptodate(&bh)) {
+			map_buffer_to_page(page, &bh, page_block);
+			goto confused;
+		}
 	
 		if (first_hole != blocks_per_page)
 			goto confused;		/* hole -> non-hole */
@@ -256,7 +311,10 @@
 confused:
 	if (bio)
 		bio = mpage_bio_submit(READ, bio);
-	block_read_full_page(page, get_block);
+	if (!PageUptodate(page))
+	        block_read_full_page(page, get_block);
+	else
+		unlock_page(page);
 	goto out;
 }
 
@@ -344,6 +402,7 @@
 	sector_t boundary_block = 0;
 	struct block_device *boundary_bdev = NULL;
 	int length;
+	struct buffer_head map_bh;
 
 	if (page_has_buffers(page)) {
 		struct buffer_head *head = page_buffers(page);
@@ -401,8 +460,8 @@
 	BUG_ON(!PageUptodate(page));
 	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
 	last_block = (inode->i_size - 1) >> blkbits;
+	map_bh.b_page = page;
 	for (page_block = 0; page_block < blocks_per_page; ) {
-		struct buffer_head map_bh;
 
 		map_bh.b_state = 0;
 		if (get_block(inode, block_in_file, &map_bh, 1))
@@ -559,7 +618,6 @@
 	int (*writepage)(struct page *page, struct writeback_control *wbc);
 
 	if (wbc->nonblocking && bdi_write_congested(bdi)) {
-		blk_run_queues();
 		wbc->encountered_congestion = 1;
 		return 0;
 	}
@@ -614,7 +672,6 @@
 			if (ret || (--(wbc->nr_to_write) <= 0))
 				done = 1;
 			if (wbc->nonblocking && bdi_write_congested(bdi)) {
-				blk_run_queues();
 				wbc->encountered_congestion = 1;
 				done = 1;
 			}
diff -Nru a/fs/msdos/Makefile b/fs/msdos/Makefile
--- a/fs/msdos/Makefile	Mon Feb 10 10:39:32 2003
+++ b/fs/msdos/Makefile	Mon Feb 10 10:39:32 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux msdos filesystem routines.
 #
 
-export-objs := msdosfs_syms.o
-
 obj-$(CONFIG_MSDOS_FS) += msdos.o
 
 msdos-objs := namei.o msdosfs_syms.o
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Mon Feb 10 10:39:24 2003
+++ b/fs/namei.c	Mon Feb 10 10:39:24 2003
@@ -1659,12 +1659,19 @@
 	return error;
 }
 
+/*
+ * Make sure that the actual truncation of the file will occur outside its
+ * directory's i_sem.  Truncate can take a long time if there is a lot of
+ * writeout happening, and we don't want to prevent access to the directory
+ * while waiting on the I/O.
+ */
 asmlinkage long sys_unlink(const char * pathname)
 {
 	int error = 0;
 	char * name;
 	struct dentry *dentry;
 	struct nameidata nd;
+	struct inode *inode = NULL;
 
 	name = getname(pathname);
 	if(IS_ERR(name))
@@ -1683,6 +1690,9 @@
 		/* Why not before? Because we want correct error value */
 		if (nd.last.name[nd.last.len])
 			goto slashes;
+		inode = dentry->d_inode;
+		if (inode)
+			inode = igrab(inode);
 		error = vfs_unlink(nd.dentry->d_inode, dentry);
 	exit2:
 		dput(dentry);
@@ -1693,6 +1703,8 @@
 exit:
 	putname(name);
 
+	if (inode)
+		iput(inode);	/* truncate the inode here */
 	return error;
 
 slashes:
diff -Nru a/fs/namespace.c b/fs/namespace.c
--- a/fs/namespace.c	Mon Feb 10 10:39:29 2003
+++ b/fs/namespace.c	Mon Feb 10 10:39:29 2003
@@ -287,7 +287,7 @@
 static int do_umount(struct vfsmount *mnt, int flags)
 {
 	struct super_block * sb = mnt->mnt_sb;
-	int retval = 0;
+	int retval;
 
 	retval = security_sb_umount(mnt, flags);
 	if (retval)
diff -Nru a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
--- a/fs/ncpfs/sock.c	Mon Feb 10 10:39:25 2003
+++ b/fs/ncpfs/sock.c	Mon Feb 10 10:39:25 2003
@@ -745,7 +745,7 @@
 		sigset_t old_set;
 		unsigned long mask, flags;
 
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		old_set = current->blocked;
 		if (current->flags & PF_EXITING)
 			mask = 0;
@@ -764,7 +764,7 @@
 		}
 		siginitsetinv(&current->blocked, mask);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 		
 		fs = get_fs();
 		set_fs(get_ds());
@@ -773,10 +773,10 @@
 
 		set_fs(fs);
 
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		current->blocked = old_set;
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 	}
 
 	DDPRINTK("do_ncp_rpc_call returned %d\n", result);
diff -Nru a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
--- a/fs/nfs/mount_clnt.c	Mon Feb 10 10:39:23 2003
+++ b/fs/nfs/mount_clnt.c	Mon Feb 10 10:39:23 2003
@@ -93,12 +93,6 @@
  * XDR encode/decode functions for MOUNT
  */
 static int
-xdr_error(struct rpc_rqst *req, u32 *p, void *dummy)
-{
-	return -EIO;
-}
-
-static int
 xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
 {
 	p = xdr_encode_string(p, path);
diff -Nru a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
--- a/fs/nfs/nfs4proc.c	Mon Feb 10 10:39:30 2003
+++ b/fs/nfs/nfs4proc.c	Mon Feb 10 10:39:30 2003
@@ -743,8 +743,8 @@
 		goto out;
 	
 	/*
-	 * Now we do a seperate LOOKUP for each component of the mount path.
-	 * The LOOKUPs are done seperately so that we can conveniently
+	 * Now we do a separate LOOKUP for each component of the mount path.
+	 * The LOOKUPs are done separately so that we can conveniently
 	 * catch an ERR_WRONGSEC if it occurs along the way...
 	 */
 	p = server->mnt_path;
diff -Nru a/fs/nfs/read.c b/fs/nfs/read.c
--- a/fs/nfs/read.c	Mon Feb 10 10:39:22 2003
+++ b/fs/nfs/read.c	Mon Feb 10 10:39:22 2003
@@ -390,11 +390,6 @@
 			       is_sync ? readpage_sync_filler :
 					 readpage_async_filler,
 			       &desc);
-	while (!list_empty(pages)) {
-		struct page *page = list_entry(pages->prev, struct page, list);
-		list_del(&page->list);
-		page_cache_release(page);
-	}
 	if (!list_empty(&head)) {
 		int err = nfs_pagein_list(&head, server->rpages);
 		if (!ret)
diff -Nru a/fs/nfs/write.c b/fs/nfs/write.c
--- a/fs/nfs/write.c	Mon Feb 10 10:39:30 2003
+++ b/fs/nfs/write.c	Mon Feb 10 10:39:30 2003
@@ -829,7 +829,6 @@
 	struct nfs_write_data	*data = (struct nfs_write_data *) task->tk_calldata;
 	struct nfs_writeargs	*argp = &data->args;
 	struct nfs_writeres	*resp = &data->res;
-	struct inode		*inode = data->inode;
 	struct nfs_page		*req;
 	struct page		*page;
 
@@ -863,7 +862,7 @@
 		if (time_before(complain, jiffies)) {
 			dprintk("NFS: faulty NFS server %s:"
 				" (committed = %d) != (stable = %d)\n",
-				NFS_SERVER(inode)->hostname,
+				NFS_SERVER(data->inode)->hostname,
 				data->verf.committed, argp->stable);
 			complain = jiffies + 300 * HZ;
 		}
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	Mon Feb 10 10:39:23 2003
+++ b/fs/nfsd/nfssvc.c	Mon Feb 10 10:39:23 2003
@@ -168,6 +168,7 @@
 	struct svc_serv	*serv = rqstp->rq_server;
 	int		err;
 	struct nfsd_list me;
+	sigset_t shutdown_mask, allowed_mask;
 
 	/* Lock module and set up kernel thread */
 	MOD_INC_USE_COUNT;
@@ -176,6 +177,9 @@
 	sprintf(current->comm, "nfsd");
 	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
+	siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
+	siginitsetinv(&allowed_mask, ALLOWED_SIGS);
+
 	nfsdstats.th_cnt++;
 
 	lockd_up();				/* start lockd */
@@ -189,10 +193,7 @@
 	 */
 	for (;;) {
 		/* Block all but the shutdown signals */
-		spin_lock_irq(&current->sig->siglock);
-		siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		sigprocmask(SIG_SETMASK, &shutdown_mask, NULL);
 
 		/*
 		 * Find a socket with data available and call its
@@ -210,10 +211,7 @@
 		exp_readlock();
 
 		/* Process request with signals blocked.  */
-		spin_lock_irq(&current->sig->siglock);
-		siginitsetinv(&current->blocked, ALLOWED_SIGS);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
 
 		svc_process(serv, rqstp);
 
diff -Nru a/fs/nls/Makefile b/fs/nls/Makefile
--- a/fs/nls/Makefile	Mon Feb 10 10:39:24 2003
+++ b/fs/nls/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for native language support
 #
 
-export-objs := nls_base.o
-
 obj-$(CONFIG_NLS)		+= nls_base.o
 
 obj-$(CONFIG_NLS_CODEPAGE_437)	+= nls_cp437.o
diff -Nru a/fs/partitions/Makefile b/fs/partitions/Makefile
--- a/fs/partitions/Makefile	Mon Feb 10 10:39:26 2003
+++ b/fs/partitions/Makefile	Mon Feb 10 10:39:26 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-export-objs := msdos.o
-
 obj-y := check.o
 
 obj-$(CONFIG_ACORN_PARTITION) += acorn.o
diff -Nru a/fs/partitions/ldm.c b/fs/partitions/ldm.c
--- a/fs/partitions/ldm.c	Mon Feb 10 10:39:25 2003
+++ b/fs/partitions/ldm.c	Mon Feb 10 10:39:25 2003
@@ -510,7 +510,7 @@
 
 	/* Are there uncommitted transactions? */
 	if (BE16(data + 0x10) != 0x01) {
-		ldm_crit ("Database is not in a consistant state.  Aborting.");
+		ldm_crit ("Database is not in a consistent state.  Aborting.");
 		goto out;
 	}
 
diff -Nru a/fs/partitions/sun.c b/fs/partitions/sun.c
--- a/fs/partitions/sun.c	Mon Feb 10 10:39:32 2003
+++ b/fs/partitions/sun.c	Mon Feb 10 10:39:32 2003
@@ -80,8 +80,8 @@
 			put_partition(state, slot, st_sector, num_sectors);
 			if (label->infos[i].id == LINUX_RAID_PARTITION)
 				state->parts[slot].flags = 1;
-			slot++;
 		}
+		slot++;
 	}
 	printk("\n");
 	put_dev_sector(sect);
diff -Nru a/fs/proc/Makefile b/fs/proc/Makefile
--- a/fs/proc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/proc/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux proc filesystem routines.
 #
 
-export-objs := root.o
-
 obj-$(CONFIG_PROC_FS) += proc.o
 
 proc-objs    := inode.o root.o base.o generic.o array.o \
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Mon Feb 10 10:39:29 2003
+++ b/fs/proc/array.c	Mon Feb 10 10:39:29 2003
@@ -126,8 +126,8 @@
 	"R (running)",		/*  0 */
 	"S (sleeping)",		/*  1 */
 	"D (disk sleep)",	/*  2 */
-	"T (stopped)",		/*  8 */
-	"Z (zombie)",		/*  4 */
+	"T (stopped)",		/*  4 */
+	"Z (zombie)",		/*  8 */
 	"X (dead)"		/* 16 */
 };
 
@@ -190,16 +190,16 @@
 	sigemptyset(catch);
 
 	read_lock(&tasklist_lock);
-	if (p->sig) {
-		spin_lock_irq(&p->sig->siglock);
-		k = p->sig->action;
+	if (p->sighand) {
+		spin_lock_irq(&p->sighand->siglock);
+		k = p->sighand->action;
 		for (i = 1; i <= _NSIG; ++i, ++k) {
 			if (k->sa.sa_handler == SIG_IGN)
 				sigaddset(ign, i);
 			else if (k->sa.sa_handler != SIG_DFL)
 				sigaddset(catch, i);
 		}
-		spin_unlock_irq(&p->sig->siglock);
+		spin_unlock_irq(&p->sighand->siglock);
 	}
 	read_unlock(&tasklist_lock);
 }
@@ -301,7 +301,7 @@
 	ppid = task->pid ? task->real_parent->pid : 0;
 	read_unlock(&tasklist_lock);
 	res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
-%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
+%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n",
 		task->pid,
 		task->comm,
@@ -324,7 +324,7 @@
 		nice,
 		0UL /* removed */,
 		jiffies_to_clock_t(task->it_real_value),
-		jiffies_to_clock_t(task->start_time),
+		(unsigned long long) jiffies_64_to_clock_t(task->start_time),
 		vsize,
 		mm ? mm->rss : 0, /* you might want to shift this left 3 */
 		task->rlim[RLIMIT_RSS].rlim_cur,
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Mon Feb 10 10:39:23 2003
+++ b/fs/proc/proc_misc.c	Mon Feb 10 10:39:23 2003
@@ -41,11 +41,13 @@
 #include <linux/profile.h>
 #include <linux/blkdev.h>
 #include <linux/hugetlb.h>
+#include <linux/jiffies.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
+#include <asm/div64.h>
 
 #define LOAD_INT(x) ((x) >> FSHIFT)
 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
@@ -98,34 +100,35 @@
 static int uptime_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
-	unsigned long uptime;
-	unsigned long idle;
+	u64 uptime;
+	unsigned long uptime_remainder;
 	int len;
 
-	uptime = jiffies;
-	idle = init_task.utime + init_task.stime;
+	uptime = get_jiffies_64();
+	uptime_remainder = (unsigned long) do_div(uptime, HZ);
 
-	/* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
-	   that would overflow about every five days at HZ == 100.
-	   Therefore the identity a = (a / b) * b + a % b is used so that it is
-	   calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
-	   The part in front of the '+' always evaluates as 0 (mod 100). All divisions
-	   in the above formulas are truncating. For HZ being a power of 10, the
-	   calculations simplify to the version in the #else part (if the printf
-	   format is adapted to the same number of digits as zeroes in HZ.
-	 */
 #if HZ!=100
-	len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
-		uptime / HZ,
-		(((uptime % HZ) * 100) / HZ) % 100,
-		idle / HZ,
-		(((idle % HZ) * 100) / HZ) % 100);
+	{
+		u64 idle = init_task.utime + init_task.stime;
+		unsigned long idle_remainder;
+
+		idle_remainder = (unsigned long) do_div(idle, HZ);
+		len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
+			(unsigned long) uptime,
+			(uptime_remainder * 100) / HZ,
+			(unsigned long) idle,
+			(idle_remainder * 100) / HZ);
+	}
 #else
-	len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
-		uptime / HZ,
-		uptime % HZ,
-		idle / HZ,
-		idle % HZ);
+	{
+		unsigned long idle = init_task.utime + init_task.stime;
+
+		len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
+			(unsigned long) uptime,
+			uptime_remainder,
+			idle / HZ,
+			idle % HZ);
+	}
 #endif
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
@@ -317,7 +320,7 @@
 {
 	int i, len;
 	extern unsigned long total_forks;
-	unsigned long jif = jiffies;
+	u64 jif = get_jiffies_64();
 	unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0;
 
 	for (i = 0 ; i < NR_CPUS; i++) {
@@ -358,6 +361,7 @@
 		len += sprintf(page + len, " %u", kstat_irqs(i));
 #endif
 
+	do_div(jif, HZ);
 	len += sprintf(page + len,
 		"\nctxt %lu\n"
 		"btime %lu\n"
@@ -365,7 +369,7 @@
 		"procs_running %lu\n"
 		"procs_blocked %lu\n",
 		nr_context_switches(),
-		xtime.tv_sec - jif / HZ,
+		xtime.tv_sec - (unsigned long) jif,
 		total_forks,
 		nr_running(),
 		nr_iowait());
diff -Nru a/fs/quota.c b/fs/quota.c
--- a/fs/quota.c	Mon Feb 10 10:39:33 2003
+++ b/fs/quota.c	Mon Feb 10 10:39:33 2003
@@ -123,13 +123,13 @@
 		case Q_GETFMT: {
 			__u32 fmt;
 
-			down_read(&sb_dqopt(sb)->dqoff_sem);
+			down_read(&sb_dqopt(sb)->dqptr_sem);
 			if (!sb_has_quota_enabled(sb, type)) {
-				up_read(&sb_dqopt(sb)->dqoff_sem);
+				up_read(&sb_dqopt(sb)->dqptr_sem);
 				return -ESRCH;
 			}
 			fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
-			up_read(&sb_dqopt(sb)->dqoff_sem);
+			up_read(&sb_dqopt(sb)->dqptr_sem);
 			if (copy_to_user(addr, &fmt, sizeof(fmt)))
 				return -EFAULT;
 			return 0;
diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c
--- a/fs/quota_v2.c	Mon Feb 10 10:39:31 2003
+++ b/fs/quota_v2.c	Mon Feb 10 10:39:31 2003
@@ -306,6 +306,7 @@
 		blk = get_free_dqblk(filp, info);
 		if ((int)blk < 0) {
 			*err = blk;
+			freedqbuf(buf);
 			return 0;
 		}
 		memset(buf, 0, V2_DQBLKSIZE);
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c	Mon Feb 10 10:39:29 2003
+++ b/fs/read_write.c	Mon Feb 10 10:39:29 2003
@@ -531,6 +531,10 @@
 	if (retval)
 		goto fput_in;
 
+	retval = security_file_permission (in_file, MAY_READ);
+	if (retval)
+		goto fput_in;
+
 	/*
 	 * Get output file, and verify that it is ok..
 	 */
@@ -545,6 +549,10 @@
 		goto fput_out;
 	out_inode = out_file->f_dentry->d_inode;
 	retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count);
+	if (retval)
+		goto fput_out;
+
+	retval = security_file_permission (out_file, MAY_WRITE);
 	if (retval)
 		goto fput_out;
 
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Mon Feb 10 10:39:24 2003
+++ b/fs/reiserfs/inode.c	Mon Feb 10 10:39:24 2003
@@ -11,6 +11,8 @@
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/buffer_head.h>
+#include <linux/mpage.h>
+#include <linux/writeback.h>
 
 /* args for the create parameter of reiserfs_get_block */
 #define GET_BLOCK_NO_CREATE 0 /* don't create new blocks or convert tails */
@@ -262,7 +264,10 @@
 	blocknr = get_block_num(ind_item, path.pos_in_item) ;
 	ret = 0 ;
 	if (blocknr) {
-		map_bh(bh_result, inode->i_sb, blocknr);
+	    map_bh(bh_result, inode->i_sb, blocknr);
+	    if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) {
+		set_buffer_boundary(bh_result);
+	    }
 	} else 
 	    // We do not return -ENOENT if there is a hole but page is uptodate, because it means
 	    // That there is some MMAPED data associated with it that is yet to  be written to disk.
@@ -286,7 +291,7 @@
 	return -ENOENT;
     }
 
-    /* if we've got a direct item, and the buffer was uptodate,
+    /* if we've got a direct item, and the buffer or page was uptodate,
     ** we don't want to pull data off disk again.  skip to the
     ** end, where we map the buffer and return
     */
@@ -367,7 +372,9 @@
 
 finished:
     pathrelse (&path);
-    /* I _really_ doubt that you want it.  Chris? */
+    /* this buffer has valid data, but isn't valid for io.  mapping it to
+     * block #0 tells the rest of reiserfs it just has a tail in it
+     */
     map_bh(bh_result, inode->i_sb, 0);
     set_buffer_uptodate (bh_result);
     return 0;
@@ -842,6 +849,12 @@
     return retval;
 }
 
+static int
+reiserfs_readpages(struct file *file, struct address_space *mapping,
+		struct list_head *pages, unsigned nr_pages)
+{
+    return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
+}
 
 //
 // BAD: new directories have stat data of new type and all other items
@@ -1809,13 +1822,19 @@
     int use_get_block = 0 ;
     int bytes_copied = 0 ;
     int copy_size ;
+    int trans_running = 0;
+
+    /* catch places below that try to log something without starting a trans */
+    th.t_trans_id = 0;
+
+    if (!buffer_uptodate(bh_result)) {
+        buffer_error();
+	return -EIO;
+    }
 
     kmap(bh_result->b_page) ;
 start_over:
     reiserfs_write_lock(inode->i_sb);
-    journal_begin(&th, inode->i_sb, jbegin_count) ;
-    reiserfs_update_inode_transaction(inode) ;
-
     make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;
 
 research:
@@ -1841,7 +1860,6 @@
 	    goto out ;
 	}
 	set_block_dev_mapped(bh_result, get_block_num(item,pos_in_item),inode);
-        set_buffer_uptodate(bh_result);
     } else if (is_direct_le_ih(ih)) {
         char *p ; 
         p = page_address(bh_result->b_page) ;
@@ -1850,7 +1868,20 @@
 
 	fs_gen = get_generation(inode->i_sb) ;
 	copy_item_head(&tmp_ih, ih) ;
+
+	if (!trans_running) {
+	    /* vs-3050 is gone, no need to drop the path */
+	    journal_begin(&th, inode->i_sb, jbegin_count) ;
+	    reiserfs_update_inode_transaction(inode) ;
+	    trans_running = 1;
+	    if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
+		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
+		goto research;
+	    }
+	}
+
 	reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
+
 	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
 	    reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
 	    goto research;
@@ -1861,7 +1892,6 @@
 	journal_mark_dirty(&th, inode->i_sb, bh) ;
 	bytes_copied += copy_size ;
 	set_block_dev_mapped(bh_result, 0, inode);
-        set_buffer_uptodate(bh_result);
 
 	/* are there still bytes left? */
         if (bytes_copied < bh_result->b_size && 
@@ -1878,7 +1908,10 @@
     
 out:
     pathrelse(&path) ;
-    journal_end(&th, inode->i_sb, jbegin_count) ;
+    if (trans_running) {
+	journal_end(&th, inode->i_sb, jbegin_count) ;
+	trans_running = 0;
+    }
     reiserfs_write_unlock(inode->i_sb);
 
     /* this is where we fill in holes in the file. */
@@ -1894,49 +1927,77 @@
 	}
     }
     kunmap(bh_result->b_page) ;
+
+    if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
+	/* we've copied data from the page into the direct item, so the
+	 * buffer in the page is now clean, mark it to reflect that.
+	 */
+        lock_buffer(bh_result);
+	clear_buffer_dirty(bh_result);
+	unlock_buffer(bh_result);
+    }
     return retval ;
 }
 
-/* helper func to get a buffer head ready for writepage to send to
-** ll_rw_block
-*/
-static inline void submit_bh_for_writepage(struct buffer_head **bhp, int nr) {
-    struct buffer_head *bh ;
-    int i;
-    for(i = 0 ; i < nr ; i++) {
-        bh = bhp[i] ;
-	lock_buffer(bh) ;
-	mark_buffer_async_write(bh) ;
-	/* submit_bh doesn't care if the buffer is dirty, but nobody
-	** later on in the call chain will be cleaning it.  So, we
-	** clean the buffer here, it still gets written either way.
-	*/
-	clear_buffer_dirty(bh) ;
-	set_buffer_uptodate(bh) ;
-	submit_bh(WRITE, bh) ;
+/*
+ * does the right thing for deciding when to lock a buffer and
+ * mark it for io during a writepage.  make sure the buffer is
+ * dirty before sending it here though.
+ */
+static void lock_buffer_for_writepage(struct page *page, 
+                                      struct writeback_control *wbc, 
+			              struct buffer_head *bh)
+{
+    if (wbc->sync_mode != WB_SYNC_NONE) {
+	lock_buffer(bh);
+    } else {
+	if (test_set_buffer_locked(bh)) {
+	    __set_page_dirty_nobuffers(page);
+	    return;
+	}
+    }
+    if (test_clear_buffer_dirty(bh)) {
+	if (!buffer_uptodate(bh))
+	    buffer_error();
+	mark_buffer_async_write(bh);
+    } else {
+	unlock_buffer(bh);
     }
 }
 
+/* 
+ * mason@suse.com: updated in 2.5.54 to follow the same general io 
+ * start/recovery path as __block_write_full_page, along with special
+ * code to handle reiserfs tails.
+ */
 static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) {
     struct inode *inode = page->mapping->host ;
     unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ;
-    unsigned last_offset = PAGE_CACHE_SIZE;
     int error = 0;
     unsigned long block ;
-    unsigned cur_offset = 0 ;
-    struct buffer_head *head, *bh ;
+    struct buffer_head *head, *bh;
     int partial = 0 ;
-    struct buffer_head *arr[PAGE_CACHE_SIZE/512] ;
-    int nr = 0 ;
+    int nr = 0;
 
-    if (!page_has_buffers(page))
-        block_prepare_write(page, 0, 0, NULL) ;
+    /* The page dirty bit is cleared before writepage is called, which
+     * means we have to tell create_empty_buffers to make dirty buffers
+     * The page really should be up to date at this point, so tossing
+     * in the BH_Uptodate is just a sanity check.
+     */
+    if (!page_has_buffers(page)) {
+	if (!PageUptodate(page))
+	    buffer_error();
+	create_empty_buffers(page, inode->i_sb->s_blocksize, 
+	                    (1 << BH_Dirty) | (1 << BH_Uptodate));
+    }
+    head = page_buffers(page) ;
 
     /* last page in the file, zero out any contents past the
     ** last byte in the file
     */
     if (page->index >= end_index) {
 	char *kaddr;
+	unsigned last_offset;
 
         last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ;
 	/* no file contents in this page */
@@ -1949,66 +2010,107 @@
 	flush_dcache_page(page) ;
 	kunmap_atomic(kaddr, KM_USER0) ;
     }
-    head = page_buffers(page) ;
     bh = head ;
     block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits) ;
     do {
-	/* if this offset in the page is outside the file */
-	if (cur_offset >= last_offset) {
-	    if (!buffer_uptodate(bh))
-	        partial = 1 ;
-	} else {
-	    /* fast path, buffer mapped to an unformatted node */
+	get_bh(bh);
+	if (buffer_dirty(bh)) {
 	    if (buffer_mapped(bh) && bh->b_blocknr != 0) {
-		arr[nr++] = bh ;
+		/* buffer mapped to an unformatted node */
+		lock_buffer_for_writepage(page, wbc, bh);
 	    } else {
-		/* buffer not mapped yet, or points to a direct item.
-		** search and dirty or log
-		*/
+		/* not mapped yet, or it points to a direct item, search
+		 * the btree for the mapping info, and log any direct
+		 * items found
+		 */
 		if ((error = map_block_for_writepage(inode, bh, block))) {
 		    goto fail ;
 		}
-		/* map_block_for_writepage either found an unformatted node
-		** and mapped it for us, or it found a direct item
-		** and logged the changes.  
-		*/
-		if (buffer_mapped(bh) && bh->b_blocknr != 0) {
-		    arr[nr++] = bh ;
-		}
+		if (buffer_mapped(bh) && bh->b_blocknr != 0)  {
+		    lock_buffer_for_writepage(page, wbc, bh);
+		} 
 	    }
 	}
-        bh = bh->b_this_page ;
-	cur_offset += bh->b_size ;
-	block++ ;
+        bh = bh->b_this_page;
+	block++;
     } while(bh != head) ;
 
-    if (!partial)
-        SetPageUptodate(page) ;
     BUG_ON(PageWriteback(page));
     SetPageWriteback(page);
     unlock_page(page);
 
-    /* if this page only had a direct item, it is very possible for
-    ** nr == 0 without there being any kind of error.
-    */
-    if (nr) {
-        submit_bh_for_writepage(arr, nr) ;
-    } else {
-        end_page_writeback(page) ;
+    /*
+     * since any buffer might be the only dirty buffer on the page, 
+     * the first submit_bh can bring the page out of writeback.
+     * be careful with the buffers.
+     */
+    do {
+        struct buffer_head *next = bh->b_this_page;
+	if (buffer_async_write(bh)) {
+	    submit_bh(WRITE, bh);
+	    nr++;
+	}
+	put_bh(bh);
+	bh = next;
+    } while(bh != head);
+
+    error = 0;
+done:
+    if (nr == 0) {
+        /*
+         * if this page only had a direct item, it is very possible for
+         * no io to be required without there being an error.  Or, 
+	 * someone else could have locked them and sent them down the 
+	 * pipe without locking the page
+	 */
+	do {
+	    if (!buffer_uptodate(bh)) {
+	        partial = 1;
+		break;
+	    }
+	} while(bh != head);
+	if (!partial)
+	    SetPageUptodate(page);
+	end_page_writeback(page);
     }
-
-    return 0 ;
+    return error;
 
 fail:
-    if (nr) {
-        SetPageWriteback(page);
-        unlock_page(page);
-        submit_bh_for_writepage(arr, nr) ;
-    } else {
-        unlock_page(page) ;
-    }
-    ClearPageUptodate(page) ;
-    return error ;
+    /* catches various errors, we need to make sure any valid dirty blocks
+     * get to the media.  The page is currently locked and not marked for 
+     * writeback
+     */
+    ClearPageUptodate(page);
+    bh = head;
+    do {
+	get_bh(bh);
+	if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) {
+	    lock_buffer(bh);
+	    mark_buffer_async_write(bh);
+	} else {
+	    /*
+	     * clear any dirty bits that might have come from getting
+	     * attached to a dirty page
+	     */
+	     clear_buffer_dirty(bh);
+	}
+        bh = bh->b_this_page;
+    } while(bh != head);
+    SetPageError(page);
+    BUG_ON(PageWriteback(page));
+    SetPageWriteback(page);
+    unlock_page(page);
+    do {
+        struct buffer_head *next = bh->b_this_page;
+	if (buffer_async_write(bh)) {
+	    clear_buffer_dirty(bh);
+	    submit_bh(WRITE, bh);
+	    nr++;
+	}
+	put_bh(bh);
+	bh = next;
+    } while(bh != head);
+    goto done;
 }
 
 
@@ -2115,6 +2217,7 @@
 struct address_space_operations reiserfs_address_space_operations = {
     .writepage = reiserfs_writepage,
     .readpage = reiserfs_readpage, 
+    .readpages = reiserfs_readpages, 
     .releasepage = reiserfs_releasepage,
     .sync_page = block_sync_page,
     .prepare_write = reiserfs_prepare_write,
diff -Nru a/fs/seq_file.c b/fs/seq_file.c
--- a/fs/seq_file.c	Mon Feb 10 10:39:30 2003
+++ b/fs/seq_file.c	Mon Feb 10 10:39:30 2003
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 
 #include <asm/uaccess.h>
+#include <asm/page.h>
 
 /**
  *	seq_open -	initialize sequential file
diff -Nru a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
--- a/fs/smbfs/smbiod.c	Mon Feb 10 10:39:29 2003
+++ b/fs/smbfs/smbiod.c	Mon Feb 10 10:39:29 2003
@@ -285,10 +285,10 @@
 	MOD_INC_USE_COUNT;
 	daemonize();
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked, sigmask(SIGKILL));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	strcpy(current->comm, "smbiod");
 
diff -Nru a/fs/stat.c b/fs/stat.c
--- a/fs/stat.c	Mon Feb 10 10:39:24 2003
+++ b/fs/stat.c	Mon Feb 10 10:39:24 2003
@@ -316,3 +316,45 @@
 }
 
 #endif /* LFS-64 */
+
+void inode_add_bytes(struct inode *inode, loff_t bytes)
+{
+	spin_lock(&inode->i_lock);
+	inode->i_blocks += bytes >> 9;
+	bytes &= 511;
+	inode->i_bytes += bytes;
+	if (inode->i_bytes >= 512) {
+		inode->i_blocks++;
+		inode->i_bytes -= 512;
+	}
+	spin_unlock(&inode->i_lock);
+}
+
+void inode_sub_bytes(struct inode *inode, loff_t bytes)
+{
+	spin_lock(&inode->i_lock);
+	inode->i_blocks -= bytes >> 9;
+	bytes &= 511;
+	if (inode->i_bytes < bytes) {
+		inode->i_blocks--;
+		inode->i_bytes += 512;
+	}
+	inode->i_bytes -= bytes;
+	spin_unlock(&inode->i_lock);
+}
+
+loff_t inode_get_bytes(struct inode *inode)
+{
+	loff_t ret;
+
+	spin_lock(&inode->i_lock);
+	ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
+	spin_unlock(&inode->i_lock);
+	return ret;
+}
+
+void inode_set_bytes(struct inode *inode, loff_t bytes)
+{
+	inode->i_blocks = bytes >> 9;
+	inode->i_bytes = bytes & 511;
+}
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Mon Feb 10 10:39:26 2003
+++ b/fs/super.c	Mon Feb 10 10:39:26 2003
@@ -71,7 +71,8 @@
 		atomic_set(&s->s_active, 1);
 		sema_init(&s->s_vfs_rename_sem,1);
 		sema_init(&s->s_dquot.dqio_sem, 1);
-		init_rwsem(&s->s_dquot.dqoff_sem);
+		sema_init(&s->s_dquot.dqonoff_sem, 1);
+		init_rwsem(&s->s_dquot.dqptr_sem);
 		s->s_maxbytes = MAX_NON_LFS;
 		s->dq_op = sb_dquot_ops;
 		s->s_qcop = sb_quotactl_ops;
@@ -310,7 +311,7 @@
 	spin_lock(&sb_lock);
 	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
 			sb = sb_entry(sb->s_list.next)) {
-		if (!sb->s_op->sync_fs);
+		if (!sb->s_op->sync_fs)
 			continue;
 		if (sb->s_flags & MS_RDONLY)
 			continue;
diff -Nru a/fs/sysfs/Makefile b/fs/sysfs/Makefile
--- a/fs/sysfs/Makefile	Mon Feb 10 10:39:23 2003
+++ b/fs/sysfs/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,6 +2,4 @@
 # Makefile for the sysfs virtual filesystem
 #
 
-export-objs	:= inode.o
-
 obj-y		:= inode.o
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Mon Feb 10 10:39:31 2003
+++ b/fs/sysfs/inode.c	Mon Feb 10 10:39:31 2003
@@ -37,6 +37,7 @@
 #include <linux/backing-dev.h>
 #include <linux/kobject.h>
 #include <linux/mount.h>
+#include <linux/dnotify.h>
 #include <asm/uaccess.h>
 
 /* Random magic number */
@@ -716,6 +717,46 @@
 	up(&dir->d_inode->i_sem);
 }
 
+/**
+ * sysfs_update_file - update the modified timestamp on an object attribute.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ *
+ * Also call dnotify for the dentry, which lots of userspace programs
+ * use.
+ */
+int sysfs_update_file(struct kobject * kobj, struct attribute * attr)
+{
+	struct dentry * dir = kobj->dentry;
+	struct dentry * victim;
+	int res = -ENOENT;
+
+	down(&dir->d_inode->i_sem);
+	victim = get_dentry(dir, attr->name);
+	if (!IS_ERR(victim)) {
+		/* make sure dentry is really there */
+		if (victim->d_inode && 
+		    (victim->d_parent->d_inode == dir->d_inode)) {
+			victim->d_inode->i_mtime = CURRENT_TIME;
+			dnotify_parent(victim, DN_MODIFY);
+
+			/**
+			 * Drop reference from initial get_dentry().
+			 */
+			dput(victim);
+			res = 0;
+		}
+		
+		/**
+		 * Drop the reference acquired from get_dentry() above.
+		 */
+		dput(victim);
+	}
+	up(&dir->d_inode->i_sem);
+
+	return res;
+}
+
 
 /**
  *	sysfs_remove_file - remove an object attribute.
@@ -814,6 +855,7 @@
 }
 
 EXPORT_SYMBOL(sysfs_create_file);
+EXPORT_SYMBOL(sysfs_update_file);
 EXPORT_SYMBOL(sysfs_remove_file);
 EXPORT_SYMBOL(sysfs_create_link);
 EXPORT_SYMBOL(sysfs_remove_link);
diff -Nru a/fs/vfat/Makefile b/fs/vfat/Makefile
--- a/fs/vfat/Makefile	Mon Feb 10 10:39:31 2003
+++ b/fs/vfat/Makefile	Mon Feb 10 10:39:31 2003
@@ -2,8 +2,6 @@
 # Makefile for the linux vfat-filesystem routines.
 #
 
-export-objs := vfatfs_syms.o
-
 obj-$(CONFIG_VFAT_FS) += vfat.o
 
 vfat-objs := namei.o vfatfs_syms.o
diff -Nru a/fs/xfs/Makefile b/fs/xfs/Makefile
--- a/fs/xfs/Makefile	Mon Feb 10 10:39:29 2003
+++ b/fs/xfs/Makefile	Mon Feb 10 10:39:29 2003
@@ -45,9 +45,6 @@
 	EXTRA_CFLAGS += -DPAGEBUF_TRACE
 endif
 
-export-objs			:= pagebuf/page_buf.o support/ktrace.o \
-				   linux/xfs_globals.o
-
 obj-$(CONFIG_XFS_FS)		+= xfs.o
 
 
diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
--- a/fs/xfs/linux/xfs_aops.c	Mon Feb 10 10:39:32 2003
+++ b/fs/xfs/linux/xfs_aops.c	Mon Feb 10 10:39:32 2003
@@ -50,7 +50,7 @@
 
 	if (((flags & (PBF_DIRECT|PBF_SYNC)) == PBF_DIRECT) &&
 	    (offset >= inode->i_size))
-		count = max(count, XFS_WRITE_IO_LOG);
+		count = max_t(ssize_t, count, XFS_WRITE_IO_LOG);
 retry:
 	VOP_BMAP(vp, offset, count, flags, pbmapp, &nmaps, error);
 	if (flags & PBF_WRITE) {
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Mon Feb 10 10:39:23 2003
+++ b/fs/xfs/pagebuf/page_buf.c	Mon Feb 10 10:39:23 2003
@@ -1299,7 +1299,6 @@
 	int			status = 0;
 	int			i, map_i, total_nr_pages, nr_pages;
 	struct bio		*bio;
-	struct bio_vec		*bvec;
 	int			offset = pb->pb_offset;
 	int			size = pb->pb_count_desired;
 	sector_t		sector = pb->pb_bn;
@@ -1335,13 +1334,8 @@
 		bio->bi_sector = sector - (offset >> BBSHIFT);
 		bio->bi_end_io = bio_end_io_pagebuf;
 		bio->bi_private = pb;
-		bio->bi_vcnt++;
-		bio->bi_size = PAGE_CACHE_SIZE;
 
-		bvec = bio->bi_io_vec;
-		bvec->bv_page = pb->pb_pages[0];
-		bvec->bv_len = PAGE_CACHE_SIZE;
-		bvec->bv_offset = 0;
+		bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0);
 
 		atomic_inc(&pb->pb_io_remaining);
 		submit_bio(READ, bio);
@@ -1389,9 +1383,7 @@
 	bio->bi_end_io = bio_end_io_pagebuf;
 	bio->bi_private = pb;
 
-	bvec = bio->bi_io_vec;
-
-	for (; size && nr_pages; nr_pages--, bvec++, map_i++) {
+	for (; size && nr_pages; nr_pages--, map_i++) {
 		int	nbytes = PAGE_CACHE_SIZE - offset;
 
 		if (nbytes > size)
@@ -1589,10 +1581,10 @@
 	daemonize();
 
 	/* Avoid signals */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sigfillset(&current->blocked);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	strcpy(current->comm, "pagebufd");
 	current->flags |= PF_MEMALLOC;
diff -Nru a/fs/xfs/support/move.c b/fs/xfs/support/move.c
--- a/fs/xfs/support/move.c	Mon Feb 10 10:39:27 2003
+++ b/fs/xfs/support/move.c	Mon Feb 10 10:39:27 2003
@@ -30,6 +30,7 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
+#include <linux/string.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 
diff -Nru a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
--- a/fs/xfs/xfs_bmap.c	Mon Feb 10 10:39:32 2003
+++ b/fs/xfs/xfs_bmap.c	Mon Feb 10 10:39:32 2003
@@ -5522,7 +5522,7 @@
 	int			prealloced;	/* this is a file with
 						 * preallocated data space */
 	int			sh_unwritten;	/* true, if unwritten */
-						/* extents listed seperately */
+						/* extents listed separately */
 	int			bmapi_flags;	/* flags for xfs_bmapi */
 	__int32_t		oflags;		/* getbmapx bmv_oflags field */
 
diff -Nru a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
--- a/fs/xfs/xfs_buf_item.c	Mon Feb 10 10:39:23 2003
+++ b/fs/xfs/xfs_buf_item.c	Mon Feb 10 10:39:23 2003
@@ -379,7 +379,8 @@
  */
 void
 xfs_buf_item_unpin(
-	xfs_buf_log_item_t	*bip)
+	xfs_buf_log_item_t	*bip,
+	int			stale)
 {
 	xfs_mount_t	*mp;
 	xfs_buf_t	*bp;
@@ -396,7 +397,8 @@
 	freed = atomic_dec_and_test(&bip->bli_refcount);
 	mp = bip->bli_item.li_mountp;
 	xfs_bunpin(bp);
-	if (freed && (bip->bli_flags & XFS_BLI_STALE)) {
+	if (freed && stale) {
+		ASSERT(bip->bli_flags & XFS_BLI_STALE);
 		ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
 		ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
 		ASSERT(XFS_BUF_ISSTALE(bp));
@@ -418,7 +420,6 @@
 		ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL);
 		xfs_buf_relse(bp);
 	}
-
 }
 
 /*
@@ -435,6 +436,7 @@
 {
 	xfs_buf_t		*bp;
 	xfs_log_item_desc_t	*lidp;
+	int			stale = 0;
 
 	bp = bip->bli_buf;
 	/*
@@ -454,6 +456,7 @@
 		 * will be able to bump up the refcount.
 		 */
 		lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) bip);
+		stale = lidp->lid_flags & XFS_LID_BUF_STALE;
 		xfs_trans_free_item(tp, lidp);
 		/*
 		 * Since the transaction no longer refers to the buffer,
@@ -462,7 +465,7 @@
 		XFS_BUF_SET_FSPRIVATE2(bp, NULL);
 	}
 
-	xfs_buf_item_unpin(bip);
+	xfs_buf_item_unpin(bip, stale);
 
 	return;
 }
@@ -686,7 +689,7 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_buf_item_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_buf_item_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_buf_item_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
 					xfs_buf_item_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock,
diff -Nru a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
--- a/fs/xfs/xfs_dquot_item.c	Mon Feb 10 10:39:23 2003
+++ b/fs/xfs/xfs_dquot_item.c	Mon Feb 10 10:39:23 2003
@@ -93,9 +93,11 @@
  * anyone in xfs_dqwait_unpin() if the count goes to 0.	 The
  * dquot must have been previously pinned with a call to xfs_dqpin().
  */
+/* ARGSUSED */
 STATIC void
 xfs_qm_dquot_logitem_unpin(
-	xfs_dq_logitem_t *logitem)
+	xfs_dq_logitem_t *logitem,
+	int		  stale)
 {
 	unsigned long	s;
 	xfs_dquot_t *dqp;
@@ -116,7 +118,7 @@
 	xfs_dq_logitem_t *logitem,
 	xfs_trans_t	 *tp)
 {
-	xfs_qm_dquot_logitem_unpin(logitem);
+	xfs_qm_dquot_logitem_unpin(logitem, 0);
 }
 
 /*
@@ -396,7 +398,8 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_dquot_logitem_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))
+					xfs_qm_dquot_logitem_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
 					xfs_qm_dquot_logitem_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))
@@ -492,7 +495,7 @@
  */
 /*ARGSUSED*/
 STATIC void
-xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale)
 {
 	return;
 }
@@ -613,7 +616,8 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_qoff_logitem_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t* ,int))
+					xfs_qm_qoff_logitem_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
 					xfs_qm_qoff_logitem_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
@@ -635,7 +639,8 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_qoff_logitem_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))
+					xfs_qm_qoff_logitem_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
 					xfs_qm_qoff_logitem_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
diff -Nru a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
--- a/fs/xfs/xfs_extfree_item.c	Mon Feb 10 10:39:31 2003
+++ b/fs/xfs/xfs_extfree_item.c	Mon Feb 10 10:39:31 2003
@@ -105,7 +105,7 @@
  */
 /*ARGSUSED*/
 STATIC void
-xfs_efi_item_unpin(xfs_efi_log_item_t *efip)
+xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
 {
 	int		nexts;
 	int		size;
@@ -280,7 +280,7 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_efi_item_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_efi_item_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_efi_item_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))xfs_efi_item_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
 					xfs_efi_item_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock,
@@ -474,7 +474,7 @@
  */
 /*ARGSUSED*/
 STATIC void
-xfs_efd_item_unpin(xfs_efd_log_item_t *efdp)
+xfs_efd_item_unpin(xfs_efd_log_item_t *efdp, int stale)
 {
 	return;
 }
@@ -607,7 +607,7 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_efd_item_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_efd_item_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_efd_item_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))xfs_efd_item_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
 					xfs_efd_item_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock,
diff -Nru a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
--- a/fs/xfs/xfs_inode_item.c	Mon Feb 10 10:39:29 2003
+++ b/fs/xfs/xfs_inode_item.c	Mon Feb 10 10:39:29 2003
@@ -534,9 +534,11 @@
  * item which was previously pinned with a call to xfs_inode_item_pin().
  * Just call xfs_iunpin() on the inode to do this.
  */
+/* ARGSUSED */
 STATIC void
 xfs_inode_item_unpin(
-	xfs_inode_log_item_t	*iip)
+	xfs_inode_log_item_t	*iip,
+	int			stale)
 {
 	xfs_iunpin(iip->ili_inode);
 }
@@ -880,7 +882,7 @@
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_inode_item_format,
 	.iop_pin	= (void(*)(xfs_log_item_t*))xfs_inode_item_pin,
-	.iop_unpin	= (void(*)(xfs_log_item_t*))xfs_inode_item_unpin,
+	.iop_unpin	= (void(*)(xfs_log_item_t*, int))xfs_inode_item_unpin,
 	.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
 					xfs_inode_item_unpin_remove,
 	.iop_trylock	= (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock,
diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
--- a/fs/xfs/xfs_log.c	Mon Feb 10 10:39:33 2003
+++ b/fs/xfs/xfs_log.c	Mon Feb 10 10:39:33 2003
@@ -45,7 +45,7 @@
 /* Local miscellaneous function prototypes */
 STATIC int	 xlog_bdstrat_cb(struct xfs_buf *);
 STATIC int	 xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket,
-				    xfs_lsn_t *);
+				    xlog_in_core_t **, xfs_lsn_t *);
 STATIC xlog_t *	 xlog_alloc_log(xfs_mount_t	*mp,
 				dev_t		log_dev,
 				xfs_daddr_t	blk_offset,
@@ -55,7 +55,9 @@
 STATIC void	 xlog_unalloc_log(xlog_t *log);
 STATIC int	 xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
 			    int nentries, xfs_log_ticket_t tic,
-			    xfs_lsn_t *start_lsn, uint flags);
+			    xfs_lsn_t *start_lsn,
+			    xlog_in_core_t **commit_iclog,
+			    uint flags);
 
 /* local state machine functions */
 STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
@@ -70,10 +72,6 @@
 				       xlog_ticket_t	*ticket,
 				       int		*continued_write,
 				       int		*logoffsetp);
-STATIC int  xlog_state_lsn_is_synced(xlog_t		*log,
-				     xfs_lsn_t		lsn,
-				     xfs_log_callback_t *cb,
-				     int		*abortflg);
 STATIC void xlog_state_put_ticket(xlog_t	*log,
 				  xlog_ticket_t *tic);
 STATIC int  xlog_state_release_iclog(xlog_t		*log,
@@ -254,6 +252,7 @@
 xfs_lsn_t
 xfs_log_done(xfs_mount_t	*mp,
 	     xfs_log_ticket_t	xtic,
+	     void		**iclog,
 	     uint		flags)
 {
 	xlog_t		*log	= mp->m_log;
@@ -271,7 +270,8 @@
 	     * If we get an error, just continue and give back the log ticket.
 	     */
 	    (((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
-	     (xlog_commit_record(mp, ticket, &lsn)))) {
+	     (xlog_commit_record(mp, ticket,
+				 (xlog_in_core_t **)iclog, &lsn)))) {
 		lsn = (xfs_lsn_t) -1;
 		if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
 			flags |= XFS_LOG_REL_PERM_RESERV;
@@ -354,21 +354,39 @@
  * been synced to disk, we add the callback to the callback list of the
  * in-core log.
  */
-void
+int
 xfs_log_notify(xfs_mount_t	  *mp,		/* mount of partition */
-	       xfs_lsn_t	  lsn,		/* lsn looking for */
+	       void		  *iclog_hndl,	/* iclog to hang callback off */
 	       xfs_log_callback_t *cb)
 {
 	xlog_t *log = mp->m_log;
-	int	abortflg;
+	xlog_in_core_t	  *iclog = (xlog_in_core_t *)iclog_hndl;
+	int	abortflg, spl;
 
 #if defined(DEBUG) || defined(XLOG_NOLOG)
 	if (! xlog_debug && xlog_devt == log->l_dev)
-		return;
+		return 0;
 #endif
 	cb->cb_next = 0;
-	if (xlog_state_lsn_is_synced(log, lsn, cb, &abortflg))
+	spl = LOG_LOCK(log);
+	abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
+	if (!abortflg) {
+		ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
+			      (iclog->ic_state == XLOG_STATE_WANT_SYNC));
+		cb->cb_next = 0;
+		*(iclog->ic_callback_tail) = cb;
+		iclog->ic_callback_tail = &(cb->cb_next);
+	}
+	LOG_UNLOCK(log, spl);
+	if (!abortflg) {
+		if (xlog_state_release_iclog(log, iclog)) {
+			xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
+			return EIO;
+		}
+	} else {
 		cb->cb_func(cb->cb_arg, abortflg);
+	}
+	return 0;
 }	/* xfs_log_notify */
 
 
@@ -611,7 +629,7 @@
 			/* remove inited flag */
 			((xlog_ticket_t *)tic)->t_flags = 0;
 			error = xlog_write(mp, reg, 1, tic, &lsn,
-					   XLOG_UNMOUNT_TRANS);
+					   NULL, XLOG_UNMOUNT_TRANS);
 			/*
 			 * At this point, we're umounting anyway,
 			 * so there's no point in transitioning log state
@@ -717,7 +735,7 @@
 	if (XLOG_FORCED_SHUTDOWN(log))
 		return XFS_ERROR(EIO);
 
-	if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, 0))) {
+	if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
 		xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
 	}
 	return (error);
@@ -1259,6 +1277,7 @@
 STATIC int
 xlog_commit_record(xfs_mount_t	*mp,
 		   xlog_ticket_t *ticket,
+		   xlog_in_core_t **iclog,
 		   xfs_lsn_t	*commitlsnp)
 {
 	int		error;
@@ -1267,8 +1286,9 @@
 	reg[0].i_addr = 0;
 	reg[0].i_len = 0;
 
+	ASSERT_ALWAYS(iclog);
 	if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
-			       XLOG_COMMIT_TRANS))) {
+			       iclog, XLOG_COMMIT_TRANS))) {
 		xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
 	}
 	return (error);
@@ -1614,6 +1634,7 @@
 	   int			nentries,
 	   xfs_log_ticket_t	tic,
 	   xfs_lsn_t		*start_lsn,
+	   xlog_in_core_t	**commit_iclog,
 	   uint			flags)
 {
     xlog_t	     *log    = mp->m_log;
@@ -1776,7 +1797,10 @@
 
 		if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
 		    xlog_state_want_sync(log, iclog);
-		    if ((error = xlog_state_release_iclog(log, iclog)))
+		    if (commit_iclog) {
+			ASSERT(flags & XLOG_COMMIT_TRANS);
+			*commit_iclog = iclog;
+		    } else if ((error = xlog_state_release_iclog(log, iclog)))
 			   return (error);
 		    if (index == nentries)
 			    return 0;		/* we are done */
@@ -1788,6 +1812,11 @@
     } /* for (index = 0; index < nentries; ) */
     ASSERT(len == 0);
 
+    if (commit_iclog) {
+	ASSERT(flags & XLOG_COMMIT_TRANS);
+	*commit_iclog = iclog;
+	return 0;
+    }
     return (xlog_state_release_iclog(log, iclog));
 }	/* xlog_write */
 
@@ -2060,6 +2089,12 @@
 			if (!(iclog->ic_state & XLOG_STATE_IOERROR))
 				iclog->ic_state = XLOG_STATE_DIRTY;
 
+			/*
+			 * Transition from DIRTY to ACTIVE if applicable.
+			 * NOP if STATE_IOERROR.
+			 */
+			xlog_state_clean_log(log);
+
 			/* wake up threads waiting in xfs_log_force() */
 			sv_broadcast(&iclog->ic_forcesema);
 
@@ -2098,12 +2133,6 @@
 	}
 #endif
 
-	/*
-	 * Transition from DIRTY to ACTIVE if applicable. NOP if
-	 * STATE_IOERROR.
-	 */
-	xlog_state_clean_log(log);
-
 	if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
 		flushcnt = log->l_flushcnt;
 		log->l_flushcnt = 0;
@@ -2652,52 +2681,6 @@
 	GRANT_UNLOCK(log, s);
 	xfs_log_move_tail(log->l_mp, 1);
 }	/* xlog_ungrant_log_space */
-
-
-/*
- * If the lsn is not found or the iclog with the lsn is in the callback
- * state, we need to call the function directly.  This is done outside
- * this function's scope.  Otherwise, we insert the callback at the end
- * of the iclog's callback list.
- */
-int
-xlog_state_lsn_is_synced(xlog_t		    *log,
-			 xfs_lsn_t	    lsn,
-			 xfs_log_callback_t *cb,
-			 int		    *abortflg)
-{
-	xlog_in_core_t *iclog;
-	SPLDECL(s);
-	int	      lsn_is_synced = 1;
-
-	*abortflg = 0;
-	s = LOG_LOCK(log);
-
-	iclog = log->l_iclog;
-	do {
-		if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
-			iclog = iclog->ic_next;
-			continue;
-		} else {
-			if (iclog->ic_state & XLOG_STATE_DIRTY) /* call it*/
-				break;
-
-			if (iclog->ic_state & XLOG_STATE_IOERROR) {
-				*abortflg = XFS_LI_ABORTED;
-				break;
-			}
-			/* insert callback onto end of list */
-			cb->cb_next = 0;
-			*(iclog->ic_callback_tail) = cb;
-			iclog->ic_callback_tail = &(cb->cb_next);
-			lsn_is_synced = 0;
-			break;
-		}
-	} while (iclog != log->l_iclog);
-
-	LOG_UNLOCK(log, s);
-	return lsn_is_synced;
-}	/* xlog_state_lsn_is_synced */
 
 
 /*
diff -Nru a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
--- a/fs/xfs/xfs_log.h	Mon Feb 10 10:39:33 2003
+++ b/fs/xfs/xfs_log.h	Mon Feb 10 10:39:33 2003
@@ -148,6 +148,7 @@
 struct xfs_mount;
 xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
 		       xfs_log_ticket_t ticket,
+		       void		**iclog,
 		       uint		flags);
 int	  xfs_log_force(struct xfs_mount *mp,
 			xfs_lsn_t	 lsn,
@@ -160,8 +161,8 @@
 int	  xfs_log_mount_finish(struct xfs_mount *mp, int);
 void	  xfs_log_move_tail(struct xfs_mount	*mp,
 			    xfs_lsn_t		tail_lsn);
-void	  xfs_log_notify(struct xfs_mount	*mp,
-			 xfs_lsn_t		lsn,
+int	  xfs_log_notify(struct xfs_mount	*mp,
+			 void			*iclog,
 			 xfs_log_callback_t	*callback_entry);
 int	  xfs_log_reserve(struct xfs_mount *mp,
 			  int		   length,
diff -Nru a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
--- a/fs/xfs/xfs_trans.c	Mon Feb 10 10:39:27 2003
+++ b/fs/xfs/xfs_trans.c	Mon Feb 10 10:39:27 2003
@@ -285,7 +285,7 @@
 		} else {
 			log_flags = 0;
 		}
-		xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags);
+		xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
 		tp->t_ticket = NULL;
 		tp->t_log_res = 0;
 		tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES;
@@ -669,6 +669,7 @@
 #if defined(XLOG_NOLOG) || defined(DEBUG)
 	static xfs_lsn_t	trans_lsn = 1;
 #endif
+	void			*commit_iclog;
 	int			shutdown;
 
 	commit_lsn = -1;
@@ -706,7 +707,8 @@
 			xfs_trans_unreserve_and_mod_dquots(tp);
 		}
 		if (tp->t_ticket) {
-			commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags);
+			commit_lsn = xfs_log_done(mp, tp->t_ticket,
+							NULL, log_flags);
 			if (commit_lsn == -1 && !shutdown)
 				shutdown = XFS_ERROR(EIO);
 		}
@@ -773,7 +775,7 @@
 #if defined(XLOG_NOLOG) || defined(DEBUG)
 	if (xlog_debug) {
 		commit_lsn = xfs_log_done(mp, tp->t_ticket,
-					  log_flags);
+					  &commit_iclog, log_flags);
 	} else {
 		commit_lsn = 0;
 		tp->t_lsn = trans_lsn++;
@@ -785,7 +787,7 @@
 	 * any time.  However, all the items associated with the transaction
 	 * are still locked and pinned in memory.
 	 */
-	commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags);
+	commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags);
 #endif
 
 	tp->t_commit_lsn = commit_lsn;
@@ -845,21 +847,28 @@
 	if (xlog_debug) {
 		tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed;
 		tp->t_logcb.cb_arg = tp;
-		xfs_log_notify(mp, commit_lsn, &(tp->t_logcb));
+		error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
 	} else {
 		xfs_trans_committed(tp, 0);
 	}
 #else
 	tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed;
 	tp->t_logcb.cb_arg = tp;
-	xfs_log_notify(mp, commit_lsn, &(tp->t_logcb));
+
+	/* We need to pass the iclog buffer which was used for the
+	 * transaction commit record into this function, attach
+	 * the callback to it, and then release it. This will guarantee
+	 * that we do callbacks on the transaction in the correct order.
+	 */
+	error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
 #endif
 	/*
 	 * If the transaction needs to be synchronous, then force the
 	 * log out now and wait for it.
 	 */
 	if (sync) {
-		error = xfs_log_force(mp, commit_lsn,
+		if (!error)
+			error = xfs_log_force(mp, commit_lsn,
 				      XFS_LOG_FORCE | XFS_LOG_SYNC);
 		XFS_STATS_INC(xfsstats.xs_trans_sync);
 	} else {
@@ -1070,7 +1079,7 @@
 		} else {
 			log_flags = 0;
 		}
-		xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags);
+		xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
 	}
 	xfs_trans_free_items(tp, flags);
 	xfs_trans_free_busy(tp);
@@ -1262,8 +1271,11 @@
 
 		/*
 		 * Now that we've repositioned the item in the AIL,
-		 * unpin it so it can be flushed.
+		 * unpin it so it can be flushed. Pass information
+		 * about buffer stale state down from the log item
+		 * flags, if anyone else stales the buffer we do not
+		 * want to pay any attention to it.
 		 */
-		IOP_UNPIN(lip);
+		IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE);
 	}
 }
diff -Nru a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
--- a/fs/xfs/xfs_trans.h	Mon Feb 10 10:39:30 2003
+++ b/fs/xfs/xfs_trans.h	Mon Feb 10 10:39:30 2003
@@ -170,7 +170,7 @@
 	uint (*iop_size)(xfs_log_item_t *);
 	void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
 	void (*iop_pin)(xfs_log_item_t *);
-	void (*iop_unpin)(xfs_log_item_t *);
+	void (*iop_unpin)(xfs_log_item_t *, int);
 	void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *);
 	uint (*iop_trylock)(xfs_log_item_t *);
 	void (*iop_unlock)(xfs_log_item_t *);
@@ -184,7 +184,7 @@
 #define IOP_SIZE(ip)		(*(ip)->li_ops->iop_size)(ip)
 #define IOP_FORMAT(ip,vp)	(*(ip)->li_ops->iop_format)(ip, vp)
 #define IOP_PIN(ip)		(*(ip)->li_ops->iop_pin)(ip)
-#define IOP_UNPIN(ip)		(*(ip)->li_ops->iop_unpin)(ip)
+#define IOP_UNPIN(ip, flags)	(*(ip)->li_ops->iop_unpin)(ip, flags)
 #define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp)
 #define IOP_TRYLOCK(ip)		(*(ip)->li_ops->iop_trylock)(ip)
 #define IOP_UNLOCK(ip)		(*(ip)->li_ops->iop_unlock)(ip)
@@ -222,6 +222,7 @@
 #define XFS_LID_DIRTY		0x1
 #define XFS_LID_PINNED		0x2
 #define XFS_LID_SYNC_UNLOCK	0x4
+#define XFS_LID_BUF_STALE	0x8
 
 /*
  * This structure is used to maintain a chunk list of log_item_desc
diff -Nru a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
--- a/fs/xfs/xfs_trans_buf.c	Mon Feb 10 10:39:23 2003
+++ b/fs/xfs/xfs_trans_buf.c	Mon Feb 10 10:39:23 2003
@@ -796,6 +796,7 @@
 
 	tp->t_flags |= XFS_TRANS_DIRTY;
 	lidp->lid_flags |= XFS_LID_DIRTY;
+	lidp->lid_flags &= ~XFS_LID_BUF_STALE;
 	bip->bli_flags |= XFS_BLI_LOGGED;
 	xfs_buf_item_log(bip, first, last);
 	xfs_buf_item_trace("BLOG", bip);
@@ -882,7 +883,7 @@
 	bip->bli_format.blf_flags |= XFS_BLI_CANCEL;
 	memset((char *)(bip->bli_format.blf_data_map), 0,
 	      (bip->bli_format.blf_map_size * sizeof(uint)));
-	lidp->lid_flags |= XFS_LID_DIRTY;
+	lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE;
 	tp->t_flags |= XFS_TRANS_DIRTY;
 	xfs_buftrace("XFS_BINVAL", bp);
 	xfs_buf_item_trace("BINVAL", bip);
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	Mon Feb 10 10:39:24 2003
+++ b/fs/xfs/xfs_vfsops.c	Mon Feb 10 10:39:24 2003
@@ -873,7 +873,6 @@
 	boolean_t	mount_locked;
 	boolean_t	vnode_refed;
 	int		preempt;
-	int		do_mmap_flush;
 	xfs_dinode_t	*dip;
 	xfs_buf_log_item_t	*bip;
 	xfs_iptr_t	*ipointer;
@@ -944,8 +943,6 @@
 		fflag = XFS_B_DELWRI;
 	if (flags & SYNC_WAIT)
 		fflag = 0;		/* synchronous overrides all */
-	do_mmap_flush = (flags & (SYNC_DELWRI|SYNC_BDFLUSH)) !=
-						(SYNC_DELWRI|SYNC_BDFLUSH);
 
 	base_lock_flags = XFS_ILOCK_SHARED;
 	if (flags & (SYNC_DELWRI | SYNC_CLOSE)) {
@@ -1177,12 +1174,8 @@
 				 * across calls to the buffer cache.
 				 */
 				xfs_iunlock(ip, XFS_ILOCK_SHARED);
-				if (do_mmap_flush) {
-					VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
-						fflag, FI_NONE, error);
-				} else {
-					filemap_fdatawrite(LINVFS_GET_IP(vp)->i_mapping);
-				}
+				VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
+							fflag, FI_NONE, error);
 				xfs_ilock(ip, XFS_ILOCK_SHARED);
 			}
 
diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c
--- a/fs/xfs/xfsidbg.c	Mon Feb 10 10:39:30 2003
+++ b/fs/xfs/xfsidbg.c	Mon Feb 10 10:39:30 2003
@@ -5248,6 +5248,7 @@
 		"dirty",	/* 0x1 */
 		"pinned",	/* 0x2 */
 		"sync unlock",	/* 0x4 */
+		"buf stale",	/* 0x8 */
 		0
 		};
 
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acconfig.h	Mon Feb 10 10:39:30 2003
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * Name: acconfig.h - Global configuration constants
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 _ACCONFIG_H
+#define _ACCONFIG_H
+
+
+/******************************************************************************
+ *
+ * Compile-time options
+ *
+ *****************************************************************************/
+
+/*
+ * ACPI_DEBUG_OUTPUT    - This switch enables all the debug facilities of the
+ *                        ACPI subsystem.  This includes the DEBUG_PRINT output
+ *                        statements.  When disabled, all DEBUG_PRINT
+ *                        statements are compiled out.
+ *
+ * ACPI_APPLICATION     - Use this switch if the subsystem is going to be run
+ *                        at the application level.
+ *
+ */
+
+
+/******************************************************************************
+ *
+ * Subsystem Constants
+ *
+ *****************************************************************************/
+
+
+/* Version string */
+
+#define ACPI_CA_VERSION                 0x20030122
+
+/* Version of ACPI supported */
+
+#define ACPI_CA_SUPPORT_LEVEL           2
+
+/* Maximum objects in the various object caches */
+
+#define ACPI_MAX_STATE_CACHE_DEPTH      64          /* State objects for stacks */
+#define ACPI_MAX_PARSE_CACHE_DEPTH      96          /* Parse tree objects */
+#define ACPI_MAX_EXTPARSE_CACHE_DEPTH   64          /* Parse tree objects */
+#define ACPI_MAX_OBJECT_CACHE_DEPTH     64          /* Interpreter operand objects */
+#define ACPI_MAX_WALK_CACHE_DEPTH       4           /* Objects for parse tree walks */
+
+/* String size constants */
+
+#define ACPI_MAX_STRING_LENGTH          512
+#define ACPI_PATHNAME_MAX               256         /* A full namespace pathname */
+
+/* Maximum count for a semaphore object */
+
+#define ACPI_MAX_SEMAPHORE_COUNT        256
+
+/* Max reference count (for debug only) */
+
+#define ACPI_MAX_REFERENCE_COUNT        0x400
+
+/* Size of cached memory mapping for system memory operation region */
+
+#define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
+
+
+/******************************************************************************
+ *
+ * Configuration of subsystem behavior
+ *
+ *****************************************************************************/
+
+
+/*
+ * Should the subystem abort the loading of an ACPI table if the
+ * table checksum is incorrect?
+ */
+#define ACPI_CHECKSUM_ABORT             FALSE
+
+
+/******************************************************************************
+ *
+ * ACPI Specification constants (Do not change unless the specification changes)
+ *
+ *****************************************************************************/
+
+/* Number of distinct GPE register blocks and register width */
+
+#define ACPI_MAX_GPE_BLOCKS             2
+#define ACPI_GPE_REGISTER_WIDTH         8
+
+/*
+ * Method info (in WALK_STATE), containing local variables and argumetns
+ */
+#define ACPI_METHOD_NUM_LOCALS          8
+#define ACPI_METHOD_MAX_LOCAL           7
+
+#define ACPI_METHOD_NUM_ARGS            7
+#define ACPI_METHOD_MAX_ARG             6
+
+/* Maximum length of resulting string when converting from a buffer */
+
+#define ACPI_MAX_STRING_CONVERSION      200
+
+/*
+ * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG
+ */
+#define ACPI_OBJ_NUM_OPERANDS           8
+#define ACPI_OBJ_MAX_OPERAND            7
+
+/* Names within the namespace are 4 bytes long */
+
+#define ACPI_NAME_SIZE                  4
+#define ACPI_PATH_SEGMENT_LENGTH        5           /* 4 chars for name + 1 char for separator */
+#define ACPI_PATH_SEPARATOR             '.'
+
+/* Constants used in searching for the RSDP in low memory */
+
+#define ACPI_LO_RSDP_WINDOW_BASE        0           /* Physical Address */
+#define ACPI_HI_RSDP_WINDOW_BASE        0xE0000     /* Physical Address */
+#define ACPI_LO_RSDP_WINDOW_SIZE        0x400
+#define ACPI_HI_RSDP_WINDOW_SIZE        0x20000
+#define ACPI_RSDP_SCAN_STEP             16
+
+/* Operation regions */
+
+#define ACPI_NUM_PREDEFINED_REGIONS     8
+#define ACPI_USER_REGION_BEGIN          0x80
+
+/* Maximum space_ids for Operation Regions */
+
+#define ACPI_MAX_ADDRESS_SPACE          255
+
+/* Array sizes.  Used for range checking also */
+
+#define ACPI_NUM_ACCESS_TYPES           6
+#define ACPI_NUM_UPDATE_RULES           3
+#define ACPI_NUM_LOCK_RULES             2
+#define ACPI_NUM_MATCH_OPS              6
+#define ACPI_NUM_OPCODES                256
+#define ACPI_NUM_FIELD_NAMES            2
+
+/* RSDP checksums */
+
+#define ACPI_RSDP_CHECKSUM_LENGTH       20
+#define ACPI_RSDP_XCHECKSUM_LENGTH      36
+
+/* SMBus bidirectional buffer size */
+
+#define ACPI_SMBUS_BUFFER_SIZE          34
+
+
+/******************************************************************************
+ *
+ * ACPI AML Debugger
+ *
+ *****************************************************************************/
+
+
+#define ACPI_DEBUGGER_MAX_ARGS          8  /* Must be max method args + 1 */
+
+#define ACPI_DEBUGGER_COMMAND_PROMPT    '-'
+#define ACPI_DEBUGGER_EXECUTE_PROMPT    '%'
+
+
+#endif /* _ACCONFIG_H */
+
diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acdebug.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,452 @@
+/******************************************************************************
+ *
+ * Name: acdebug.h - ACPI/AML debugger
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACDEBUG_H__
+#define __ACDEBUG_H__
+
+
+#define ACPI_DEBUG_BUFFER_SIZE  4196
+
+struct command_info
+{
+	char                            *name;          /* Command Name */
+	u8                              min_args;       /* Minimum arguments required */
+};
+
+
+struct argument_info
+{
+	char                            *name;          /* Argument Name */
+};
+
+
+#define PARAM_LIST(pl)                  pl
+
+#define DBTEST_OUTPUT_LEVEL(lvl)        if (acpi_gbl_db_opt_verbose)
+
+#define VERBOSE_PRINT(fp)               DBTEST_OUTPUT_LEVEL(lvl) {\
+			  acpi_os_printf PARAM_LIST(fp);}
+
+#define EX_NO_SINGLE_STEP               1
+#define EX_SINGLE_STEP                  2
+
+
+/* Prototypes */
+
+
+/*
+ * dbxface - external debugger interfaces
+ */
+
+acpi_status
+acpi_db_initialize (
+	void);
+
+void
+acpi_db_terminate (
+	void);
+
+acpi_status
+acpi_db_single_step (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u32                             op_type);
+
+acpi_status
+acpi_db_start_command (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+void
+acpi_db_method_end (
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * dbcmds - debug commands and output routines
+ */
+
+void
+acpi_db_display_table_info (
+	char                            *table_arg);
+
+void
+acpi_db_unload_acpi_table (
+	char                            *table_arg,
+	char                            *instance_arg);
+
+void
+acpi_db_set_method_breakpoint (
+	char                            *location,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+void
+acpi_db_set_method_call_breakpoint (
+	union acpi_parse_object         *op);
+
+void
+acpi_db_disassemble_aml (
+	char                            *statements,
+	union acpi_parse_object         *op);
+
+void
+acpi_db_dump_namespace (
+	char                            *start_arg,
+	char                            *depth_arg);
+
+void
+acpi_db_dump_namespace_by_owner (
+	char                            *owner_arg,
+	char                            *depth_arg);
+
+void
+acpi_db_send_notify (
+	char                            *name,
+	u32                             value);
+
+void
+acpi_db_set_method_data (
+	char                            *type_arg,
+	char                            *index_arg,
+	char                            *value_arg);
+
+acpi_status
+acpi_db_display_objects (
+	char                            *obj_type_arg,
+	char                            *display_count_arg);
+
+acpi_status
+acpi_db_find_name_in_namespace (
+	char                            *name_arg);
+
+void
+acpi_db_set_scope (
+	char                            *name);
+
+void
+acpi_db_find_references (
+	char                            *object_arg);
+
+void
+acpi_db_display_locks (void);
+
+
+void
+acpi_db_display_resources (
+	char                            *object_arg);
+
+void
+acpi_db_check_integrity (
+	void);
+
+acpi_status
+acpi_db_integrity_walk (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_db_walk_and_match_name (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_db_walk_for_references (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_db_walk_for_specific_objects (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+
+/*
+ * dbdisply - debug display commands
+ */
+
+void
+acpi_db_display_method_info (
+	union acpi_parse_object         *op);
+
+void
+acpi_db_decode_and_display_object (
+	char                            *target,
+	char                            *output_type);
+
+void
+acpi_db_decode_node (
+	struct acpi_namespace_node      *node);
+
+void
+acpi_db_display_result_object (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_db_display_all_methods (
+	char                            *display_count_arg);
+
+void
+acpi_db_display_internal_object (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_db_display_arguments (
+	void);
+
+void
+acpi_db_display_locals (
+	void);
+
+void
+acpi_db_display_results (
+	void);
+
+void
+acpi_db_display_calling_tree (
+	void);
+
+void
+acpi_db_display_argument_object (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_db_dump_parser_descriptor (
+	union acpi_parse_object         *op);
+
+void *
+acpi_db_get_pointer (
+	void                            *target);
+
+void
+acpi_db_decode_internal_object (
+	union acpi_operand_object       *obj_desc);
+
+
+/*
+ * dbexec - debugger control method execution
+ */
+
+void
+acpi_db_execute (
+	char                            *name,
+	char                            **args,
+	u32                             flags);
+
+void
+acpi_db_create_execution_threads (
+	char                            *num_threads_arg,
+	char                            *num_loops_arg,
+	char                            *method_name_arg);
+
+acpi_status
+acpi_db_execute_method (
+	struct acpi_db_method_info      *info,
+	struct acpi_buffer              *return_obj);
+
+void
+acpi_db_execute_setup (
+	struct acpi_db_method_info      *info);
+
+u32
+acpi_db_get_outstanding_allocations (
+	void);
+
+void ACPI_SYSTEM_XFACE
+acpi_db_method_thread (
+	void                            *context);
+
+acpi_status
+acpi_db_execution_walk (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+
+/*
+ * dbfileio - Debugger file I/O commands
+ */
+
+acpi_object_type
+acpi_db_match_argument (
+	char                            *user_argument,
+	struct argument_info            *arguments);
+
+acpi_status
+ae_local_load_table (
+	struct acpi_table_header        *table_ptr);
+
+void
+acpi_db_close_debug_file (
+	void);
+
+void
+acpi_db_open_debug_file (
+	char                            *name);
+
+acpi_status
+acpi_db_load_acpi_table (
+	char                            *filename);
+
+acpi_status
+acpi_db_get_table_from_file (
+	char                            *filename,
+	struct acpi_table_header        **table);
+
+acpi_status
+acpi_db_read_table_from_file (
+	char                            *filename,
+	struct acpi_table_header        **table);
+
+/*
+ * dbhistry - debugger HISTORY command
+ */
+
+void
+acpi_db_add_to_history (
+	char                            *command_line);
+
+void
+acpi_db_display_history (void);
+
+char *
+acpi_db_get_from_history (
+	char                            *command_num_arg);
+
+
+/*
+ * dbinput - user front-end to the AML debugger
+ */
+
+acpi_status
+acpi_db_command_dispatch (
+	char                            *input_buffer,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+void ACPI_SYSTEM_XFACE
+acpi_db_execute_thread (
+	void                            *context);
+
+acpi_status
+acpi_db_user_commands (
+	char                            prompt,
+	union acpi_parse_object         *op);
+
+void
+acpi_db_display_help (
+	char                            *help_type);
+
+char *
+acpi_db_get_next_token (
+	char                            *string,
+	char                            **next);
+
+u32
+acpi_db_get_line (
+	char                            *input_buffer);
+
+u32
+acpi_db_match_command (
+	char                            *user_command);
+
+void
+acpi_db_single_thread (
+	void);
+
+
+/*
+ * dbstats - Generation and display of ACPI table statistics
+ */
+
+void
+acpi_db_generate_statistics (
+	union acpi_parse_object         *root,
+	u8                              is_method);
+
+
+acpi_status
+acpi_db_display_statistics (
+	char                            *type_arg);
+
+acpi_status
+acpi_db_classify_one_object (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+void
+acpi_db_count_namespace_objects (
+	void);
+
+void
+acpi_db_enumerate_object (
+	union acpi_operand_object       *obj_desc);
+
+
+/*
+ * dbutils - AML debugger utilities
+ */
+
+void
+acpi_db_set_output_destination (
+	u32                             where);
+
+void
+acpi_db_dump_buffer (
+	u32                             address);
+
+void
+acpi_db_dump_object (
+	union acpi_object               *obj_desc,
+	u32                             level);
+
+void
+acpi_db_prep_namestring (
+	char                            *name);
+
+
+acpi_status
+acpi_db_second_pass_parse (
+	union acpi_parse_object         *root);
+
+struct acpi_namespace_node *
+acpi_db_local_ns_lookup (
+	char                            *name);
+
+
+#endif  /* __ACDEBUG_H__ */
diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acdispat.h	Mon Feb 10 10:39:30 2003
@@ -0,0 +1,494 @@
+/******************************************************************************
+ *
+ * Name: acdispat.h - dispatcher (parser to interpreter interface)
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 _ACDISPAT_H_
+#define _ACDISPAT_H_
+
+
+#define NAMEOF_LOCAL_NTE    "__L0"
+#define NAMEOF_ARG_NTE      "__A0"
+
+
+/* Common interfaces */
+
+acpi_status
+acpi_ds_obj_stack_push (
+	void                            *object,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_obj_stack_pop (
+	u32                             pop_count,
+	struct acpi_walk_state          *walk_state);
+
+void *
+acpi_ds_obj_stack_get_value (
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_obj_stack_pop_object (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state);
+
+
+/* dsopcode - support for late evaluation */
+
+acpi_status
+acpi_ds_execute_arguments (
+	struct acpi_namespace_node      *node,
+	struct acpi_namespace_node      *scope_node,
+	u32                             aml_length,
+	u8                              *aml_start);
+
+acpi_status
+acpi_ds_get_buffer_field_arguments (
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ds_get_region_arguments (
+	union acpi_operand_object       *rgn_desc);
+
+acpi_status
+acpi_ds_get_buffer_arguments (
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ds_get_package_arguments (
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ds_init_buffer_field (
+	u16                             aml_opcode,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *buffer_desc,
+	union acpi_operand_object       *offset_desc,
+	union acpi_operand_object       *length_desc,
+	union acpi_operand_object       *result_desc);
+
+acpi_status
+acpi_ds_eval_buffer_field_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ds_eval_region_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ds_eval_data_object_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ds_initialize_region (
+	acpi_handle                     obj_handle);
+
+
+/* dsctrl - Parser/Interpreter interface, control stack routines */
+
+
+acpi_status
+acpi_ds_exec_begin_control_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ds_exec_end_control_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+
+/* dsexec - Parser/Interpreter interface, method execution callbacks */
+
+
+acpi_status
+acpi_ds_get_predicate_value (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *result_obj);
+
+acpi_status
+acpi_ds_exec_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op);
+
+acpi_status
+acpi_ds_exec_end_op (
+	struct acpi_walk_state          *state);
+
+
+/* dsfield - Parser/Interpreter interface for AML fields */
+
+acpi_status
+acpi_ds_get_field_names (
+	struct acpi_create_field_info   *info,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *arg);
+
+acpi_status
+acpi_ds_create_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_create_bank_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_create_index_field (
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *region_node,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_create_buffer_field (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_init_field_objects (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state);
+
+
+/* dsload - Parser/Interpreter interface, namespace load callbacks */
+
+acpi_status
+acpi_ds_load1_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op);
+
+acpi_status
+acpi_ds_load1_end_op (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_load2_begin_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op);
+
+acpi_status
+acpi_ds_load2_end_op (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_init_callbacks (
+	struct acpi_walk_state          *walk_state,
+	u32                             pass_number);
+
+
+/* dsmthdat - method data (locals/args) */
+
+
+acpi_status
+acpi_ds_store_object_to_local (
+	u16                             opcode,
+	u32                             index,
+	union acpi_operand_object       *src_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_method_data_get_entry (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       ***node);
+
+void
+acpi_ds_method_data_delete_all (
+	struct acpi_walk_state          *walk_state);
+
+u8
+acpi_ds_is_method_value (
+	union acpi_operand_object       *obj_desc);
+
+acpi_object_type
+acpi_ds_method_data_get_type (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_method_data_get_value (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       **dest_desc);
+
+void
+acpi_ds_method_data_delete_value (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_method_data_init_args (
+	union acpi_operand_object       **params,
+	u32                             max_param_count,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_method_data_get_node (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      **node);
+
+void
+acpi_ds_method_data_init (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_method_data_set_value (
+	u16                             opcode,
+	u32                             index,
+	union acpi_operand_object       *object,
+	struct acpi_walk_state          *walk_state);
+
+
+/* dsmethod - Parser/Interpreter interface - control method parsing */
+
+acpi_status
+acpi_ds_parse_method (
+	acpi_handle                     obj_handle);
+
+acpi_status
+acpi_ds_call_control_method (
+	struct acpi_thread_state        *thread,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ds_restart_control_method (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *return_desc);
+
+acpi_status
+acpi_ds_terminate_control_method (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_begin_method_execution (
+	struct acpi_namespace_node      *method_node,
+	union acpi_operand_object       *obj_desc,
+	struct acpi_namespace_node      *calling_method_node);
+
+
+/* dsobj - Parser/Interpreter interface - object initialization and conversion */
+
+acpi_status
+acpi_ds_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_ds_initialize_objects (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *start_node);
+
+acpi_status
+acpi_ds_build_internal_buffer_obj (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u32                             buffer_length,
+	union acpi_operand_object       **obj_desc_ptr);
+
+acpi_status
+acpi_ds_build_internal_package_obj (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u32                             package_length,
+	union acpi_operand_object       **obj_desc);
+
+acpi_status
+acpi_ds_build_internal_object (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	union acpi_operand_object       **obj_desc_ptr);
+
+acpi_status
+acpi_ds_init_object_from_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	u16                             opcode,
+	union acpi_operand_object       **obj_desc);
+
+acpi_status
+acpi_ds_create_node (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *node,
+	union acpi_parse_object         *op);
+
+
+/* dsutils - Parser/Interpreter interface utility routines */
+
+u8
+acpi_ds_is_result_used (
+	union acpi_parse_object         *op,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_ds_delete_result_if_not_used (
+	union acpi_parse_object         *op,
+	union acpi_operand_object       *result_obj,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_create_operand (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *arg,
+	u32                             args_remaining);
+
+acpi_status
+acpi_ds_create_operands (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *first_arg);
+
+acpi_status
+acpi_ds_resolve_operands (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_ds_clear_operands (
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * dswscope - Scope Stack manipulation
+ */
+
+acpi_status
+acpi_ds_scope_stack_push (
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_walk_state          *walk_state);
+
+
+acpi_status
+acpi_ds_scope_stack_pop (
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_ds_scope_stack_clear (
+	struct acpi_walk_state          *walk_state);
+
+
+/* dswstate - parser WALK_STATE management routines */
+
+struct acpi_walk_state *
+acpi_ds_create_walk_state (
+	acpi_owner_id                   owner_id,
+	union acpi_parse_object         *origin,
+	union acpi_operand_object       *mth_desc,
+	struct acpi_thread_state        *thread);
+
+acpi_status
+acpi_ds_init_aml_walk (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	struct acpi_namespace_node      *method_node,
+	u8                              *aml_start,
+	u32                             aml_length,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_obj_desc,
+	u32                             pass_number);
+
+acpi_status
+acpi_ds_obj_stack_delete_all (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_obj_stack_pop_and_delete (
+	u32                             pop_count,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_ds_delete_walk_state (
+	struct acpi_walk_state          *walk_state);
+
+struct acpi_walk_state *
+acpi_ds_pop_walk_state (
+	struct acpi_thread_state        *thread);
+
+void
+acpi_ds_push_walk_state (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_thread_state        *thread);
+
+acpi_status
+acpi_ds_result_stack_pop (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_stack_push (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_stack_clear (
+	struct acpi_walk_state          *walk_state);
+
+struct acpi_walk_state *
+acpi_ds_get_current_walk_state (
+	struct acpi_thread_state        *thread);
+
+void
+acpi_ds_delete_walk_state_cache (
+	void);
+
+acpi_status
+acpi_ds_result_insert (
+	void                            *object,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_remove (
+	union acpi_operand_object       **object,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_pop (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_push (
+	union acpi_operand_object       *object,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_result_pop_from_bottom (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state);
+
+#endif /* _ACDISPAT_H_ */
diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acevents.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,221 @@
+/******************************************************************************
+ *
+ * Name: acevents.h - Event subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACEVENTS_H__
+#define __ACEVENTS_H__
+
+
+acpi_status
+acpi_ev_initialize (
+	void);
+
+acpi_status
+acpi_ev_handler_initialize (
+	void);
+
+
+/*
+ * Evfixed - Fixed event handling
+ */
+
+acpi_status
+acpi_ev_fixed_event_initialize (
+	void);
+
+u32
+acpi_ev_fixed_event_detect (
+	void);
+
+u32
+acpi_ev_fixed_event_dispatch (
+	u32                             event);
+
+
+/*
+ * Evmisc
+ */
+
+u8
+acpi_ev_is_notify_object (
+	struct acpi_namespace_node      *node);
+
+acpi_status
+acpi_ev_acquire_global_lock(
+	u16                             timeout);
+
+acpi_status
+acpi_ev_release_global_lock(
+	void);
+
+acpi_status
+acpi_ev_init_global_lock_handler (
+	void);
+
+u32
+acpi_ev_get_gpe_register_index (
+	u32                             gpe_number);
+
+u32
+acpi_ev_get_gpe_number_index (
+	u32                             gpe_number);
+
+acpi_status
+acpi_ev_queue_notify_request (
+	struct acpi_namespace_node      *node,
+	u32                             notify_value);
+
+void ACPI_SYSTEM_XFACE
+acpi_ev_notify_dispatch (
+	void                            *context);
+
+
+/*
+ * Evgpe - GPE handling and dispatch
+ */
+
+acpi_status
+acpi_ev_gpe_initialize (
+	void);
+
+acpi_status
+acpi_ev_init_gpe_control_methods (
+	void);
+
+u32
+acpi_ev_gpe_dispatch (
+	u32                             gpe_number);
+
+u32
+acpi_ev_gpe_detect (
+	void);
+
+/*
+ * Evregion - Address Space handling
+ */
+
+acpi_status
+acpi_ev_init_address_spaces (
+	void);
+
+acpi_status
+acpi_ev_address_space_dispatch (
+	union acpi_operand_object      *region_obj,
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	void                            *value);
+
+acpi_status
+acpi_ev_addr_handler_helper (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_ev_attach_region (
+	union acpi_operand_object       *handler_obj,
+	union acpi_operand_object       *region_obj,
+	u8                              acpi_ns_is_locked);
+
+void
+acpi_ev_detach_region (
+	union acpi_operand_object      *region_obj,
+	u8                              acpi_ns_is_locked);
+
+
+/*
+ * Evregini - Region initialization and setup
+ */
+
+acpi_status
+acpi_ev_system_memory_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_io_space_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_pci_config_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_cmos_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_pci_bar_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_default_region_setup (
+	acpi_handle                     handle,
+	u32                             function,
+	void                            *handler_context,
+	void                            **region_context);
+
+acpi_status
+acpi_ev_initialize_region (
+	union acpi_operand_object       *region_obj,
+	u8                              acpi_ns_locked);
+
+
+/*
+ * Evsci - SCI (System Control Interrupt) handling/dispatch
+ */
+
+u32
+acpi_ev_install_sci_handler (
+	void);
+
+acpi_status
+acpi_ev_remove_sci_handler (
+	void);
+
+u32
+acpi_ev_initialize_sCI (
+	u32                             program_sCI);
+
+void
+acpi_ev_terminate (
+	void);
+
+
+#endif  /* __ACEVENTS_H__  */
diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acexcep.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,283 @@
+/******************************************************************************
+ *
+ * Name: acexcep.h - Exception codes returned by the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACEXCEP_H__
+#define __ACEXCEP_H__
+
+
+/*
+ * Exceptions returned by external ACPI interfaces
+ */
+
+#define AE_CODE_ENVIRONMENTAL           0x0000
+#define AE_CODE_PROGRAMMER              0x1000
+#define AE_CODE_ACPI_TABLES             0x2000
+#define AE_CODE_AML                     0x3000
+#define AE_CODE_CONTROL                 0x4000
+#define AE_CODE_MASK                    0xF000
+
+
+#define ACPI_SUCCESS(a)                 (!(a))
+#define ACPI_FAILURE(a)                 (a)
+
+
+#define AE_OK                           (acpi_status) 0x0000
+
+/*
+ * Environmental exceptions
+ */
+#define AE_ERROR                        (acpi_status) (0x0001 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_ACPI_TABLES               (acpi_status) (0x0002 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_NAMESPACE                 (acpi_status) (0x0003 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_MEMORY                    (acpi_status) (0x0004 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_FOUND                    (acpi_status) (0x0005 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_EXIST                    (acpi_status) (0x0006 | AE_CODE_ENVIRONMENTAL)
+#define AE_ALREADY_EXISTS               (acpi_status) (0x0007 | AE_CODE_ENVIRONMENTAL)
+#define AE_TYPE                         (acpi_status) (0x0008 | AE_CODE_ENVIRONMENTAL)
+#define AE_NULL_OBJECT                  (acpi_status) (0x0009 | AE_CODE_ENVIRONMENTAL)
+#define AE_NULL_ENTRY                   (acpi_status) (0x000A | AE_CODE_ENVIRONMENTAL)
+#define AE_BUFFER_OVERFLOW              (acpi_status) (0x000B | AE_CODE_ENVIRONMENTAL)
+#define AE_STACK_OVERFLOW               (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL)
+#define AE_STACK_UNDERFLOW              (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_IMPLEMENTED              (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL)
+#define AE_VERSION_MISMATCH             (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL)
+#define AE_SUPPORT                      (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL)
+#define AE_SHARE                        (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL)
+#define AE_LIMIT                        (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL)
+#define AE_TIME                         (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL)
+#define AE_UNKNOWN_STATUS               (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL)
+#define AE_ACQUIRE_DEADLOCK             (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL)
+#define AE_RELEASE_DEADLOCK             (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_ACQUIRED                 (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
+#define AE_ALREADY_ACQUIRED             (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_HARDWARE_RESPONSE         (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_GLOBAL_LOCK               (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
+#define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
+#define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
+
+#define AE_CODE_ENV_MAX                 0x001C
+
+/*
+ * Programmer exceptions
+ */
+#define AE_BAD_PARAMETER                (acpi_status) (0x0001 | AE_CODE_PROGRAMMER)
+#define AE_BAD_CHARACTER                (acpi_status) (0x0002 | AE_CODE_PROGRAMMER)
+#define AE_BAD_PATHNAME                 (acpi_status) (0x0003 | AE_CODE_PROGRAMMER)
+#define AE_BAD_DATA                     (acpi_status) (0x0004 | AE_CODE_PROGRAMMER)
+#define AE_BAD_ADDRESS                  (acpi_status) (0x0005 | AE_CODE_PROGRAMMER)
+#define AE_ALIGNMENT                    (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
+#define AE_BAD_HEX_CONSTANT             (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
+#define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
+#define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
+
+#define AE_CODE_PGM_MAX                 0x0009
+
+
+/*
+ * Acpi table exceptions
+ */
+#define AE_BAD_SIGNATURE                (acpi_status) (0x0001 | AE_CODE_ACPI_TABLES)
+#define AE_BAD_HEADER                   (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES)
+#define AE_BAD_CHECKSUM                 (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES)
+#define AE_BAD_VALUE                    (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES)
+#define AE_TABLE_NOT_SUPPORTED          (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES)
+#define AE_INVALID_TABLE_LENGTH         (acpi_status) (0x0006 | AE_CODE_ACPI_TABLES)
+
+#define AE_CODE_TBL_MAX                 0x0006
+
+
+/*
+ * AML exceptions.  These are caused by problems with
+ * the actual AML byte stream
+ */
+#define AE_AML_ERROR                    (acpi_status) (0x0001 | AE_CODE_AML)
+#define AE_AML_PARSE                    (acpi_status) (0x0002 | AE_CODE_AML)
+#define AE_AML_BAD_OPCODE               (acpi_status) (0x0003 | AE_CODE_AML)
+#define AE_AML_NO_OPERAND               (acpi_status) (0x0004 | AE_CODE_AML)
+#define AE_AML_OPERAND_TYPE             (acpi_status) (0x0005 | AE_CODE_AML)
+#define AE_AML_OPERAND_VALUE            (acpi_status) (0x0006 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_LOCAL      (acpi_status) (0x0007 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ARG        (acpi_status) (0x0008 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ELEMENT    (acpi_status) (0x0009 | AE_CODE_AML)
+#define AE_AML_NUMERIC_OVERFLOW         (acpi_status) (0x000A | AE_CODE_AML)
+#define AE_AML_REGION_LIMIT             (acpi_status) (0x000B | AE_CODE_AML)
+#define AE_AML_BUFFER_LIMIT             (acpi_status) (0x000C | AE_CODE_AML)
+#define AE_AML_PACKAGE_LIMIT            (acpi_status) (0x000D | AE_CODE_AML)
+#define AE_AML_DIVIDE_BY_ZERO           (acpi_status) (0x000E | AE_CODE_AML)
+#define AE_AML_BAD_NAME                 (acpi_status) (0x000F | AE_CODE_AML)
+#define AE_AML_NAME_NOT_FOUND           (acpi_status) (0x0010 | AE_CODE_AML)
+#define AE_AML_INTERNAL                 (acpi_status) (0x0011 | AE_CODE_AML)
+#define AE_AML_INVALID_SPACE_ID         (acpi_status) (0x0012 | AE_CODE_AML)
+#define AE_AML_STRING_LIMIT             (acpi_status) (0x0013 | AE_CODE_AML)
+#define AE_AML_NO_RETURN_VALUE          (acpi_status) (0x0014 | AE_CODE_AML)
+#define AE_AML_METHOD_LIMIT             (acpi_status) (0x0015 | AE_CODE_AML)
+#define AE_AML_NOT_OWNER                (acpi_status) (0x0016 | AE_CODE_AML)
+#define AE_AML_MUTEX_ORDER              (acpi_status) (0x0017 | AE_CODE_AML)
+#define AE_AML_MUTEX_NOT_ACQUIRED       (acpi_status) (0x0018 | AE_CODE_AML)
+#define AE_AML_INVALID_RESOURCE_TYPE    (acpi_status) (0x0019 | AE_CODE_AML)
+#define AE_AML_INVALID_INDEX            (acpi_status) (0x001A | AE_CODE_AML)
+#define AE_AML_REGISTER_LIMIT           (acpi_status) (0x001B | AE_CODE_AML)
+#define AE_AML_NO_WHILE                 (acpi_status) (0x001C | AE_CODE_AML)
+#define AE_AML_ALIGNMENT                (acpi_status) (0x001D | AE_CODE_AML)
+#define AE_AML_NO_RESOURCE_END_TAG      (acpi_status) (0x001E | AE_CODE_AML)
+#define AE_AML_BAD_RESOURCE_VALUE       (acpi_status) (0x001F | AE_CODE_AML)
+#define AE_AML_CIRCULAR_REFERENCE       (acpi_status) (0x0020 | AE_CODE_AML)
+
+#define AE_CODE_AML_MAX                 0x0020
+
+/*
+ * Internal exceptions used for control
+ */
+#define AE_CTRL_RETURN_VALUE            (acpi_status) (0x0001 | AE_CODE_CONTROL)
+#define AE_CTRL_PENDING                 (acpi_status) (0x0002 | AE_CODE_CONTROL)
+#define AE_CTRL_TERMINATE               (acpi_status) (0x0003 | AE_CODE_CONTROL)
+#define AE_CTRL_TRUE                    (acpi_status) (0x0004 | AE_CODE_CONTROL)
+#define AE_CTRL_FALSE                   (acpi_status) (0x0005 | AE_CODE_CONTROL)
+#define AE_CTRL_DEPTH                   (acpi_status) (0x0006 | AE_CODE_CONTROL)
+#define AE_CTRL_END                     (acpi_status) (0x0007 | AE_CODE_CONTROL)
+#define AE_CTRL_TRANSFER                (acpi_status) (0x0008 | AE_CODE_CONTROL)
+#define AE_CTRL_BREAK                   (acpi_status) (0x0009 | AE_CODE_CONTROL)
+#define AE_CTRL_CONTINUE                (acpi_status) (0x000A | AE_CODE_CONTROL)
+#define AE_CTRL_SKIP                    (acpi_status) (0x000B | AE_CODE_CONTROL)
+
+#define AE_CODE_CTRL_MAX                0x000B
+
+
+#ifdef DEFINE_ACPI_GLOBALS
+
+/*
+ * String versions of the exception codes above
+ * These strings must match the corresponding defines exactly
+ */
+char const   *acpi_gbl_exception_names_env[] =
+{
+	"AE_OK",
+	"AE_ERROR",
+	"AE_NO_ACPI_TABLES",
+	"AE_NO_NAMESPACE",
+	"AE_NO_MEMORY",
+	"AE_NOT_FOUND",
+	"AE_NOT_EXIST",
+	"AE_ALREADY_EXISTS",
+	"AE_TYPE",
+	"AE_NULL_OBJECT",
+	"AE_NULL_ENTRY",
+	"AE_BUFFER_OVERFLOW",
+	"AE_STACK_OVERFLOW",
+	"AE_STACK_UNDERFLOW",
+	"AE_NOT_IMPLEMENTED",
+	"AE_VERSION_MISMATCH",
+	"AE_SUPPORT",
+	"AE_SHARE",
+	"AE_LIMIT",
+	"AE_TIME",
+	"AE_UNKNOWN_STATUS",
+	"AE_ACQUIRE_DEADLOCK",
+	"AE_RELEASE_DEADLOCK",
+	"AE_NOT_ACQUIRED",
+	"AE_ALREADY_ACQUIRED",
+	"AE_NO_HARDWARE_RESPONSE",
+	"AE_NO_GLOBAL_LOCK",
+	"AE_LOGICAL_ADDRESS",
+	"AE_ABORT_METHOD"
+};
+
+char const   *acpi_gbl_exception_names_pgm[] =
+{
+	"AE_BAD_PARAMETER",
+	"AE_BAD_CHARACTER",
+	"AE_BAD_PATHNAME",
+	"AE_BAD_DATA",
+	"AE_BAD_ADDRESS",
+	"AE_ALIGNMENT",
+	"AE_BAD_HEX_CONSTANT",
+	"AE_BAD_OCTAL_CONSTANT",
+	"AE_BAD_DECIMAL_CONSTANT"
+};
+
+char const   *acpi_gbl_exception_names_tbl[] =
+{
+	"AE_BAD_SIGNATURE",
+	"AE_BAD_HEADER",
+	"AE_BAD_CHECKSUM",
+	"AE_BAD_VALUE",
+	"AE_TABLE_NOT_SUPPORTED",
+	"AE_INVALID_TABLE_LENGTH"
+};
+
+char const   *acpi_gbl_exception_names_aml[] =
+{
+	"AE_AML_ERROR",
+	"AE_AML_PARSE",
+	"AE_AML_BAD_OPCODE",
+	"AE_AML_NO_OPERAND",
+	"AE_AML_OPERAND_TYPE",
+	"AE_AML_OPERAND_VALUE",
+	"AE_AML_UNINITIALIZED_LOCAL",
+	"AE_AML_UNINITIALIZED_ARG",
+	"AE_AML_UNINITIALIZED_ELEMENT",
+	"AE_AML_NUMERIC_OVERFLOW",
+	"AE_AML_REGION_LIMIT",
+	"AE_AML_BUFFER_LIMIT",
+	"AE_AML_PACKAGE_LIMIT",
+	"AE_AML_DIVIDE_BY_ZERO",
+	"AE_AML_BAD_NAME",
+	"AE_AML_NAME_NOT_FOUND",
+	"AE_AML_INTERNAL",
+	"AE_AML_INVALID_SPACE_ID",
+	"AE_AML_STRING_LIMIT",
+	"AE_AML_NO_RETURN_VALUE",
+	"AE_AML_METHOD_LIMIT",
+	"AE_AML_NOT_OWNER",
+	"AE_AML_MUTEX_ORDER",
+	"AE_AML_MUTEX_NOT_ACQUIRED",
+	"AE_AML_INVALID_RESOURCE_TYPE",
+	"AE_AML_INVALID_INDEX",
+	"AE_AML_REGISTER_LIMIT",
+	"AE_AML_NO_WHILE",
+	"AE_AML_ALIGNMENT",
+	"AE_AML_NO_RESOURCE_END_TAG",
+	"AE_AML_BAD_RESOURCE_VALUE",
+	"AE_AML_CIRCULAR_REFERENCE"
+};
+
+char const   *acpi_gbl_exception_names_ctrl[] =
+{
+	"AE_CTRL_RETURN_VALUE",
+	"AE_CTRL_PENDING",
+	"AE_CTRL_TERMINATE",
+	"AE_CTRL_TRUE",
+	"AE_CTRL_FALSE",
+	"AE_CTRL_DEPTH",
+	"AE_CTRL_END",
+	"AE_CTRL_TRANSFER",
+	"AE_CTRL_BREAK",
+	"AE_CTRL_CONTINUE",
+	"AE_CTRL_SKIP"
+};
+
+#endif /* ACPI GLOBALS */
+
+
+#endif /* __ACEXCEP_H__ */
diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acglobal.h	Mon Feb 10 10:39:22 2003
@@ -0,0 +1,298 @@
+/******************************************************************************
+ *
+ * Name: acglobal.h - Declarations for global variables
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACGLOBAL_H__
+#define __ACGLOBAL_H__
+
+
+/*
+ * Ensure that the globals are actually defined only once.
+ *
+ * The use of these defines allows a single list of globals (here) in order
+ * to simplify maintenance of the code.
+ */
+#ifdef DEFINE_ACPI_GLOBALS
+#define ACPI_EXTERN
+#else
+#define ACPI_EXTERN extern
+#endif
+
+
+/*****************************************************************************
+ *
+ * Debug support
+ *
+ ****************************************************************************/
+
+/* Runtime configuration of debug print levels */
+
+extern      u32                                 acpi_dbg_level;
+extern      u32                                 acpi_dbg_layer;
+
+/* Procedure nesting level for debug output */
+
+extern      u32                                 acpi_gbl_nesting_level;
+
+
+/*****************************************************************************
+ *
+ * ACPI Table globals
+ *
+ ****************************************************************************/
+
+/*
+ * Table pointers.
+ * Although these pointers are somewhat redundant with the global acpi_table,
+ * they are convenient because they are typed pointers.
+ *
+ * These tables are single-table only; meaning that there can be at most one
+ * of each in the system.  Each global points to the actual table.
+ *
+ */
+ACPI_EXTERN u32                                 acpi_gbl_table_flags;
+ACPI_EXTERN u32                                 acpi_gbl_rsdt_table_count;
+ACPI_EXTERN struct rsdp_descriptor             *acpi_gbl_RSDP;
+ACPI_EXTERN XSDT_DESCRIPTOR            *acpi_gbl_XSDT;
+ACPI_EXTERN FADT_DESCRIPTOR            *acpi_gbl_FADT;
+ACPI_EXTERN struct acpi_table_header           *acpi_gbl_DSDT;
+ACPI_EXTERN FACS_DESCRIPTOR            *acpi_gbl_FACS;
+ACPI_EXTERN struct acpi_common_facs             acpi_gbl_common_fACS;
+
+/*
+ * Handle both ACPI 1.0 and ACPI 2.0 Integer widths
+ * If we are running a method that exists in a 32-bit ACPI table.
+ * Use only 32 bits of the Integer for conversion.
+ */
+ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
+ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
+
+/*
+ * Since there may be multiple SSDTs and PSDTS, a single pointer is not
+ * sufficient; Therefore, there isn't one!
+ */
+
+
+/*
+ * ACPI Table info arrays
+ */
+extern      struct acpi_table_desc              acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+extern      struct acpi_table_support           acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
+
+/*
+ * Predefined mutex objects.  This array contains the
+ * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
+ * (The table maps local handles to the real OS handles)
+ */
+ACPI_EXTERN struct acpi_mutex_info              acpi_gbl_acpi_mutex_info [NUM_MTX];
+
+
+/*****************************************************************************
+ *
+ * Miscellaneous globals
+ *
+ ****************************************************************************/
+
+
+ACPI_EXTERN struct acpi_memory_list             acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
+ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_drv_notify;
+ACPI_EXTERN struct acpi_object_notify_handler   acpi_gbl_sys_notify;
+ACPI_EXTERN acpi_init_handler                   acpi_gbl_init_handler;
+ACPI_EXTERN struct acpi_walk_state             *acpi_gbl_breakpoint_walk;
+ACPI_EXTERN acpi_handle                         acpi_gbl_global_lock_semaphore;
+
+ACPI_EXTERN u32                                 acpi_gbl_global_lock_thread_count;
+ACPI_EXTERN u32                                 acpi_gbl_original_mode;
+ACPI_EXTERN u32                                 acpi_gbl_rsdp_original_location;
+ACPI_EXTERN u32                                 acpi_gbl_ns_lookup_count;
+ACPI_EXTERN u32                                 acpi_gbl_ps_find_count;
+ACPI_EXTERN u16                                 acpi_gbl_pm1_enable_register_save;
+ACPI_EXTERN u16                                 acpi_gbl_next_table_owner_id;
+ACPI_EXTERN u16                                 acpi_gbl_next_method_owner_id;
+ACPI_EXTERN u16                                 acpi_gbl_global_lock_handle;
+ACPI_EXTERN u8                                  acpi_gbl_debugger_configuration;
+ACPI_EXTERN u8                                  acpi_gbl_global_lock_acquired;
+ACPI_EXTERN u8                                  acpi_gbl_step_to_next_call;
+ACPI_EXTERN u8                                  acpi_gbl_acpi_hardware_present;
+ACPI_EXTERN u8                                  acpi_gbl_global_lock_present;
+ACPI_EXTERN u8                                  acpi_gbl_events_initialized;
+
+extern u8                                       acpi_gbl_shutdown;
+extern u32                                      acpi_gbl_startup_flags;
+extern const u8                                 acpi_gbl_decode_to8bit[8];
+extern const char                              *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT];
+extern const struct acpi_opcode_info            acpi_gbl_aml_op_info[AML_NUM_OPCODES];
+extern const char                              *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
+
+
+/*****************************************************************************
+ *
+ * Namespace globals
+ *
+ ****************************************************************************/
+
+#define NUM_NS_TYPES                    ACPI_TYPE_INVALID+1
+
+#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#define NUM_PREDEFINED_NAMES            10
+#else
+#define NUM_PREDEFINED_NAMES            9
+#endif
+
+ACPI_EXTERN struct acpi_namespace_node          acpi_gbl_root_node_struct;
+ACPI_EXTERN struct acpi_namespace_node         *acpi_gbl_root_node;
+
+extern const u8                                 acpi_gbl_ns_properties[NUM_NS_TYPES];
+extern const struct acpi_predefined_names       acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
+
+#ifdef ACPI_DEBUG_OUTPUT
+ACPI_EXTERN u32                                 acpi_gbl_current_node_count;
+ACPI_EXTERN u32                                 acpi_gbl_current_node_size;
+ACPI_EXTERN u32                                 acpi_gbl_max_concurrent_node_count;
+ACPI_EXTERN acpi_size                           acpi_gbl_entry_stack_pointer;
+ACPI_EXTERN acpi_size                           acpi_gbl_lowest_stack_pointer;
+ACPI_EXTERN u32                                 acpi_gbl_deepest_nesting;
+#endif
+
+/*****************************************************************************
+ *
+ * Interpreter globals
+ *
+ ****************************************************************************/
+
+
+ACPI_EXTERN struct acpi_thread_state            *acpi_gbl_current_walk_list;
+
+/* Control method single step flag */
+
+ACPI_EXTERN u8                                  acpi_gbl_cm_single_step;
+
+
+/*****************************************************************************
+ *
+ * Parser globals
+ *
+ ****************************************************************************/
+
+ACPI_EXTERN union acpi_parse_object             *acpi_gbl_parsed_namespace_root;
+
+/*****************************************************************************
+ *
+ * Hardware globals
+ *
+ ****************************************************************************/
+
+extern      struct acpi_bit_register_info       acpi_gbl_bit_register_info[ACPI_NUM_BITREG];
+ACPI_EXTERN u8                                  acpi_gbl_sleep_type_a;
+ACPI_EXTERN u8                                  acpi_gbl_sleep_type_b;
+
+
+/*****************************************************************************
+ *
+ * Event and GPE globals
+ *
+ ****************************************************************************/
+
+extern      struct acpi_fixed_event_info        acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
+ACPI_EXTERN struct acpi_fixed_event_handler     acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
+
+ACPI_EXTERN acpi_handle                         acpi_gbl_gpe_obj_handle;
+ACPI_EXTERN u32                                 acpi_gbl_gpe_register_count;
+ACPI_EXTERN u32                                 acpi_gbl_gpe_number_max;
+ACPI_EXTERN struct acpi_gpe_register_info      *acpi_gbl_gpe_register_info;
+ACPI_EXTERN struct acpi_gpe_number_info        *acpi_gbl_gpe_number_info;
+ACPI_EXTERN struct acpi_gpe_block_info          acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS];
+
+/*
+ * GPE translation table
+ * Indexed by the GPE number, returns a valid index into the global GPE tables.
+ *
+ * This table is needed because the GPE numbers supported by block 1 do not
+ * have to be contiguous with the GPE numbers supported by block 0.
+ */
+ACPI_EXTERN struct acpi_gpe_index_info         *acpi_gbl_gpe_number_to_index;
+
+
+/*****************************************************************************
+ *
+ * Debugger globals
+ *
+ ****************************************************************************/
+
+
+ACPI_EXTERN u8                                  acpi_gbl_db_output_flags;
+
+#ifdef ACPI_DISASSEMBLER
+
+ACPI_EXTERN u8                                  acpi_gbl_db_opt_disasm;
+ACPI_EXTERN u8                                  acpi_gbl_db_opt_verbose;
+#endif
+
+
+#ifdef ACPI_DEBUGGER
+
+extern      u8                                  acpi_gbl_method_executing;
+extern      u8                                  acpi_gbl_abort_method;
+extern      u8                                  acpi_gbl_db_terminate_threads;
+
+ACPI_EXTERN int                                 optind;
+ACPI_EXTERN char                               *optarg;
+
+ACPI_EXTERN u8                                  acpi_gbl_db_opt_tables;
+ACPI_EXTERN u8                                  acpi_gbl_db_opt_stats;
+ACPI_EXTERN u8                                  acpi_gbl_db_opt_ini_methods;
+
+
+ACPI_EXTERN char                               *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS];
+ACPI_EXTERN char                                acpi_gbl_db_line_buf[80];
+ACPI_EXTERN char                                acpi_gbl_db_parsed_buf[80];
+ACPI_EXTERN char                                acpi_gbl_db_scope_buf[40];
+ACPI_EXTERN char                                acpi_gbl_db_debug_filename[40];
+ACPI_EXTERN u8                                  acpi_gbl_db_output_to_file;
+ACPI_EXTERN char                               *acpi_gbl_db_buffer;
+ACPI_EXTERN char                               *acpi_gbl_db_filename;
+ACPI_EXTERN u32                                 acpi_gbl_db_debug_level;
+ACPI_EXTERN u32                                 acpi_gbl_db_console_debug_level;
+ACPI_EXTERN struct acpi_table_header           *acpi_gbl_db_table_ptr;
+ACPI_EXTERN struct acpi_namespace_node         *acpi_gbl_db_scope_node;
+
+/*
+ * Statistic globals
+ */
+ACPI_EXTERN u16                                 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX+1];
+ACPI_EXTERN u16                                 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX+1];
+ACPI_EXTERN u16                                 acpi_gbl_obj_type_count_misc;
+ACPI_EXTERN u16                                 acpi_gbl_node_type_count_misc;
+ACPI_EXTERN u32                                 acpi_gbl_num_nodes;
+ACPI_EXTERN u32                                 acpi_gbl_num_objects;
+
+
+ACPI_EXTERN u32                                 acpi_gbl_size_of_parse_tree;
+ACPI_EXTERN u32                                 acpi_gbl_size_of_method_trees;
+ACPI_EXTERN u32                                 acpi_gbl_size_of_node_entries;
+ACPI_EXTERN u32                                 acpi_gbl_size_of_acpi_objects;
+
+#endif /* ACPI_DEBUGGER */
+
+
+#endif /* __ACGLOBAL_H__ */
diff -Nru a/include/acpi/achware.h b/include/acpi/achware.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/achware.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ * Name: achware.h -- hardware specific interfaces
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACHWARE_H__
+#define __ACHWARE_H__
+
+
+/* PM Timer ticks per second (HZ) */
+#define PM_TIMER_FREQUENCY  3579545
+
+
+/* Prototypes */
+
+
+acpi_status
+acpi_hw_initialize (
+	void);
+
+acpi_status
+acpi_hw_shutdown (
+	void);
+
+acpi_status
+acpi_hw_initialize_system_info (
+	void);
+
+acpi_status
+acpi_hw_set_mode (
+	u32                             mode);
+
+u32
+acpi_hw_get_mode (
+	void);
+
+u32
+acpi_hw_get_mode_capabilities (
+	void);
+
+/* Register I/O Prototypes */
+
+struct acpi_bit_register_info *
+acpi_hw_get_bit_register_info (
+	u32                             register_id);
+
+acpi_status
+acpi_hw_register_read (
+	u8                              use_lock,
+	u32                             register_id,
+	u32                             *return_value);
+
+acpi_status
+acpi_hw_register_write (
+	u8                              use_lock,
+	u32                             register_id,
+	u32                             value);
+
+acpi_status
+acpi_hw_low_level_read (
+	u32                             width,
+	u32                             *value,
+	struct acpi_generic_address     *reg,
+	u32                             offset);
+
+acpi_status
+acpi_hw_low_level_write (
+	u32                             width,
+	u32                             value,
+	struct acpi_generic_address     *reg,
+	u32                             offset);
+
+acpi_status
+acpi_hw_clear_acpi_status (
+   void);
+
+
+/* GPE support */
+
+u8
+acpi_hw_get_gpe_bit_mask (
+	u32                             gpe_number);
+
+acpi_status
+acpi_hw_enable_gpe (
+	u32                             gpe_number);
+
+void
+acpi_hw_enable_gpe_for_wakeup (
+	u32                             gpe_number);
+
+acpi_status
+acpi_hw_disable_gpe (
+	u32                             gpe_number);
+
+void
+acpi_hw_disable_gpe_for_wakeup (
+	u32                             gpe_number);
+
+acpi_status
+acpi_hw_clear_gpe (
+	u32                             gpe_number);
+
+acpi_status
+acpi_hw_get_gpe_status (
+	u32                             gpe_number,
+	acpi_event_status               *event_status);
+
+acpi_status
+acpi_hw_disable_non_wakeup_gpes (
+	void);
+
+acpi_status
+acpi_hw_enable_non_wakeup_gpes (
+	void);
+
+
+/* ACPI Timer prototypes */
+
+acpi_status
+acpi_get_timer_resolution (
+	u32                             *resolution);
+
+acpi_status
+acpi_get_timer (
+	u32                             *ticks);
+
+acpi_status
+acpi_get_timer_duration (
+	u32                             start_ticks,
+	u32                             end_ticks,
+	u32                             *time_elapsed);
+
+
+#endif /* __ACHWARE_H__ */
diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acinterp.h	Mon Feb 10 10:39:31 2003
@@ -0,0 +1,717 @@
+/******************************************************************************
+ *
+ * Name: acinterp.h - Interpreter subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACINTERP_H__
+#define __ACINTERP_H__
+
+
+#define ACPI_WALK_OPERANDS       (&(walk_state->operands [walk_state->num_operands -1]))
+
+
+acpi_status
+acpi_ex_resolve_operands (
+	u16                             opcode,
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_check_object_type (
+	acpi_object_type                type_needed,
+	acpi_object_type                this_type,
+	void                            *object);
+
+/*
+ * exxface - External interpreter interfaces
+ */
+
+acpi_status
+acpi_ex_load_table (
+	acpi_table_type                 table_id);
+
+acpi_status
+acpi_ex_execute_method (
+	struct acpi_namespace_node      *method_node,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_obj_desc);
+
+
+/*
+ * exconvrt - object conversion
+ */
+
+acpi_status
+acpi_ex_convert_to_integer (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_convert_to_buffer (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_convert_to_string (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc,
+	u32                             base,
+	u32                             max_length,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_convert_to_target_type (
+	acpi_object_type                destination_type,
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       **result_desc,
+	struct acpi_walk_state          *walk_state);
+
+u32
+acpi_ex_convert_to_ascii (
+	acpi_integer                    integer,
+	u32                             base,
+	u8                              *string,
+	u8                              max_length);
+
+/*
+ * exfield - ACPI AML (p-code) execution - field manipulation
+ */
+
+acpi_status
+acpi_ex_extract_from_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length);
+
+acpi_status
+acpi_ex_insert_into_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length);
+
+acpi_status
+acpi_ex_setup_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset);
+
+acpi_status
+acpi_ex_access_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             read_write);
+
+u8
+acpi_ex_register_overflow (
+	union acpi_operand_object       *obj_desc,
+	acpi_integer                    value);
+
+acpi_status
+acpi_ex_field_datum_io (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             read_write);
+
+acpi_status
+acpi_ex_write_with_update_rule (
+	union acpi_operand_object       *obj_desc,
+	acpi_integer                    mask,
+	acpi_integer                    field_value,
+	u32                             field_datum_byte_offset);
+
+void
+acpi_ex_get_buffer_datum(
+	acpi_integer                    *datum,
+	void                            *buffer,
+	u32                             byte_granularity,
+	u32                             offset);
+
+void
+acpi_ex_set_buffer_datum (
+	acpi_integer                    merged_datum,
+	void                            *buffer,
+	u32                             byte_granularity,
+	u32                             offset);
+
+acpi_status
+acpi_ex_read_data_from_field (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **ret_buffer_desc);
+
+acpi_status
+acpi_ex_write_data_to_field (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **result_desc);
+
+/*
+ * exmisc - ACPI AML (p-code) execution - specific opcodes
+ */
+
+acpi_status
+acpi_ex_opcode_3A_0T_0R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_3A_1T_1R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_6A_0T_1R (
+	struct acpi_walk_state          *walk_state);
+
+u8
+acpi_ex_do_match (
+	u32                             match_op,
+	acpi_integer                    package_value,
+	acpi_integer                    match_value);
+
+acpi_status
+acpi_ex_get_object_reference (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       **return_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_resolve_multiple (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *operand,
+	acpi_object_type                *return_type,
+	union acpi_operand_object       **return_desc);
+
+acpi_status
+acpi_ex_concat_template (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *obj_desc2,
+	union acpi_operand_object       **actual_return_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_do_concatenate (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *obj_desc2,
+	union acpi_operand_object       **actual_return_desc,
+	struct acpi_walk_state          *walk_state);
+
+u8
+acpi_ex_do_logical_op (
+	u16                             opcode,
+	acpi_integer                    operand0,
+	acpi_integer                    operand1);
+
+acpi_integer
+acpi_ex_do_math_op (
+	u16                             opcode,
+	acpi_integer                    operand0,
+	acpi_integer                    operand1);
+
+acpi_status
+acpi_ex_create_mutex (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_processor (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_power_resource (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_region (
+	u8                              *aml_start,
+	u32                             aml_length,
+	u8                              region_space,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_table_region (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_event (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_alias (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_create_method (
+	u8                              *aml_start,
+	u32                             aml_length,
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * exconfig - dynamic table load/unload
+ */
+
+acpi_status
+acpi_ex_add_table (
+	struct acpi_table_header        *table,
+	struct acpi_namespace_node      *parent_node,
+	union acpi_operand_object       **ddb_handle);
+
+acpi_status
+acpi_ex_load_op (
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *target,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_load_table_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       **return_desc);
+
+acpi_status
+acpi_ex_unload_table (
+	union acpi_operand_object       *ddb_handle);
+
+
+/*
+ * exmutex - mutex support
+ */
+
+acpi_status
+acpi_ex_acquire_mutex (
+	union acpi_operand_object       *time_desc,
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_release_mutex (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_walk_state          *walk_state);
+
+void
+acpi_ex_release_all_mutexes (
+	struct acpi_thread_state        *thread);
+
+void
+acpi_ex_unlink_mutex (
+	union acpi_operand_object       *obj_desc);
+
+void
+acpi_ex_link_mutex (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_thread_state        *thread);
+
+/*
+ * exprep - ACPI AML (p-code) execution - prep utilities
+ */
+
+acpi_status
+acpi_ex_prep_common_field_object (
+	union acpi_operand_object       *obj_desc,
+	u8                              field_flags,
+	u8                              field_attribute,
+	u32                             field_bit_position,
+	u32                             field_bit_length);
+
+acpi_status
+acpi_ex_prep_field_value (
+	struct acpi_create_field_info   *info);
+
+/*
+ * exsystem - Interface to OS services
+ */
+
+acpi_status
+acpi_ex_system_do_notify_op (
+	union acpi_operand_object       *value,
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_do_suspend(
+	u32                             time);
+
+acpi_status
+acpi_ex_system_do_stall (
+	u32                             time);
+
+acpi_status
+acpi_ex_system_acquire_mutex(
+	union acpi_operand_object       *time,
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_release_mutex(
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_signal_event(
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_wait_event(
+	union acpi_operand_object       *time,
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_reset_event(
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ex_system_wait_semaphore (
+	acpi_handle                     semaphore,
+	u16                             timeout);
+
+
+/*
+ * exmonadic - ACPI AML (p-code) execution, monadic operators
+ */
+
+acpi_status
+acpi_ex_opcode_1A_0T_0R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_1A_0T_1R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_1A_1T_1R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_1A_1T_0R (
+	struct acpi_walk_state          *walk_state);
+
+/*
+ * exdyadic - ACPI AML (p-code) execution, dyadic operators
+ */
+
+acpi_status
+acpi_ex_opcode_2A_0T_0R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_2A_0T_1R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_2A_1T_1R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_2A_2T_1R (
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * exresolv  - Object resolution and get value functions
+ */
+
+acpi_status
+acpi_ex_resolve_to_value (
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_resolve_node_to_value (
+	struct acpi_namespace_node      **stack_ptr,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_resolve_object_to_value (
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * exdump - Scanner debug output routines
+ */
+
+void
+acpi_ex_dump_operand (
+	union acpi_operand_object       *entry_desc);
+
+void
+acpi_ex_dump_operands (
+	union acpi_operand_object       **operands,
+	acpi_interpreter_mode           interpreter_mode,
+	char                            *ident,
+	u32                             num_levels,
+	char                            *note,
+	char                            *module_name,
+	u32                             line_number);
+
+void
+acpi_ex_dump_object_descriptor (
+	union acpi_operand_object       *object,
+	u32                             flags);
+
+void
+acpi_ex_dump_node (
+	struct acpi_namespace_node      *node,
+	u32                             flags);
+
+void
+acpi_ex_out_string (
+	char                            *title,
+	char                            *value);
+
+void
+acpi_ex_out_pointer (
+	char                            *title,
+	void                            *value);
+
+void
+acpi_ex_out_integer (
+	char                            *title,
+	u32                             value);
+
+void
+acpi_ex_out_address (
+	char                            *title,
+	acpi_physical_address           value);
+
+
+/*
+ * exnames - interpreter/scanner name load/execute
+ */
+
+char *
+acpi_ex_allocate_name_string (
+	u32                             prefix_count,
+	u32                             num_name_segs);
+
+u32
+acpi_ex_good_char (
+	u32                             character);
+
+acpi_status
+acpi_ex_name_segment (
+	u8                              **in_aml_address,
+	char                            *name_string);
+
+acpi_status
+acpi_ex_get_name_string (
+	acpi_object_type                data_type,
+	u8                              *in_aml_address,
+	char                            **out_name_string,
+	u32                             *out_name_length);
+
+acpi_status
+acpi_ex_do_name (
+	acpi_object_type                data_type,
+	acpi_interpreter_mode           load_exec_mode);
+
+
+/*
+ * exstore - Object store support
+ */
+
+acpi_status
+acpi_ex_store (
+	union acpi_operand_object       *val_desc,
+	union acpi_operand_object       *dest_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_store_object_to_index (
+	union acpi_operand_object       *val_desc,
+	union acpi_operand_object       *dest_desc,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_store_object_to_node (
+	union acpi_operand_object       *source_desc,
+	struct acpi_namespace_node      *node,
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * exstoren
+ */
+
+acpi_status
+acpi_ex_resolve_object (
+	union acpi_operand_object       **source_desc_ptr,
+	acpi_object_type                target_type,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_store_object_to_object (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc,
+	union acpi_operand_object       **new_desc,
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * excopy - object copy
+ */
+
+acpi_status
+acpi_ex_store_buffer_to_buffer (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc);
+
+acpi_status
+acpi_ex_store_string_to_string (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc);
+
+acpi_status
+acpi_ex_copy_integer_to_index_field (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc);
+
+acpi_status
+acpi_ex_copy_integer_to_bank_field (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc);
+
+acpi_status
+acpi_ex_copy_data_to_named_field (
+	union acpi_operand_object       *source_desc,
+	struct acpi_namespace_node      *node);
+
+acpi_status
+acpi_ex_copy_integer_to_buffer_field (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *target_desc);
+
+/*
+ * exutils - interpreter/scanner utilities
+ */
+
+acpi_status
+acpi_ex_enter_interpreter (
+	void);
+
+void
+acpi_ex_exit_interpreter (
+	void);
+
+void
+acpi_ex_truncate_for32bit_table (
+	union acpi_operand_object       *obj_desc);
+
+u8
+acpi_ex_acquire_global_lock (
+	u32                             rule);
+
+void
+acpi_ex_release_global_lock (
+	u8                              locked);
+
+u32
+acpi_ex_digits_needed (
+	acpi_integer                    value,
+	u32                             base);
+
+void
+acpi_ex_eisa_id_to_string (
+	u32                             numeric_id,
+	char                            *out_string);
+
+void
+acpi_ex_unsigned_integer_to_string (
+	acpi_integer                    value,
+	char                            *out_string);
+
+
+/*
+ * exregion - default op_region handlers
+ */
+
+acpi_status
+acpi_ex_system_memory_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_system_io_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_pci_config_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_cmos_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_pci_bar_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_embedded_controller_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+acpi_status
+acpi_ex_sm_bus_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+
+acpi_status
+acpi_ex_data_table_space_handler (
+	u32                             function,
+	acpi_physical_address           address,
+	u32                             bit_width,
+	acpi_integer                    *value,
+	void                            *handler_context,
+	void                            *region_context);
+
+#endif /* __INTERP_H__ */
diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/aclocal.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,953 @@
+/******************************************************************************
+ *
+ * Name: aclocal.h - Internal data types used across the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACLOCAL_H__
+#define __ACLOCAL_H__
+
+
+#define ACPI_WAIT_FOREVER               0xFFFF  /* u16, as per ACPI spec */
+
+typedef void *                                  acpi_mutex;
+typedef u32                                     acpi_mutex_handle;
+
+
+/* Total number of aml opcodes defined */
+
+#define AML_NUM_OPCODES                 0x7E
+
+
+/*****************************************************************************
+ *
+ * Mutex typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/*
+ * Predefined handles for the mutex objects used within the subsystem
+ * All mutex objects are automatically created by acpi_ut_mutex_initialize.
+ *
+ * The acquire/release ordering protocol is implied via this list.  Mutexes
+ * with a lower value must be acquired before mutexes with a higher value.
+ *
+ * NOTE: any changes here must be reflected in the acpi_gbl_mutex_names table also!
+ */
+
+#define ACPI_MTX_EXECUTE                0
+#define ACPI_MTX_INTERPRETER            1
+#define ACPI_MTX_PARSER                 2
+#define ACPI_MTX_DISPATCHER             3
+#define ACPI_MTX_TABLES                 4
+#define ACPI_MTX_OP_REGIONS             5
+#define ACPI_MTX_NAMESPACE              6
+#define ACPI_MTX_EVENTS                 7
+#define ACPI_MTX_HARDWARE               8
+#define ACPI_MTX_CACHES                 9
+#define ACPI_MTX_MEMORY                 10
+#define ACPI_MTX_DEBUG_CMD_COMPLETE     11
+#define ACPI_MTX_DEBUG_CMD_READY        12
+
+#define MAX_MTX                         12
+#define NUM_MTX                         MAX_MTX+1
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+#ifdef DEFINE_ACPI_GLOBALS
+
+/* Names for the mutexes used in the subsystem */
+
+static char                         *acpi_gbl_mutex_names[] =
+{
+	"ACPI_MTX_Execute",
+	"ACPI_MTX_Interpreter",
+	"ACPI_MTX_Parser",
+	"ACPI_MTX_Dispatcher",
+	"ACPI_MTX_Tables",
+	"ACPI_MTX_op_regions",
+	"ACPI_MTX_Namespace",
+	"ACPI_MTX_Events",
+	"ACPI_MTX_Hardware",
+	"ACPI_MTX_Caches",
+	"ACPI_MTX_Memory",
+	"ACPI_MTX_debug_cmd_complete",
+	"ACPI_MTX_debug_cmd_ready",
+};
+
+#endif
+#endif
+
+
+/* Table for the global mutexes */
+
+struct acpi_mutex_info
+{
+	acpi_mutex                          mutex;
+	u32                                 use_count;
+	u32                                 owner_id;
+};
+
+/* This owner ID means that the mutex is not in use (unlocked) */
+
+#define ACPI_MUTEX_NOT_ACQUIRED         (u32) (-1)
+
+
+/* Lock flag parameter for various interfaces */
+
+#define ACPI_MTX_DO_NOT_LOCK            0
+#define ACPI_MTX_LOCK                   1
+
+
+typedef u16                                     acpi_owner_id;
+#define ACPI_OWNER_TYPE_TABLE           0x0
+#define ACPI_OWNER_TYPE_METHOD          0x1
+#define ACPI_FIRST_METHOD_ID            0x0000
+#define ACPI_FIRST_TABLE_ID             0x8000
+
+/* TBD: [Restructure] get rid of the need for this! */
+
+#define TABLE_ID_DSDT                   (acpi_owner_id) 0x8000
+
+
+/* Field access granularities */
+
+#define ACPI_FIELD_BYTE_GRANULARITY     1
+#define ACPI_FIELD_WORD_GRANULARITY     2
+#define ACPI_FIELD_DWORD_GRANULARITY    4
+#define ACPI_FIELD_QWORD_GRANULARITY    8
+
+/*****************************************************************************
+ *
+ * Namespace typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/* Operational modes of the AML interpreter/scanner */
+
+typedef enum
+{
+	ACPI_IMODE_LOAD_PASS1               = 0x01,
+	ACPI_IMODE_LOAD_PASS2               = 0x02,
+	ACPI_IMODE_EXECUTE                  = 0x0E
+
+} acpi_interpreter_mode;
+
+
+/*
+ * The Node describes a named object that appears in the AML
+ * An acpi_node is used to store Nodes.
+ *
+ * data_type is used to differentiate between internal descriptors, and MUST
+ * be the first byte in this structure.
+ */
+
+union acpi_name_union
+{
+	u32                                 integer;
+	char                                ascii[4];
+};
+
+struct acpi_namespace_node
+{
+	u8                                  descriptor;     /* Used to differentiate object descriptor types */
+	u8                                  type;           /* Type associated with this name */
+	u16                                 owner_id;
+	union acpi_name_union               name;           /* ACPI Name, always 4 chars per ACPI spec */
+
+
+	union acpi_operand_object           *object;        /* Pointer to attached ACPI object (optional) */
+	struct acpi_namespace_node          *child;         /* first child */
+	struct acpi_namespace_node          *peer;          /* Next peer*/
+	u16                                 reference_count; /* Current count of references and children */
+	u8                                  flags;
+};
+
+
+#define ACPI_ENTRY_NOT_FOUND            NULL
+
+
+/* Node flags */
+
+#define ANOBJ_RESERVED                  0x01
+#define ANOBJ_END_OF_PEER_LIST          0x02
+#define ANOBJ_DATA_WIDTH_32             0x04     /* Parent table is 64-bits */
+#define ANOBJ_METHOD_ARG                0x08
+#define ANOBJ_METHOD_LOCAL              0x10
+#define ANOBJ_METHOD_NO_RETVAL          0x20
+#define ANOBJ_METHOD_SOME_NO_RETVAL     0x40
+
+#define ANOBJ_IS_BIT_OFFSET             0x80
+
+
+/*
+ * ACPI Table Descriptor.  One per ACPI table
+ */
+struct acpi_table_desc
+{
+	struct acpi_table_desc          *prev;
+	struct acpi_table_desc          *next;
+	struct acpi_table_desc          *installed_desc;
+	struct acpi_table_header        *pointer;
+	u8                              *aml_start;
+	u64                             physical_address;
+	u32                             aml_length;
+	acpi_size                       length;
+	u32                             count;
+	acpi_owner_id                   table_id;
+	u8                              type;
+	u8                              allocation;
+	u8                              loaded_into_namespace;
+};
+
+
+struct acpi_find_context
+{
+	char                            *search_for;
+	acpi_handle                     *list;
+	u32                             *count;
+};
+
+
+struct acpi_ns_search_data
+{
+	struct acpi_namespace_node      *node;
+};
+
+
+/*
+ * Predefined Namespace items
+ */
+struct acpi_predefined_names
+{
+	char                            *name;
+	u8                              type;
+	char                            *val;
+};
+
+
+/* Object types used during package copies */
+
+
+#define ACPI_COPY_TYPE_SIMPLE           0
+#define ACPI_COPY_TYPE_PACKAGE          1
+
+/* Info structure used to convert external<->internal namestrings */
+
+struct acpi_namestring_info
+{
+	char                            *external_name;
+	char                            *next_external_char;
+	char                            *internal_name;
+	u32                             length;
+	u32                             num_segments;
+	u32                             num_carats;
+	u8                              fully_qualified;
+};
+
+
+/* Field creation info */
+
+struct acpi_create_field_info
+{
+	struct acpi_namespace_node      *region_node;
+	struct acpi_namespace_node      *field_node;
+	struct acpi_namespace_node      *register_node;
+	struct acpi_namespace_node      *data_register_node;
+	u32                             bank_value;
+	u32                             field_bit_position;
+	u32                             field_bit_length;
+	u8                              field_flags;
+	u8                              attribute;
+	u8                              field_type;
+};
+
+
+/*****************************************************************************
+ *
+ * Event typedefs and structs
+ *
+ ****************************************************************************/
+
+/* Information about each GPE register block */
+
+struct acpi_gpe_block_info
+{
+	struct acpi_generic_address     *block_address;
+	u16                             register_count;
+	u8                              block_base_number;
+};
+
+/* Information about a particular GPE register pair */
+
+struct acpi_gpe_register_info
+{
+	struct acpi_generic_address     status_address; /* Address of status reg */
+	struct acpi_generic_address     enable_address; /* Address of enable reg */
+	u8                              status;         /* Current value of status reg */
+	u8                              enable;         /* Current value of enable reg */
+	u8                              wake_enable;    /* Mask of bits to keep enabled when sleeping */
+	u8                              base_gpe_number; /* Base GPE number for this register */
+};
+
+
+#define ACPI_GPE_LEVEL_TRIGGERED        1
+#define ACPI_GPE_EDGE_TRIGGERED         2
+
+
+/* Information about each particular GPE level */
+
+struct acpi_gpe_number_info
+{
+	struct acpi_namespace_node      *method_node;   /* Method node for this GPE level */
+	acpi_gpe_handler                handler;        /* Address of handler, if any */
+	void                            *context;       /* Context to be passed to handler */
+	u8                              type;           /* Level or Edge */
+	u8                              bit_mask;
+};
+
+
+struct acpi_gpe_index_info
+{
+	u8                              number_index;
+};
+
+/* Information about each particular fixed event */
+
+struct acpi_fixed_event_handler
+{
+	acpi_event_handler              handler;        /* Address of handler. */
+	void                            *context;       /* Context to be passed to handler */
+};
+
+
+struct acpi_fixed_event_info
+{
+	u8                              status_register_id;
+	u8                              enable_register_id;
+	u16                             status_bit_mask;
+	u16                             enable_bit_mask;
+};
+
+/* Information used during field processing */
+
+struct acpi_field_info
+{
+	u8                              skip_field;
+	u8                              field_flag;
+	u32                             pkg_length;
+};
+
+
+/*****************************************************************************
+ *
+ * Generic "state" object for stacks
+ *
+ ****************************************************************************/
+
+
+#define ACPI_CONTROL_NORMAL                  0xC0
+#define ACPI_CONTROL_CONDITIONAL_EXECUTING   0xC1
+#define ACPI_CONTROL_PREDICATE_EXECUTING     0xC2
+#define ACPI_CONTROL_PREDICATE_FALSE         0xC3
+#define ACPI_CONTROL_PREDICATE_TRUE          0xC4
+
+
+/* Forward declarations */
+struct acpi_walk_state        ;
+struct acpi_obj_mutex;
+union acpi_parse_object        ;
+
+
+#define ACPI_STATE_COMMON                  /* Two 32-bit fields and a pointer */\
+	u8                                  data_type;          /* To differentiate various internal objs */\
+	u8                                  flags;      \
+	u16                                 value;      \
+	u16                                 state;      \
+	u16                                 reserved;   \
+	void                                *next;      \
+
+struct acpi_common_state
+{
+	ACPI_STATE_COMMON
+};
+
+
+/*
+ * Update state - used to traverse complex objects such as packages
+ */
+struct acpi_update_state
+{
+	ACPI_STATE_COMMON
+	union acpi_operand_object           *object;
+};
+
+
+/*
+ * Pkg state - used to traverse nested package structures
+ */
+struct acpi_pkg_state
+{
+	ACPI_STATE_COMMON
+	union acpi_operand_object           *source_object;
+	union acpi_operand_object           *dest_object;
+	struct acpi_walk_state              *walk_state;
+	void                                *this_target_obj;
+	u32                                 num_packages;
+	u16                                 index;
+};
+
+
+/*
+ * Control state - one per if/else and while constructs.
+ * Allows nesting of these constructs
+ */
+struct acpi_control_state
+{
+	ACPI_STATE_COMMON
+	union acpi_parse_object             *predicate_op;
+	u8                                  *aml_predicate_start;   /* Start of if/while predicate */
+	u8                                  *package_end;           /* End of if/while block */
+	u16                                 opcode;
+};
+
+
+/*
+ * Scope state - current scope during namespace lookups
+ */
+struct acpi_scope_state
+{
+	ACPI_STATE_COMMON
+	struct acpi_namespace_node          *node;
+};
+
+
+struct acpi_pscope_state
+{
+	ACPI_STATE_COMMON
+	union acpi_parse_object             *op;                    /* current op being parsed */
+	u8                                  *arg_end;               /* current argument end */
+	u8                                  *pkg_end;               /* current package end */
+	u32                                 arg_list;               /* next argument to parse */
+	u32                                 arg_count;              /* Number of fixed arguments */
+};
+
+
+/*
+ * Thread state - one per thread across multiple walk states.  Multiple walk
+ * states are created when there are nested control methods executing.
+ */
+struct acpi_thread_state
+{
+	ACPI_STATE_COMMON
+	struct acpi_walk_state              *walk_state_list;       /* Head of list of walk_states for this thread */
+	union acpi_operand_object           *acquired_mutex_list;   /* List of all currently acquired mutexes */
+	u32                                 thread_id;              /* Running thread ID */
+	u16                                 current_sync_level;     /* Mutex Sync (nested acquire) level */
+};
+
+
+/*
+ * Result values - used to accumulate the results of nested
+ * AML arguments
+ */
+struct acpi_result_values
+{
+	ACPI_STATE_COMMON
+	union acpi_operand_object           *obj_desc [ACPI_OBJ_NUM_OPERANDS];
+	u8                                  num_results;
+	u8                                  last_insert;
+};
+
+
+typedef
+acpi_status (*acpi_parse_downwards) (
+	struct acpi_walk_state              *walk_state,
+	union acpi_parse_object             **out_op);
+
+typedef
+acpi_status (*acpi_parse_upwards) (
+	struct acpi_walk_state              *walk_state);
+
+
+/*
+ * Notify info - used to pass info to the deferred notify
+ * handler/dispatcher.
+ */
+struct acpi_notify_info
+{
+	ACPI_STATE_COMMON
+	struct acpi_namespace_node          *node;
+	union acpi_operand_object           *handler_obj;
+};
+
+
+/* Generic state is union of structs above */
+
+union acpi_generic_state
+{
+	struct acpi_common_state            common;
+	struct acpi_control_state           control;
+	struct acpi_update_state            update;
+	struct acpi_scope_state             scope;
+	struct acpi_pscope_state            parse_scope;
+	struct acpi_pkg_state               pkg;
+	struct acpi_thread_state            thread;
+	struct acpi_result_values           results;
+	struct acpi_notify_info             notify;
+};
+
+
+/*****************************************************************************
+ *
+ * Interpreter typedefs and structs
+ *
+ ****************************************************************************/
+
+typedef
+acpi_status (*ACPI_EXECUTE_OP) (
+	struct acpi_walk_state              *walk_state);
+
+
+/*****************************************************************************
+ *
+ * Parser typedefs and structs
+ *
+ ****************************************************************************/
+
+/*
+ * AML opcode, name, and argument layout
+ */
+struct acpi_opcode_info
+{
+#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT)
+	char                                *name;          /* Opcode name (disassembler/debug only) */
+#endif
+	u32                                 parse_args;     /* Grammar/Parse time arguments */
+	u32                                 runtime_args;   /* Interpret time arguments */
+	u32                                 flags;          /* Misc flags */
+	u8                                  object_type;    /* Corresponding internal object type */
+	u8                                  class;          /* Opcode class */
+	u8                                  type;           /* Opcode type */
+};
+
+
+union acpi_parse_value
+{
+	acpi_integer                        integer;        /* integer constant (Up to 64 bits) */
+	struct uint64_struct                integer64;      /* Structure overlay for 2 32-bit Dwords */
+	u32                                 integer32;      /* integer constant, 32 bits only */
+	u16                                 integer16;      /* integer constant, 16 bits only */
+	u8                                  integer8;       /* integer constant, 8 bits only */
+	u32                                 size;           /* bytelist or field size */
+	char                                *string;        /* NULL terminated string */
+	u8                                  *buffer;        /* buffer or string */
+	char                                *name;          /* NULL terminated string */
+	union acpi_parse_object             *arg;           /* arguments and contained ops */
+};
+
+
+#define ACPI_PARSE_COMMON \
+	u8                                  data_type;      /* To differentiate various internal objs */\
+	u8                                  flags;          /* Type of Op */\
+	u16                                 aml_opcode;     /* AML opcode */\
+	u32                                 aml_offset;     /* offset of declaration in AML */\
+	union acpi_parse_object             *parent;        /* parent op */\
+	union acpi_parse_object             *next;          /* next op */\
+	ACPI_DISASM_ONLY_MEMBERS (\
+	u8                                  disasm_flags;   /* Used during AML disassembly */\
+	u8                                  disasm_opcode;  /* Subtype used for disassembly */\
+	char                                aml_op_name[16]) /* op name (debug only) */\
+			   /* NON-DEBUG members below: */\
+	struct acpi_namespace_node          *node;          /* for use by interpreter */\
+	union acpi_parse_value              value;          /* Value or args associated with the opcode */\
+
+
+#define ACPI_DASM_BUFFER        0x00
+#define ACPI_DASM_RESOURCE      0x01
+#define ACPI_DASM_STRING        0x02
+#define ACPI_DASM_UNICODE       0x03
+#define ACPI_DASM_EISAID        0x04
+#define ACPI_DASM_MATCHOP       0x05
+
+/*
+ * generic operation (for example:  If, While, Store)
+ */
+struct acpi_parse_obj_common
+{
+	ACPI_PARSE_COMMON
+};
+
+
+/*
+ * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and op_regions),
+ * and bytelists.
+ */
+struct acpi_parse_obj_named
+{
+	ACPI_PARSE_COMMON
+	u8                                  *path;
+	u8                                  *data;          /* AML body or bytelist data */
+	u32                                 length;         /* AML length */
+	u32                                 name;           /* 4-byte name or zero if no name */
+};
+
+
+/* The parse node is the fundamental element of the parse tree */
+
+struct acpi_parse_obj_asl
+{
+	ACPI_PARSE_COMMON
+	union acpi_parse_object             *child;
+	union acpi_parse_object             *parent_method;
+	char                                *filename;
+	char                                *external_name;
+	char                                *namepath;
+	char                                name_seg[4];
+	u32                                 extra_value;
+	u32                                 column;
+	u32                                 line_number;
+	u32                                 logical_line_number;
+	u32                                 logical_byte_offset;
+	u32                                 end_line;
+	u32                                 end_logical_line;
+	u32                                 acpi_btype;
+	u32                                 aml_length;
+	u32                                 aml_subtree_length;
+	u32                                 final_aml_length;
+	u32                                 final_aml_offset;
+	u32                                 compile_flags;
+	u16                                 parse_opcode;
+	u8                                  aml_opcode_length;
+	u8                                  aml_pkg_len_bytes;
+	u8                                  extra;
+	char                                parse_op_name[12];
+};
+
+
+union acpi_parse_object
+{
+	struct acpi_parse_obj_common        common;
+	struct acpi_parse_obj_named         named;
+	struct acpi_parse_obj_asl           asl;
+};
+
+
+/*
+ * Parse state - one state per parser invocation and each control
+ * method.
+ */
+struct acpi_parse_state
+{
+	u32                                 aml_size;
+	u8                                  *aml_start;     /* first AML byte */
+	u8                                  *aml;           /* next AML byte */
+	u8                                  *aml_end;       /* (last + 1) AML byte */
+	u8                                  *pkg_start;     /* current package begin */
+	u8                                  *pkg_end;       /* current package end */
+	union acpi_parse_object             *start_op;      /* root of parse tree */
+	struct acpi_namespace_node          *start_node;
+	union acpi_generic_state            *scope;         /* current scope */
+	union acpi_parse_object             *start_scope;
+};
+
+
+/* Parse object flags */
+
+#define ACPI_PARSEOP_GENERIC                    0x01
+#define ACPI_PARSEOP_NAMED                      0x02
+#define ACPI_PARSEOP_DEFERRED                   0x04
+#define ACPI_PARSEOP_BYTELIST                   0x08
+#define ACPI_PARSEOP_IN_CACHE                   0x80
+
+/* Parse object disasm_flags */
+
+#define ACPI_PARSEOP_IGNORE                     0x01
+#define ACPI_PARSEOP_PARAMLIST                  0x02
+#define ACPI_PARSEOP_EMPTY_TERMLIST             0x04
+#define ACPI_PARSEOP_SPECIAL                    0x10
+
+
+/*****************************************************************************
+ *
+ * Hardware (ACPI registers) and PNP
+ *
+ ****************************************************************************/
+
+#define PCI_ROOT_HID_STRING         "PNP0A03"
+
+struct acpi_bit_register_info
+{
+	u8                                  parent_register;
+	u8                                  bit_position;
+	u16                                 access_bit_mask;
+};
+
+
+/*
+ * Register IDs
+ * These are the full ACPI registers
+ */
+#define ACPI_REGISTER_PM1_STATUS                0x01
+#define ACPI_REGISTER_PM1_ENABLE                0x02
+#define ACPI_REGISTER_PM1_CONTROL               0x03
+#define ACPI_REGISTER_PM1A_CONTROL              0x04
+#define ACPI_REGISTER_PM1B_CONTROL              0x05
+#define ACPI_REGISTER_PM2_CONTROL               0x06
+#define ACPI_REGISTER_PM_TIMER                  0x07
+#define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
+
+
+/* Masks used to access the bit_registers */
+
+#define ACPI_BITMASK_TIMER_STATUS               0x0001
+#define ACPI_BITMASK_BUS_MASTER_STATUS          0x0010
+#define ACPI_BITMASK_GLOBAL_LOCK_STATUS         0x0020
+#define ACPI_BITMASK_POWER_BUTTON_STATUS        0x0100
+#define ACPI_BITMASK_SLEEP_BUTTON_STATUS        0x0200
+#define ACPI_BITMASK_RT_CLOCK_STATUS            0x0400
+#define ACPI_BITMASK_WAKE_STATUS                0x8000
+
+#define ACPI_BITMASK_ALL_FIXED_STATUS           (ACPI_BITMASK_TIMER_STATUS          | \
+			 ACPI_BITMASK_BUS_MASTER_STATUS     | \
+			 ACPI_BITMASK_GLOBAL_LOCK_STATUS    | \
+			 ACPI_BITMASK_POWER_BUTTON_STATUS   | \
+			 ACPI_BITMASK_SLEEP_BUTTON_STATUS   | \
+			 ACPI_BITMASK_RT_CLOCK_STATUS       | \
+			 ACPI_BITMASK_WAKE_STATUS)
+
+#define ACPI_BITMASK_TIMER_ENABLE               0x0001
+#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE         0x0020
+#define ACPI_BITMASK_POWER_BUTTON_ENABLE        0x0100
+#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE        0x0200
+#define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
+
+#define ACPI_BITMASK_SCI_ENABLE                 0x0001
+#define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
+#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
+#define ACPI_BITMASK_SLEEP_TYPE_X               0x1C00
+#define ACPI_BITMASK_SLEEP_ENABLE               0x2000
+
+#define ACPI_BITMASK_ARB_DISABLE                0x0001
+
+
+/* Raw bit position of each bit_register */
+
+#define ACPI_BITPOSITION_TIMER_STATUS           0x00
+#define ACPI_BITPOSITION_BUS_MASTER_STATUS      0x04
+#define ACPI_BITPOSITION_GLOBAL_LOCK_STATUS     0x05
+#define ACPI_BITPOSITION_POWER_BUTTON_STATUS    0x08
+#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS    0x09
+#define ACPI_BITPOSITION_RT_CLOCK_STATUS        0x0A
+#define ACPI_BITPOSITION_WAKE_STATUS            0x0F
+
+#define ACPI_BITPOSITION_TIMER_ENABLE           0x00
+#define ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE     0x05
+#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE    0x08
+#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE    0x09
+#define ACPI_BITPOSITION_RT_CLOCK_ENABLE        0x0A
+
+#define ACPI_BITPOSITION_SCI_ENABLE             0x00
+#define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
+#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE    0x02
+#define ACPI_BITPOSITION_SLEEP_TYPE_X           0x0A
+#define ACPI_BITPOSITION_SLEEP_ENABLE           0x0D
+
+#define ACPI_BITPOSITION_ARB_DISABLE            0x00
+
+
+/*****************************************************************************
+ *
+ * Resource descriptors
+ *
+ ****************************************************************************/
+
+
+/* resource_type values */
+
+#define ACPI_RESOURCE_TYPE_MEMORY_RANGE         0
+#define ACPI_RESOURCE_TYPE_IO_RANGE             1
+#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE     2
+
+/* Resource descriptor types and masks */
+
+#define ACPI_RDESC_TYPE_LARGE                   0x80
+#define ACPI_RDESC_TYPE_SMALL                   0x00
+
+#define ACPI_RDESC_TYPE_MASK                    0x80
+#define ACPI_RDESC_SMALL_MASK                   0x78 /* Only bits 6:3 contain the type */
+
+
+/*
+ * Small resource descriptor types
+ * Note: The 3 length bits (2:0) must be zero
+ */
+#define ACPI_RDESC_TYPE_IRQ_FORMAT              0x20
+#define ACPI_RDESC_TYPE_DMA_FORMAT              0x28
+#define ACPI_RDESC_TYPE_START_DEPENDENT         0x30
+#define ACPI_RDESC_TYPE_END_DEPENDENT           0x38
+#define ACPI_RDESC_TYPE_IO_PORT                 0x40
+#define ACPI_RDESC_TYPE_FIXED_IO_PORT           0x48
+#define ACPI_RDESC_TYPE_SMALL_VENDOR            0x70
+#define ACPI_RDESC_TYPE_END_TAG                 0x78
+
+/*
+ * Large resource descriptor types
+ */
+
+#define ACPI_RDESC_TYPE_MEMORY_24               0x81
+#define ACPI_RDESC_TYPE_GENERAL_REGISTER        0x82
+#define ACPI_RDESC_TYPE_LARGE_VENDOR            0x84
+#define ACPI_RDESC_TYPE_MEMORY_32               0x85
+#define ACPI_RDESC_TYPE_FIXED_MEMORY_32         0x86
+#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE     0x87
+#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE      0x88
+#define ACPI_RDESC_TYPE_EXTENDED_XRUPT          0x89
+#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE     0x8A
+
+
+/* String version of device HIDs and UIDs */
+
+#define ACPI_DEVICE_ID_LENGTH                   0x09
+
+struct acpi_device_id
+{
+	char                    buffer[ACPI_DEVICE_ID_LENGTH];
+};
+
+
+/*****************************************************************************
+ *
+ * Miscellaneous
+ *
+ ****************************************************************************/
+
+#define ACPI_ASCII_ZERO                      0x30
+
+
+/*****************************************************************************
+ *
+ * Debugger
+ *
+ ****************************************************************************/
+
+struct acpi_db_method_info
+{
+	acpi_handle                     thread_gate;
+	char                            *name;
+	char                            **args;
+	u32                             flags;
+	u32                             num_loops;
+	char                            pathname[128];
+};
+
+struct acpi_integrity_info
+{
+	u32                         nodes;
+	u32                         objects;
+};
+
+
+#define ACPI_DB_REDIRECTABLE_OUTPUT  0x01
+#define ACPI_DB_CONSOLE_OUTPUT       0x02
+#define ACPI_DB_DUPLICATE_OUTPUT     0x03
+
+
+/*****************************************************************************
+ *
+ * Debug
+ *
+ ****************************************************************************/
+
+struct acpi_debug_print_info
+{
+	u32                             component_id;
+	char                            *proc_name;
+	char                            *module_name;
+};
+
+
+/* Entry for a memory allocation (debug only) */
+
+#define ACPI_MEM_MALLOC                      0
+#define ACPI_MEM_CALLOC                      1
+#define ACPI_MAX_MODULE_NAME                 16
+
+#define ACPI_COMMON_DEBUG_MEM_HEADER \
+	struct acpi_debug_mem_block         *previous; \
+	struct acpi_debug_mem_block         *next; \
+	u32                                 size; \
+	u32                                 component; \
+	u32                                 line; \
+	char                                module[ACPI_MAX_MODULE_NAME]; \
+	u8                                  alloc_type;
+
+struct acpi_debug_mem_header
+{
+	ACPI_COMMON_DEBUG_MEM_HEADER
+};
+
+struct acpi_debug_mem_block
+{
+	ACPI_COMMON_DEBUG_MEM_HEADER
+	u64                                 user_space;
+};
+
+
+#define ACPI_MEM_LIST_GLOBAL            0
+#define ACPI_MEM_LIST_NSNODE            1
+
+#define ACPI_MEM_LIST_FIRST_CACHE_LIST  2
+#define ACPI_MEM_LIST_STATE             2
+#define ACPI_MEM_LIST_PSNODE            3
+#define ACPI_MEM_LIST_PSNODE_EXT        4
+#define ACPI_MEM_LIST_OPERAND           5
+#define ACPI_MEM_LIST_WALK              6
+#define ACPI_MEM_LIST_MAX               6
+#define ACPI_NUM_MEM_LISTS              7
+
+
+struct acpi_memory_list
+{
+	void                                *list_head;
+	u16                                 link_offset;
+	u16                                 max_cache_depth;
+	u16                                 cache_depth;
+	u16                                 object_size;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+	/* Statistics for debug memory tracking only */
+
+	u32                                 total_allocated;
+	u32                                 total_freed;
+	u32                                 current_total_size;
+	u32                                 cache_requests;
+	u32                                 cache_hits;
+	char                                *list_name;
+#endif
+};
+
+
+#endif /* __ACLOCAL_H__ */
diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acmacros.h	Mon Feb 10 10:39:27 2003
@@ -0,0 +1,578 @@
+/******************************************************************************
+ *
+ * Name: acmacros.h - C macros for the entire subsystem.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACMACROS_H__
+#define __ACMACROS_H__
+
+
+/*
+ * Data manipulation macros
+ */
+
+#define ACPI_LOWORD(l)                  ((u16)(u32)(l))
+#define ACPI_HIWORD(l)                  ((u16)((((u32)(l)) >> 16) & 0xFFFF))
+#define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
+#define ACPI_HIBYTE(l)                  ((u8)((((u16)(l)) >> 8) & 0xFF))
+
+
+#if ACPI_MACHINE_WIDTH == 16
+
+/*
+ * For 16-bit addresses, we have to assume that the upper 32 bits
+ * are zero.
+ */
+#define ACPI_LODWORD(l)                 ((u32)(l))
+#define ACPI_HIDWORD(l)                 ((u32)(0))
+
+#define ACPI_GET_ADDRESS(a)             ((a).lo)
+#define ACPI_STORE_ADDRESS(a,b)         {(a).hi=0;(a).lo=(u32)(b);}
+#define ACPI_VALID_ADDRESS(a)           ((a).hi | (a).lo)
+
+#else
+#ifdef ACPI_NO_INTEGER64_SUPPORT
+/*
+ * acpi_integer is 32-bits, no 64-bit support on this platform
+ */
+#define ACPI_LODWORD(l)                 ((u32)(l))
+#define ACPI_HIDWORD(l)                 ((u32)(0))
+
+#define ACPI_GET_ADDRESS(a)             (a)
+#define ACPI_STORE_ADDRESS(a,b)         ((a)=(b))
+#define ACPI_VALID_ADDRESS(a)           (a)
+
+#else
+
+/*
+ * Full 64-bit address/integer on both 32-bit and 64-bit platforms
+ */
+#define ACPI_LODWORD(l)                 ((u32)(u64)(l))
+#define ACPI_HIDWORD(l)                 ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi))
+
+#define ACPI_GET_ADDRESS(a)             (a)
+#define ACPI_STORE_ADDRESS(a,b)         ((a)=(acpi_physical_address)(b))
+#define ACPI_VALID_ADDRESS(a)           (a)
+#endif
+#endif
+
+ /*
+  * Extract a byte of data using a pointer.  Any more than a byte and we
+  * get into potential aligment issues -- see the STORE macros below
+  */
+#define ACPI_GET8(addr)                 (*(u8*)(addr))
+
+/* Pointer arithmetic */
+
+#define ACPI_PTR_ADD(t,a,b)             (t *) (void *)((char *)(a) + (acpi_native_uint)(b))
+#define ACPI_PTR_DIFF(a,b)              (acpi_native_uint) ((char *)(a) - (char *)(b))
+
+/* Pointer/Integer type conversions */
+
+#define ACPI_TO_POINTER(i)              ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i)
+#define ACPI_TO_INTEGER(p)              ACPI_PTR_DIFF (p,(void *) NULL)
+#define ACPI_OFFSET(d,f)                (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
+#define ACPI_FADT_OFFSET(f)             ACPI_OFFSET (FADT_DESCRIPTOR, f)
+
+#define ACPI_CAST_PTR(t, p)             ((t *)(void *)(p))
+#define ACPI_CAST_INDIRECT_PTR(t, p)    ((t **)(void *)(p))
+
+#if ACPI_MACHINE_WIDTH == 16
+#define ACPI_STORE_POINTER(d,s)         ACPI_MOVE_UNALIGNED32_TO_32(d,s)
+#define ACPI_PHYSADDR_TO_PTR(i)         (void *)(i)
+#define ACPI_PTR_TO_PHYSADDR(i)         (u32) (char *)(i)
+#else
+#define ACPI_PHYSADDR_TO_PTR(i)         ACPI_TO_POINTER(i)
+#define ACPI_PTR_TO_PHYSADDR(i)         ACPI_TO_INTEGER(i)
+#endif
+
+/*
+ * Macros for moving data around to/from buffers that are possibly unaligned.
+ * If the hardware supports the transfer of unaligned data, just do the store.
+ * Otherwise, we have to move one byte at a time.
+ */
+
+#ifdef _HW_ALIGNMENT_SUPPORT
+
+/* The hardware supports unaligned transfers, just do the move */
+
+#define ACPI_MOVE_UNALIGNED16_TO_16(d,s)    *(u16 *)(void *)(d) = *(u16 *)(void *)(s)
+#define ACPI_MOVE_UNALIGNED32_TO_32(d,s)    *(u32 *)(void *)(d) = *(u32 *)(void *)(s)
+#define ACPI_MOVE_UNALIGNED16_TO_32(d,s)    *(u32 *)(void *)(d) = *(u16 *)(void *)(s)
+#define ACPI_MOVE_UNALIGNED64_TO_64(d,s)    *(u64 *)(void *)(d) = *(u64 *)(void *)(s)
+
+#else
+/*
+ * The hardware does not support unaligned transfers.  We must move the
+ * data one byte at a time.  These macros work whether the source or
+ * the destination (or both) is/are unaligned.
+ */
+
+#define ACPI_MOVE_UNALIGNED16_TO_16(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+	  ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];}
+
+#define ACPI_MOVE_UNALIGNED32_TO_32(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+			   ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
+			   ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
+			   ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];}
+
+#define ACPI_MOVE_UNALIGNED16_TO_32(d,s)    {(*(u32*)(void *)(d)) = 0; ACPI_MOVE_UNALIGNED16_TO_16(d,s);}
+
+#define ACPI_MOVE_UNALIGNED64_TO_64(d,s)    {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\
+					 ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\
+					 ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\
+					 ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\
+					 ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[4];\
+					 ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[5];\
+					 ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[6];\
+					 ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[7];}
+
+#endif
+
+
+/*
+ * Fast power-of-two math macros for non-optimized compilers
+ */
+
+#define _ACPI_DIV(value,power_of2)      ((u32) ((value) >> (power_of2)))
+#define _ACPI_MUL(value,power_of2)      ((u32) ((value) << (power_of2)))
+#define _ACPI_MOD(value,divisor)        ((u32) ((value) & ((divisor) -1)))
+
+#define ACPI_DIV_2(a)                   _ACPI_DIV(a,1)
+#define ACPI_MUL_2(a)                   _ACPI_MUL(a,1)
+#define ACPI_MOD_2(a)                   _ACPI_MOD(a,2)
+
+#define ACPI_DIV_4(a)                   _ACPI_DIV(a,2)
+#define ACPI_MUL_4(a)                   _ACPI_MUL(a,2)
+#define ACPI_MOD_4(a)                   _ACPI_MOD(a,4)
+
+#define ACPI_DIV_8(a)                   _ACPI_DIV(a,3)
+#define ACPI_MUL_8(a)                   _ACPI_MUL(a,3)
+#define ACPI_MOD_8(a)                   _ACPI_MOD(a,8)
+
+#define ACPI_DIV_16(a)                  _ACPI_DIV(a,4)
+#define ACPI_MUL_16(a)                  _ACPI_MUL(a,4)
+#define ACPI_MOD_16(a)                  _ACPI_MOD(a,16)
+
+
+/*
+ * Rounding macros (Power of two boundaries only)
+ */
+#define ACPI_ROUND_DOWN(value,boundary)      (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1)))
+#define ACPI_ROUND_UP(value,boundary)        ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1)))
+
+#define ACPI_ROUND_DOWN_TO_32_BITS(a)        ACPI_ROUND_DOWN(a,4)
+#define ACPI_ROUND_DOWN_TO_64_BITS(a)        ACPI_ROUND_DOWN(a,8)
+#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a)    ACPI_ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY)
+
+#define ACPI_ROUND_UP_to_32_bITS(a)          ACPI_ROUND_UP(a,4)
+#define ACPI_ROUND_UP_to_64_bITS(a)          ACPI_ROUND_UP(a,8)
+#define ACPI_ROUND_UP_TO_NATIVE_WORD(a)      ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
+
+
+#define ACPI_ROUND_BITS_UP_TO_BYTES(a)       ACPI_DIV_8((a) + 7)
+#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a)     ACPI_DIV_8((a))
+
+#define ACPI_ROUND_UP_TO_1K(a)               (((a) + 1023) >> 10)
+
+/* Generic (non-power-of-two) rounding */
+
+#define ACPI_ROUND_UP_TO(value,boundary)     (((value) + ((boundary)-1)) / (boundary))
+
+/*
+ * Bitmask creation
+ * Bit positions start at zero.
+ * MASK_BITS_ABOVE creates a mask starting AT the position and above
+ * MASK_BITS_BELOW creates a mask starting one bit BELOW the position
+ */
+#define ACPI_MASK_BITS_ABOVE(position)       (~((ACPI_INTEGER_MAX) << ((u32) (position))))
+#define ACPI_MASK_BITS_BELOW(position)       ((ACPI_INTEGER_MAX) << ((u32) (position)))
+
+#define ACPI_IS_OCTAL_DIGIT(d)               (((char)(d) >= '0') && ((char)(d) <= '7'))
+
+/* Macros for GAS addressing */
+
+#if ACPI_MACHINE_WIDTH != 16
+
+#define ACPI_PCI_DEVICE_MASK            (u64) 0x0000FFFF00000000
+#define ACPI_PCI_FUNCTION_MASK          (u64) 0x00000000FFFF0000
+#define ACPI_PCI_REGISTER_MASK          (u64) 0x000000000000FFFF
+
+/*
+ * Obsolete
+ */
+
+/*
+#define ACPI_PCI_FUNCTION(a)            (u16) ((((u64)((u64)(a) & ACPI_PCI_FUNCTION_MASK)) >> 16))
+#define ACPI_PCI_DEVICE(a)              (u16) ((((u64)((u64)(a) & ACPI_PCI_DEVICE_MASK)) >> 32))
+#define ACPI_PCI_REGISTER(a)            (u16) (((u64)((u64)(a) & ACPI_PCI_REGISTER_MASK)))
+*/
+
+
+#define ACPI_PCI_DEVICE(a)              (u16) ((ACPI_HIDWORD ((a))) & 0x0000FFFF)
+#define ACPI_PCI_FUNCTION(a)            (u16) ((ACPI_LODWORD ((a))) >> 16)
+#define ACPI_PCI_REGISTER(a)            (u16) ((ACPI_LODWORD ((a))) & 0x0000FFFF)
+
+#else
+
+/* No support for GAS and PCI IDs in 16-bit mode  */
+
+#define ACPI_PCI_FUNCTION(a)            (u16) ((a) & 0xFFFF0000)
+#define ACPI_PCI_DEVICE(a)              (u16) ((a) & 0x0000FFFF)
+#define ACPI_PCI_REGISTER(a)            (u16) ((a) & 0x0000FFFF)
+
+#endif
+
+
+/* Bitfields within ACPI registers */
+
+#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
+#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val)  reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+
+/*
+ * An struct acpi_namespace_node * can appear in some contexts,
+ * where a pointer to an union acpi_operand_object    can also
+ * appear.  This macro is used to distinguish them.
+ *
+ * The "Descriptor" field is the first field in both structures.
+ */
+#define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->descriptor_id)
+#define ACPI_SET_DESCRIPTOR_TYPE(d,t)   (((union acpi_descriptor *)(void *)(d))->descriptor_id = t)
+
+
+/* Macro to test the object type */
+
+#define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
+
+/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */
+
+#define ACPI_IS_SINGLE_TABLE(x)         (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0)
+
+/*
+ * Macros for the master AML opcode table
+ */
+#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
+#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
+#else
+#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags)    {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type}
+#endif
+
+#ifdef ACPI_DISASSEMBLER
+#define ACPI_DISASM_ONLY_MEMBERS(a)     a;
+#else
+#define ACPI_DISASM_ONLY_MEMBERS(a)
+#endif
+
+#define ARG_TYPE_WIDTH                  5
+#define ARG_1(x)                        ((u32)(x))
+#define ARG_2(x)                        ((u32)(x) << (1 * ARG_TYPE_WIDTH))
+#define ARG_3(x)                        ((u32)(x) << (2 * ARG_TYPE_WIDTH))
+#define ARG_4(x)                        ((u32)(x) << (3 * ARG_TYPE_WIDTH))
+#define ARG_5(x)                        ((u32)(x) << (4 * ARG_TYPE_WIDTH))
+#define ARG_6(x)                        ((u32)(x) << (5 * ARG_TYPE_WIDTH))
+
+#define ARGI_LIST1(a)                   (ARG_1(a))
+#define ARGI_LIST2(a,b)                 (ARG_1(b)|ARG_2(a))
+#define ARGI_LIST3(a,b,c)               (ARG_1(c)|ARG_2(b)|ARG_3(a))
+#define ARGI_LIST4(a,b,c,d)             (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
+#define ARGI_LIST5(a,b,c,d,e)           (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
+#define ARGI_LIST6(a,b,c,d,e,f)         (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
+
+#define ARGP_LIST1(a)                   (ARG_1(a))
+#define ARGP_LIST2(a,b)                 (ARG_1(a)|ARG_2(b))
+#define ARGP_LIST3(a,b,c)               (ARG_1(a)|ARG_2(b)|ARG_3(c))
+#define ARGP_LIST4(a,b,c,d)             (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
+#define ARGP_LIST5(a,b,c,d,e)           (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
+#define ARGP_LIST6(a,b,c,d,e,f)         (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
+
+#define GET_CURRENT_ARG_TYPE(list)      (list & ((u32) 0x1F))
+#define INCREMENT_ARG_LIST(list)        (list >>= ((u32) ARG_TYPE_WIDTH))
+
+
+/*
+ * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions)
+ *
+ * 1) Address space
+ * 2) Length in bytes -- convert to length in bits
+ * 3) Bit offset is zero
+ * 4) Reserved field is zero
+ * 5) Expand address to 64 bits
+ */
+#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d)   do {a.address_space_id = (u8) d;\
+							  a.register_bit_width = (u8) ACPI_MUL_8 (b);\
+							  a.register_bit_offset = 0;\
+							  a.reserved = 0;\
+							  ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0)
+
+/* ACPI V1.0 entries -- address space is always I/O */
+
+#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c)  ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO)
+
+
+/*
+ * Reporting macros that are never compiled out
+ */
+
+#define ACPI_PARAM_LIST(pl)                  pl
+
+/*
+ * Error reporting.  These versions add callers module and line#.  Since
+ * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only
+ * use it in debug mode.
+ */
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
+									   acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \
+											 acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e);
+
+#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e);
+
+#else
+
+#define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_ERROR(fp)               {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_WARNING(fp)             {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define ACPI_REPORT_NSERROR(s,e)            acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e);
+
+#define ACPI_REPORT_METHOD_ERROR(s,n,p,e)   acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e);
+
+#endif
+
+/* Error reporting.  These versions pass thru the module and line# */
+
+#define _ACPI_REPORT_INFO(a,b,c,fp)         {acpi_ut_report_info(a,b,c); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define _ACPI_REPORT_ERROR(a,b,c,fp)        {acpi_ut_report_error(a,b,c); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+#define _ACPI_REPORT_WARNING(a,b,c,fp)      {acpi_ut_report_warning(a,b,c); \
+												acpi_os_printf ACPI_PARAM_LIST(fp);}
+
+/*
+ * Debug macros that are conditionally compiled
+ */
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+#define ACPI_MODULE_NAME(name)               static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
+
+/*
+ * Function entry tracing.
+ * The first parameter should be the procedure name as a quoted string.  This is declared
+ * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
+ */
+
+#define ACPI_FUNCTION_NAME(a)           struct acpi_debug_print_info _dbg;     \
+										_dbg.component_id = _COMPONENT; \
+										_dbg.proc_name   = a;           \
+										_dbg.module_name = _THIS_MODULE;
+
+#define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a)\
+											acpi_ut_trace(__LINE__,&_dbg)
+#define ACPI_FUNCTION_TRACE_PTR(a,b)    ACPI_FUNCTION_NAME(a)\
+											acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b)
+#define ACPI_FUNCTION_TRACE_U32(a,b)    ACPI_FUNCTION_NAME(a)\
+											acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b)
+#define ACPI_FUNCTION_TRACE_STR(a,b)    ACPI_FUNCTION_NAME(a)\
+											acpi_ut_trace_str(__LINE__,&_dbg,(char *)b)
+
+#define ACPI_FUNCTION_ENTRY()           acpi_ut_track_stack_ptr()
+
+/*
+ * Function exit tracing.
+ * WARNING: These macros include a return statement.  This is usually considered
+ * bad form, but having a separate exit macro is very ugly and difficult to maintain.
+ * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
+ * so that "_proc_name" is defined.
+ */
+#ifdef ACPI_USE_DO_WHILE_0
+#define ACPI_DO_WHILE0(a)               do a while(0)
+#else
+#define ACPI_DO_WHILE0(a)               a
+#endif
+
+#define return_VOID                     ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;})
+#define return_ACPI_STATUS(s)           ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));})
+#define return_VALUE(s)                 ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));})
+#define return_PTR(s)                   ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));})
+
+/* Conditional execution */
+
+#define ACPI_DEBUG_EXEC(a)              a
+#define ACPI_NORMAL_EXEC(a)
+
+#define ACPI_DEBUG_DEFINE(a)            a;
+#define ACPI_DEBUG_ONLY_MEMBERS(a)      a;
+#define _VERBOSE_STRUCTURES
+
+
+/* Stack and buffer dumping */
+
+#define ACPI_DUMP_STACK_ENTRY(a)        acpi_ex_dump_operand(a)
+#define ACPI_DUMP_OPERANDS(a,b,c,d,e)   acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
+
+
+#define ACPI_DUMP_ENTRY(a,b)            acpi_ns_dump_entry (a,b)
+#define ACPI_DUMP_TABLES(a,b)           acpi_ns_dump_tables(a,b)
+#define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
+#define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
+#define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
+#define ACPI_BREAK_MSG(a)               acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a))
+
+
+/*
+ * Generate INT3 on ACPI_ERROR (Debug only!)
+ */
+
+#define ACPI_ERROR_BREAK
+#ifdef  ACPI_ERROR_BREAK
+#define ACPI_BREAK_ON_ERROR(lvl)        if ((lvl)&ACPI_ERROR) \
+											acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n")
+#else
+#define ACPI_BREAK_ON_ERROR(lvl)
+#endif
+
+/*
+ * Master debug print macros
+ * Print iff:
+ *    1) Debug print for the current component is enabled
+ *    2) Debug error level or trace level for the print statement is enabled
+ */
+
+#define ACPI_DEBUG_PRINT(pl)            acpi_ut_debug_print ACPI_PARAM_LIST(pl)
+#define ACPI_DEBUG_PRINT_RAW(pl)        acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
+
+
+#else
+/*
+ * This is the non-debug case -- make everything go away,
+ * leaving no executable debug code!
+ */
+
+#define ACPI_MODULE_NAME(name)
+#define _THIS_MODULE ""
+
+#define ACPI_DEBUG_EXEC(a)
+#define ACPI_NORMAL_EXEC(a)             a;
+
+#define ACPI_DEBUG_DEFINE(a)
+#define ACPI_DEBUG_ONLY_MEMBERS(a)
+#define ACPI_FUNCTION_NAME(a)
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_TRACE_PTR(a,b)
+#define ACPI_FUNCTION_TRACE_U32(a,b)
+#define ACPI_FUNCTION_TRACE_STR(a,b)
+#define ACPI_FUNCTION_EXIT
+#define ACPI_FUNCTION_STATUS_EXIT(s)
+#define ACPI_FUNCTION_VALUE_EXIT(s)
+#define ACPI_FUNCTION_ENTRY()
+#define ACPI_DUMP_STACK_ENTRY(a)
+#define ACPI_DUMP_OPERANDS(a,b,c,d,e)
+#define ACPI_DUMP_ENTRY(a,b)
+#define ACPI_DUMP_TABLES(a,b)
+#define ACPI_DUMP_PATHNAME(a,b,c,d)
+#define ACPI_DUMP_RESOURCE_LIST(a)
+#define ACPI_DUMP_BUFFER(a,b)
+#define ACPI_DEBUG_PRINT(pl)
+#define ACPI_DEBUG_PRINT_RAW(pl)
+#define ACPI_BREAK_MSG(a)
+
+#define return_VOID                     return
+#define return_ACPI_STATUS(s)           return(s)
+#define return_VALUE(s)                 return(s)
+#define return_PTR(s)                   return(s)
+
+#endif
+
+/*
+ * Some code only gets executed when the debugger is built in.
+ * Note that this is entirely independent of whether the
+ * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not.
+ */
+#ifdef ACPI_DEBUGGER
+#define ACPI_DEBUGGER_EXEC(a)           a
+#else
+#define ACPI_DEBUGGER_EXEC(a)
+#endif
+
+
+/*
+ * For 16-bit code, we want to shrink some things even though
+ * we are using ACPI_DEBUG_OUTPUT to get the debug output
+ */
+#if ACPI_MACHINE_WIDTH == 16
+#undef ACPI_DEBUG_ONLY_MEMBERS
+#undef _VERBOSE_STRUCTURES
+#define ACPI_DEBUG_ONLY_MEMBERS(a)
+#endif
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+/*
+ * 1) Set name to blanks
+ * 2) Copy the object name
+ */
+#define ACPI_ADD_OBJECT_NAME(a,b)       ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\
+										ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name))
+#else
+
+#define ACPI_ADD_OBJECT_NAME(a,b)
+#endif
+
+
+/*
+ * Memory allocation tracking (DEBUG ONLY)
+ */
+
+#ifndef ACPI_DBG_TRACK_ALLOCATIONS
+
+/* Memory allocation */
+
+#define ACPI_MEM_ALLOCATE(a)            acpi_ut_allocate((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_CALLOCATE(a)           acpi_ut_callocate((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_FREE(a)                acpi_os_free(a)
+#define ACPI_MEM_TRACKING(a)
+
+
+#else
+
+/* Memory allocation */
+
+#define ACPI_MEM_ALLOCATE(a)            acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_CALLOCATE(a)           acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_FREE(a)                acpi_ut_free_and_track(a,_COMPONENT,_THIS_MODULE,__LINE__)
+#define ACPI_MEM_TRACKING(a)            a
+
+#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
+
+
+#define ACPI_GET_STACK_POINTER          _asm {mov eax, ebx}
+
+#endif /* ACMACROS_H */
diff -Nru a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acnamesp.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,489 @@
+/******************************************************************************
+ *
+ * Name: acnamesp.h - Namespace subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACNAMESP_H__
+#define __ACNAMESP_H__
+
+
+/* To search the entire name space, pass this as search_base */
+
+#define ACPI_NS_ALL                 ((acpi_handle)0)
+
+/*
+ * Elements of acpi_ns_properties are bit significant
+ * and should be one-to-one with values of acpi_object_type
+ */
+#define ACPI_NS_NORMAL              0
+#define ACPI_NS_NEWSCOPE            1   /* a definition of this type opens a name scope */
+#define ACPI_NS_LOCAL               2   /* suppress search of enclosing scopes */
+
+
+/* Definitions of the predefined namespace names  */
+
+#define ACPI_UNKNOWN_NAME           (u32) 0x3F3F3F3F     /* Unknown name is  "????" */
+#define ACPI_ROOT_NAME              (u32) 0x5F5F5F5C     /* Root name is     "\___" */
+#define ACPI_SYS_BUS_NAME           (u32) 0x5F53425F     /* Sys bus name is  "_SB_" */
+
+#define ACPI_NS_ROOT_PATH           "\\"
+#define ACPI_NS_SYSTEM_BUS          "_SB_"
+
+
+/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */
+
+#define ACPI_NS_NO_UPSEARCH         0
+#define ACPI_NS_SEARCH_PARENT       0x01
+#define ACPI_NS_DONT_OPEN_SCOPE     0x02
+#define ACPI_NS_NO_PEER_SEARCH      0x04
+#define ACPI_NS_ERROR_IF_FOUND      0x08
+
+#define ACPI_NS_WALK_UNLOCK         TRUE
+#define ACPI_NS_WALK_NO_UNLOCK      FALSE
+
+
+acpi_status
+acpi_ns_load_namespace (
+	void);
+
+acpi_status
+acpi_ns_initialize_objects (
+	void);
+
+acpi_status
+acpi_ns_initialize_devices (
+	void);
+
+
+/* Namespace init - nsxfinit */
+
+acpi_status
+acpi_ns_init_one_device (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_ns_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+
+acpi_status
+acpi_ns_walk_namespace (
+	acpi_object_type                type,
+	acpi_handle                     start_object,
+	u32                             max_depth,
+	u8                              unlock_before_callback,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value);
+
+struct acpi_namespace_node *
+acpi_ns_get_next_node (
+	acpi_object_type                type,
+	struct acpi_namespace_node      *parent,
+	struct acpi_namespace_node      *child);
+
+void
+acpi_ns_delete_namespace_by_owner (
+	u16                             table_id);
+
+
+/* Namespace loading - nsload */
+
+acpi_status
+acpi_ns_one_complete_parse (
+	u32                             pass_number,
+	struct acpi_table_desc          *table_desc);
+
+acpi_status
+acpi_ns_parse_table (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *scope);
+
+acpi_status
+acpi_ns_load_table (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *node);
+
+acpi_status
+acpi_ns_load_table_by_type (
+	acpi_table_type                 table_type);
+
+
+/*
+ * Top-level namespace access - nsaccess
+ */
+
+acpi_status
+acpi_ns_root_initialize (
+	void);
+
+acpi_status
+acpi_ns_lookup (
+	union acpi_generic_state        *scope_info,
+	char                            *name,
+	acpi_object_type                type,
+	acpi_interpreter_mode           interpreter_mode,
+	u32                             flags,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      **ret_node);
+
+
+/*
+ * Named object allocation/deallocation - nsalloc
+ */
+
+struct acpi_namespace_node *
+acpi_ns_create_node (
+	u32                             name);
+
+void
+acpi_ns_delete_node (
+	struct acpi_namespace_node      *node);
+
+void
+acpi_ns_delete_namespace_subtree (
+	struct acpi_namespace_node      *parent_handle);
+
+void
+acpi_ns_detach_object (
+	struct acpi_namespace_node      *node);
+
+void
+acpi_ns_delete_children (
+	struct acpi_namespace_node      *parent);
+
+int
+acpi_ns_compare_names (
+	char                            *name1,
+	char                            *name2);
+
+/*
+ * Namespace modification - nsmodify
+ */
+
+acpi_status
+acpi_ns_unload_namespace (
+	acpi_handle                     handle);
+
+acpi_status
+acpi_ns_delete_subtree (
+	acpi_handle                     start_handle);
+
+
+/*
+ * Namespace dump/print utilities - nsdump
+ */
+
+void
+acpi_ns_dump_tables (
+	acpi_handle                     search_base,
+	u32                             max_depth);
+
+void
+acpi_ns_dump_entry (
+	acpi_handle                     handle,
+	u32                             debug_level);
+
+void
+acpi_ns_dump_pathname (
+	acpi_handle                     handle,
+	char                            *msg,
+	u32                             level,
+	u32                             component);
+
+void
+acpi_ns_print_pathname (
+	u32                             num_segments,
+	char                            *pathname);
+
+acpi_status
+acpi_ns_dump_one_device (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+void
+acpi_ns_dump_root_devices (
+	void);
+
+acpi_status
+acpi_ns_dump_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+void
+acpi_ns_dump_objects (
+	acpi_object_type                type,
+	u8                              display_type,
+	u32                             max_depth,
+	u32                             ownder_id,
+	acpi_handle                     start_handle);
+
+
+/*
+ * Namespace evaluation functions - nseval
+ */
+
+acpi_status
+acpi_ns_evaluate_by_handle (
+	struct acpi_namespace_node      *prefix_node,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_object);
+
+acpi_status
+acpi_ns_evaluate_by_name (
+	char                            *pathname,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_object);
+
+acpi_status
+acpi_ns_evaluate_relative (
+	struct acpi_namespace_node      *prefix_node,
+	char                            *pathname,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_object);
+
+acpi_status
+acpi_ns_execute_control_method (
+	struct acpi_namespace_node      *method_node,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_obj_desc);
+
+acpi_status
+acpi_ns_get_object_value (
+	struct acpi_namespace_node      *object_node,
+	union acpi_operand_object       **return_obj_desc);
+
+
+/*
+ * Parent/Child/Peer utility functions
+ */
+
+acpi_name
+acpi_ns_find_parent_name (
+	struct acpi_namespace_node      *node_to_search);
+
+
+/*
+ * Name and Scope manipulation - nsnames
+ */
+
+u32
+acpi_ns_opens_scope (
+	acpi_object_type                type);
+
+void
+acpi_ns_build_external_path (
+	struct acpi_namespace_node      *node,
+	acpi_size                       size,
+	char                            *name_buffer);
+
+char *
+acpi_ns_get_external_pathname (
+	struct acpi_namespace_node      *node);
+
+char *
+acpi_ns_name_of_current_scope (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ns_handle_to_pathname (
+	acpi_handle                     target_handle,
+	struct acpi_buffer              *buffer);
+
+u8
+acpi_ns_pattern_match (
+	struct acpi_namespace_node      *obj_node,
+	char                            *search_for);
+
+acpi_status
+acpi_ns_get_node_by_path (
+	char                            *external_pathname,
+	struct acpi_namespace_node      *in_prefix_node,
+	u32                             flags,
+	struct acpi_namespace_node      **out_node);
+
+acpi_size
+acpi_ns_get_pathname_length (
+	struct acpi_namespace_node      *node);
+
+
+/*
+ * Object management for namespace nodes - nsobject
+ */
+
+acpi_status
+acpi_ns_attach_object (
+	struct acpi_namespace_node      *node,
+	union acpi_operand_object       *object,
+	acpi_object_type                type);
+
+union acpi_operand_object *
+acpi_ns_get_attached_object (
+	struct acpi_namespace_node      *node);
+
+union acpi_operand_object *
+acpi_ns_get_secondary_object (
+	union acpi_operand_object       *obj_desc);
+
+acpi_status
+acpi_ns_attach_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler,
+	void                            *data);
+
+acpi_status
+acpi_ns_detach_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler);
+
+acpi_status
+acpi_ns_get_attached_data (
+	struct acpi_namespace_node      *node,
+	acpi_object_handler             handler,
+	void                            **data);
+
+
+/*
+ * Namespace searching and entry - nssearch
+ */
+
+acpi_status
+acpi_ns_search_and_enter (
+	u32                             entry_name,
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *node,
+	acpi_interpreter_mode           interpreter_mode,
+	acpi_object_type                type,
+	u32                             flags,
+	struct acpi_namespace_node      **ret_node);
+
+acpi_status
+acpi_ns_search_node (
+	u32                             entry_name,
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_namespace_node      **ret_node);
+
+void
+acpi_ns_install_node (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_namespace_node      *parent_node,
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type);
+
+
+/*
+ * Utility functions - nsutils
+ */
+
+u8
+acpi_ns_valid_root_prefix (
+	char                            prefix);
+
+u8
+acpi_ns_valid_path_separator (
+	char                            sep);
+
+acpi_object_type
+acpi_ns_get_type (
+	struct acpi_namespace_node      *node);
+
+u32
+acpi_ns_local (
+	acpi_object_type                type);
+
+void
+acpi_ns_report_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	char                            *internal_name,
+	acpi_status                     lookup_status);
+
+void
+acpi_ns_report_method_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	char                            *message,
+	struct acpi_namespace_node      *node,
+	char                            *path,
+	acpi_status                     lookup_status);
+
+void
+acpi_ns_print_node_pathname (
+	struct acpi_namespace_node      *node,
+	char                            *msg);
+
+acpi_status
+acpi_ns_build_internal_name (
+	struct acpi_namestring_info     *info);
+
+void
+acpi_ns_get_internal_name_length (
+	struct acpi_namestring_info     *info);
+
+acpi_status
+acpi_ns_internalize_name (
+	char                            *dotted_name,
+	char                            **converted_name);
+
+acpi_status
+acpi_ns_externalize_name (
+	u32                             internal_name_length,
+	char                            *internal_name,
+	u32                             *converted_name_length,
+	char                            **converted_name);
+
+struct acpi_namespace_node *
+acpi_ns_map_handle_to_node (
+	acpi_handle                     handle);
+
+acpi_handle
+acpi_ns_convert_entry_to_handle(
+	struct acpi_namespace_node      *node);
+
+void
+acpi_ns_terminate (
+	void);
+
+struct acpi_namespace_node *
+acpi_ns_get_parent_node (
+	struct acpi_namespace_node      *node);
+
+
+struct acpi_namespace_node *
+acpi_ns_get_next_valid_node (
+	struct acpi_namespace_node      *node);
+
+
+#endif /* __ACNAMESP_H__ */
diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acobject.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,473 @@
+
+/******************************************************************************
+ *
+ * Name: acobject.h - Definition of union acpi_operand_object    (Internal object only)
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 _ACOBJECT_H
+#define _ACOBJECT_H
+
+
+/*
+ * The union acpi_operand_object    is used to pass AML operands from the dispatcher
+ * to the interpreter, and to keep track of the various handlers such as
+ * address space handlers and notify handlers.  The object is a constant
+ * size in order to allow it to be cached and reused.
+ */
+
+/*******************************************************************************
+ *
+ * Common Descriptors
+ *
+ ******************************************************************************/
+
+/*
+ * Common area for all objects.
+ *
+ * data_type is used to differentiate between internal descriptors, and MUST
+ * be the first byte in this structure.
+ */
+#define ACPI_OBJECT_COMMON_HEADER   /* SIZE/ALIGNMENT: 32 bits, one ptr plus trailing 8-bit flag */\
+	u8                                      descriptor;         /* To differentiate various internal objs */\
+	u8                                      type;               /* acpi_object_type */\
+	u16                                     reference_count;    /* For object deletion management */\
+	union acpi_operand_object               *next_object;       /* Objects linked to parent NS node */\
+	u8                                      flags; \
+
+/* Values for flag byte above */
+
+#define AOPOBJ_AML_CONSTANT         0x01
+#define AOPOBJ_STATIC_POINTER       0x02
+#define AOPOBJ_DATA_VALID           0x04
+#define AOPOBJ_OBJECT_INITIALIZED   0x08
+#define AOPOBJ_SETUP_COMPLETE       0x10
+#define AOPOBJ_SINGLE_DATUM         0x20
+
+
+/*
+ * Common bitfield for the field objects
+ * "Field Datum"  -- a datum from the actual field object
+ * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field
+ */
+#define ACPI_COMMON_FIELD_INFO      /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\
+	u8                                      field_flags;        /* Access, update, and lock bits */\
+	u8                                      attribute;          /* From access_as keyword */\
+	u8                                      access_byte_width;  /* Read/Write size in bytes */\
+	u32                                     bit_length;         /* Length of field in bits */\
+	u32                                     base_byte_offset;   /* Byte offset within containing object */\
+	u8                                      start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
+	u8                                      datum_valid_bits;   /* Valid bit in first "Field datum" */\
+	u8                                      end_field_valid_bits; /* Valid bits in the last "field datum" */\
+	u8                                      end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\
+	u32                                     value;              /* Value to store into the Bank or Index register */\
+	struct acpi_namespace_node              *node;              /* Link back to parent node */
+
+
+/*
+ * Fields common to both Strings and Buffers
+ */
+#define ACPI_COMMON_BUFFER_INFO \
+	u32                                     length;
+
+
+/*
+ * Common fields for objects that support ASL notifications
+ */
+#define ACPI_COMMON_NOTIFY_INFO \
+	union acpi_operand_object               *sys_handler;        /* Handler for system notifies */\
+	union acpi_operand_object               *drv_handler;        /* Handler for driver notifies */\
+	union acpi_operand_object               *addr_handler;       /* Handler for Address space */
+
+
+/******************************************************************************
+ *
+ * Basic data types
+ *
+ *****************************************************************************/
+
+struct acpi_object_common
+{
+	ACPI_OBJECT_COMMON_HEADER
+};
+
+
+struct acpi_object_integer
+{
+	ACPI_OBJECT_COMMON_HEADER
+	acpi_integer                            value;
+};
+
+
+struct acpi_object_string           /* Null terminated, ASCII characters only */
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_BUFFER_INFO
+	char                                    *pointer;           /* String in AML stream or allocated string */
+};
+
+
+struct acpi_object_buffer
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_BUFFER_INFO
+	u8                                      *pointer;           /* Buffer in AML stream or allocated buffer */
+	struct acpi_namespace_node              *node;              /* Link back to parent node */
+	u8                                      *aml_start;
+	u32                                     aml_length;
+};
+
+
+struct acpi_object_package
+{
+	ACPI_OBJECT_COMMON_HEADER
+
+	u32                                     count;              /* # of elements in package */
+	u32                                     aml_length;
+	u8                                      *aml_start;
+	struct acpi_namespace_node              *node;              /* Link back to parent node */
+	union acpi_operand_object               **elements;         /* Array of pointers to acpi_objects */
+};
+
+
+/******************************************************************************
+ *
+ * Complex data types
+ *
+ *****************************************************************************/
+
+struct acpi_object_event
+{
+	ACPI_OBJECT_COMMON_HEADER
+	void                                    *semaphore;
+};
+
+
+#define INFINITE_CONCURRENCY        0xFF
+
+struct acpi_object_method
+{
+	ACPI_OBJECT_COMMON_HEADER
+	u8                                      method_flags;
+	u8                                      param_count;
+	u32                                     aml_length;
+	void                                    *semaphore;
+	u8                                      *aml_start;
+	u8                                      concurrency;
+	u8                                      thread_count;
+	acpi_owner_id                           owning_id;
+};
+
+
+struct acpi_object_mutex
+{
+	ACPI_OBJECT_COMMON_HEADER
+	u16                                     sync_level;
+	u16                                     acquisition_depth;
+	struct acpi_thread_state                *owner_thread;
+	void                                    *semaphore;
+	union acpi_operand_object               *prev;              /* Link for list of acquired mutexes */
+	union acpi_operand_object               *next;              /* Link for list of acquired mutexes */
+	struct acpi_namespace_node              *node;              /* containing object */
+};
+
+
+struct acpi_object_region
+{
+	ACPI_OBJECT_COMMON_HEADER
+
+	u8                                      space_id;
+	union acpi_operand_object               *addr_handler;      /* Handler for system notifies */
+	struct acpi_namespace_node              *node;              /* containing object */
+	union acpi_operand_object               *next;
+	u32                                     length;
+	acpi_physical_address                   address;
+};
+
+
+/******************************************************************************
+ *
+ * Objects that can be notified.  All share a common notify_info area.
+ *
+ *****************************************************************************/
+
+struct acpi_object_notify_common            /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_NOTIFY_INFO
+};
+
+
+struct acpi_object_device
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_NOTIFY_INFO
+};
+
+
+struct acpi_object_power_resource
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_NOTIFY_INFO
+	u32                                     system_level;
+	u32                                     resource_order;
+};
+
+
+struct acpi_object_processor
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_NOTIFY_INFO
+	u32                                     proc_id;
+	u32                                     length;
+	acpi_io_address                         address;
+};
+
+
+struct acpi_object_thermal_zone
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_NOTIFY_INFO
+};
+
+
+/******************************************************************************
+ *
+ * Fields.  All share a common header/info field.
+ *
+ *****************************************************************************/
+
+struct acpi_object_field_common                         /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_object               *region_obj;        /* Containing Operation Region object */
+			  /* (REGION/BANK fields only) */
+};
+
+
+struct acpi_object_region_field
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_object               *region_obj;        /* Containing op_region object */
+};
+
+
+struct acpi_object_bank_field
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_object               *region_obj;        /* Containing op_region object */
+	union acpi_operand_object               *bank_obj;          /* bank_select Register object */
+};
+
+
+struct acpi_object_index_field
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+
+	/*
+	 * No "region_obj" pointer needed since the Index and Data registers
+	 * are each field definitions unto themselves.
+	 */
+	union acpi_operand_object               *index_obj;         /* Index register */
+	union acpi_operand_object               *data_obj;          /* Data register */
+};
+
+
+/* The buffer_field is different in that it is part of a Buffer, not an op_region */
+
+struct acpi_object_buffer_field
+{
+	ACPI_OBJECT_COMMON_HEADER
+	ACPI_COMMON_FIELD_INFO
+	union acpi_operand_object               *buffer_obj;        /* Containing Buffer object */
+};
+
+
+/******************************************************************************
+ *
+ * Objects for handlers
+ *
+ *****************************************************************************/
+
+struct acpi_object_notify_handler
+{
+	ACPI_OBJECT_COMMON_HEADER
+	struct acpi_namespace_node              *node;              /* Parent device */
+	acpi_notify_handler                     handler;
+	void                                    *context;
+};
+
+
+/* Flags for address handler */
+
+#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED  0x1
+
+
+struct acpi_object_addr_handler
+{
+	ACPI_OBJECT_COMMON_HEADER
+	u8                                      space_id;
+	u16                                     hflags;
+	acpi_adr_space_handler                  handler;
+	struct acpi_namespace_node              *node;              /* Parent device */
+	void                                    *context;
+	acpi_adr_space_setup                    setup;
+	union acpi_operand_object               *region_list;       /* regions using this handler */
+	union acpi_operand_object               *next;
+};
+
+
+/******************************************************************************
+ *
+ * Special internal objects
+ *
+ *****************************************************************************/
+
+/*
+ * The Reference object type is used for these opcodes:
+ * Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op
+ */
+struct acpi_object_reference
+{
+	ACPI_OBJECT_COMMON_HEADER
+	u8                                      target_type;        /* Used for index_op */
+	u16                                     opcode;
+	u32                                     offset;             /* Used for arg_op, local_op, and index_op */
+	void                                    *object;            /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object  */
+	struct acpi_namespace_node              *node;
+	union acpi_operand_object               **where;
+};
+
+
+/*
+ * Extra object is used as additional storage for types that
+ * have AML code in their declarations (term_args) that must be
+ * evaluated at run time.
+ *
+ * Currently: Region and field_unit types
+ */
+struct acpi_object_extra
+{
+	ACPI_OBJECT_COMMON_HEADER
+	u8                                      byte_fill1;
+	u16                                     word_fill1;
+	u32                                     aml_length;
+	u8                                      *aml_start;
+	struct acpi_namespace_node              *method_REG;        /* _REG method for this region (if any) */
+	void                                    *region_context;    /* Region-specific data */
+};
+
+
+/* Additional data that can be attached to namespace nodes */
+
+struct acpi_object_data
+{
+	ACPI_OBJECT_COMMON_HEADER
+	acpi_object_handler                     handler;
+	void                                    *pointer;
+};
+
+
+/* Structure used when objects are cached for reuse */
+
+struct acpi_object_cache_list
+{
+	ACPI_OBJECT_COMMON_HEADER
+	union acpi_operand_object               *next;              /* Link for object cache and internal lists*/
+};
+
+
+/******************************************************************************
+ *
+ * union acpi_operand_object Descriptor - a giant union of all of the above
+ *
+ *****************************************************************************/
+
+union acpi_operand_object
+{
+	struct acpi_object_common               common;
+	struct acpi_object_integer              integer;
+	struct acpi_object_string               string;
+	struct acpi_object_buffer               buffer;
+	struct acpi_object_package              package;
+	struct acpi_object_event                event;
+	struct acpi_object_method               method;
+	struct acpi_object_mutex                mutex;
+	struct acpi_object_region               region;
+	struct acpi_object_notify_common        common_notify;
+	struct acpi_object_device               device;
+	struct acpi_object_power_resource       power_resource;
+	struct acpi_object_processor            processor;
+	struct acpi_object_thermal_zone         thermal_zone;
+	struct acpi_object_field_common         common_field;
+	struct acpi_object_region_field         field;
+	struct acpi_object_buffer_field         buffer_field;
+	struct acpi_object_bank_field           bank_field;
+	struct acpi_object_index_field          index_field;
+	struct acpi_object_notify_handler       notify_handler;
+	struct acpi_object_addr_handler         addr_handler;
+	struct acpi_object_reference            reference;
+	struct acpi_object_extra                extra;
+	struct acpi_object_data                 data;
+	struct acpi_object_cache_list           cache;
+};
+
+
+/******************************************************************************
+ *
+ * union acpi_descriptor - objects that share a common descriptor identifier
+ *
+ *****************************************************************************/
+
+
+/* Object descriptor types */
+
+#define ACPI_DESC_TYPE_CACHED           0x11        /* Used only when object is cached */
+#define ACPI_DESC_TYPE_STATE            0x20
+#define ACPI_DESC_TYPE_STATE_UPDATE     0x21
+#define ACPI_DESC_TYPE_STATE_PACKAGE    0x22
+#define ACPI_DESC_TYPE_STATE_CONTROL    0x23
+#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x24
+#define ACPI_DESC_TYPE_STATE_PSCOPE     0x25
+#define ACPI_DESC_TYPE_STATE_WSCOPE     0x26
+#define ACPI_DESC_TYPE_STATE_RESULT     0x27
+#define ACPI_DESC_TYPE_STATE_NOTIFY     0x28
+#define ACPI_DESC_TYPE_STATE_THREAD     0x29
+#define ACPI_DESC_TYPE_WALK             0x44
+#define ACPI_DESC_TYPE_PARSER           0x66
+#define ACPI_DESC_TYPE_OPERAND          0x88
+#define ACPI_DESC_TYPE_NAMED            0xAA
+
+
+union acpi_descriptor
+{
+	u8                                      descriptor_id;  /* To differentiate various internal objs */\
+	union acpi_operand_object               object;
+	struct acpi_namespace_node              node;
+	union acpi_parse_object                 op;
+};
+
+
+#endif /* _ACOBJECT_H */
diff -Nru a/include/acpi/acoutput.h b/include/acpi/acoutput.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acoutput.h	Mon Feb 10 10:39:24 2003
@@ -0,0 +1,166 @@
+/******************************************************************************
+ *
+ * Name: acoutput.h -- debug output
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACOUTPUT_H__
+#define __ACOUTPUT_H__
+
+/*
+ * Debug levels and component IDs.  These are used to control the
+ * granularity of the output of the DEBUG_PRINT macro -- on a per-
+ * component basis and a per-exception-type basis.
+ */
+
+/* Component IDs are used in the global "debug_layer" */
+
+#define ACPI_UTILITIES              0x00000001
+#define ACPI_HARDWARE               0x00000002
+#define ACPI_EVENTS                 0x00000004
+#define ACPI_TABLES                 0x00000008
+#define ACPI_NAMESPACE              0x00000010
+#define ACPI_PARSER                 0x00000020
+#define ACPI_DISPATCHER             0x00000040
+#define ACPI_EXECUTER               0x00000080
+#define ACPI_RESOURCES              0x00000100
+#define ACPI_CA_DEBUGGER            0x00000200
+#define ACPI_OS_SERVICES            0x00000400
+#define ACPI_CA_DISASSEMBLER        0x00000800
+
+/* Component IDs for ACPI tools and utilities */
+
+#define ACPI_COMPILER               0x00001000
+#define ACPI_TOOLS                  0x00002000
+
+#define ACPI_ALL_COMPONENTS         0x00003FFF
+#define ACPI_COMPONENT_DEFAULT      (ACPI_ALL_COMPONENTS)
+
+
+/* Component IDs reserved for ACPI drivers */
+
+#define ACPI_ALL_DRIVERS            0xFFFF0000
+
+
+/*
+ * Raw debug output levels, do not use these in the DEBUG_PRINT macros
+ */
+#define ACPI_LV_ERROR               0x00000001
+#define ACPI_LV_WARN                0x00000002
+#define ACPI_LV_INIT                0x00000004
+#define ACPI_LV_DEBUG_OBJECT        0x00000008
+#define ACPI_LV_INFO                0x00000010
+#define ACPI_LV_ALL_EXCEPTIONS      0x0000001F
+
+/* Trace verbosity level 1 [Standard Trace Level] */
+
+#define ACPI_LV_INIT_NAMES          0x00000020
+#define ACPI_LV_PARSE               0x00000040
+#define ACPI_LV_LOAD                0x00000080
+#define ACPI_LV_DISPATCH            0x00000100
+#define ACPI_LV_EXEC                0x00000200
+#define ACPI_LV_NAMES               0x00000400
+#define ACPI_LV_OPREGION            0x00000800
+#define ACPI_LV_BFIELD              0x00001000
+#define ACPI_LV_TABLES              0x00002000
+#define ACPI_LV_VALUES              0x00004000
+#define ACPI_LV_OBJECTS             0x00008000
+#define ACPI_LV_RESOURCES           0x00010000
+#define ACPI_LV_USER_REQUESTS       0x00020000
+#define ACPI_LV_PACKAGE             0x00040000
+#define ACPI_LV_VERBOSITY1          0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS
+
+/* Trace verbosity level 2 [Function tracing and memory allocation] */
+
+#define ACPI_LV_ALLOCATIONS         0x00100000
+#define ACPI_LV_FUNCTIONS           0x00200000
+#define ACPI_LV_OPTIMIZATIONS       0x00400000
+#define ACPI_LV_VERBOSITY2          0x00700000 | ACPI_LV_VERBOSITY1
+#define ACPI_LV_ALL                 ACPI_LV_VERBOSITY2
+
+/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
+
+#define ACPI_LV_MUTEX               0x01000000
+#define ACPI_LV_THREADS             0x02000000
+#define ACPI_LV_IO                  0x04000000
+#define ACPI_LV_INTERRUPTS          0x08000000
+#define ACPI_LV_VERBOSITY3          0x0F000000 | ACPI_LV_VERBOSITY2
+
+/* Exceptionally verbose output -- also used in the global "debug_level" */
+
+#define ACPI_LV_AML_DISASSEMBLE     0x10000000
+#define ACPI_LV_VERBOSE_INFO        0x20000000
+#define ACPI_LV_FULL_TABLES         0x40000000
+#define ACPI_LV_EVENTS              0x80000000
+
+#define ACPI_LV_VERBOSE             0xF0000000
+
+
+/*
+ * Debug level macros that are used in the DEBUG_PRINT macros
+ */
+#define ACPI_DEBUG_LEVEL(dl)        (u32) dl,__LINE__,&_dbg
+
+/* Exception level -- used in the global "debug_level" */
+
+#define ACPI_DB_ERROR               ACPI_DEBUG_LEVEL (ACPI_LV_ERROR)
+#define ACPI_DB_WARN                ACPI_DEBUG_LEVEL (ACPI_LV_WARN)
+#define ACPI_DB_INIT                ACPI_DEBUG_LEVEL (ACPI_LV_INIT)
+#define ACPI_DB_DEBUG_OBJECT        ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DB_INFO                ACPI_DEBUG_LEVEL (ACPI_LV_INFO)
+#define ACPI_DB_ALL_EXCEPTIONS      ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS)
+
+
+/* Trace level -- also used in the global "debug_level" */
+
+#define ACPI_DB_INIT_NAMES          ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES)
+#define ACPI_DB_THREADS             ACPI_DEBUG_LEVEL (ACPI_LV_THREADS)
+#define ACPI_DB_PARSE               ACPI_DEBUG_LEVEL (ACPI_LV_PARSE)
+#define ACPI_DB_DISPATCH            ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH)
+#define ACPI_DB_LOAD                ACPI_DEBUG_LEVEL (ACPI_LV_LOAD)
+#define ACPI_DB_EXEC                ACPI_DEBUG_LEVEL (ACPI_LV_EXEC)
+#define ACPI_DB_NAMES               ACPI_DEBUG_LEVEL (ACPI_LV_NAMES)
+#define ACPI_DB_OPREGION            ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION)
+#define ACPI_DB_BFIELD              ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD)
+#define ACPI_DB_TABLES              ACPI_DEBUG_LEVEL (ACPI_LV_TABLES)
+#define ACPI_DB_FUNCTIONS           ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS)
+#define ACPI_DB_OPTIMIZATIONS       ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS)
+#define ACPI_DB_VALUES              ACPI_DEBUG_LEVEL (ACPI_LV_VALUES)
+#define ACPI_DB_OBJECTS             ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS)
+#define ACPI_DB_ALLOCATIONS         ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS)
+#define ACPI_DB_RESOURCES           ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES)
+#define ACPI_DB_IO                  ACPI_DEBUG_LEVEL (ACPI_LV_IO)
+#define ACPI_DB_INTERRUPTS          ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS)
+#define ACPI_DB_USER_REQUESTS       ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
+#define ACPI_DB_PACKAGE             ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
+#define ACPI_DB_MUTEX               ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
+
+#define ACPI_DB_ALL                 ACPI_DEBUG_LEVEL (ACPI_LV_ALL)
+
+
+/* Defaults for debug_level, debug and normal */
+
+#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DEBUG_ALL              (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
+
+
+#endif /* __ACOUTPUT_H__ */
diff -Nru a/include/acpi/acparser.h b/include/acpi/acparser.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acparser.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,328 @@
+/******************************************************************************
+ *
+ * Module Name: acparser.h - AML Parser subcomponent prototypes and defines
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACPARSER_H__
+#define __ACPARSER_H__
+
+
+#define OP_HAS_RETURN_VALUE             1
+
+/* variable # arguments */
+
+#define ACPI_VAR_ARGS                   ACPI_UINT32_MAX
+
+
+#define ACPI_PARSE_DELETE_TREE          0x0001
+#define ACPI_PARSE_NO_TREE_DELETE       0x0000
+#define ACPI_PARSE_TREE_MASK            0x0001
+
+#define ACPI_PARSE_LOAD_PASS1           0x0010
+#define ACPI_PARSE_LOAD_PASS2           0x0020
+#define ACPI_PARSE_EXECUTE              0x0030
+#define ACPI_PARSE_MODE_MASK            0x0030
+
+#define ACPI_PARSE_DEFERRED_OP          0x0100
+
+/* Parser external interfaces */
+
+acpi_status
+acpi_psx_load_table (
+	u8                              *pcode_addr,
+	u32                             pcode_length);
+
+acpi_status
+acpi_psx_execute (
+	struct acpi_namespace_node      *method_node,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **return_obj_desc);
+
+
+/******************************************************************************
+ *
+ * Parser interfaces
+ *
+ *****************************************************************************/
+
+
+/* psargs - Parse AML opcode arguments */
+
+u8 *
+acpi_ps_get_next_package_end (
+	struct acpi_parse_state         *parser_state);
+
+u32
+acpi_ps_get_next_package_length (
+	struct acpi_parse_state         *parser_state);
+
+char *
+acpi_ps_get_next_namestring (
+	struct acpi_parse_state         *parser_state);
+
+void
+acpi_ps_get_next_simple_arg (
+	struct acpi_parse_state         *parser_state,
+	u32                             arg_type,
+	union acpi_parse_object         *arg);
+
+acpi_status
+acpi_ps_get_next_namepath (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *arg,
+	u8                              method_call);
+
+union acpi_parse_object *
+acpi_ps_get_next_field (
+	struct acpi_parse_state         *parser_state);
+
+acpi_status
+acpi_ps_get_next_arg (
+	struct acpi_walk_state          *walk_state,
+	struct acpi_parse_state         *parser_state,
+	u32                             arg_type,
+	union acpi_parse_object         **return_arg);
+
+
+/* psfind */
+
+union acpi_parse_object *
+acpi_ps_find_name (
+	union acpi_parse_object         *scope,
+	u32                             name,
+	u32                             opcode);
+
+union acpi_parse_object*
+acpi_ps_get_parent (
+	union acpi_parse_object         *op);
+
+
+/* psopcode - AML Opcode information */
+
+const struct acpi_opcode_info *
+acpi_ps_get_opcode_info (
+	u16                             opcode);
+
+char *
+acpi_ps_get_opcode_name (
+	u16                             opcode);
+
+
+/* psparse - top level parsing routines */
+
+u32
+acpi_ps_get_opcode_size (
+	u32                             opcode);
+
+void
+acpi_ps_complete_this_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+acpi_status
+acpi_ps_next_parse_state (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	acpi_status                     callback_status);
+
+acpi_status
+acpi_ps_find_object (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         **out_op);
+
+void
+acpi_ps_delete_parse_tree (
+	union acpi_parse_object         *root);
+
+acpi_status
+acpi_ps_parse_loop (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ps_parse_aml (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ps_parse_table (
+	u8                              *aml,
+	u32                             aml_size,
+	acpi_parse_downwards            descending_callback,
+	acpi_parse_upwards              ascending_callback,
+	union acpi_parse_object         **root_object);
+
+u16
+acpi_ps_peek_opcode (
+	struct acpi_parse_state         *state);
+
+
+/* psscope - Scope stack management routines */
+
+
+acpi_status
+acpi_ps_init_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *root);
+
+union acpi_parse_object *
+acpi_ps_get_parent_scope (
+	struct acpi_parse_state         *state);
+
+u8
+acpi_ps_has_completed_scope (
+	struct acpi_parse_state         *parser_state);
+
+void
+acpi_ps_pop_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         **op,
+	u32                             *arg_list,
+	u32                             *arg_count);
+
+acpi_status
+acpi_ps_push_scope (
+	struct acpi_parse_state         *parser_state,
+	union acpi_parse_object         *op,
+	u32                             remaining_args,
+	u32                             arg_count);
+
+void
+acpi_ps_cleanup_scope (
+	struct acpi_parse_state         *state);
+
+
+/* pstree - parse tree manipulation routines */
+
+void
+acpi_ps_append_arg(
+	union acpi_parse_object         *op,
+	union acpi_parse_object         *arg);
+
+union acpi_parse_object*
+acpi_ps_find (
+	union acpi_parse_object         *scope,
+	char                            *path,
+	u16                             opcode,
+	u32                             create);
+
+union acpi_parse_object *
+acpi_ps_get_arg(
+	union acpi_parse_object         *op,
+	u32                              argn);
+
+union acpi_parse_object *
+acpi_ps_get_child (
+	union acpi_parse_object         *op);
+
+union acpi_parse_object *
+acpi_ps_get_depth_next (
+	union acpi_parse_object         *origin,
+	union acpi_parse_object         *op);
+
+
+/* pswalk - parse tree walk routines */
+
+acpi_status
+acpi_ps_walk_parsed_aml (
+	union acpi_parse_object         *start_op,
+	union acpi_parse_object         *end_op,
+	union acpi_operand_object       *mth_desc,
+	struct acpi_namespace_node      *start_node,
+	union acpi_operand_object       **params,
+	union acpi_operand_object       **caller_return_desc,
+	acpi_owner_id                   owner_id,
+	acpi_parse_downwards            descending_callback,
+	acpi_parse_upwards              ascending_callback);
+
+acpi_status
+acpi_ps_get_next_walk_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	acpi_parse_upwards              ascending_callback);
+
+acpi_status
+acpi_ps_delete_completed_op (
+	struct acpi_walk_state          *walk_state);
+
+
+/* psutils - parser utilities */
+
+union acpi_parse_object *
+acpi_ps_create_scope_op (
+	void);
+
+void
+acpi_ps_init_op (
+	union acpi_parse_object         *op,
+	u16                             opcode);
+
+union acpi_parse_object *
+acpi_ps_alloc_op (
+	u16                             opcode);
+
+void
+acpi_ps_free_op (
+	union acpi_parse_object         *op);
+
+void
+acpi_ps_delete_parse_cache (
+	void);
+
+u8
+acpi_ps_is_leading_char (
+	u32                             c);
+
+u8
+acpi_ps_is_prefix_char (
+	u32                             c);
+
+u32
+acpi_ps_get_name(
+	union acpi_parse_object         *op);
+
+void
+acpi_ps_set_name(
+	union acpi_parse_object         *op,
+	u32                             name);
+
+
+/* psdump - display parser tree */
+
+u32
+acpi_ps_sprint_path (
+	char                            *buffer_start,
+	u32                             buffer_size,
+	union acpi_parse_object         *op);
+
+u32
+acpi_ps_sprint_op (
+	char                            *buffer_start,
+	u32                             buffer_size,
+	union acpi_parse_object         *op);
+
+void
+acpi_ps_show (
+	union acpi_parse_object         *op);
+
+
+#endif /* __ACPARSER_H__ */
diff -Nru a/include/acpi/acpi.h b/include/acpi/acpi.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acpi.h	Mon Feb 10 10:39:27 2003
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Name: acpi.h - Master include file, Publics and external data.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACPI_H__
+#define __ACPI_H__
+
+/*
+ * Common includes for all ACPI driver files
+ * We put them here because we don't want to duplicate them
+ * in the rest of the source code again and again.
+ */
+#include "acconfig.h"           /* Configuration constants */
+#include "platform/acenv.h"     /* Target environment specific items */
+#include "actypes.h"            /* Fundamental common data types */
+#include "acexcep.h"            /* ACPI exception codes */
+#include "acmacros.h"           /* C macros */
+#include "actbl.h"              /* ACPI table definitions */
+#include "aclocal.h"            /* Internal data types */
+#include "acoutput.h"           /* Error output and Debug macros */
+#include "acpiosxf.h"           /* Interfaces to the ACPI-to-OS layer*/
+#include "acpixf.h"             /* ACPI core subsystem external interfaces */
+#include "acobject.h"           /* ACPI internal object */
+#include "acstruct.h"           /* Common structures */
+#include "acglobal.h"           /* All global variables */
+#include "achware.h"            /* Hardware defines and interfaces */
+#include "acutils.h"            /* Utility interfaces */
+
+
+#endif /* __ACPI_H__ */
diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acpi_bus.h	Mon Feb 10 10:39:25 2003
@@ -0,0 +1,312 @@
+/*
+ *  acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more 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 __ACPI_BUS_H__
+#define __ACPI_BUS_H__
+
+#include <linux/version.h>
+#include <linux/kobject.h>
+
+#include <acpi/acpi.h>
+
+#define PREFIX			"ACPI: "
+
+extern int			acpi_disabled;
+
+/* TBD: Make dynamic */
+#define ACPI_MAX_HANDLES	10
+struct acpi_handle_list {
+	u32			count;
+	acpi_handle		handles[ACPI_MAX_HANDLES];
+};
+
+
+/* acpi_utils.h */
+acpi_status
+acpi_extract_package (
+	union acpi_object       *package,
+	struct acpi_buffer      *format,
+	struct acpi_buffer      *buffer);
+acpi_status
+acpi_evaluate_integer (
+	acpi_handle             handle,
+	acpi_string             pathname,
+	struct acpi_object_list *arguments,
+	unsigned long           *data);
+acpi_status
+acpi_evaluate_reference (
+	acpi_handle             handle,
+	acpi_string             pathname,
+	struct acpi_object_list *arguments,
+	struct acpi_handle_list *list);
+
+
+#ifdef CONFIG_ACPI_BUS
+
+#include <linux/proc_fs.h>
+
+#define ACPI_BUS_FILE_ROOT	"acpi"
+extern struct proc_dir_entry	*acpi_root_dir;
+extern FADT_DESCRIPTOR		acpi_fadt;
+
+enum acpi_bus_removal_type {
+	ACPI_BUS_REMOVAL_NORMAL	= 0,
+	ACPI_BUS_REMOVAL_EJECT,
+	ACPI_BUS_REMOVAL_SUPRISE,
+	ACPI_BUS_REMOVAL_TYPE_COUNT
+};
+
+enum acpi_bus_device_type {
+	ACPI_BUS_TYPE_DEVICE	= 0,
+	ACPI_BUS_TYPE_POWER,
+	ACPI_BUS_TYPE_PROCESSOR,
+	ACPI_BUS_TYPE_THERMAL,
+	ACPI_BUS_TYPE_SYSTEM,
+	ACPI_BUS_TYPE_POWER_BUTTON,
+	ACPI_BUS_TYPE_SLEEP_BUTTON,
+	ACPI_BUS_DEVICE_TYPE_COUNT
+};
+
+struct acpi_driver;
+struct acpi_device;
+
+
+/*
+ * ACPI Driver
+ * -----------
+ */
+
+typedef int (*acpi_op_add)	(struct acpi_device *device);
+typedef int (*acpi_op_remove)	(struct acpi_device *device, int type);
+typedef int (*acpi_op_lock)	(struct acpi_device *device, int type);
+typedef int (*acpi_op_start)	(struct acpi_device *device);
+typedef int (*acpi_op_stop)	(struct acpi_device *device, int type);
+typedef int (*acpi_op_suspend)	(struct acpi_device *device, int state);
+typedef int (*acpi_op_resume)	(struct acpi_device *device, int state);
+typedef int (*acpi_op_scan)	(struct acpi_device *device);
+typedef int (*acpi_op_bind)	(struct acpi_device *device);
+
+struct acpi_device_ops {
+	acpi_op_add		add;
+	acpi_op_remove		remove;
+	acpi_op_lock		lock;
+	acpi_op_start		start;
+	acpi_op_stop		stop;
+	acpi_op_suspend		suspend;
+	acpi_op_resume		resume;
+	acpi_op_scan		scan;
+	acpi_op_bind		bind;
+};
+
+struct acpi_driver {
+	struct list_head	node;
+	char			name[80];
+	char			class[80];
+	atomic_t		references;
+	char			*ids;		/* Supported Hardware IDs */
+	struct acpi_device_ops	ops;
+};
+
+/*
+ * ACPI Device
+ * -----------
+ */
+
+/* Status (_STA) */
+
+struct acpi_device_status {
+	u32			present:1;
+	u32			enabled:1;
+	u32			show_in_ui:1;
+	u32			functional:1;
+	u32			battery_present:1;
+	u32			reserved:27;
+};
+
+
+/* Flags */
+
+struct acpi_device_flags {
+	u32			dynamic_status:1;
+	u32			hardware_id:1;
+	u32			compatible_ids:1;
+	u32			bus_address:1;
+	u32			unique_id:1;
+	u32			removable:1;
+	u32			ejectable:1;
+	u32			lockable:1;
+	u32			suprise_removal_ok:1;
+	u32			power_manageable:1;
+	u32			performance_manageable:1;
+	u32			reserved:21;
+};
+
+
+/* File System */
+
+struct acpi_device_dir {
+	struct proc_dir_entry	*entry;
+};
+
+#define acpi_device_dir(d)	((d)->dir.entry)
+
+
+/* Plug and Play */
+
+typedef char			acpi_bus_id[5];
+typedef unsigned long		acpi_bus_address;
+typedef char			acpi_hardware_id[9];
+typedef char			acpi_unique_id[9];
+typedef char			acpi_device_name[40];
+typedef char			acpi_device_class[20];
+
+struct acpi_device_pnp {
+	acpi_bus_id		bus_id;		               /* Object name */
+	acpi_bus_address	bus_address;	                      /* _ADR */
+	acpi_hardware_id	hardware_id;	                      /* _HID */
+	acpi_unique_id		unique_id;	                      /* _UID */
+	acpi_device_name	device_name;	         /* Driver-determined */
+	acpi_device_class	device_class;	         /*        "          */
+};
+
+#define acpi_device_bid(d)	((d)->pnp.bus_id)
+#define acpi_device_adr(d)	((d)->pnp.bus_address)
+#define acpi_device_hid(d)	((d)->pnp.hardware_id)
+#define acpi_device_uid(d)	((d)->pnp.unique_id)
+#define acpi_device_name(d)	((d)->pnp.device_name)
+#define acpi_device_class(d)	((d)->pnp.device_class)
+
+
+/* Power Management */
+
+struct acpi_device_power_flags {
+	u32			explicit_get:1;		     /* _PSC present? */
+	u32			power_resources:1;	   /* Power resources */
+	u32			inrush_current:1;	  /* Serialize Dx->D0 */
+	u32			wake_capable:1;		 /* Wakeup supported? */
+	u32			wake_enabled:1;		/* Enabled for wakeup */
+	u32			power_removed:1;	   /* Optimize Dx->D0 */
+	u32			reserved:26;
+};
+
+struct acpi_device_power_state {
+	struct {
+		u8			valid:1;	
+		u8			explicit_set:1;	     /* _PSx present? */
+		u8			reserved:6;
+	}			flags;
+	int			power;		  /* % Power (compared to D0) */
+	int			latency;	/* Dx->D0 time (microseconds) */
+	struct acpi_handle_list	resources;	/* Power resources referenced */
+};
+
+struct acpi_device_power {
+	int			state;		             /* Current state */
+	struct acpi_device_power_flags flags;
+	struct acpi_device_power_state states[4];     /* Power states (D0-D3) */
+};
+
+
+/* Performance Management */
+
+struct acpi_device_perf_flags {
+	u8			reserved:8;
+};
+
+struct acpi_device_perf_state {
+	struct {
+		u8			valid:1;	
+		u8			reserved:7;
+	}			flags;
+	u8			power;		  /* % Power (compared to P0) */
+	u8			performance;	  /* % Performance (    "   ) */
+	int			latency;	/* Px->P0 time (microseconds) */
+};
+
+struct acpi_device_perf {
+	int			state;
+	struct acpi_device_perf_flags flags;
+	int			state_count;
+	struct acpi_device_perf_state *states;
+};
+
+
+/* Device */
+
+struct acpi_device {
+	acpi_handle		handle;
+	struct acpi_device	*parent;
+	struct list_head	children;
+	struct list_head	node;
+	struct list_head	g_list;
+	struct acpi_device_status status;
+	struct acpi_device_flags flags;
+	struct acpi_device_pnp	pnp;
+	struct acpi_device_power power;
+	struct acpi_device_perf	performance;
+	struct acpi_device_dir	dir;
+	struct acpi_device_ops	ops;
+	struct acpi_driver	*driver;
+	void			*driver_data;
+	struct kobject		kobj;
+};
+
+#define acpi_driver_data(d)	((d)->driver_data)
+
+
+/*
+ * Events
+ * ------
+ */
+
+struct acpi_bus_event {
+	struct list_head	node;
+	acpi_device_class	device_class;
+	acpi_bus_id		bus_id;
+	u32			type;
+	u32			data;
+};
+
+extern struct subsystem acpi_subsys;
+
+/*
+ * External Functions
+ */
+
+int acpi_bus_get_device(acpi_handle, struct acpi_device **device);
+int acpi_bus_get_status (struct acpi_device *device);
+int acpi_bus_get_power (acpi_handle handle, int *state);
+int acpi_bus_set_power (acpi_handle handle, int state);
+int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
+int acpi_bus_receive_event (struct acpi_bus_event *event);
+int acpi_bus_register_driver (struct acpi_driver *driver);
+int acpi_bus_unregister_driver (struct acpi_driver *driver);
+
+int acpi_create_dir(struct acpi_device *);
+void acpi_remove_dir(struct acpi_device *);
+
+#endif /*CONFIG_ACPI_BUS*/
+
+#endif /*__ACPI_BUS_H__*/
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acpi_drivers.h	Mon Feb 10 10:39:30 2003
@@ -0,0 +1,163 @@
+/*
+ *  acpi_drivers.h  ($Revision: 31 $)
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more 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 __ACPI_DRIVERS_H__
+#define __ACPI_DRIVERS_H__
+
+#include <linux/acpi.h>
+#include "acpi_bus.h"
+
+
+#define ACPI_MAX_STRING			80
+
+#define ACPI_BUS_COMPONENT		0x00010000
+#define ACPI_SYSTEM_COMPONENT		0x02000000
+
+/* _HID definitions */
+
+#define ACPI_POWER_HID			"ACPI_PWR"
+#define ACPI_PROCESSOR_HID		"ACPI_CPU"
+#define ACPI_SYSTEM_HID			"ACPI_SYS"
+#define ACPI_THERMAL_HID		"ACPI_THM"
+#define ACPI_BUTTON_HID_POWERF		"ACPI_FPB"
+#define ACPI_BUTTON_HID_SLEEPF		"ACPI_FSB"
+
+
+/* --------------------------------------------------------------------------
+                                       PCI
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_PCI
+
+#define ACPI_PCI_COMPONENT		0x00400000
+
+/* ACPI PCI Root Bridge (pci_root.c) */
+
+void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra);
+
+/* ACPI PCI Interrupt Link (pci_link.c) */
+
+int acpi_pci_link_check (void);
+int acpi_pci_link_get_irq (acpi_handle handle, int index);
+
+/* ACPI PCI Interrupt Routing (pci_irq.c) */
+
+int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus);
+
+/* ACPI PCI Device Binding (pci_bind.c) */
+
+struct pci_bus;
+
+int acpi_pci_bind (struct acpi_device *device);
+int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
+
+#endif /*CONFIG_ACPI_PCI*/
+
+
+/* --------------------------------------------------------------------------
+                                  Power Resource
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_POWER
+
+int acpi_power_get_inferred_state (struct acpi_device *device);
+int acpi_power_transition (struct acpi_device *device, int state);
+#endif
+
+
+/* --------------------------------------------------------------------------
+                                  Embedded Controller
+   -------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_EC
+int acpi_ec_ecdt_probe (void);
+#endif
+
+/* --------------------------------------------------------------------------
+                                    Processor
+   -------------------------------------------------------------------------- */
+
+#define ACPI_PROCESSOR_LIMIT_NONE	0x00
+#define ACPI_PROCESSOR_LIMIT_INCREMENT	0x01
+#define ACPI_PROCESSOR_LIMIT_DECREMENT	0x02
+
+int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
+
+
+/* --------------------------------------------------------------------------
+                                Debug Support
+   -------------------------------------------------------------------------- */
+
+#define ACPI_DEBUG_RESTORE	0
+#define ACPI_DEBUG_LOW		1
+#define ACPI_DEBUG_MEDIUM	2
+#define ACPI_DEBUG_HIGH		3
+#define ACPI_DEBUG_DRIVERS	4
+
+extern u32 acpi_dbg_level;
+extern u32 acpi_dbg_layer;
+
+static inline void
+acpi_set_debug (
+	u32			flag)
+{
+	static u32		layer_save;
+	static u32		level_save;
+
+	switch (flag) {
+	case ACPI_DEBUG_RESTORE:
+		acpi_dbg_layer = layer_save;
+		acpi_dbg_level = level_save;
+		break;
+	case ACPI_DEBUG_LOW:
+	case ACPI_DEBUG_MEDIUM:
+	case ACPI_DEBUG_HIGH:
+	case ACPI_DEBUG_DRIVERS:
+		layer_save = acpi_dbg_layer;
+		level_save = acpi_dbg_level;
+		break;
+	}
+
+	switch (flag) {
+	case ACPI_DEBUG_LOW:
+		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
+		acpi_dbg_level = ACPI_DEBUG_DEFAULT;
+		break;
+	case ACPI_DEBUG_MEDIUM:
+		acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS;
+		acpi_dbg_level = ACPI_LV_FUNCTIONS | ACPI_LV_ALL_EXCEPTIONS;
+		break;
+	case ACPI_DEBUG_HIGH:
+		acpi_dbg_layer = 0xFFFFFFFF;
+		acpi_dbg_level = 0xFFFFFFFF;
+		break;
+	case ACPI_DEBUG_DRIVERS:
+		acpi_dbg_layer = ACPI_ALL_DRIVERS;
+		acpi_dbg_level = 0xFFFFFFFF;
+		break;
+	}
+}
+
+
+#endif /*__ACPI_DRIVERS_H__*/
diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acpiosxf.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,344 @@
+
+/******************************************************************************
+ *
+ * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL).  These
+ *                    interfaces must be implemented by OSL to interface the
+ *                    ACPI components to the host operating system.
+ *
+ *****************************************************************************/
+
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACPIOSXF_H__
+#define __ACPIOSXF_H__
+
+#include "platform/acenv.h"
+#include "actypes.h"
+
+
+/* Priorities for acpi_os_queue_for_execution */
+
+#define OSD_PRIORITY_GPE            1
+#define OSD_PRIORITY_HIGH           2
+#define OSD_PRIORITY_MED            3
+#define OSD_PRIORITY_LO             4
+
+#define ACPI_NO_UNIT_LIMIT          ((u32) -1)
+#define ACPI_MUTEX_SEM              1
+
+
+/* Functions for acpi_os_signal */
+
+#define ACPI_SIGNAL_FATAL           0
+#define ACPI_SIGNAL_BREAKPOINT      1
+
+struct acpi_signal_fatal_info
+{
+	u32                             type;
+	u32                             code;
+	u32                             argument;
+};
+
+
+/*
+ * Types specific to the OS service interfaces
+ */
+
+typedef u32
+(ACPI_SYSTEM_XFACE *OSD_HANDLER) (
+	void                            *context);
+
+typedef void
+(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) (
+	void                            *context);
+
+
+/*
+ * OSL Initialization and shutdown primitives
+ */
+
+acpi_status
+acpi_os_initialize (
+	void);
+
+acpi_status
+acpi_os_terminate (
+	void);
+
+
+/*
+ * ACPI Table interfaces
+ */
+
+acpi_status
+acpi_os_get_root_pointer (
+	u32                             flags,
+	struct acpi_pointer             *address);
+
+acpi_status
+acpi_os_table_override (
+	struct acpi_table_header        *existing_table,
+	struct acpi_table_header        **new_table);
+
+
+/*
+ * Synchronization primitives
+ */
+
+acpi_status
+acpi_os_create_semaphore (
+	u32                             max_units,
+	u32                             initial_units,
+	acpi_handle                     *out_handle);
+
+acpi_status
+acpi_os_delete_semaphore (
+	acpi_handle                     handle);
+
+acpi_status
+acpi_os_wait_semaphore (
+	acpi_handle                     handle,
+	u32                             units,
+	u16                             timeout);
+
+acpi_status
+acpi_os_signal_semaphore (
+	acpi_handle                     handle,
+	u32                             units);
+
+
+/*
+ * Memory allocation and mapping
+ */
+
+void *
+acpi_os_allocate (
+	acpi_size                       size);
+
+void
+acpi_os_free (
+	void *                          memory);
+
+acpi_status
+acpi_os_map_memory (
+	acpi_physical_address           physical_address,
+	acpi_size                       size,
+	void                            **logical_address);
+
+void
+acpi_os_unmap_memory (
+	void                            *logical_address,
+	acpi_size                       size);
+
+acpi_status
+acpi_os_get_physical_address (
+	void                            *logical_address,
+	acpi_physical_address           *physical_address);
+
+
+/*
+ * Interrupt handlers
+ */
+
+acpi_status
+acpi_os_install_interrupt_handler (
+	u32                             interrupt_number,
+	OSD_HANDLER             service_routine,
+	void                            *context);
+
+acpi_status
+acpi_os_remove_interrupt_handler (
+	u32                             interrupt_number,
+	OSD_HANDLER             service_routine);
+
+
+/*
+ * Threads and Scheduling
+ */
+
+u32
+acpi_os_get_thread_id (
+	void);
+
+acpi_status
+acpi_os_queue_for_execution (
+	u32                             priority,
+	OSD_EXECUTION_CALLBACK  function,
+	void                            *context);
+
+void
+acpi_os_sleep (
+	u32                             seconds,
+	u32                             milliseconds);
+
+void
+acpi_os_stall (
+	u32                             microseconds);
+
+
+/*
+ * Platform and hardware-independent I/O interfaces
+ */
+
+acpi_status
+acpi_os_read_port (
+	acpi_io_address                 address,
+	void                            *value,
+	u32                             width);
+
+acpi_status
+acpi_os_write_port (
+	acpi_io_address                 address,
+	acpi_integer                    value,
+	u32                             width);
+
+
+/*
+ * Platform and hardware-independent physical memory interfaces
+ */
+
+acpi_status
+acpi_os_read_memory (
+	acpi_physical_address           address,
+	void                            *value,
+	u32                             width);
+
+acpi_status
+acpi_os_write_memory (
+	acpi_physical_address           address,
+	acpi_integer                    value,
+	u32                             width);
+
+
+/*
+ * Platform and hardware-independent PCI configuration space access
+ */
+
+acpi_status
+acpi_os_read_pci_configuration (
+	struct acpi_pci_id              *pci_id,
+	u32                             register,
+	void                            *value,
+	u32                             width);
+
+acpi_status
+acpi_os_write_pci_configuration (
+	struct acpi_pci_id              *pci_id,
+	u32                             register,
+	acpi_integer                    value,
+	u32                             width);
+
+/*
+ * Interim function needed for PCI IRQ routing
+ */
+void
+acpi_os_derive_pci_id(
+	acpi_handle                     rhandle,
+	acpi_handle                     chandle,
+	struct acpi_pci_id              **pci_id);
+
+/*
+ * Miscellaneous
+ */
+
+u8
+acpi_os_readable (
+	void                            *pointer,
+	u32                             length);
+
+u8
+acpi_os_writable (
+	void                            *pointer,
+	u32                             length);
+
+u32
+acpi_os_get_timer (
+	void);
+
+acpi_status
+acpi_os_signal (
+	u32                             function,
+	void                            *info);
+
+/*
+ * Debug print routines
+ */
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_os_printf (
+	const char                      *format,
+	...);
+
+void
+acpi_os_vprintf (
+	const char                      *format,
+	va_list                 args);
+
+void
+acpi_os_redirect_output (
+	void                            *destination);
+
+
+/*
+ * Debug input
+ */
+
+u32
+acpi_os_get_line (
+	char                            *buffer);
+
+
+/*
+ * Directory manipulation
+ */
+
+void *
+acpi_os_open_directory (
+	char                            *pathname,
+	char                            *wildcard_spec,
+	char                            requested_file_type);
+
+/* requeste_file_type values */
+
+#define REQUEST_FILE_ONLY                   0
+#define REQUEST_DIR_ONLY                    1
+
+
+char *
+acpi_os_get_next_filename (
+	void                            *dir_handle);
+
+void
+acpi_os_close_directory (
+	void                            *dir_handle);
+
+/*
+ * Debug
+ */
+
+void
+acpi_os_dbg_assert(
+	void                            *failed_assertion,
+	void                            *file_name,
+	u32                             line_number,
+	char                            *message);
+
+
+#endif /* __ACPIOSXF_H__ */
diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acpixf.h	Mon Feb 10 10:39:22 2003
@@ -0,0 +1,387 @@
+
+/******************************************************************************
+ *
+ * Name: acpixf.h - External interfaces to the ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACXFACE_H__
+#define __ACXFACE_H__
+
+#include "actypes.h"
+#include "actbl.h"
+
+
+ /*
+ * Global interfaces
+ */
+
+acpi_status
+acpi_initialize_subsystem (
+	void);
+
+acpi_status
+acpi_enable_subsystem (
+	u32                             flags);
+
+acpi_status
+acpi_initialize_objects (
+	u32                             flags);
+
+acpi_status
+acpi_terminate (
+	void);
+
+acpi_status
+acpi_subsystem_status (
+	void);
+
+acpi_status
+acpi_enable (
+	void);
+
+acpi_status
+acpi_disable (
+	void);
+
+acpi_status
+acpi_get_system_info (
+	struct acpi_buffer              *ret_buffer);
+
+const char *
+acpi_format_exception (
+	acpi_status                     exception);
+
+acpi_status
+acpi_purge_cached_objects (
+	void);
+
+acpi_status
+acpi_install_initialization_handler (
+	acpi_init_handler               handler,
+	u32                             function);
+
+/*
+ * ACPI Memory manager
+ */
+
+void *
+acpi_allocate (
+	u32                             size);
+
+void *
+acpi_callocate (
+	u32                             size);
+
+void
+acpi_free (
+	void                            *address);
+
+
+/*
+ * ACPI table manipulation interfaces
+ */
+
+acpi_status
+acpi_find_root_pointer (
+	u32                             flags,
+	struct acpi_pointer             *rsdp_address);
+
+acpi_status
+acpi_load_tables (
+	void);
+
+acpi_status
+acpi_load_table (
+	struct acpi_table_header        *table_ptr);
+
+acpi_status
+acpi_unload_table (
+	acpi_table_type                 table_type);
+
+acpi_status
+acpi_get_table_header (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_table_header        *out_table_header);
+
+acpi_status
+acpi_get_table (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_get_firmware_table (
+	acpi_string                     signature,
+	u32                             instance,
+	u32                             flags,
+	struct acpi_table_header        **table_pointer);
+
+
+/*
+ * Namespace and name interfaces
+ */
+
+acpi_status
+acpi_walk_namespace (
+	acpi_object_type                type,
+	acpi_handle                     start_object,
+	u32                             max_depth,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_get_devices (
+	char                            *HID,
+	acpi_walk_callback              user_function,
+	void                            *context,
+	void                            **return_value);
+
+acpi_status
+acpi_get_name (
+	acpi_handle                     handle,
+	u32                             name_type,
+	struct acpi_buffer              *ret_path_ptr);
+
+acpi_status
+acpi_get_handle (
+	acpi_handle                     parent,
+	acpi_string                     pathname,
+	acpi_handle                     *ret_handle);
+
+acpi_status
+acpi_attach_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler,
+	void                            *data);
+
+acpi_status
+acpi_detach_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler);
+
+acpi_status
+acpi_get_data (
+	acpi_handle                     obj_handle,
+	acpi_object_handler             handler,
+	void                            **data);
+
+
+/*
+ * Object manipulation and enumeration
+ */
+
+acpi_status
+acpi_evaluate_object (
+	acpi_handle                     object,
+	acpi_string                     pathname,
+	struct acpi_object_list         *parameter_objects,
+	struct acpi_buffer              *return_object_buffer);
+
+acpi_status
+acpi_evaluate_object_typed (
+	acpi_handle                     object,
+	acpi_string                     pathname,
+	struct acpi_object_list         *external_params,
+	struct acpi_buffer              *return_buffer,
+	acpi_object_type                return_type);
+
+acpi_status
+acpi_get_object_info (
+	acpi_handle                     device,
+	struct acpi_device_info         *info);
+
+acpi_status
+acpi_get_next_object (
+	acpi_object_type                type,
+	acpi_handle                     parent,
+	acpi_handle                     child,
+	acpi_handle                     *out_handle);
+
+acpi_status
+acpi_get_type (
+	acpi_handle                     object,
+	acpi_object_type                *out_type);
+
+acpi_status
+acpi_get_parent (
+	acpi_handle                     object,
+	acpi_handle                     *out_handle);
+
+
+/*
+ * Event handler interfaces
+ */
+
+acpi_status
+acpi_install_fixed_event_handler (
+	u32                             acpi_event,
+	acpi_event_handler              handler,
+	void                            *context);
+
+acpi_status
+acpi_remove_fixed_event_handler (
+	u32                             acpi_event,
+	acpi_event_handler              handler);
+
+acpi_status
+acpi_install_notify_handler (
+	acpi_handle                     device,
+	u32                             handler_type,
+	acpi_notify_handler             handler,
+	void                            *context);
+
+acpi_status
+acpi_remove_notify_handler (
+	acpi_handle                     device,
+	u32                             handler_type,
+	acpi_notify_handler             handler);
+
+acpi_status
+acpi_install_address_space_handler (
+	acpi_handle                     device,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler,
+	acpi_adr_space_setup            setup,
+	void                            *context);
+
+acpi_status
+acpi_remove_address_space_handler (
+	acpi_handle                     device,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler);
+
+acpi_status
+acpi_install_gpe_handler (
+	u32                             gpe_number,
+	u32                             type,
+	acpi_gpe_handler                handler,
+	void                            *context);
+
+acpi_status
+acpi_acquire_global_lock (
+	u16                             timeout,
+	u32                             *handle);
+
+acpi_status
+acpi_release_global_lock (
+	u32                             handle);
+
+acpi_status
+acpi_remove_gpe_handler (
+	u32                             gpe_number,
+	acpi_gpe_handler                handler);
+
+acpi_status
+acpi_enable_event (
+	u32                             acpi_event,
+	u32                             type,
+	u32                             flags);
+
+acpi_status
+acpi_disable_event (
+	u32                             acpi_event,
+	u32                             type,
+	u32                             flags);
+
+acpi_status
+acpi_clear_event (
+	u32                             acpi_event,
+	u32                             type);
+
+acpi_status
+acpi_get_event_status (
+	u32                             acpi_event,
+	u32                             type,
+	acpi_event_status               *event_status);
+
+/*
+ * Resource interfaces
+ */
+
+acpi_status
+acpi_get_current_resources(
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_get_possible_resources(
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_set_current_resources (
+	acpi_handle                     device_handle,
+	struct acpi_buffer              *in_buffer);
+
+acpi_status
+acpi_get_irq_routing_table (
+	acpi_handle                     bus_device_handle,
+	struct acpi_buffer              *ret_buffer);
+
+
+/*
+ * Hardware (ACPI device) interfaces
+ */
+
+acpi_status
+acpi_get_register (
+	u32                             register_id,
+	u32                             *return_value,
+	u32                             flags);
+
+acpi_status
+acpi_set_register (
+	u32                             register_id,
+	u32                             value,
+	u32                             flags);
+
+acpi_status
+acpi_set_firmware_waking_vector (
+	acpi_physical_address           physical_address);
+
+acpi_status
+acpi_get_firmware_waking_vector (
+	acpi_physical_address           *physical_address);
+
+acpi_status
+acpi_get_sleep_type_data (
+	u8                              sleep_state,
+	u8                              *slp_typ_a,
+	u8                              *slp_typ_b);
+
+acpi_status
+acpi_enter_sleep_state_prep (
+	u8                              sleep_state);
+
+acpi_status
+acpi_enter_sleep_state (
+	u8                              sleep_state);
+
+acpi_status
+acpi_leave_sleep_state (
+	u8                              sleep_state);
+
+
+#endif /* __ACXFACE_H__ */
diff -Nru a/include/acpi/acresrc.h b/include/acpi/acresrc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acresrc.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,366 @@
+/******************************************************************************
+ *
+ * Name: acresrc.h - Resource Manager function prototypes
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACRESRC_H__
+#define __ACRESRC_H__
+
+
+/*
+ *  Function prototypes called from Acpi* APIs
+ */
+
+acpi_status
+acpi_rs_get_prt_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer);
+
+
+acpi_status
+acpi_rs_get_crs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_rs_get_prs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_rs_set_srs_method_data (
+	acpi_handle                     handle,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_rs_create_resource_list (
+	union acpi_operand_object       *byte_stream_buffer,
+	struct acpi_buffer              *output_buffer);
+
+acpi_status
+acpi_rs_create_byte_stream (
+	struct acpi_resource            *linked_list_buffer,
+	struct acpi_buffer              *output_buffer);
+
+acpi_status
+acpi_rs_create_pci_routing_table (
+	union acpi_operand_object       *package_object,
+	struct acpi_buffer              *output_buffer);
+
+
+/*
+ * Function prototypes called from acpi_rs_create*
+ */
+void
+acpi_rs_dump_irq (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_address16 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_address32 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_address64 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_dma (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_io (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_extended_irq (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_fixed_io (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_fixed_memory32 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_memory24 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_memory32 (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_start_depend_fns (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_vendor_specific (
+	union acpi_resource_data        *data);
+
+void
+acpi_rs_dump_resource_list (
+	struct acpi_resource            *resource);
+
+void
+acpi_rs_dump_irq_list (
+	u8                              *route_table);
+
+acpi_status
+acpi_rs_get_byte_stream_start (
+	u8                              *byte_stream_buffer,
+	u8                              **byte_stream_start,
+	u32                             *size);
+
+acpi_status
+acpi_rs_get_list_length (
+	u8                              *byte_stream_buffer,
+	u32                             byte_stream_buffer_length,
+	acpi_size                       *size_needed);
+
+acpi_status
+acpi_rs_get_byte_stream_length (
+	struct acpi_resource            *linked_list_buffer,
+	acpi_size                       *size_needed);
+
+acpi_status
+acpi_rs_get_pci_routing_table_length (
+	union acpi_operand_object       *package_object,
+	acpi_size                       *buffer_size_needed);
+
+acpi_status
+acpi_rs_byte_stream_to_list (
+	u8                              *byte_stream_buffer,
+	u32                             byte_stream_buffer_length,
+	u8                              *output_buffer);
+
+acpi_status
+acpi_rs_list_to_byte_stream (
+	struct acpi_resource            *linked_list,
+	acpi_size                       byte_stream_size_needed,
+	u8                              *output_buffer);
+
+acpi_status
+acpi_rs_io_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_fixed_io_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_io_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_fixed_io_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_irq_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_irq_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_dma_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_dma_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_address16_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_address16_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_address32_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_address32_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_address64_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_address64_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_start_depend_fns_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_end_depend_fns_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_start_depend_fns_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_end_depend_fns_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_memory24_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_memory24_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_memory32_range_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_fixed_memory32_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_memory32_range_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_fixed_memory32_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_extended_irq_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_extended_irq_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_end_tag_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_end_tag_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+acpi_status
+acpi_rs_vendor_resource (
+	u8                              *byte_stream_buffer,
+	acpi_size                       *bytes_consumed,
+	u8                              **output_buffer,
+	acpi_size                       *structure_size);
+
+acpi_status
+acpi_rs_vendor_stream (
+	struct acpi_resource            *linked_list,
+	u8                              **output_buffer,
+	acpi_size                       *bytes_consumed);
+
+u8
+acpi_rs_get_resource_type (
+	u8                              resource_start_byte);
+
+#endif  /* __ACRESRC_H__ */
diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acstruct.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,183 @@
+/******************************************************************************
+ *
+ * Name: acstruct.h - Internal structs
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACSTRUCT_H__
+#define __ACSTRUCT_H__
+
+
+/*****************************************************************************
+ *
+ * Tree walking typedefs and structs
+ *
+ ****************************************************************************/
+
+
+/*
+ * Walk state - current state of a parse tree walk.  Used for both a leisurely stroll through
+ * the tree (for whatever reason), and for control method execution.
+ */
+
+#define ACPI_NEXT_OP_DOWNWARD       1
+#define ACPI_NEXT_OP_UPWARD         2
+
+#define ACPI_WALK_NON_METHOD        0
+#define ACPI_WALK_METHOD            1
+#define ACPI_WALK_METHOD_RESTART    2
+#define ACPI_WALK_CONST_REQUIRED    3
+#define ACPI_WALK_CONST_OPTIONAL    4
+
+struct acpi_walk_state
+{
+	u8                                  data_type;                          /* To differentiate various internal objs MUST BE FIRST!*/\
+	acpi_owner_id                       owner_id;                           /* Owner of objects created during the walk */
+	u8                                  last_predicate;                     /* Result of last predicate */
+	u8                                  current_result;                     /* */
+	u8                                  next_op_info;                       /* Info about next_op */
+	u8                                  num_operands;                       /* Stack pointer for Operands[] array */
+	u8                                  return_used;
+	u8                                  walk_type;
+	u16                                 opcode;                             /* Current AML opcode */
+	u8                                  scope_depth;
+	u8                                  reserved1;
+	u32                                 arg_count;                          /* push for fixed or var args */
+	u32                                 aml_offset;
+	u32                                 arg_types;
+	u32                                 method_breakpoint;                  /* For single stepping */
+	u32                                 user_breakpoint;                    /* User AML breakpoint */
+	u32                                 parse_flags;
+	u32                                 prev_arg_types;
+
+	u8                                  *aml_last_while;
+	struct acpi_namespace_node          arguments[ACPI_METHOD_NUM_ARGS];    /* Control method arguments */
+	union acpi_operand_object           **caller_return_desc;
+	union acpi_generic_state            *control_state;                     /* List of control states (nested IFs) */
+	struct acpi_namespace_node          local_variables[ACPI_METHOD_NUM_LOCALS];    /* Control method locals */
+	struct acpi_namespace_node          *method_call_node;                  /* Called method Node*/
+	union acpi_parse_object             *method_call_op;                    /* method_call Op if running a method */
+	union acpi_operand_object           *method_desc;                       /* Method descriptor if running a method */
+	struct acpi_namespace_node          *method_node;                       /* Method Node if running a method */
+	union acpi_parse_object             *op;                                /* Current parser op */
+	union acpi_operand_object           *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */
+	const struct acpi_opcode_info       *op_info;                           /* Info on current opcode */
+	union acpi_parse_object             *origin;                            /* Start of walk [Obsolete] */
+	union acpi_operand_object           **params;
+	struct acpi_parse_state             parser_state;                       /* Current state of parser */
+	union acpi_operand_object           *result_obj;
+	union acpi_generic_state            *results;                           /* Stack of accumulated results */
+	union acpi_operand_object           *return_desc;                       /* Return object, if any */
+	union acpi_generic_state            *scope_info;                        /* Stack of nested scopes */
+
+	union acpi_parse_object             *prev_op;                           /* Last op that was processed */
+	union acpi_parse_object             *next_op;                           /* next op to be processed */
+	acpi_parse_downwards                descending_callback;
+	acpi_parse_upwards                  ascending_callback;
+	struct acpi_thread_state            *thread;
+	struct acpi_walk_state              *next;                              /* Next walk_state in list */
+};
+
+
+/* Info used by acpi_ps_init_objects */
+
+struct acpi_init_walk_info
+{
+	u16                             method_count;
+	u16                             device_count;
+	u16                             op_region_count;
+	u16                             field_count;
+	u16                             buffer_count;
+	u16                             package_count;
+	u16                             op_region_init;
+	u16                             field_init;
+	u16                             buffer_init;
+	u16                             package_init;
+	u16                             object_count;
+	struct acpi_table_desc          *table_desc;
+};
+
+
+/* Info used by acpi_ns_initialize_devices */
+
+struct acpi_device_walk_info
+{
+	u16                             device_count;
+	u16                             num_STA;
+	u16                             num_INI;
+	struct acpi_table_desc          *table_desc;
+};
+
+
+/* TBD: [Restructure] Merge with struct above */
+
+struct acpi_walk_info
+{
+	u32                             debug_level;
+	u32                             owner_id;
+	u8                              display_type;
+};
+
+/* Display Types */
+
+#define ACPI_DISPLAY_SUMMARY    0
+#define ACPI_DISPLAY_OBJECTS    1
+
+struct acpi_get_devices_info
+{
+	acpi_walk_callback              user_function;
+	void                            *context;
+	char                            *hid;
+};
+
+
+union acpi_aml_operands
+{
+	union acpi_operand_object           *operands[7];
+
+	struct
+	{
+		struct acpi_object_integer      *type;
+		struct acpi_object_integer      *code;
+		struct acpi_object_integer      *argument;
+
+	} fatal;
+
+	struct
+	{
+		union acpi_operand_object       *source;
+		struct acpi_object_integer      *index;
+		union acpi_operand_object       *target;
+
+	} index;
+
+	struct
+	{
+		union acpi_operand_object       *source;
+		struct acpi_object_integer      *index;
+		struct acpi_object_integer      *length;
+		union acpi_operand_object       *target;
+
+	} mid;
+};
+
+
+#endif
diff -Nru a/include/acpi/actables.h b/include/acpi/actables.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actables.h	Mon Feb 10 10:39:24 2003
@@ -0,0 +1,218 @@
+/******************************************************************************
+ *
+ * Name: actables.h - ACPI table management
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTABLES_H__
+#define __ACTABLES_H__
+
+
+/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */
+
+#define SIZE_IN_HEADER          0
+
+
+acpi_status
+acpi_tb_handle_to_object (
+	u16                             table_id,
+	struct acpi_table_desc          **table_desc);
+
+/*
+ * tbconvrt - Table conversion routines
+ */
+
+acpi_status
+acpi_tb_convert_to_xsdt (
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_convert_table_fadt (
+	void);
+
+acpi_status
+acpi_tb_build_common_facs (
+	struct acpi_table_desc          *table_info);
+
+u32
+acpi_tb_get_table_count (
+	struct rsdp_descriptor          *RSDP,
+	struct acpi_table_header        *RSDT);
+
+/*
+ * tbget - Table "get" routines
+ */
+
+acpi_status
+acpi_tb_get_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_get_table_header (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *return_header);
+
+acpi_status
+acpi_tb_get_table_body (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_get_this_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_table_override (
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_get_table_ptr (
+	acpi_table_type                 table_type,
+	u32                             instance,
+	struct acpi_table_header        **table_ptr_loc);
+
+acpi_status
+acpi_tb_verify_rsdp (
+	struct acpi_pointer             *address);
+
+void
+acpi_tb_get_rsdt_address (
+	struct acpi_pointer             *out_address);
+
+acpi_status
+acpi_tb_validate_rsdt (
+	struct acpi_table_header        *table_ptr);
+
+acpi_status
+acpi_tb_get_required_tables (
+	void);
+
+acpi_status
+acpi_tb_get_primary_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_get_secondary_table (
+	struct acpi_pointer             *address,
+	acpi_string                     signature,
+	struct acpi_table_desc          *table_info);
+
+/*
+ * tbinstall - Table installation
+ */
+
+acpi_status
+acpi_tb_install_table (
+	struct acpi_table_desc          *table_info);
+
+acpi_status
+acpi_tb_match_signature (
+	char                            *signature,
+	struct acpi_table_desc          *table_info,
+	u8                              search_type);
+
+acpi_status
+acpi_tb_recognize_table (
+	struct acpi_table_desc          *table_info,
+	u8                             search_type);
+
+acpi_status
+acpi_tb_init_table_descriptor (
+	acpi_table_type                 table_type,
+	struct acpi_table_desc          *table_info);
+
+
+/*
+ * tbremove - Table removal and deletion
+ */
+
+void
+acpi_tb_delete_acpi_tables (
+	void);
+
+void
+acpi_tb_delete_acpi_table (
+	acpi_table_type                 type);
+
+void
+acpi_tb_delete_single_table (
+	struct acpi_table_desc          *table_desc);
+
+struct acpi_table_desc *
+acpi_tb_uninstall_table (
+	struct acpi_table_desc          *table_desc);
+
+void
+acpi_tb_free_acpi_tables_of_type (
+	struct acpi_table_desc          *table_info);
+
+
+/*
+ * tbrsd - RSDP, RSDT utilities
+ */
+
+acpi_status
+acpi_tb_get_table_rsdt (
+	void);
+
+u8 *
+acpi_tb_scan_memory_for_rsdp (
+	u8                              *start_address,
+	u32                             length);
+
+acpi_status
+acpi_tb_find_rsdp (
+	struct acpi_table_desc          *table_info,
+	u32                             flags);
+
+
+/*
+ * tbutils - common table utilities
+ */
+
+acpi_status
+acpi_tb_find_table (
+	char                            *signature,
+	char                            *oem_id,
+	char                            *oem_table_id,
+	struct acpi_table_header        **table_ptr);
+
+acpi_status
+acpi_tb_verify_table_checksum (
+	struct acpi_table_header        *table_header);
+
+u8
+acpi_tb_checksum (
+	void                            *buffer,
+	u32                             length);
+
+acpi_status
+acpi_tb_validate_table_header (
+	struct acpi_table_header        *table_header);
+
+
+#endif /* __ACTABLES_H__ */
diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actbl.h	Mon Feb 10 10:39:27 2003
@@ -0,0 +1,208 @@
+/******************************************************************************
+ *
+ * Name: actbl.h - Table data structures defined in ACPI specification
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTBL_H__
+#define __ACTBL_H__
+
+
+/*
+ *  Values for description table header signatures
+ */
+#define RSDP_NAME               "RSDP"
+#define RSDP_SIG                "RSD PTR "  /* RSDT Pointer signature */
+#define APIC_SIG                "APIC"      /* Multiple APIC Description Table */
+#define DSDT_SIG                "DSDT"      /* Differentiated System Description Table */
+#define FADT_SIG                "FACP"      /* Fixed ACPI Description Table */
+#define FACS_SIG                "FACS"      /* Firmware ACPI Control Structure */
+#define PSDT_SIG                "PSDT"      /* Persistent System Description Table */
+#define RSDT_SIG                "RSDT"      /* Root System Description Table */
+#define XSDT_SIG                "XSDT"      /* Extended  System Description Table */
+#define SSDT_SIG                "SSDT"      /* Secondary System Description Table */
+#define SBST_SIG                "SBST"      /* Smart Battery Specification Table */
+#define SPIC_SIG                "SPIC"      /* IOSAPIC table */
+#define BOOT_SIG                "BOOT"      /* Boot table */
+
+
+#define GL_OWNED                0x02        /* Ownership of global lock is bit 1 */
+
+/* values of Mapic.Model */
+
+#define DUAL_PIC                0
+#define MULTIPLE_APIC           1
+
+/* values of Type in struct apic_header */
+
+#define APIC_PROC               0
+#define APIC_IO                 1
+
+
+/*
+ * Common table types.  The base code can remain
+ * constant if the underlying tables are changed
+ */
+#define RSDT_DESCRIPTOR         struct rsdt_descriptor_rev2
+#define XSDT_DESCRIPTOR         struct xsdt_descriptor_rev2
+#define FACS_DESCRIPTOR         struct facs_descriptor_rev2
+#define FADT_DESCRIPTOR         struct fadt_descriptor_rev2
+
+
+#pragma pack(1)
+
+/*
+ * Architecture-independent tables
+ * The architecture dependent tables are in separate files
+ */
+struct rsdp_descriptor         /* Root System Descriptor Pointer */
+{
+	char                            signature [8];          /* ACPI signature, contains "RSD PTR " */
+	u8                              checksum;               /* To make sum of struct == 0 */
+	char                            oem_id [6];             /* OEM identification */
+	u8                              revision;               /* Must be 0 for 1.0, 2 for 2.0 */
+	u32                             rsdt_physical_address;  /* 32-bit physical address of RSDT */
+	u32                             length;                 /* XSDT Length in bytes including hdr */
+	u64                             xsdt_physical_address;  /* 64-bit physical address of XSDT */
+	u8                              extended_checksum;      /* Checksum of entire table */
+	char                            reserved [3];           /* Reserved field must be 0 */
+};
+
+
+struct acpi_table_header         /* ACPI common table header */
+{
+	char                            signature [4];          /* ACPI signature (4 ASCII characters) */
+	u32                             length;                 /* Length of table, in bytes, including header */
+	u8                              revision;               /* ACPI Specification minor version # */
+	u8                              checksum;               /* To make sum of entire table == 0 */
+	char                            oem_id [6];             /* OEM identification */
+	char                            oem_table_id [8];       /* OEM table identification */
+	u32                             oem_revision;           /* OEM revision number */
+	char                            asl_compiler_id [4];    /* ASL compiler vendor ID */
+	u32                             asl_compiler_revision;  /* ASL compiler revision number */
+};
+
+
+struct acpi_common_facs          /* Common FACS for internal use */
+{
+	u32                             *global_lock;
+	u64                             *firmware_waking_vector;
+	u8                              vector_width;
+};
+
+
+struct apic_table
+{
+	struct acpi_table_header        header;                 /* ACPI table header */
+	u32                             local_apic_address;     /* Physical address for accessing local APICs */
+	u32                             PCATcompat      : 1;    /* a one indicates system also has dual 8259s */
+	u32                             reserved1       : 31;
+};
+
+
+struct apic_header
+{
+	u8                              type;                   /* APIC type.  Either APIC_PROC or APIC_IO */
+	u8                              length;                 /* Length of APIC structure */
+};
+
+
+struct processor_apic
+{
+	struct apic_header              header;
+	u8                              processor_apic_id;      /* ACPI processor id */
+	u8                              local_apic_id;          /* Processor's local APIC id */
+	u32                             processor_enabled: 1;   /* Processor is usable if set */
+	u32                             reserved1       : 31;
+};
+
+
+struct io_apic
+{
+	struct apic_header              header;
+	u8                              io_apic_id;             /* I/O APIC ID */
+	u8                              reserved;               /* Reserved - must be zero */
+	u32                             io_apic_address;        /* APIC's physical address */
+	u32                             vector;                 /* Interrupt vector index where INTI
+			  * lines start */
+};
+
+
+/*
+ *  IA64 TBD:  Add SAPIC Tables
+ */
+
+/*
+ *  IA64 TBD:   Modify Smart Battery Description to comply with ACPI IA64
+ *              extensions.
+ */
+struct smart_battery_description_table
+{
+	struct acpi_table_header        header;
+	u32                             warning_level;
+	u32                             low_level;
+	u32                             critical_level;
+};
+
+
+#pragma pack()
+
+
+/*
+ * ACPI Table information.  We save the table address, length,
+ * and type of memory allocation (mapped or allocated) for each
+ * table for 1) when we exit, and 2) if a new table is installed
+ */
+#define ACPI_MEM_NOT_ALLOCATED  0
+#define ACPI_MEM_ALLOCATED      1
+#define ACPI_MEM_MAPPED         2
+
+/* Definitions for the Flags bitfield member of struct acpi_table_support */
+
+#define ACPI_TABLE_SINGLE       0x00
+#define ACPI_TABLE_MULTIPLE     0x01
+#define ACPI_TABLE_EXECUTABLE   0x02
+
+#define ACPI_TABLE_ROOT         0x00
+#define ACPI_TABLE_PRIMARY      0x10
+#define ACPI_TABLE_SECONDARY    0x20
+#define ACPI_TABLE_ALL          0x30
+#define ACPI_TABLE_TYPE_MASK    0x30
+
+/* Data about each known table type */
+
+struct acpi_table_support
+{
+	char                            *name;
+	char                            *signature;
+	void                            **global_ptr;
+	u8                              sig_length;
+	u8                              flags;
+};
+
+
+/*
+ * Get the architecture-specific tables
+ */
+#include "actbl1.h"   /* Acpi 1.0 table definitions */
+#include "actbl2.h"   /* Acpi 2.0 table definitions */
+
+#endif /* __ACTBL_H__ */
diff -Nru a/include/acpi/actbl1.h b/include/acpi/actbl1.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actbl1.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *
+ * Name: actbl1.h - ACPI 1.0 tables
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTBL1_H__
+#define __ACTBL1_H__
+
+#pragma pack(1)
+
+/*
+ * ACPI 1.0 Root System Description Table (RSDT)
+ */
+struct rsdt_descriptor_rev1
+{
+	struct acpi_table_header        header;                 /* ACPI Table header */
+	u32                             table_offset_entry [1]; /* Array of pointers to other */
+			 /* ACPI tables */
+};
+
+
+/*
+ * ACPI 1.0 Firmware ACPI Control Structure (FACS)
+ */
+struct facs_descriptor_rev1
+{
+	char                            signature[4];           /* ACPI Signature */
+	u32                             length;                 /* Length of structure, in bytes */
+	u32                             hardware_signature;     /* Hardware configuration signature */
+	u32                             firmware_waking_vector; /* ACPI OS waking vector */
+	u32                             global_lock;            /* Global Lock */
+	u32                             S4bios_f        : 1;    /* Indicates if S4BIOS support is present */
+	u32                             reserved1       : 31;   /* Must be 0 */
+	u8                              resverved3 [40];        /* Reserved - must be zero */
+};
+
+
+/*
+ * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ */
+struct fadt_descriptor_rev1
+{
+	struct acpi_table_header        header;                 /* ACPI Table header */
+	u32                             firmware_ctrl;          /* Physical address of FACS */
+	u32                             dsdt;                   /* Physical address of DSDT */
+	u8                              model;                  /* System Interrupt Model */
+	u8                              reserved1;              /* Reserved */
+	u16                             sci_int;                /* System vector of SCI interrupt */
+	u32                             smi_cmd;                /* Port address of SMI command port */
+	u8                              acpi_enable;            /* Value to write to smi_cmd to enable ACPI */
+	u8                              acpi_disable;           /* Value to write to smi_cmd to disable ACPI */
+	u8                              S4bios_req;             /* Value to write to SMI CMD to enter S4BIOS state */
+	u8                              reserved2;              /* Reserved - must be zero */
+	u32                             pm1a_evt_blk;           /* Port address of Power Mgt 1a acpi_event Reg Blk */
+	u32                             pm1b_evt_blk;           /* Port address of Power Mgt 1b acpi_event Reg Blk */
+	u32                             pm1a_cnt_blk;           /* Port address of Power Mgt 1a Control Reg Blk */
+	u32                             pm1b_cnt_blk;           /* Port address of Power Mgt 1b Control Reg Blk */
+	u32                             pm2_cnt_blk;            /* Port address of Power Mgt 2 Control Reg Blk */
+	u32                             pm_tmr_blk;             /* Port address of Power Mgt Timer Ctrl Reg Blk */
+	u32                             gpe0_blk;               /* Port addr of General Purpose acpi_event 0 Reg Blk */
+	u32                             gpe1_blk;               /* Port addr of General Purpose acpi_event 1 Reg Blk */
+	u8                              pm1_evt_len;            /* Byte length of ports at pm1_x_evt_blk */
+	u8                              pm1_cnt_len;            /* Byte length of ports at pm1_x_cnt_blk */
+	u8                              pm2_cnt_len;            /* Byte Length of ports at pm2_cnt_blk */
+	u8                              pm_tm_len;              /* Byte Length of ports at pm_tm_blk */
+	u8                              gpe0_blk_len;           /* Byte Length of ports at gpe0_blk */
+	u8                              gpe1_blk_len;           /* Byte Length of ports at gpe1_blk */
+	u8                              gpe1_base;              /* Offset in gpe model where gpe1 events start */
+	u8                              reserved3;              /* Reserved */
+	u16                             plvl2_lat;              /* Worst case HW latency to enter/exit C2 state */
+	u16                             plvl3_lat;              /* Worst case HW latency to enter/exit C3 state */
+	u16                             flush_size;             /* Size of area read to flush caches */
+	u16                             flush_stride;           /* Stride used in flushing caches */
+	u8                              duty_offset;            /* Bit location of duty cycle field in p_cnt reg */
+	u8                              duty_width;             /* Bit width of duty cycle field in p_cnt reg */
+	u8                              day_alrm;               /* Index to day-of-month alarm in RTC CMOS RAM */
+	u8                              mon_alrm;               /* Index to month-of-year alarm in RTC CMOS RAM */
+	u8                              century;                /* Index to century in RTC CMOS RAM */
+	u8                              reserved4;              /* Reserved */
+	u8                              reserved4a;             /* Reserved */
+	u8                              reserved4b;             /* Reserved */
+	u32                             wb_invd         : 1;    /* The wbinvd instruction works properly */
+	u32                             wb_invd_flush   : 1;    /* The wbinvd flushes but does not invalidate */
+	u32                             proc_c1         : 1;    /* All processors support C1 state */
+	u32                             plvl2_up        : 1;    /* C2 state works on MP system */
+	u32                             pwr_button      : 1;    /* Power button is handled as a generic feature */
+	u32                             sleep_button    : 1;    /* Sleep button is handled as a generic feature, or not present */
+	u32                             fixed_rTC       : 1;    /* RTC wakeup stat not in fixed register space */
+	u32                             rtcs4           : 1;    /* RTC wakeup stat not possible from S4 */
+	u32                             tmr_val_ext     : 1;    /* The tmr_val width is 32 bits (0 = 24 bits) */
+	u32                             reserved5       : 23;   /* Reserved - must be zero */
+};
+
+#pragma pack()
+
+#endif /* __ACTBL1_H__ */
+
+
diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actbl2.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ * Name: actbl2.h - ACPI Specification Revision 2.0 Tables
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTBL2_H__
+#define __ACTBL2_H__
+
+/*
+ * Prefered Power Management Profiles
+ */
+#define PM_UNSPECIFIED                  0
+#define PM_DESKTOP                      1
+#define PM_MOBILE                       2
+#define PM_WORKSTATION                  3
+#define PM_ENTERPRISE_SERVER            4
+#define PM_SOHO_SERVER                  5
+#define PM_APPLIANCE_PC                 6
+
+/*
+ * ACPI Boot Arch Flags
+ */
+#define BAF_LEGACY_DEVICES              0x0001
+#define BAF_8042_KEYBOARD_CONTROLLER    0x0002
+
+#define FADT2_REVISION_ID               3
+
+
+#pragma pack(1)
+
+/*
+ * ACPI 2.0 Root System Description Table (RSDT)
+ */
+struct rsdt_descriptor_rev2
+{
+	struct acpi_table_header        header;                 /* ACPI table header */
+	u32                             table_offset_entry [1]; /* Array of pointers to  */
+			 /* ACPI table headers */
+};
+
+
+/*
+ * ACPI 2.0 Extended System Description Table (XSDT)
+ */
+struct xsdt_descriptor_rev2
+{
+	struct acpi_table_header        header;                 /* ACPI table header */
+	u64                             table_offset_entry [1]; /* Array of pointers to  */
+			 /* ACPI table headers */
+};
+
+
+/*
+ * ACPI 2.0 Firmware ACPI Control Structure (FACS)
+ */
+struct facs_descriptor_rev2
+{
+	char                            signature[4];           /* ACPI signature */
+	u32                             length;                 /* Length of structure, in bytes */
+	u32                             hardware_signature;     /* Hardware configuration signature */
+	u32                             firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */
+	u32                             global_lock;            /* Global Lock used to synchronize access to shared hardware resources */
+	u32                             S4bios_f        : 1;    /* S4Bios_f - Indicates if S4BIOS support is present */
+	u32                             reserved1       : 31;   /* Must be 0 */
+	u64                             xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */
+	u8                              version;                /* Version of this table */
+	u8                              reserved3 [31];         /* Reserved - must be zero */
+};
+
+
+/*
+ * ACPI 2.0 Generic Address Structure (GAS)
+ */
+struct acpi_generic_address
+{
+	u8                              address_space_id;       /* Address space where struct or register exists. */
+	u8                              register_bit_width;     /* Size in bits of given register */
+	u8                              register_bit_offset;    /* Bit offset within the register */
+	u8                              reserved;               /* Must be 0 */
+	u64                             address;                /* 64-bit address of struct or register */
+};
+
+
+/*
+ * ACPI 2.0 Fixed ACPI Description Table (FADT)
+ */
+struct fadt_descriptor_rev2
+{
+	struct acpi_table_header        header;             /* ACPI table header */
+	u32                             V1_firmware_ctrl;   /* 32-bit physical address of FACS */
+	u32                             V1_dsdt;            /* 32-bit physical address of DSDT */
+	u8                              reserved1;          /* System Interrupt Model isn't used in ACPI 2.0*/
+	u8                              prefer_PM_profile;  /* Conveys preferred power management profile to OSPM. */
+	u16                             sci_int;            /* System vector of SCI interrupt */
+	u32                             smi_cmd;            /* Port address of SMI command port */
+	u8                              acpi_enable;        /* Value to write to smi_cmd to enable ACPI */
+	u8                              acpi_disable;       /* Value to write to smi_cmd to disable ACPI */
+	u8                              S4bios_req;         /* Value to write to SMI CMD to enter S4BIOS state */
+	u8                              pstate_cnt;         /* Processor performance state control*/
+	u32                             V1_pm1a_evt_blk;    /* Port address of Power Mgt 1a acpi_event Reg Blk */
+	u32                             V1_pm1b_evt_blk;    /* Port address of Power Mgt 1b acpi_event Reg Blk */
+	u32                             V1_pm1a_cnt_blk;    /* Port address of Power Mgt 1a Control Reg Blk */
+	u32                             V1_pm1b_cnt_blk;    /* Port address of Power Mgt 1b Control Reg Blk */
+	u32                             V1_pm2_cnt_blk;     /* Port address of Power Mgt 2 Control Reg Blk */
+	u32                             V1_pm_tmr_blk;      /* Port address of Power Mgt Timer Ctrl Reg Blk */
+	u32                             V1_gpe0_blk;        /* Port addr of General Purpose acpi_event 0 Reg Blk */
+	u32                             V1_gpe1_blk;        /* Port addr of General Purpose acpi_event 1 Reg Blk */
+	u8                              pm1_evt_len;        /* Byte length of ports at pm1_x_evt_blk */
+	u8                              pm1_cnt_len;        /* Byte length of ports at pm1_x_cnt_blk */
+	u8                              pm2_cnt_len;        /* Byte Length of ports at pm2_cnt_blk */
+	u8                              pm_tm_len;          /* Byte Length of ports at pm_tm_blk */
+	u8                              gpe0_blk_len;       /* Byte Length of ports at gpe0_blk */
+	u8                              gpe1_blk_len;       /* Byte Length of ports at gpe1_blk */
+	u8                              gpe1_base;          /* Offset in gpe model where gpe1 events start */
+	u8                              cst_cnt;            /* Support for the _CST object and C States change notification.*/
+	u16                             plvl2_lat;          /* Worst case HW latency to enter/exit C2 state */
+	u16                             plvl3_lat;          /* Worst case HW latency to enter/exit C3 state */
+	u16                             flush_size;         /* Number of flush strides that need to be read */
+	u16                             flush_stride;       /* Processor's memory cache line width, in bytes */
+	u8                              duty_offset;        /* Processor's duty cycle index in processor's P_CNT reg*/
+	u8                              duty_width;         /* Processor's duty cycle value bit width in P_CNT register.*/
+	u8                              day_alrm;           /* Index to day-of-month alarm in RTC CMOS RAM */
+	u8                              mon_alrm;           /* Index to month-of-year alarm in RTC CMOS RAM */
+	u8                              century;            /* Index to century in RTC CMOS RAM */
+	u16                             iapc_boot_arch;     /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
+	u8                              reserved2;          /* Reserved */
+	u32                             wb_invd     : 1;    /* The wbinvd instruction works properly */
+	u32                             wb_invd_flush : 1;  /* The wbinvd flushes but does not invalidate */
+	u32                             proc_c1     : 1;    /* All processors support C1 state */
+	u32                             plvl2_up    : 1;    /* C2 state works on MP system */
+	u32                             pwr_button  : 1;    /* Power button is handled as a generic feature */
+	u32                             sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
+	u32                             fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
+	u32                             rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
+	u32                             tmr_val_ext : 1;    /* Indicates tmr_val is 32 bits 0=24-bits*/
+	u32                             dock_cap    : 1;    /* Supports Docking */
+	u32                             reset_reg_sup : 1;  /* Indicates system supports system reset via the FADT RESET_REG*/
+	u32                             sealed_case : 1;    /* Indicates system has no internal expansion capabilities and case is sealed. */
+	u32                             headless    : 1;    /* Indicates system does not have local video capabilities or local input devices.*/
+	u32                             cpu_sw_sleep : 1;   /* Indicates to OSPM that a processor native instruction */
+			   /* Must be executed after writing the SLP_TYPx register. */
+	u32                             reserved6   : 18;   /* Reserved - must be zero */
+
+	struct acpi_generic_address     reset_register;     /* Reset register address in GAS format */
+	u8                              reset_value;        /* Value to write to the reset_register port to reset the system. */
+	u8                              reserved7[3];       /* These three bytes must be zero */
+	u64                             xfirmware_ctrl;     /* 64-bit physical address of FACS */
+	u64                             Xdsdt;              /* 64-bit physical address of DSDT */
+	struct acpi_generic_address     xpm1a_evt_blk;      /* Extended Power Mgt 1a acpi_event Reg Blk address */
+	struct acpi_generic_address     xpm1b_evt_blk;      /* Extended Power Mgt 1b acpi_event Reg Blk address */
+	struct acpi_generic_address     xpm1a_cnt_blk;      /* Extended Power Mgt 1a Control Reg Blk address */
+	struct acpi_generic_address     xpm1b_cnt_blk;      /* Extended Power Mgt 1b Control Reg Blk address */
+	struct acpi_generic_address     xpm2_cnt_blk;       /* Extended Power Mgt 2 Control Reg Blk address */
+	struct acpi_generic_address     xpm_tmr_blk;        /* Extended Power Mgt Timer Ctrl Reg Blk address */
+	struct acpi_generic_address     xgpe0_blk;          /* Extended General Purpose acpi_event 0 Reg Blk address */
+	struct acpi_generic_address     xgpe1_blk;          /* Extended General Purpose acpi_event 1 Reg Blk address */
+};
+
+
+#pragma pack()
+
+#endif /* __ACTBL2_H__ */
+
diff -Nru a/include/acpi/actbl71.h b/include/acpi/actbl71.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actbl71.h	Mon Feb 10 10:39:26 2003
@@ -0,0 +1,144 @@
+/******************************************************************************
+ *
+ * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71
+ *                   This file includes tables specific to this
+ *                   specification revision.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTBL71_H__
+#define __ACTBL71_H__
+
+
+/* 0.71 FADT address_space data item bitmasks defines */
+/* If the associated bit is zero then it is in memory space else in io space */
+
+#define SMI_CMD_ADDRESS_SPACE       0x01
+#define PM1_BLK_ADDRESS_SPACE       0x02
+#define PM2_CNT_BLK_ADDRESS_SPACE   0x04
+#define PM_TMR_BLK_ADDRESS_SPACE    0x08
+#define GPE0_BLK_ADDRESS_SPACE      0x10
+#define GPE1_BLK_ADDRESS_SPACE      0x20
+
+/* Only for clarity in declarations */
+
+typedef u64                         IO_ADDRESS;
+
+
+#pragma pack(1)
+struct  /* Root System Descriptor Pointer */
+{
+	NATIVE_CHAR             signature [8];          /* contains "RSD PTR " */
+	u8                              checksum;               /* to make sum of struct == 0 */
+	NATIVE_CHAR             oem_id [6];             /* OEM identification */
+	u8                              reserved;               /* Must be 0 for 1.0, 2 for 2.0 */
+	u64                             rsdt_physical_address;  /* 64-bit physical address of RSDT */
+};
+
+
+/*****************************************/
+/* IA64 Extensions to ACPI Spec Rev 0.71 */
+/* for the Root System Description Table */
+/*****************************************/
+struct
+{
+	struct acpi_table_header    header;                 /* Table header */
+	u32                         reserved_pad;           /* IA64 alignment, must be 0 */
+	u64                         table_offset_entry [1]; /* Array of pointers to other */
+			   /* tables' headers */
+};
+
+
+/*******************************************/
+/* IA64 Extensions to ACPI Spec Rev 0.71   */
+/* for the Firmware ACPI Control Structure */
+/*******************************************/
+struct
+{
+	NATIVE_CHAR         signature[4];         /* signature "FACS" */
+	u32                         length;               /* length of structure, in bytes */
+	u32                         hardware_signature;   /* hardware configuration signature */
+	u32                         reserved4;            /* must be 0 */
+	u64                         firmware_waking_vector; /* ACPI OS waking vector */
+	u64                         global_lock;          /* Global Lock */
+	u32                         S4bios_f      : 1;    /* Indicates if S4BIOS support is present */
+	u32                         reserved1     : 31;   /* must be 0 */
+	u8                          reserved3 [28];       /* reserved - must be zero */
+};
+
+
+/******************************************/
+/* IA64 Extensions to ACPI Spec Rev 0.71  */
+/* for the Fixed ACPI Description Table   */
+/******************************************/
+struct
+{
+	struct acpi_table_header    header;             /* table header */
+	u32                         reserved_pad;       /* IA64 alignment, must be 0 */
+	u64                         firmware_ctrl;      /* 64-bit Physical address of FACS */
+	u64                         dsdt;               /* 64-bit Physical address of DSDT */
+	u8                          model;              /* System Interrupt Model */
+	u8                          address_space;      /* Address Space Bitmask */
+	u16                         sci_int;            /* System vector of SCI interrupt */
+	u8                          acpi_enable;        /* value to write to smi_cmd to enable ACPI */
+	u8                          acpi_disable;       /* value to write to smi_cmd to disable ACPI */
+	u8                          S4bios_req;         /* Value to write to SMI CMD to enter S4BIOS state */
+	u8                          reserved2;          /* reserved - must be zero */
+	u64                         smi_cmd;            /* Port address of SMI command port */
+	u64                         pm1a_evt_blk;       /* Port address of Power Mgt 1a acpi_event Reg Blk */
+	u64                         pm1b_evt_blk;       /* Port address of Power Mgt 1b acpi_event Reg Blk */
+	u64                         pm1a_cnt_blk;       /* Port address of Power Mgt 1a Control Reg Blk */
+	u64                         pm1b_cnt_blk;       /* Port address of Power Mgt 1b Control Reg Blk */
+	u64                         pm2_cnt_blk;        /* Port address of Power Mgt 2 Control Reg Blk */
+	u64                         pm_tmr_blk;         /* Port address of Power Mgt Timer Ctrl Reg Blk */
+	u64                         gpe0_blk;           /* Port addr of General Purpose acpi_event 0 Reg Blk */
+	u64                         gpe1_blk;           /* Port addr of General Purpose acpi_event 1 Reg Blk */
+	u8                          pm1_evt_len;        /* Byte length of ports at pm1_x_evt_blk */
+	u8                          pm1_cnt_len;        /* Byte length of ports at pm1_x_cnt_blk */
+	u8                          pm2_cnt_len;        /* Byte Length of ports at pm2_cnt_blk */
+	u8                          pm_tm_len;          /* Byte Length of ports at pm_tm_blk */
+	u8                          gpe0_blk_len;       /* Byte Length of ports at gpe0_blk */
+	u8                          gpe1_blk_len;       /* Byte Length of ports at gpe1_blk */
+	u8                          gpe1_base;          /* offset in gpe model where gpe1 events start */
+	u8                          reserved3;          /* reserved */
+	u16                         plvl2_lat;          /* worst case HW latency to enter/exit C2 state */
+	u16                         plvl3_lat;          /* worst case HW latency to enter/exit C3 state */
+	u8                          day_alrm;           /* index to day-of-month alarm in RTC CMOS RAM */
+	u8                          mon_alrm;           /* index to month-of-year alarm in RTC CMOS RAM */
+	u8                          century;            /* index to century in RTC CMOS RAM */
+	u8                          reserved4;          /* reserved */
+	u32                         flush_cash  : 1;    /* PAL_FLUSH_CACHE is correctly supported */
+	u32                         reserved5   : 1;    /* reserved - must be zero */
+	u32                         proc_c1     : 1;    /* all processors support C1 state */
+	u32                         plvl2_up    : 1;    /* C2 state works on MP system */
+	u32                         pwr_button  : 1;    /* Power button is handled as a generic feature */
+	u32                         sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
+	u32                         fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
+	u32                         rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
+	u32                         tmr_val_ext : 1;    /* tmr_val is 32 bits */
+	u32                         dock_cap    : 1;    /* Supports Docking */
+	u32                         reserved6   : 22;    /* reserved - must be zero */
+};
+
+#pragma pack()
+
+#endif /* __ACTBL71_H__ */
+
diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/actypes.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,1189 @@
+/******************************************************************************
+ *
+ * Name: actypes.h - Common data types for the entire ACPI subsystem
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACTYPES_H__
+#define __ACTYPES_H__
+
+/*! [Begin] no source code translation (keep the typedefs) */
+
+
+
+/*
+ * Data type ranges
+ */
+#define ACPI_UINT8_MAX                  (UINT8)  0xFF
+#define ACPI_UINT16_MAX                 (UINT16) 0xFFFF
+#define ACPI_UINT32_MAX                 (UINT32) 0xFFFFFFFF
+#define ACPI_UINT64_MAX                 (UINT64) 0xFFFFFFFFFFFFFFFF
+#define ACPI_ASCII_MAX                  0x7F
+
+
+#ifdef DEFINE_ALTERNATE_TYPES
+/*
+ * Types used only in translated source, defined here to enable
+ * cross-platform compilation only.
+ */
+typedef int                             s32;
+typedef unsigned char                   u8;
+typedef unsigned short                  u16;
+typedef unsigned int                    u32;
+typedef COMPILER_DEPENDENT_UINT64       u64;
+
+#endif
+
+
+/*
+ * Data types - Fixed across all compilation models (16/32/64)
+ *
+ * BOOLEAN          Logical Boolean.
+ * INT8             8-bit  (1 byte) signed value
+ * UINT8            8-bit  (1 byte) unsigned value
+ * INT16            16-bit (2 byte) signed value
+ * UINT16           16-bit (2 byte) unsigned value
+ * INT32            32-bit (4 byte) signed value
+ * UINT32           32-bit (4 byte) unsigned value
+ * INT64            64-bit (8 byte) signed value
+ * UINT64           64-bit (8 byte) unsigned value
+ * ACPI_NATIVE_INT  32-bit on IA-32, 64-bit on IA-64 signed value
+ * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value
+ */
+
+#ifndef ACPI_MACHINE_WIDTH
+#error ACPI_MACHINE_WIDTH not defined
+#endif
+
+#if ACPI_MACHINE_WIDTH == 64
+
+/*! [Begin] no source code translation (keep the typedefs) */
+
+/*
+ * 64-bit type definitions
+ */
+typedef unsigned char                   UINT8;
+typedef unsigned char                   BOOLEAN;
+typedef unsigned short                  UINT16;
+typedef int                             INT32;
+typedef unsigned int                    UINT32;
+typedef COMPILER_DEPENDENT_INT64        INT64;
+typedef COMPILER_DEPENDENT_UINT64       UINT64;
+
+/*! [End] no source code translation !*/
+
+typedef s64                                     acpi_native_int;
+typedef u64                                     acpi_native_uint;
+
+typedef u64                                     acpi_table_ptr;
+typedef u64                                     acpi_io_address;
+typedef u64                                     acpi_physical_address;
+typedef u64                                     acpi_size;
+
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000008      /* No hardware alignment support in IA64 */
+#define ACPI_USE_NATIVE_DIVIDE                          /* Native 64-bit integer support */
+#define ACPI_MAX_PTR                    ACPI_UINT64_MAX
+#define ACPI_SIZE_MAX                   ACPI_UINT64_MAX
+
+
+#elif ACPI_MACHINE_WIDTH == 16
+
+/*! [Begin] no source code translation (keep the typedefs) */
+
+/*
+ * 16-bit type definitions
+ */
+typedef unsigned char                   UINT8;
+typedef unsigned char                   BOOLEAN;
+typedef unsigned int                    UINT16;
+typedef long                            INT32;
+typedef int                             INT16;
+typedef unsigned long                   UINT32;
+
+struct
+{
+	UINT32                                  Lo;
+	UINT32                                  Hi;
+};
+
+/*! [End] no source code translation !*/
+
+typedef u16                                     acpi_native_uint;
+typedef s16                                     acpi_native_int;
+
+typedef u32                                     acpi_table_ptr;
+typedef u32                                     acpi_io_address;
+typedef char                                    *acpi_physical_address;
+typedef u16                                     acpi_size;
+
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000002
+#define _HW_ALIGNMENT_SUPPORT
+#define ACPI_USE_NATIVE_DIVIDE                          /* No 64-bit integers, ok to use native divide */
+#define ACPI_MAX_PTR                    ACPI_UINT16_MAX
+#define ACPI_SIZE_MAX                   ACPI_UINT16_MAX
+
+/*
+ * (16-bit only) internal integers must be 32-bits, so
+ * 64-bit integers cannot be supported
+ */
+#define ACPI_NO_INTEGER64_SUPPORT
+
+
+#elif ACPI_MACHINE_WIDTH == 32
+
+/*! [Begin] no source code translation (keep the typedefs) */
+
+/*
+ * 32-bit type definitions (default)
+ */
+typedef unsigned char                   UINT8;
+typedef unsigned char                   BOOLEAN;
+typedef unsigned short                  UINT16;
+typedef int                             INT32;
+typedef unsigned int                    UINT32;
+typedef COMPILER_DEPENDENT_INT64        INT64;
+typedef COMPILER_DEPENDENT_UINT64       UINT64;
+
+/*! [End] no source code translation !*/
+
+typedef s32                                     acpi_native_int;
+typedef u32                                     acpi_native_uint;
+
+typedef u64                                     acpi_table_ptr;
+typedef u32                                     acpi_io_address;
+typedef u64                                     acpi_physical_address;
+typedef u32                                     acpi_size;
+
+#define ALIGNED_ADDRESS_BOUNDARY        0x00000004
+#define _HW_ALIGNMENT_SUPPORT
+#define ACPI_MAX_PTR                    ACPI_UINT32_MAX
+#define ACPI_SIZE_MAX                   ACPI_UINT32_MAX
+
+#else
+#error unknown ACPI_MACHINE_WIDTH
+#endif
+
+
+/*
+ * Miscellaneous common types
+ */
+typedef u32                                     UINT32_BIT;
+typedef acpi_native_uint                        ACPI_PTRDIFF;
+
+/*
+ * Pointer overlays to avoid lots of typecasting for
+ * code that accepts both physical and logical pointers.
+ */
+union acpi_pointers
+{
+	acpi_physical_address               physical;
+	void                                *logical;
+	acpi_table_ptr                      value;
+};
+
+struct acpi_pointer
+{
+	u32                                 pointer_type;
+	union acpi_pointers                 pointer;
+};
+
+/* pointer_types for above */
+
+#define ACPI_PHYSICAL_POINTER           0x01
+#define ACPI_LOGICAL_POINTER            0x02
+
+/* Processor mode */
+
+#define ACPI_PHYSICAL_ADDRESSING        0x04
+#define ACPI_LOGICAL_ADDRESSING         0x08
+#define ACPI_MEMORY_MODE                0x0C
+
+#define ACPI_PHYSMODE_PHYSPTR           ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
+#define ACPI_LOGMODE_PHYSPTR            ACPI_LOGICAL_ADDRESSING  | ACPI_PHYSICAL_POINTER
+#define ACPI_LOGMODE_LOGPTR             ACPI_LOGICAL_ADDRESSING  | ACPI_LOGICAL_POINTER
+
+
+/*
+ * Useful defines
+ */
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE                           (1 == 0)
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE                            (1 == 1)
+
+#ifndef NULL
+#define NULL                            (void *) 0
+#endif
+
+
+/*
+ * Local datatypes
+ */
+typedef u32                                     acpi_status;    /* All ACPI Exceptions */
+typedef u32                                     acpi_name;      /* 4-byte ACPI name */
+typedef char *                                  acpi_string;    /* Null terminated ASCII string */
+typedef void *                                  acpi_handle;    /* Actually a ptr to an Node */
+
+struct uint64_struct
+{
+	u32                                 lo;
+	u32                                 hi;
+};
+
+union uint64_overlay
+{
+	u64                                 full;
+	struct uint64_struct                part;
+};
+
+struct uint32_struct
+{
+	u32                                 lo;
+	u32                                 hi;
+};
+
+
+/*
+ * Acpi integer width. In ACPI version 1, integers are
+ * 32 bits.  In ACPI version 2, integers are 64 bits.
+ * Note that this pertains to the ACPI integer type only, not
+ * other integers used in the implementation of the ACPI CA
+ * subsystem.
+ */
+#ifdef ACPI_NO_INTEGER64_SUPPORT
+
+/* 32-bit integers only, no 64-bit support */
+
+typedef u32                                     acpi_integer;
+#define ACPI_INTEGER_MAX                ACPI_UINT32_MAX
+#define ACPI_INTEGER_BIT_SIZE           32
+#define ACPI_MAX_BCD_VALUE              99999999
+#define ACPI_MAX_BCD_DIGITS             8
+#define ACPI_MAX_DECIMAL_DIGITS         10
+
+#define ACPI_USE_NATIVE_DIVIDE          /* Use compiler native 32-bit divide */
+
+
+#else
+
+/* 64-bit integers */
+
+typedef u64                                     acpi_integer;
+#define ACPI_INTEGER_MAX                ACPI_UINT64_MAX
+#define ACPI_INTEGER_BIT_SIZE           64
+#define ACPI_MAX_BCD_VALUE              9999999999999999
+#define ACPI_MAX_BCD_DIGITS             16
+#define ACPI_MAX_DECIMAL_DIGITS         19
+
+#if ACPI_MACHINE_WIDTH == 64
+#define ACPI_USE_NATIVE_DIVIDE          /* Use compiler native 64-bit divide */
+#endif
+#endif
+
+
+/*
+ * Constants with special meanings
+ */
+#define ACPI_ROOT_OBJECT                (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR)
+
+
+/*
+ * Initialization sequence
+ */
+#define ACPI_FULL_INITIALIZATION        0x00
+#define ACPI_NO_ADDRESS_SPACE_INIT      0x01
+#define ACPI_NO_HARDWARE_INIT           0x02
+#define ACPI_NO_EVENT_INIT              0x04
+#define ACPI_NO_HANDLER_INIT            0x08
+#define ACPI_NO_ACPI_ENABLE             0x10
+#define ACPI_NO_DEVICE_INIT             0x20
+#define ACPI_NO_OBJECT_INIT             0x40
+
+/*
+ * Initialization state
+ */
+#define ACPI_INITIALIZED_OK             0x01
+
+/*
+ * Power state values
+ */
+
+#define ACPI_STATE_UNKNOWN              (u8) 0xFF
+
+#define ACPI_STATE_S0                   (u8) 0
+#define ACPI_STATE_S1                   (u8) 1
+#define ACPI_STATE_S2                   (u8) 2
+#define ACPI_STATE_S3                   (u8) 3
+#define ACPI_STATE_S4                   (u8) 4
+#define ACPI_STATE_S5                   (u8) 5
+#define ACPI_S_STATES_MAX               ACPI_STATE_S5
+#define ACPI_S_STATE_COUNT              6
+
+#define ACPI_STATE_D0                   (u8) 0
+#define ACPI_STATE_D1                   (u8) 1
+#define ACPI_STATE_D2                   (u8) 2
+#define ACPI_STATE_D3                   (u8) 3
+#define ACPI_D_STATES_MAX               ACPI_STATE_D3
+#define ACPI_D_STATE_COUNT              4
+
+#define ACPI_STATE_C0                   (u8) 0
+#define ACPI_STATE_C1                   (u8) 1
+#define ACPI_STATE_C2                   (u8) 2
+#define ACPI_STATE_C3                   (u8) 3
+#define ACPI_C_STATES_MAX               ACPI_STATE_C3
+#define ACPI_C_STATE_COUNT              4
+
+/*
+ * Sleep type invalid value
+ */
+#define ACPI_SLEEP_TYPE_MAX             0x7
+#define ACPI_SLEEP_TYPE_INVALID         0xFF
+
+/*
+ * Standard notify values
+ */
+#define ACPI_NOTIFY_BUS_CHECK           (u8) 0
+#define ACPI_NOTIFY_DEVICE_CHECK        (u8) 1
+#define ACPI_NOTIFY_DEVICE_WAKE         (u8) 2
+#define ACPI_NOTIFY_EJECT_REQUEST       (u8) 3
+#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT  (u8) 4
+#define ACPI_NOTIFY_FREQUENCY_MISMATCH  (u8) 5
+#define ACPI_NOTIFY_BUS_MODE_MISMATCH   (u8) 6
+#define ACPI_NOTIFY_POWER_FAULT         (u8) 7
+
+
+/*
+ *  Table types.  These values are passed to the table related APIs
+ */
+typedef u32                                     acpi_table_type;
+
+#define ACPI_TABLE_RSDP                 (acpi_table_type) 0
+#define ACPI_TABLE_DSDT                 (acpi_table_type) 1
+#define ACPI_TABLE_FADT                 (acpi_table_type) 2
+#define ACPI_TABLE_FACS                 (acpi_table_type) 3
+#define ACPI_TABLE_PSDT                 (acpi_table_type) 4
+#define ACPI_TABLE_SSDT                 (acpi_table_type) 5
+#define ACPI_TABLE_XSDT                 (acpi_table_type) 6
+#define ACPI_TABLE_MAX                  6
+#define NUM_ACPI_TABLES                 (ACPI_TABLE_MAX+1)
+
+
+/*
+ * Types associated with ACPI names and objects.  The first group of
+ * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
+ * of the ACPI object_type() operator (See the ACPI Spec). Therefore,
+ * only add to the first group if the spec changes.
+ *
+ * Types must be kept in sync with the global acpi_ns_properties
+ * and acpi_ns_type_names arrays.
+ */
+typedef u32                                     acpi_object_type;
+
+#define ACPI_TYPE_ANY                   0x00
+#define ACPI_TYPE_INTEGER               0x01  /* Byte/Word/Dword/Zero/One/Ones */
+#define ACPI_TYPE_STRING                0x02
+#define ACPI_TYPE_BUFFER                0x03
+#define ACPI_TYPE_PACKAGE               0x04  /* byte_const, multiple data_term/Constant/super_name */
+#define ACPI_TYPE_FIELD_UNIT            0x05
+#define ACPI_TYPE_DEVICE                0x06  /* Name, multiple Node */
+#define ACPI_TYPE_EVENT                 0x07
+#define ACPI_TYPE_METHOD                0x08  /* Name, byte_const, multiple Code */
+#define ACPI_TYPE_MUTEX                 0x09
+#define ACPI_TYPE_REGION                0x0A
+#define ACPI_TYPE_POWER                 0x0B  /* Name,byte_const,word_const,multi Node */
+#define ACPI_TYPE_PROCESSOR             0x0C  /* Name,byte_const,Dword_const,byte_const,multi nm_o */
+#define ACPI_TYPE_THERMAL               0x0D  /* Name, multiple Node */
+#define ACPI_TYPE_BUFFER_FIELD          0x0E
+#define ACPI_TYPE_DDB_HANDLE            0x0F
+#define ACPI_TYPE_DEBUG_OBJECT          0x10
+
+#define ACPI_TYPE_EXTERNAL_MAX          0x10
+
+/*
+ * These are object types that do not map directly to the ACPI
+ * object_type() operator. They are used for various internal purposes only.
+ * If new predefined ACPI_TYPEs are added (via the ACPI specification), these
+ * internal types must move upwards. (There is code that depends on these
+ * values being contiguous with the external types above.)
+ */
+#define ACPI_TYPE_LOCAL_REGION_FIELD    0x11
+#define ACPI_TYPE_LOCAL_BANK_FIELD      0x12
+#define ACPI_TYPE_LOCAL_INDEX_FIELD     0x13
+#define ACPI_TYPE_LOCAL_REFERENCE       0x14  /* Arg#, Local#, Name, Debug, ref_of, Index */
+#define ACPI_TYPE_LOCAL_ALIAS           0x15
+#define ACPI_TYPE_LOCAL_NOTIFY          0x16
+#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x17
+#define ACPI_TYPE_LOCAL_RESOURCE        0x18
+#define ACPI_TYPE_LOCAL_RESOURCE_FIELD  0x19
+#define ACPI_TYPE_LOCAL_SCOPE           0x1A  /* 1 Name, multiple object_list Nodes */
+
+#define ACPI_TYPE_NS_NODE_MAX           0x1A  /* Last typecode used within a NS Node */
+
+/*
+ * These are special object types that never appear in
+ * a Namespace node, only in an union acpi_operand_object
+ */
+#define ACPI_TYPE_LOCAL_EXTRA           0x1B
+#define ACPI_TYPE_LOCAL_DATA            0x1C
+
+#define ACPI_TYPE_LOCAL_MAX             0x1C
+
+/* All types above here are invalid */
+
+#define ACPI_TYPE_INVALID               0x1D
+#define ACPI_TYPE_NOT_FOUND             0xFF
+
+
+/*
+ * Bitmapped ACPI types.  Used internally only
+ */
+#define ACPI_BTYPE_ANY                  0x00000000
+#define ACPI_BTYPE_INTEGER              0x00000001
+#define ACPI_BTYPE_STRING               0x00000002
+#define ACPI_BTYPE_BUFFER               0x00000004
+#define ACPI_BTYPE_PACKAGE              0x00000008
+#define ACPI_BTYPE_FIELD_UNIT           0x00000010
+#define ACPI_BTYPE_DEVICE               0x00000020
+#define ACPI_BTYPE_EVENT                0x00000040
+#define ACPI_BTYPE_METHOD               0x00000080
+#define ACPI_BTYPE_MUTEX                0x00000100
+#define ACPI_BTYPE_REGION               0x00000200
+#define ACPI_BTYPE_POWER                0x00000400
+#define ACPI_BTYPE_PROCESSOR            0x00000800
+#define ACPI_BTYPE_THERMAL              0x00001000
+#define ACPI_BTYPE_BUFFER_FIELD         0x00002000
+#define ACPI_BTYPE_DDB_HANDLE           0x00004000
+#define ACPI_BTYPE_DEBUG_OBJECT         0x00008000
+#define ACPI_BTYPE_REFERENCE            0x00010000
+#define ACPI_BTYPE_RESOURCE             0x00020000
+
+#define ACPI_BTYPE_COMPUTE_DATA         (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER)
+
+#define ACPI_BTYPE_DATA                 (ACPI_BTYPE_COMPUTE_DATA  | ACPI_BTYPE_PACKAGE)
+#define ACPI_BTYPE_DATA_REFERENCE       (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE)
+#define ACPI_BTYPE_DEVICE_OBJECTS       (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR)
+#define ACPI_BTYPE_OBJECTS_AND_REFS     0x0001FFFF  /* ARG or LOCAL */
+#define ACPI_BTYPE_ALL_OBJECTS          0x0000FFFF
+
+/*
+ * All I/O
+ */
+#define ACPI_READ                       0
+#define ACPI_WRITE                      1
+#define ACPI_IO_MASK                    1
+
+
+/*
+ * acpi_event Types: Fixed & General Purpose
+ */
+typedef u32                                     acpi_event_type;
+
+#define ACPI_EVENT_FIXED                0
+#define ACPI_EVENT_GPE                  1
+
+/*
+ * Fixed events
+ */
+#define ACPI_EVENT_PMTIMER              0
+#define ACPI_EVENT_GLOBAL               1
+#define ACPI_EVENT_POWER_BUTTON         2
+#define ACPI_EVENT_SLEEP_BUTTON         3
+#define ACPI_EVENT_RTC                  4
+#define ACPI_EVENT_MAX                  4
+#define ACPI_NUM_FIXED_EVENTS           ACPI_EVENT_MAX + 1
+
+#define ACPI_GPE_INVALID                0xFF
+#define ACPI_GPE_MAX                    0xFF
+#define ACPI_NUM_GPE                    256
+
+#define ACPI_EVENT_LEVEL_TRIGGERED      1
+#define ACPI_EVENT_EDGE_TRIGGERED       2
+
+/*
+ * GPEs
+ */
+#define ACPI_EVENT_WAKE_ENABLE          0x1
+#define ACPI_EVENT_WAKE_DISABLE         0x1
+
+
+/*
+ * acpi_event Status:
+ * -------------
+ * The encoding of acpi_event_status is illustrated below.
+ * Note that a set bit (1) indicates the property is TRUE
+ * (e.g. if bit 0 is set then the event is enabled).
+ * +-------------+-+-+-+
+ * |   Bits 31:3 |2|1|0|
+ * +-------------+-+-+-+
+ *          |     | | |
+ *          |     | | +- Enabled?
+ *          |     | +--- Enabled for wake?
+ *          |     +----- Set?
+ *          +----------- <Reserved>
+ */
+typedef u32                                     acpi_event_status;
+
+#define ACPI_EVENT_FLAG_DISABLED        (acpi_event_status) 0x00
+#define ACPI_EVENT_FLAG_ENABLED         (acpi_event_status) 0x01
+#define ACPI_EVENT_FLAG_WAKE_ENABLED    (acpi_event_status) 0x02
+#define ACPI_EVENT_FLAG_SET             (acpi_event_status) 0x04
+
+
+/* Notify types */
+
+#define ACPI_SYSTEM_NOTIFY              0
+#define ACPI_DEVICE_NOTIFY              1
+#define ACPI_MAX_NOTIFY_HANDLER_TYPE    1
+
+#define ACPI_MAX_SYS_NOTIFY             0x7f
+
+
+/* Address Space (Operation Region) Types */
+
+typedef u8                                      acpi_adr_space_type;
+
+#define ACPI_ADR_SPACE_SYSTEM_MEMORY    (acpi_adr_space_type) 0
+#define ACPI_ADR_SPACE_SYSTEM_IO        (acpi_adr_space_type) 1
+#define ACPI_ADR_SPACE_PCI_CONFIG       (acpi_adr_space_type) 2
+#define ACPI_ADR_SPACE_EC               (acpi_adr_space_type) 3
+#define ACPI_ADR_SPACE_SMBUS            (acpi_adr_space_type) 4
+#define ACPI_ADR_SPACE_CMOS             (acpi_adr_space_type) 5
+#define ACPI_ADR_SPACE_PCI_BAR_TARGET   (acpi_adr_space_type) 6
+#define ACPI_ADR_SPACE_DATA_TABLE       (acpi_adr_space_type) 7
+#define ACPI_ADR_SPACE_FIXED_HARDWARE   (acpi_adr_space_type) 127
+
+
+/*
+ * bit_register IDs
+ * These are bitfields defined within the full ACPI registers
+ */
+#define ACPI_BITREG_TIMER_STATUS                0x00
+#define ACPI_BITREG_BUS_MASTER_STATUS           0x01
+#define ACPI_BITREG_GLOBAL_LOCK_STATUS          0x02
+#define ACPI_BITREG_POWER_BUTTON_STATUS         0x03
+#define ACPI_BITREG_SLEEP_BUTTON_STATUS         0x04
+#define ACPI_BITREG_RT_CLOCK_STATUS             0x05
+#define ACPI_BITREG_WAKE_STATUS                 0x06
+
+#define ACPI_BITREG_TIMER_ENABLE                0x07
+#define ACPI_BITREG_GLOBAL_LOCK_ENABLE          0x08
+#define ACPI_BITREG_POWER_BUTTON_ENABLE         0x09
+#define ACPI_BITREG_SLEEP_BUTTON_ENABLE         0x0A
+#define ACPI_BITREG_RT_CLOCK_ENABLE             0x0B
+#define ACPI_BITREG_WAKE_ENABLE                 0x0C
+
+#define ACPI_BITREG_SCI_ENABLE                  0x0D
+#define ACPI_BITREG_BUS_MASTER_RLD              0x0E
+#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x0F
+#define ACPI_BITREG_SLEEP_TYPE_A                0x10
+#define ACPI_BITREG_SLEEP_TYPE_B                0x11
+#define ACPI_BITREG_SLEEP_ENABLE                0x12
+
+#define ACPI_BITREG_ARB_DISABLE                 0x13
+
+#define ACPI_BITREG_MAX                         0x13
+#define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
+
+
+/*
+ * External ACPI object definition
+ */
+union acpi_object
+{
+	acpi_object_type                    type;   /* See definition of acpi_ns_type for values */
+	struct
+	{
+		acpi_object_type                    type;
+		acpi_integer                        value;      /* The actual number */
+	} integer;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 length;     /* # of bytes in string, excluding trailing null */
+		char                                *pointer;   /* points to the string value */
+	} string;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 length;     /* # of bytes in buffer */
+		u8                                  *pointer;   /* points to the buffer */
+	} buffer;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 fill1;
+		acpi_handle                         handle;     /* object reference */
+	} reference;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 count;      /* # of elements in package */
+		union acpi_object                   *elements;  /* Pointer to an array of ACPI_OBJECTs */
+	} package;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 proc_id;
+		acpi_io_address                     pblk_address;
+		u32                                 pblk_length;
+	} processor;
+
+	struct
+	{
+		acpi_object_type                    type;
+		u32                                 system_level;
+		u32                                 resource_order;
+	} power_resource;
+};
+
+
+/*
+ * List of objects, used as a parameter list for control method evaluation
+ */
+struct acpi_object_list
+{
+	u32                                 count;
+	union acpi_object                   *pointer;
+};
+
+
+/*
+ * Miscellaneous common Data Structures used by the interfaces
+ */
+#define ACPI_NO_BUFFER              0
+#define ACPI_ALLOCATE_BUFFER        (acpi_size) (-1)
+#define ACPI_ALLOCATE_LOCAL_BUFFER  (acpi_size) (-2)
+
+struct acpi_buffer
+{
+	acpi_size                           length;         /* Length in bytes of the buffer */
+	void                                *pointer;       /* pointer to buffer */
+};
+
+
+/*
+ * name_type for acpi_get_name
+ */
+#define ACPI_FULL_PATHNAME              0
+#define ACPI_SINGLE_NAME                1
+#define ACPI_NAME_TYPE_MAX              1
+
+
+/*
+ * Structure and flags for acpi_get_system_info
+ */
+#define ACPI_SYS_MODE_UNKNOWN           0x0000
+#define ACPI_SYS_MODE_ACPI              0x0001
+#define ACPI_SYS_MODE_LEGACY            0x0002
+#define ACPI_SYS_MODES_MASK             0x0003
+
+
+/*
+ * ACPI Table Info.  One per ACPI table _type_
+ */
+struct acpi_table_info
+{
+	u32                                 count;
+};
+
+
+/*
+ * System info returned by acpi_get_system_info()
+ */
+struct acpi_system_info
+{
+	u32                                 acpi_ca_version;
+	u32                                 flags;
+	u32                                 timer_resolution;
+	u32                                 reserved1;
+	u32                                 reserved2;
+	u32                                 debug_level;
+	u32                                 debug_layer;
+	u32                                 num_table_types;
+	struct acpi_table_info              table_info [NUM_ACPI_TABLES];
+};
+
+
+/*
+ * Various handlers and callback procedures
+ */
+typedef
+u32 (*acpi_event_handler) (
+	void                                *context);
+
+typedef
+void (*acpi_gpe_handler) (
+	void                                *context);
+
+typedef
+void (*acpi_notify_handler) (
+	acpi_handle                         device,
+	u32                                 value,
+	void                                *context);
+
+typedef
+void (*acpi_object_handler) (
+	acpi_handle                         object,
+	u32                                 function,
+	void                                *data);
+
+typedef
+acpi_status (*acpi_init_handler) (
+	acpi_handle                         object,
+	u32                                 function);
+
+#define ACPI_INIT_DEVICE_INI        1
+
+
+/* Address Spaces (Operation Regions */
+
+typedef
+acpi_status (*acpi_adr_space_handler) (
+	u32                                 function,
+	acpi_physical_address               address,
+	u32                                 bit_width,
+	acpi_integer                        *value,
+	void                                *handler_context,
+	void                                *region_context);
+
+#define ACPI_DEFAULT_HANDLER        NULL
+
+
+typedef
+acpi_status (*acpi_adr_space_setup) (
+	acpi_handle                         region_handle,
+	u32                                 function,
+	void                                *handler_context,
+	void                                **region_context);
+
+#define ACPI_REGION_ACTIVATE    0
+#define ACPI_REGION_DEACTIVATE  1
+
+typedef
+acpi_status (*acpi_walk_callback) (
+	acpi_handle                         obj_handle,
+	u32                                 nesting_level,
+	void                                *context,
+	void                                **return_value);
+
+
+/* Interrupt handler return values */
+
+#define ACPI_INTERRUPT_NOT_HANDLED      0x00
+#define ACPI_INTERRUPT_HANDLED          0x01
+
+
+/* Structure and flags for acpi_get_device_info */
+
+#define ACPI_VALID_HID                  0x1
+#define ACPI_VALID_UID                  0x2
+#define ACPI_VALID_ADR                  0x4
+#define ACPI_VALID_STA                  0x8
+
+
+#define ACPI_COMMON_OBJ_INFO \
+	acpi_object_type                    type;           /* ACPI object type */ \
+	acpi_name                           name            /* ACPI object Name */
+
+
+struct acpi_obj_info_header
+{
+	ACPI_COMMON_OBJ_INFO;
+};
+
+
+struct acpi_device_info
+{
+	ACPI_COMMON_OBJ_INFO;
+
+	u32                                 valid;              /*  Are the next bits legit? */
+	char                                hardware_id[9];     /*  _HID value if any */
+	char                                unique_id[9];       /*  _UID value if any */
+	acpi_integer                        address;            /*  _ADR value if any */
+	u32                                 current_status;     /*  _STA value */
+};
+
+
+/* Context structs for address space handlers */
+
+struct acpi_pci_id
+{
+	u16                                 segment;
+	u16                                 bus;
+	u16                                 device;
+	u16                                 function;
+};
+
+
+struct acpi_mem_space_context
+{
+	u32                                 length;
+	acpi_physical_address               address;
+	acpi_physical_address               mapped_physical_address;
+	u8                                  *mapped_logical_address;
+	acpi_size                           mapped_length;
+};
+
+
+/*
+ * Definitions for Resource Attributes
+ */
+
+/*
+ *  Memory Attributes
+ */
+#define ACPI_READ_ONLY_MEMORY           (u8) 0x00
+#define ACPI_READ_WRITE_MEMORY          (u8) 0x01
+
+#define ACPI_NON_CACHEABLE_MEMORY       (u8) 0x00
+#define ACPI_CACHABLE_MEMORY            (u8) 0x01
+#define ACPI_WRITE_COMBINING_MEMORY     (u8) 0x02
+#define ACPI_PREFETCHABLE_MEMORY        (u8) 0x03
+
+/*
+ *  IO Attributes
+ *  The ISA Io ranges are:     n000-n0_ffh, n400-n4_ffh, n800-n8_ffh, n_c00-n_cFFh.
+ *  The non-ISA Io ranges are: n100-n3_ffh, n500-n7_ffh, n900-n_bFfh, n_cd0-n_fFFh.
+ */
+#define ACPI_NON_ISA_ONLY_RANGES        (u8) 0x01
+#define ACPI_ISA_ONLY_RANGES            (u8) 0x02
+#define ACPI_ENTIRE_RANGE               (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES)
+
+/*
+ *  IO Port Descriptor Decode
+ */
+#define ACPI_DECODE_10                  (u8) 0x00    /* 10-bit IO address decode */
+#define ACPI_DECODE_16                  (u8) 0x01    /* 16-bit IO address decode */
+
+/*
+ *  IRQ Attributes
+ */
+#define ACPI_EDGE_SENSITIVE             (u8) 0x00
+#define ACPI_LEVEL_SENSITIVE            (u8) 0x01
+
+#define ACPI_ACTIVE_HIGH                (u8) 0x00
+#define ACPI_ACTIVE_LOW                 (u8) 0x01
+
+#define ACPI_EXCLUSIVE                  (u8) 0x00
+#define ACPI_SHARED                     (u8) 0x01
+
+/*
+ *  DMA Attributes
+ */
+#define ACPI_COMPATIBILITY              (u8) 0x00
+#define ACPI_TYPE_A                     (u8) 0x01
+#define ACPI_TYPE_B                     (u8) 0x02
+#define ACPI_TYPE_F                     (u8) 0x03
+
+#define ACPI_NOT_BUS_MASTER             (u8) 0x00
+#define ACPI_BUS_MASTER                 (u8) 0x01
+
+#define ACPI_TRANSFER_8                 (u8) 0x00
+#define ACPI_TRANSFER_8_16              (u8) 0x01
+#define ACPI_TRANSFER_16                (u8) 0x02
+
+/*
+ * Start Dependent Functions Priority definitions
+ */
+#define ACPI_GOOD_CONFIGURATION         (u8) 0x00
+#define ACPI_ACCEPTABLE_CONFIGURATION   (u8) 0x01
+#define ACPI_SUB_OPTIMAL_CONFIGURATION  (u8) 0x02
+
+/*
+ *  16, 32 and 64-bit Address Descriptor resource types
+ */
+#define ACPI_MEMORY_RANGE               (u8) 0x00
+#define ACPI_IO_RANGE                   (u8) 0x01
+#define ACPI_BUS_NUMBER_RANGE           (u8) 0x02
+
+#define ACPI_ADDRESS_NOT_FIXED          (u8) 0x00
+#define ACPI_ADDRESS_FIXED              (u8) 0x01
+
+#define ACPI_POS_DECODE                 (u8) 0x00
+#define ACPI_SUB_DECODE                 (u8) 0x01
+
+#define ACPI_PRODUCER                   (u8) 0x00
+#define ACPI_CONSUMER                   (u8) 0x01
+
+
+/*
+ *  Structures used to describe device resources
+ */
+struct acpi_resource_irq
+{
+	u32                                 edge_level;
+	u32                                 active_high_low;
+	u32                                 shared_exclusive;
+	u32                                 number_of_interrupts;
+	u32                                 interrupts[1];
+};
+
+struct acpi_resource_dma
+{
+	u32                                 type;
+	u32                                 bus_master;
+	u32                                 transfer;
+	u32                                 number_of_channels;
+	u32                                 channels[1];
+};
+
+struct acpi_resource_start_dpf
+{
+	u32                                 compatibility_priority;
+	u32                                 performance_robustness;
+};
+
+/*
+ * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not
+ * needed because it has no fields
+ */
+
+struct acpi_resource_io
+{
+	u32                                 io_decode;
+	u32                                 min_base_address;
+	u32                                 max_base_address;
+	u32                                 alignment;
+	u32                                 range_length;
+};
+
+struct acpi_resource_fixed_io
+{
+	u32                                 base_address;
+	u32                                 range_length;
+};
+
+struct acpi_resource_vendor
+{
+	u32                                 length;
+	u8                                  reserved[1];
+};
+
+struct acpi_resource_end_tag
+{
+	u8                                  checksum;
+};
+
+struct acpi_resource_mem24
+{
+	u32                                 read_write_attribute;
+	u32                                 min_base_address;
+	u32                                 max_base_address;
+	u32                                 alignment;
+	u32                                 range_length;
+};
+
+struct acpi_resource_mem32
+{
+	u32                                 read_write_attribute;
+	u32                                 min_base_address;
+	u32                                 max_base_address;
+	u32                                 alignment;
+	u32                                 range_length;
+};
+
+struct acpi_resource_fixed_mem32
+{
+	u32                                 read_write_attribute;
+	u32                                 range_base_address;
+	u32                                 range_length;
+};
+
+struct acpi_memory_attribute
+{
+	u16                                 cache_attribute;
+	u16                                 read_write_attribute;
+};
+
+struct acpi_io_attribute
+{
+	u16                                 range_attribute;
+	u16                                 reserved;
+};
+
+struct acpi_bus_attribute
+{
+	u16                                 reserved1;
+	u16                                 reserved2;
+};
+
+union acpi_resource_attribute
+{
+	struct acpi_memory_attribute        memory;
+	struct acpi_io_attribute            io;
+	struct acpi_bus_attribute           bus;
+};
+
+struct acpi_resource_source
+{
+	u32                                 index;
+	u32                                 string_length;
+	char                                *string_ptr;
+};
+
+struct acpi_resource_address16
+{
+	u32                                 resource_type;
+	u32                                 producer_consumer;
+	u32                                 decode;
+	u32                                 min_address_fixed;
+	u32                                 max_address_fixed;
+	union acpi_resource_attribute       attribute;
+	u32                                 granularity;
+	u32                                 min_address_range;
+	u32                                 max_address_range;
+	u32                                 address_translation_offset;
+	u32                                 address_length;
+	struct acpi_resource_source         resource_source;
+};
+
+struct acpi_resource_address32
+{
+	u32                                 resource_type;
+	u32                                 producer_consumer;
+	u32                                 decode;
+	u32                                 min_address_fixed;
+	u32                                 max_address_fixed;
+	union acpi_resource_attribute       attribute;
+	u32                                 granularity;
+	u32                                 min_address_range;
+	u32                                 max_address_range;
+	u32                                 address_translation_offset;
+	u32                                 address_length;
+	struct acpi_resource_source         resource_source;
+};
+
+struct acpi_resource_address64
+{
+	u32                                 resource_type;
+	u32                                 producer_consumer;
+	u32                                 decode;
+	u32                                 min_address_fixed;
+	u32                                 max_address_fixed;
+	union acpi_resource_attribute       attribute;
+	u64                                 granularity;
+	u64                                 min_address_range;
+	u64                                 max_address_range;
+	u64                                 address_translation_offset;
+	u64                                 address_length;
+	struct acpi_resource_source         resource_source;
+};
+
+struct acpi_resource_ext_irq
+{
+	u32                                 producer_consumer;
+	u32                                 edge_level;
+	u32                                 active_high_low;
+	u32                                 shared_exclusive;
+	u32                                 number_of_interrupts;
+	struct acpi_resource_source         resource_source;
+	u32                                 interrupts[1];
+};
+
+
+/* ACPI_RESOURCE_TYPEs */
+
+#define ACPI_RSTYPE_IRQ                 0
+#define ACPI_RSTYPE_DMA                 1
+#define ACPI_RSTYPE_START_DPF           2
+#define ACPI_RSTYPE_END_DPF             3
+#define ACPI_RSTYPE_IO                  4
+#define ACPI_RSTYPE_FIXED_IO            5
+#define ACPI_RSTYPE_VENDOR              6
+#define ACPI_RSTYPE_END_TAG             7
+#define ACPI_RSTYPE_MEM24               8
+#define ACPI_RSTYPE_MEM32               9
+#define ACPI_RSTYPE_FIXED_MEM32         10
+#define ACPI_RSTYPE_ADDRESS16           11
+#define ACPI_RSTYPE_ADDRESS32           12
+#define ACPI_RSTYPE_ADDRESS64           13
+#define ACPI_RSTYPE_EXT_IRQ             14
+
+typedef u32                                     acpi_resource_type;
+
+union acpi_resource_data
+{
+	struct acpi_resource_irq            irq;
+	struct acpi_resource_dma            dma;
+	struct acpi_resource_start_dpf      start_dpf;
+	struct acpi_resource_io             io;
+	struct acpi_resource_fixed_io       fixed_io;
+	struct acpi_resource_vendor         vendor_specific;
+	struct acpi_resource_end_tag        end_tag;
+	struct acpi_resource_mem24          memory24;
+	struct acpi_resource_mem32          memory32;
+	struct acpi_resource_fixed_mem32    fixed_memory32;
+	struct acpi_resource_address16      address16;
+	struct acpi_resource_address32      address32;
+	struct acpi_resource_address64      address64;
+	struct acpi_resource_ext_irq        extended_irq;
+};
+
+struct acpi_resource
+{
+	acpi_resource_type                  id;
+	u32                                 length;
+	union acpi_resource_data            data;
+};
+
+#define ACPI_RESOURCE_LENGTH                12
+#define ACPI_RESOURCE_LENGTH_NO_DATA        8       /* Id + Length fields */
+
+#define ACPI_SIZEOF_RESOURCE(type)          (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type))
+
+#define ACPI_NEXT_RESOURCE(res)             (struct acpi_resource *)((u8 *) res + res->length)
+
+#ifdef _HW_ALIGNMENT_SUPPORT
+#define ACPI_ALIGN_RESOURCE_SIZE(length)    (length)
+#else
+#define ACPI_ALIGN_RESOURCE_SIZE(length)    ACPI_ROUND_UP_TO_NATIVE_WORD(length)
+#endif
+
+/*
+ * END: of definitions for Resource Attributes
+ */
+
+
+struct acpi_pci_routing_table
+{
+	u32                                 length;
+	u32                                 pin;
+	acpi_integer                        address;        /* here for 64-bit alignment */
+	u32                                 source_index;
+	char                                source[4];      /* pad to 64 bits so sizeof() works in all cases */
+};
+
+/*
+ * END: of definitions for PCI Routing tables
+ */
+
+
+#endif /* __ACTYPES_H__ */
diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/acutils.h	Mon Feb 10 10:39:23 2003
@@ -0,0 +1,815 @@
+/******************************************************************************
+ *
+ * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 _ACUTILS_H
+#define _ACUTILS_H
+
+
+typedef
+acpi_status (*acpi_pkg_callback) (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+
+acpi_status
+acpi_ut_walk_package_tree (
+	union acpi_operand_object       *source_object,
+	void                            *target_object,
+	acpi_pkg_callback               walk_callback,
+	void                            *context);
+
+
+struct acpi_pkg_info
+{
+	u8                              *free_space;
+	acpi_size                       length;
+	u32                             object_space;
+	u32                             num_packages;
+};
+
+#define REF_INCREMENT       (u16) 0
+#define REF_DECREMENT       (u16) 1
+#define REF_FORCE_DELETE    (u16) 2
+
+/* acpi_ut_dump_buffer */
+
+#define DB_BYTE_DISPLAY     1
+#define DB_WORD_DISPLAY     2
+#define DB_DWORD_DISPLAY    4
+#define DB_QWORD_DISPLAY    8
+
+
+/* Global initialization interfaces */
+
+void
+acpi_ut_init_globals (
+	void);
+
+void
+acpi_ut_terminate (
+	void);
+
+
+/*
+ * ut_init - miscellaneous initialization and shutdown
+ */
+
+acpi_status
+acpi_ut_hardware_initialize (
+	void);
+
+void
+acpi_ut_subsystem_shutdown (
+	void);
+
+acpi_status
+acpi_ut_validate_fadt (
+	void);
+
+/*
+ * ut_global - Global data structures and procedures
+ */
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+char *
+acpi_ut_get_mutex_name (
+	u32                             mutex_id);
+
+#endif
+
+char *
+acpi_ut_get_type_name (
+	acpi_object_type                type);
+
+char *
+acpi_ut_get_object_type_name (
+	union acpi_operand_object       *obj_desc);
+
+char *
+acpi_ut_get_region_name (
+	u8                              space_id);
+
+char *
+acpi_ut_get_event_name (
+	u32                             event_id);
+
+char
+acpi_ut_hex_to_ascii_char (
+	acpi_integer                    integer,
+	u32                             position);
+
+u8
+acpi_ut_valid_object_type (
+	acpi_object_type                type);
+
+acpi_owner_id
+acpi_ut_allocate_owner_id (
+	u32                             id_type);
+
+
+/*
+ * ut_clib - Local implementations of C library functions
+ */
+
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+
+acpi_size
+acpi_ut_strlen (
+	const char                      *string);
+
+char *
+acpi_ut_strcpy (
+	char                            *dst_string,
+	const char                      *src_string);
+
+char *
+acpi_ut_strncpy (
+	char                            *dst_string,
+	const char                      *src_string,
+	acpi_size                       count);
+
+int
+acpi_ut_strncmp (
+	const char                      *string1,
+	const char                      *string2,
+	acpi_size                       count);
+
+int
+acpi_ut_strcmp (
+	const char                      *string1,
+	const char                      *string2);
+
+char *
+acpi_ut_strcat (
+	char                            *dst_string,
+	const char                      *src_string);
+
+char *
+acpi_ut_strncat (
+	char                            *dst_string,
+	const char                      *src_string,
+	acpi_size                       count);
+
+u32
+acpi_ut_strtoul (
+	const char                      *string,
+	char                            **terminator,
+	u32                             base);
+
+char *
+acpi_ut_strstr (
+	char                            *string1,
+	char                            *string2);
+
+void *
+acpi_ut_memcpy (
+	void                            *dest,
+	const void                      *src,
+	acpi_size                       count);
+
+void *
+acpi_ut_memset (
+	void                            *dest,
+	acpi_native_uint                value,
+	acpi_size                       count);
+
+int
+acpi_ut_to_upper (
+	int                             c);
+
+int
+acpi_ut_to_lower (
+	int                             c);
+
+extern const u8 _acpi_ctype[];
+
+#define _ACPI_XA     0x00    /* extra alphabetic - not supported */
+#define _ACPI_XS     0x40    /* extra space */
+#define _ACPI_BB     0x00    /* BEL, BS, etc. - not supported */
+#define _ACPI_CN     0x20    /* CR, FF, HT, NL, VT */
+#define _ACPI_DI     0x04    /* '0'-'9' */
+#define _ACPI_LO     0x02    /* 'a'-'z' */
+#define _ACPI_PU     0x10    /* punctuation */
+#define _ACPI_SP     0x08    /* space */
+#define _ACPI_UP     0x01    /* 'A'-'Z' */
+#define _ACPI_XD     0x80    /* '0'-'9', 'A'-'F', 'a'-'f' */
+
+#define ACPI_IS_DIGIT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI))
+#define ACPI_IS_SPACE(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP))
+#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
+#define ACPI_IS_UPPER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
+#define ACPI_IS_LOWER(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
+#define ACPI_IS_PRINT(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
+#define ACPI_IS_ALPHA(c)  (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
+#define ACPI_IS_ASCII(c)  ((c) < 0x80)
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
+/*
+ * ut_copy - Object construction and conversion interfaces
+ */
+
+acpi_status
+acpi_ut_build_simple_object(
+	union acpi_operand_object       *obj,
+	union acpi_object               *user_obj,
+	u8                              *data_space,
+	u32                             *buffer_space_used);
+
+acpi_status
+acpi_ut_build_package_object (
+	union acpi_operand_object       *obj,
+	u8                              *buffer,
+	u32                             *space_used);
+
+acpi_status
+acpi_ut_copy_ielement_to_eelement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+acpi_status
+acpi_ut_copy_ielement_to_ielement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+acpi_status
+acpi_ut_copy_iobject_to_eobject (
+	union acpi_operand_object       *obj,
+	struct acpi_buffer              *ret_buffer);
+
+acpi_status
+acpi_ut_copy_esimple_to_isimple(
+	union acpi_object               *user_obj,
+	union acpi_operand_object       **return_obj);
+
+acpi_status
+acpi_ut_copy_eobject_to_iobject (
+	union acpi_object               *obj,
+	union acpi_operand_object       **internal_obj);
+
+acpi_status
+acpi_ut_copy_isimple_to_isimple (
+	union acpi_operand_object       *source_obj,
+	union acpi_operand_object       *dest_obj);
+
+acpi_status
+acpi_ut_copy_ipackage_to_ipackage (
+	union acpi_operand_object       *source_obj,
+	union acpi_operand_object       *dest_obj,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ut_copy_simple_object (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc);
+
+acpi_status
+acpi_ut_copy_iobject_to_iobject (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       **dest_desc,
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * ut_create - Object creation
+ */
+
+acpi_status
+acpi_ut_update_object_reference (
+	union acpi_operand_object       *object,
+	u16                             action);
+
+
+/*
+ * ut_debug - Debug interfaces
+ */
+
+void
+acpi_ut_init_stack_ptr_trace (
+	void);
+
+void
+acpi_ut_track_stack_ptr (
+	void);
+
+void
+acpi_ut_trace (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info);
+
+void
+acpi_ut_trace_ptr (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	void                            *pointer);
+
+void
+acpi_ut_trace_u32 (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	u32                             integer);
+
+void
+acpi_ut_trace_str (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *string);
+
+void
+acpi_ut_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info);
+
+void
+acpi_ut_status_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	acpi_status                     status);
+
+void
+acpi_ut_value_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	acpi_integer                    value);
+
+void
+acpi_ut_ptr_exit (
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	u8                              *ptr);
+
+void
+acpi_ut_report_info (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id);
+
+void
+acpi_ut_report_error (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id);
+
+void
+acpi_ut_report_warning (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id);
+
+void
+acpi_ut_dump_buffer (
+	u8                              *buffer,
+	u32                             count,
+	u32                             display,
+	u32                             component_id);
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print (
+	u32                             requested_debug_level,
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *format,
+	...) ACPI_PRINTF_LIKE_FUNC;
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_debug_print_raw (
+	u32                             requested_debug_level,
+	u32                             line_number,
+	struct acpi_debug_print_info    *dbg_info,
+	char                            *format,
+	...) ACPI_PRINTF_LIKE_FUNC;
+
+
+/*
+ * ut_delete - Object deletion
+ */
+
+void
+acpi_ut_delete_internal_obj (
+	union acpi_operand_object       *object);
+
+void
+acpi_ut_delete_internal_package_object (
+	union acpi_operand_object       *object);
+
+void
+acpi_ut_delete_internal_simple_object (
+	union acpi_operand_object       *object);
+
+void
+acpi_ut_delete_internal_object_list (
+	union acpi_operand_object       **obj_list);
+
+
+/*
+ * ut_eval - object evaluation
+ */
+
+/* Method name strings */
+
+#define METHOD_NAME__HID        "_HID"
+#define METHOD_NAME__CID        "_CID"
+#define METHOD_NAME__UID        "_UID"
+#define METHOD_NAME__ADR        "_ADR"
+#define METHOD_NAME__STA        "_STA"
+#define METHOD_NAME__REG        "_REG"
+#define METHOD_NAME__SEG        "_SEG"
+#define METHOD_NAME__BBN        "_BBN"
+#define METHOD_NAME__PRT        "_PRT"
+
+
+acpi_status
+acpi_ut_evaluate_object (
+	struct acpi_namespace_node      *prefix_node,
+	char                            *path,
+	u32                             expected_return_btypes,
+	union acpi_operand_object       **return_desc);
+
+acpi_status
+acpi_ut_evaluate_numeric_object (
+	char                            *object_name,
+	struct acpi_namespace_node      *device_node,
+	acpi_integer                    *address);
+
+acpi_status
+acpi_ut_execute_HID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_device_id           *hid);
+
+acpi_status
+acpi_ut_execute_CID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_device_id           *cid);
+
+acpi_status
+acpi_ut_execute_STA (
+	struct acpi_namespace_node      *device_node,
+	u32                             *status_flags);
+
+acpi_status
+acpi_ut_execute_UID (
+	struct acpi_namespace_node      *device_node,
+	struct acpi_device_id           *uid);
+
+
+/*
+ * ut_mutex - mutual exclusion interfaces
+ */
+
+acpi_status
+acpi_ut_mutex_initialize (
+	void);
+
+void
+acpi_ut_mutex_terminate (
+	void);
+
+acpi_status
+acpi_ut_create_mutex (
+	acpi_mutex_handle               mutex_id);
+
+acpi_status
+acpi_ut_delete_mutex (
+	acpi_mutex_handle               mutex_id);
+
+acpi_status
+acpi_ut_acquire_mutex (
+	acpi_mutex_handle               mutex_id);
+
+acpi_status
+acpi_ut_release_mutex (
+	acpi_mutex_handle               mutex_id);
+
+
+/*
+ * ut_object - internal object create/delete/cache routines
+ */
+
+union acpi_operand_object    *
+acpi_ut_create_internal_object_dbg (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id,
+	acpi_object_type                type);
+
+void *
+acpi_ut_allocate_object_desc_dbg (
+	char                            *module_name,
+	u32                             line_number,
+	u32                             component_id);
+
+#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t)
+#define acpi_ut_allocate_object_desc()  acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT)
+
+void
+acpi_ut_delete_object_desc (
+	union acpi_operand_object       *object);
+
+u8
+acpi_ut_valid_internal_object (
+	void                            *object);
+
+union acpi_operand_object *
+acpi_ut_create_buffer_object (
+	acpi_size                       buffer_size);
+
+
+/*
+ * ut_ref_cnt - Object reference count management
+ */
+
+void
+acpi_ut_add_reference (
+	union acpi_operand_object       *object);
+
+void
+acpi_ut_remove_reference (
+	union acpi_operand_object       *object);
+
+/*
+ * ut_size - Object size routines
+ */
+
+acpi_status
+acpi_ut_get_simple_object_size (
+	union acpi_operand_object       *obj,
+	acpi_size                       *obj_length);
+
+acpi_status
+acpi_ut_get_package_object_size (
+	union acpi_operand_object       *obj,
+	acpi_size                       *obj_length);
+
+acpi_status
+acpi_ut_get_object_size(
+	union acpi_operand_object       *obj,
+	acpi_size                       *obj_length);
+
+acpi_status
+acpi_ut_get_element_length (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+
+/*
+ * ut_state - Generic state creation/cache routines
+ */
+
+void
+acpi_ut_push_generic_state (
+	union acpi_generic_state        **list_head,
+	union acpi_generic_state        *state);
+
+union acpi_generic_state *
+acpi_ut_pop_generic_state (
+	union acpi_generic_state        **list_head);
+
+
+union acpi_generic_state *
+acpi_ut_create_generic_state (
+	void);
+
+struct acpi_thread_state *
+acpi_ut_create_thread_state (
+	void);
+
+union acpi_generic_state *
+acpi_ut_create_update_state (
+	union acpi_operand_object       *object,
+	u16                             action);
+
+union acpi_generic_state *
+acpi_ut_create_pkg_state (
+	void                            *internal_object,
+	void                            *external_object,
+	u16                             index);
+
+acpi_status
+acpi_ut_create_update_state_and_push (
+	union acpi_operand_object       *object,
+	u16                             action,
+	union acpi_generic_state        **state_list);
+
+acpi_status
+acpi_ut_create_pkg_state_and_push (
+	void                            *internal_object,
+	void                            *external_object,
+	u16                             index,
+	union acpi_generic_state        **state_list);
+
+union acpi_generic_state *
+acpi_ut_create_control_state (
+	void);
+
+void
+acpi_ut_delete_generic_state (
+	union acpi_generic_state        *state);
+
+void
+acpi_ut_delete_generic_state_cache (
+	void);
+
+void
+acpi_ut_delete_object_cache (
+	void);
+
+/*
+ * utmisc
+ */
+
+void
+acpi_ut_print_string (
+	char                            *string,
+	u8                              max_length);
+
+acpi_status
+acpi_ut_divide (
+	acpi_integer                    *in_dividend,
+	acpi_integer                    *in_divisor,
+	acpi_integer                    *out_quotient,
+	acpi_integer                    *out_remainder);
+
+acpi_status
+acpi_ut_short_divide (
+	acpi_integer                    *in_dividend,
+	u32                             divisor,
+	acpi_integer                    *out_quotient,
+	u32                             *out_remainder);
+
+u8
+acpi_ut_valid_acpi_name (
+	u32                             name);
+
+u8
+acpi_ut_valid_acpi_character (
+	char                            character);
+
+acpi_status
+acpi_ut_strtoul64 (
+	char                            *string,
+	u32                             base,
+	acpi_integer                    *ret_integer);
+
+char *
+acpi_ut_strupr (
+	char                            *src_string);
+
+u8 *
+acpi_ut_get_resource_end_tag (
+	union acpi_operand_object       *obj_desc);
+
+u8
+acpi_ut_generate_checksum (
+	u8                              *buffer,
+	u32                             length);
+
+u32
+acpi_ut_dword_byte_swap (
+	u32                             value);
+
+void
+acpi_ut_set_integer_width (
+	u8                              revision);
+
+#ifdef ACPI_DEBUG_OUTPUT
+void
+acpi_ut_display_init_pathname (
+	u8                              type,
+	struct acpi_namespace_node      *obj_handle,
+	char                            *path);
+
+#endif
+
+
+/*
+ * Utalloc - memory allocation and object caching
+ */
+
+void *
+acpi_ut_acquire_from_cache (
+	u32                             list_id);
+
+void
+acpi_ut_release_to_cache (
+	u32                             list_id,
+	void                            *object);
+
+void
+acpi_ut_delete_generic_cache (
+	u32                             list_id);
+
+acpi_status
+acpi_ut_validate_buffer (
+	struct acpi_buffer              *buffer);
+
+acpi_status
+acpi_ut_initialize_buffer (
+	struct acpi_buffer              *buffer,
+	acpi_size                       required_length);
+
+
+/* Memory allocation functions */
+
+void *
+acpi_ut_allocate (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+void *
+acpi_ut_callocate (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+void *
+acpi_ut_allocate_and_track (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+void *
+acpi_ut_callocate_and_track (
+	acpi_size                       size,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+void
+acpi_ut_free_and_track (
+	void                            *address,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+struct acpi_debug_mem_block *
+acpi_ut_find_allocation (
+	u32                             list_id,
+	void                            *allocation);
+
+acpi_status
+acpi_ut_track_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *address,
+	acpi_size                       size,
+	u8                              alloc_type,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+acpi_status
+acpi_ut_remove_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *address,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+void
+acpi_ut_dump_allocation_info (
+	void);
+
+void
+acpi_ut_dump_allocations (
+	u32                             component,
+	char                            *module);
+#endif
+
+
+#endif /* _ACUTILS_H */
diff -Nru a/include/acpi/amlcode.h b/include/acpi/amlcode.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/amlcode.h	Mon Feb 10 10:39:29 2003
@@ -0,0 +1,477 @@
+/******************************************************************************
+ *
+ * Name: amlcode.h - Definitions for AML, as included in "definition blocks"
+ *                   Declarations and definitions contained herein are derived
+ *                   directly from the ACPI specification.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __AMLCODE_H__
+#define __AMLCODE_H__
+
+/* primary opcodes */
+
+#define AML_NULL_CHAR               (u16) 0x00
+
+#define AML_ZERO_OP                 (u16) 0x00
+#define AML_ONE_OP                  (u16) 0x01
+#define AML_UNASSIGNED              (u16) 0x02
+#define AML_ALIAS_OP                (u16) 0x06
+#define AML_NAME_OP                 (u16) 0x08
+#define AML_BYTE_OP                 (u16) 0x0a
+#define AML_WORD_OP                 (u16) 0x0b
+#define AML_DWORD_OP                (u16) 0x0c
+#define AML_STRING_OP               (u16) 0x0d
+#define AML_QWORD_OP                (u16) 0x0e     /* ACPI 2.0 */
+#define AML_SCOPE_OP                (u16) 0x10
+#define AML_BUFFER_OP               (u16) 0x11
+#define AML_PACKAGE_OP              (u16) 0x12
+#define AML_VAR_PACKAGE_OP          (u16) 0x13     /* ACPI 2.0 */
+#define AML_METHOD_OP               (u16) 0x14
+#define AML_DUAL_NAME_PREFIX        (u16) 0x2e
+#define AML_MULTI_NAME_PREFIX_OP    (u16) 0x2f
+#define AML_NAME_CHAR_SUBSEQ        (u16) 0x30
+#define AML_NAME_CHAR_FIRST         (u16) 0x41
+#define AML_OP_PREFIX               (u16) 0x5b
+#define AML_ROOT_PREFIX             (u16) 0x5c
+#define AML_PARENT_PREFIX           (u16) 0x5e
+#define AML_LOCAL_OP                (u16) 0x60
+#define AML_LOCAL0                  (u16) 0x60
+#define AML_LOCAL1                  (u16) 0x61
+#define AML_LOCAL2                  (u16) 0x62
+#define AML_LOCAL3                  (u16) 0x63
+#define AML_LOCAL4                  (u16) 0x64
+#define AML_LOCAL5                  (u16) 0x65
+#define AML_LOCAL6                  (u16) 0x66
+#define AML_LOCAL7                  (u16) 0x67
+#define AML_ARG_OP                  (u16) 0x68
+#define AML_ARG0                    (u16) 0x68
+#define AML_ARG1                    (u16) 0x69
+#define AML_ARG2                    (u16) 0x6a
+#define AML_ARG3                    (u16) 0x6b
+#define AML_ARG4                    (u16) 0x6c
+#define AML_ARG5                    (u16) 0x6d
+#define AML_ARG6                    (u16) 0x6e
+#define AML_STORE_OP                (u16) 0x70
+#define AML_REF_OF_OP               (u16) 0x71
+#define AML_ADD_OP                  (u16) 0x72
+#define AML_CONCAT_OP               (u16) 0x73
+#define AML_SUBTRACT_OP             (u16) 0x74
+#define AML_INCREMENT_OP            (u16) 0x75
+#define AML_DECREMENT_OP            (u16) 0x76
+#define AML_MULTIPLY_OP             (u16) 0x77
+#define AML_DIVIDE_OP               (u16) 0x78
+#define AML_SHIFT_LEFT_OP           (u16) 0x79
+#define AML_SHIFT_RIGHT_OP          (u16) 0x7a
+#define AML_BIT_AND_OP              (u16) 0x7b
+#define AML_BIT_NAND_OP             (u16) 0x7c
+#define AML_BIT_OR_OP               (u16) 0x7d
+#define AML_BIT_NOR_OP              (u16) 0x7e
+#define AML_BIT_XOR_OP              (u16) 0x7f
+#define AML_BIT_NOT_OP              (u16) 0x80
+#define AML_FIND_SET_LEFT_BIT_OP    (u16) 0x81
+#define AML_FIND_SET_RIGHT_BIT_OP   (u16) 0x82
+#define AML_DEREF_OF_OP             (u16) 0x83
+#define AML_CONCAT_RES_OP           (u16) 0x84     /* ACPI 2.0 */
+#define AML_MOD_OP                  (u16) 0x85     /* ACPI 2.0 */
+#define AML_NOTIFY_OP               (u16) 0x86
+#define AML_SIZE_OF_OP              (u16) 0x87
+#define AML_INDEX_OP                (u16) 0x88
+#define AML_MATCH_OP                (u16) 0x89
+#define AML_CREATE_DWORD_FIELD_OP   (u16) 0x8a
+#define AML_CREATE_WORD_FIELD_OP    (u16) 0x8b
+#define AML_CREATE_BYTE_FIELD_OP    (u16) 0x8c
+#define AML_CREATE_BIT_FIELD_OP     (u16) 0x8d
+#define AML_TYPE_OP                 (u16) 0x8e
+#define AML_CREATE_QWORD_FIELD_OP   (u16) 0x8f     /* ACPI 2.0 */
+#define AML_LAND_OP                 (u16) 0x90
+#define AML_LOR_OP                  (u16) 0x91
+#define AML_LNOT_OP                 (u16) 0x92
+#define AML_LEQUAL_OP               (u16) 0x93
+#define AML_LGREATER_OP             (u16) 0x94
+#define AML_LLESS_OP                (u16) 0x95
+#define AML_TO_BUFFER_OP            (u16) 0x96     /* ACPI 2.0 */
+#define AML_TO_DECSTRING_OP         (u16) 0x97     /* ACPI 2.0 */
+#define AML_TO_HEXSTRING_OP         (u16) 0x98     /* ACPI 2.0 */
+#define AML_TO_INTEGER_OP           (u16) 0x99     /* ACPI 2.0 */
+#define AML_TO_STRING_OP            (u16) 0x9c     /* ACPI 2.0 */
+#define AML_COPY_OP                 (u16) 0x9d     /* ACPI 2.0 */
+#define AML_MID_OP                  (u16) 0x9e     /* ACPI 2.0 */
+#define AML_CONTINUE_OP             (u16) 0x9f     /* ACPI 2.0 */
+#define AML_IF_OP                   (u16) 0xa0
+#define AML_ELSE_OP                 (u16) 0xa1
+#define AML_WHILE_OP                (u16) 0xa2
+#define AML_NOOP_OP                 (u16) 0xa3
+#define AML_RETURN_OP               (u16) 0xa4
+#define AML_BREAK_OP                (u16) 0xa5
+#define AML_BREAK_POINT_OP          (u16) 0xcc
+#define AML_ONES_OP                 (u16) 0xff
+
+/* prefixed opcodes */
+
+#define AML_EXTOP                   (u16) 0x005b
+
+
+#define AML_MUTEX_OP                (u16) 0x5b01
+#define AML_EVENT_OP                (u16) 0x5b02
+#define AML_SHIFT_RIGHT_BIT_OP      (u16) 0x5b10
+#define AML_SHIFT_LEFT_BIT_OP       (u16) 0x5b11
+#define AML_COND_REF_OF_OP          (u16) 0x5b12
+#define AML_CREATE_FIELD_OP         (u16) 0x5b13
+#define AML_LOAD_TABLE_OP           (u16) 0x5b1f     /* ACPI 2.0 */
+#define AML_LOAD_OP                 (u16) 0x5b20
+#define AML_STALL_OP                (u16) 0x5b21
+#define AML_SLEEP_OP                (u16) 0x5b22
+#define AML_ACQUIRE_OP              (u16) 0x5b23
+#define AML_SIGNAL_OP               (u16) 0x5b24
+#define AML_WAIT_OP                 (u16) 0x5b25
+#define AML_RESET_OP                (u16) 0x5b26
+#define AML_RELEASE_OP              (u16) 0x5b27
+#define AML_FROM_BCD_OP             (u16) 0x5b28
+#define AML_TO_BCD_OP               (u16) 0x5b29
+#define AML_UNLOAD_OP               (u16) 0x5b2a
+#define AML_REVISION_OP             (u16) 0x5b30
+#define AML_DEBUG_OP                (u16) 0x5b31
+#define AML_FATAL_OP                (u16) 0x5b32
+#define AML_REGION_OP               (u16) 0x5b80
+#define AML_FIELD_OP                (u16) 0x5b81
+#define AML_DEVICE_OP               (u16) 0x5b82
+#define AML_PROCESSOR_OP            (u16) 0x5b83
+#define AML_POWER_RES_OP            (u16) 0x5b84
+#define AML_THERMAL_ZONE_OP         (u16) 0x5b85
+#define AML_INDEX_FIELD_OP          (u16) 0x5b86
+#define AML_BANK_FIELD_OP           (u16) 0x5b87
+#define AML_DATA_REGION_OP          (u16) 0x5b88     /* ACPI 2.0 */
+
+
+/* Bogus opcodes (they are actually two separate opcodes) */
+
+#define AML_LGREATEREQUAL_OP        (u16) 0x9295
+#define AML_LLESSEQUAL_OP           (u16) 0x9294
+#define AML_LNOTEQUAL_OP            (u16) 0x9293
+
+
+/*
+ * Internal opcodes
+ * Use only "Unknown" AML opcodes, don't attempt to use
+ * any valid ACPI ASCII values (A-Z, 0-9, '-')
+ */
+
+#define AML_INT_NAMEPATH_OP         (u16) 0x002d
+#define AML_INT_NAMEDFIELD_OP       (u16) 0x0030
+#define AML_INT_RESERVEDFIELD_OP    (u16) 0x0031
+#define AML_INT_ACCESSFIELD_OP      (u16) 0x0032
+#define AML_INT_BYTELIST_OP         (u16) 0x0033
+#define AML_INT_STATICSTRING_OP     (u16) 0x0034
+#define AML_INT_METHODCALL_OP       (u16) 0x0035
+#define AML_INT_RETURN_VALUE_OP     (u16) 0x0036
+#define AML_INT_EVAL_SUBTREE_OP     (u16) 0x0037
+
+
+#define ARG_NONE                    0x0
+
+/*
+ * Argument types for the AML Parser
+ * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments.
+ * There can be up to 31 unique argument types
+ */
+
+#define ARGP_BYTEDATA               0x01
+#define ARGP_BYTELIST               0x02
+#define ARGP_CHARLIST               0x03
+#define ARGP_DATAOBJ                0x04
+#define ARGP_DATAOBJLIST            0x05
+#define ARGP_DWORDDATA              0x06
+#define ARGP_FIELDLIST              0x07
+#define ARGP_NAME                   0x08
+#define ARGP_NAMESTRING             0x09
+#define ARGP_OBJLIST                0x0A
+#define ARGP_PKGLENGTH              0x0B
+#define ARGP_SUPERNAME              0x0C
+#define ARGP_TARGET                 0x0D
+#define ARGP_TERMARG                0x0E
+#define ARGP_TERMLIST               0x0F
+#define ARGP_WORDDATA               0x10
+#define ARGP_QWORDDATA              0x11
+#define ARGP_SIMPLENAME             0x12
+
+/*
+ * Resolved argument types for the AML Interpreter
+ * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments.
+ * There can be up to 31 unique argument types (0 is end-of-arg-list indicator)
+ *
+ * Note: If and when 5 bits becomes insufficient, it would probably be best
+ * to convert to a 6-byte array of argument types, allowing 8 bits per argument.
+ */
+
+/* "Standard" ACPI types are 1-15 (0x0F) */
+
+#define ARGI_INTEGER                ACPI_TYPE_INTEGER       /* 1 */
+#define ARGI_STRING                 ACPI_TYPE_STRING        /* 2 */
+#define ARGI_BUFFER                 ACPI_TYPE_BUFFER        /* 3 */
+#define ARGI_PACKAGE                ACPI_TYPE_PACKAGE       /* 4 */
+#define ARGI_EVENT                  ACPI_TYPE_EVENT
+#define ARGI_MUTEX                  ACPI_TYPE_MUTEX
+#define ARGI_REGION                 ACPI_TYPE_REGION
+#define ARGI_DDBHANDLE              ACPI_TYPE_DDB_HANDLE
+
+/* Custom types are 0x10 through 0x1F */
+
+#define ARGI_IF                     0x10
+#define ARGI_ANYOBJECT              0x11
+#define ARGI_ANYTYPE                0x12
+#define ARGI_COMPUTEDATA            0x13     /* Buffer, String, or Integer */
+#define ARGI_DATAOBJECT             0x14     /* Buffer, String, package or reference to a Node - Used only by size_of operator*/
+#define ARGI_COMPLEXOBJ             0x15     /* Buffer, String, or package (Used by INDEX op only) */
+#define ARGI_INTEGER_REF            0x16
+#define ARGI_OBJECT_REF             0x17
+#define ARGI_DEVICE_REF             0x18
+#define ARGI_REFERENCE              0x19
+#define ARGI_TARGETREF              0x1A     /* Target, subject to implicit conversion */
+#define ARGI_FIXED_TARGET           0x1B     /* Target, no implicit conversion */
+#define ARGI_SIMPLE_TARGET          0x1C     /* Name, Local, Arg -- no implicit conversion */
+#define ARGI_BUFFERSTRING           0x1D
+#define ARGI_REF_OR_STRING          0x1E     /* Reference or String (Used by DEREFOF op only) */
+
+#define ARGI_INVALID_OPCODE         0xFFFFFFFF
+
+
+/*
+ * hash offsets
+ */
+#define AML_EXTOP_HASH_OFFSET       22
+#define AML_LNOT_HASH_OFFSET        19
+
+
+/*
+ * opcode groups and types
+ */
+
+#define OPGRP_NAMED                 0x01
+#define OPGRP_FIELD                 0x02
+#define OPGRP_BYTELIST              0x04
+
+
+/*
+ * Opcode information
+ */
+
+/* Opcode flags */
+
+#define AML_HAS_ARGS                0x0800
+#define AML_HAS_TARGET              0x0400
+#define AML_HAS_RETVAL              0x0200
+#define AML_NSOBJECT                0x0100
+#define AML_NSOPCODE                0x0080
+#define AML_NSNODE                  0x0040
+#define AML_NAMED                   0x0020
+#define AML_DEFER                   0x0010
+#define AML_FIELD                   0x0008
+#define AML_CREATE                  0x0004
+#define AML_MATH                    0x0002
+#define AML_LOGICAL                 0x0001
+#define AML_CONSTANT                0x1000
+
+/* Convenient flag groupings */
+
+#define AML_FLAGS_EXEC_1A_0T_0R     AML_HAS_ARGS                                   /* Monadic1  */
+#define AML_FLAGS_EXEC_1A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL /* Monadic2  */
+#define AML_FLAGS_EXEC_1A_1T_0R     AML_HAS_ARGS | AML_HAS_TARGET
+#define AML_FLAGS_EXEC_1A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */
+#define AML_FLAGS_EXEC_2A_0T_0R     AML_HAS_ARGS                                   /* Dyadic1   */
+#define AML_FLAGS_EXEC_2A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL /* Dyadic2   */
+#define AML_FLAGS_EXEC_2A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r  */
+#define AML_FLAGS_EXEC_2A_2T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
+#define AML_FLAGS_EXEC_3A_0T_0R     AML_HAS_ARGS
+#define AML_FLAGS_EXEC_3A_1T_1R     AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL
+#define AML_FLAGS_EXEC_6A_0T_1R     AML_HAS_ARGS |                  AML_HAS_RETVAL
+
+
+/*
+ * The opcode Type is used in a dispatch table, do not change
+ * without updating the table.
+ */
+#define AML_TYPE_EXEC_1A_0T_0R      0x00 /* Monadic1  */
+#define AML_TYPE_EXEC_1A_0T_1R      0x01 /* Monadic2  */
+#define AML_TYPE_EXEC_1A_1T_0R      0x02
+#define AML_TYPE_EXEC_1A_1T_1R      0x03 /* monadic2_r */
+#define AML_TYPE_EXEC_2A_0T_0R      0x04 /* Dyadic1   */
+#define AML_TYPE_EXEC_2A_0T_1R      0x05 /* Dyadic2   */
+#define AML_TYPE_EXEC_2A_1T_1R      0x06 /* dyadic2_r  */
+#define AML_TYPE_EXEC_2A_2T_1R      0x07
+#define AML_TYPE_EXEC_3A_0T_0R      0x08
+#define AML_TYPE_EXEC_3A_1T_1R      0x09
+#define AML_TYPE_EXEC_6A_0T_1R      0x0A
+/* End of types used in dispatch table */
+
+#define AML_TYPE_LITERAL            0x0B
+#define AML_TYPE_CONSTANT           0x0C
+#define AML_TYPE_METHOD_ARGUMENT    0x0D
+#define AML_TYPE_LOCAL_VARIABLE     0x0E
+#define AML_TYPE_DATA_TERM          0x0F
+
+/* Generic for an op that returns a value */
+
+#define AML_TYPE_METHOD_CALL        0x10
+
+/* Misc */
+
+#define AML_TYPE_CREATE_FIELD       0x11
+#define AML_TYPE_CREATE_OBJECT      0x12
+#define AML_TYPE_CONTROL            0x13
+#define AML_TYPE_NAMED_NO_OBJ       0x14
+#define AML_TYPE_NAMED_FIELD        0x15
+#define AML_TYPE_NAMED_SIMPLE       0x16
+#define AML_TYPE_NAMED_COMPLEX      0x17
+#define AML_TYPE_RETURN             0x18
+
+#define AML_TYPE_UNDEFINED          0x19
+#define AML_TYPE_BOGUS              0x1A
+
+
+/*
+ * Opcode classes
+ */
+#define AML_CLASS_EXECUTE           0x00
+#define AML_CLASS_CREATE            0x01
+#define AML_CLASS_ARGUMENT          0x02
+#define AML_CLASS_NAMED_OBJECT      0x03
+#define AML_CLASS_CONTROL           0x04
+#define AML_CLASS_ASCII             0x05
+#define AML_CLASS_PREFIX            0x06
+#define AML_CLASS_INTERNAL          0x07
+#define AML_CLASS_RETURN_VALUE      0x08
+#define AML_CLASS_METHOD_CALL       0x09
+#define AML_CLASS_UNKNOWN           0x0A
+
+
+/* Predefined Operation Region space_iDs */
+
+typedef enum
+{
+	REGION_MEMORY                   = 0,
+	REGION_IO,
+	REGION_PCI_CONFIG,
+	REGION_EC,
+	REGION_SMBUS,
+	REGION_CMOS,
+	REGION_PCI_BAR,
+	REGION_DATA_TABLE,              /* Internal use only */
+	REGION_FIXED_HW                 = 0x7F
+
+} AML_REGION_TYPES;
+
+
+/* Comparison operation codes for match_op operator */
+
+typedef enum
+{
+	MATCH_MTR                       = 0,
+	MATCH_MEQ                       = 1,
+	MATCH_MLE                       = 2,
+	MATCH_MLT                       = 3,
+	MATCH_MGE                       = 4,
+	MATCH_MGT                       = 5
+
+} AML_MATCH_OPERATOR;
+
+#define MAX_MATCH_OPERATOR          5
+
+
+/*
+ * field_flags
+ *
+ * This byte is extracted from the AML and includes three separate
+ * pieces of information about the field:
+ * 1) The field access type
+ * 2) The field update rule
+ * 3) The lock rule for the field
+ *
+ * Bits 00 - 03 : access_type (any_acc, byte_acc, etc.)
+ *      04      : lock_rule (1 == Lock)
+ *      05 - 06 : update_rule
+ */
+#define AML_FIELD_ACCESS_TYPE_MASK  0x0F
+#define AML_FIELD_LOCK_RULE_MASK    0x10
+#define AML_FIELD_UPDATE_RULE_MASK  0x60
+
+
+/* 1) Field Access Types */
+
+typedef enum
+{
+	AML_FIELD_ACCESS_ANY            = 0x00,
+	AML_FIELD_ACCESS_BYTE           = 0x01,
+	AML_FIELD_ACCESS_WORD           = 0x02,
+	AML_FIELD_ACCESS_DWORD          = 0x03,
+	AML_FIELD_ACCESS_QWORD          = 0x04,    /* ACPI 2.0 */
+	AML_FIELD_ACCESS_BUFFER         = 0x05     /* ACPI 2.0 */
+
+} AML_ACCESS_TYPE;
+
+
+/* 2) Field Lock Rules */
+
+typedef enum
+{
+	AML_FIELD_LOCK_NEVER            = 0x00,
+	AML_FIELD_LOCK_ALWAYS           = 0x10
+
+} AML_LOCK_RULE;
+
+
+/* 3) Field Update Rules */
+
+typedef enum
+{
+	AML_FIELD_UPDATE_PRESERVE       = 0x00,
+	AML_FIELD_UPDATE_WRITE_AS_ONES  = 0x20,
+	AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40
+
+} AML_UPDATE_RULE;
+
+
+/*
+ * Field Access Attributes.
+ * This byte is extracted from the AML via the
+ * access_as keyword
+ */
+typedef enum
+{
+	AML_FIELD_ATTRIB_SMB_QUICK      = 0x02,
+	AML_FIELD_ATTRIB_SMB_SEND_RCV   = 0x04,
+	AML_FIELD_ATTRIB_SMB_BYTE       = 0x06,
+	AML_FIELD_ATTRIB_SMB_WORD       = 0x08,
+	AML_FIELD_ATTRIB_SMB_BLOCK      = 0x0A,
+	AML_FIELD_ATTRIB_SMB_WORD_CALL  = 0x0C,
+	AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D
+
+} AML_ACCESS_ATTRIBUTE;
+
+
+/* bit fields in method_flags byte */
+
+#define METHOD_FLAGS_ARG_COUNT      0x07
+#define METHOD_FLAGS_SERIALIZED     0x08
+#define METHOD_FLAGS_SYNCH_LEVEL    0xF0
+
+
+#endif /* __AMLCODE_H__ */
diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/platform/acenv.h	Mon Feb 10 10:39:24 2003
@@ -0,0 +1,344 @@
+/******************************************************************************
+ *
+ * Name: acenv.h - Generation environment specific items
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACENV_H__
+#define __ACENV_H__
+
+
+/*
+ * Configuration for ACPI tools and utilities
+ */
+
+#ifdef _ACPI_DUMP_APP
+#ifndef MSDOS
+#define ACPI_DEBUG_OUTPUT
+#endif
+#define ACPI_APPLICATION
+#define ACPI_DISASSEMBLER
+#define ACPI_NO_METHOD_EXECUTION
+#define ACPI_USE_SYSTEM_CLIBRARY
+#endif
+
+#ifdef _ACPI_EXEC_APP
+#undef DEBUGGER_THREADING
+#define DEBUGGER_THREADING      DEBUGGER_SINGLE_THREADED
+#define ACPI_DEBUG_OUTPUT
+#define ACPI_APPLICATION
+#define ACPI_DEBUGGER
+#define ACPI_DISASSEMBLER
+#define ACPI_USE_SYSTEM_CLIBRARY
+#endif
+
+#ifdef _ACPI_ASL_COMPILER
+#define ACPI_DEBUG_OUTPUT
+#define ACPI_APPLICATION
+#define ACPI_DISASSEMBLER
+#define ACPI_CONSTANT_EVAL_ONLY
+#define ACPI_USE_SYSTEM_CLIBRARY
+#endif
+
+/*
+ * Environment configuration.  The purpose of this file is to interface to the
+ * local generation environment.
+ *
+ * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
+ *      Otherwise, local versions of string/memory functions will be used.
+ * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
+ *      the standard header files may be used.
+ *
+ * The ACPI subsystem only uses low level C library functions that do not call
+ * operating system services and may therefore be inlined in the code.
+ *
+ * It may be necessary to tailor these include files to the target
+ * generation environment.
+ *
+ *
+ * Functions and constants used from each header:
+ *
+ * string.h:    memcpy
+ *              memset
+ *              strcat
+ *              strcmp
+ *              strcpy
+ *              strlen
+ *              strncmp
+ *              strncat
+ *              strncpy
+ *
+ * stdlib.h:    strtoul
+ *
+ * stdarg.h:    va_list
+ *              va_arg
+ *              va_start
+ *              va_end
+ *
+ */
+
+/*! [Begin] no source code translation */
+
+#if defined(_LINUX)
+#include "aclinux.h"
+
+#elif defined(_AED_EFI)
+#include "acefi.h"
+
+#elif defined(WIN32)
+#include "acwin.h"
+
+#elif defined(WIN64)
+#include "acwin64.h"
+
+#elif defined(MSDOS)        /* Must appear after WIN32 and WIN64 check */
+#include "acdos16.h"
+
+#elif defined(__FreeBSD__)
+#include "acfreebsd.h"
+
+#elif defined(MODESTO)
+#include "acmodesto.h"
+
+#elif defined(NETWARE)
+#include "acnetware.h"
+
+#else
+
+/* All other environments */
+
+#define ACPI_USE_STANDARD_HEADERS
+
+#define COMPILER_DEPENDENT_INT64   long long
+#define COMPILER_DEPENDENT_UINT64  unsigned long long
+
+
+/* Name of host operating system (returned by the _OS_ namespace object) */
+
+#define ACPI_OS_NAME         "Intel ACPI/CA Core Subsystem"
+
+/* This macro is used to tag functions as "printf-like" because
+ * some compilers can catch printf format string problems. MSVC
+ * doesn't, so this is proprocessed away.
+ */
+#define ACPI_PRINTF_LIKE_FUNC
+
+#endif
+
+/*
+ * Memory allocation tracking.  Used only if
+ * 1) This is the debug version
+ * 2) This is NOT a 16-bit version of the code (not enough real-mode memory)
+ */
+#ifdef ACPI_DEBUG_OUTPUT
+#if ACPI_MACHINE_WIDTH != 16
+#define ACPI_DBG_TRACK_ALLOCATIONS
+#endif
+#endif
+
+/*! [End] no source code translation !*/
+
+
+/*
+ * Debugger threading model
+ * Use single threaded if the entire subsystem is contained in an application
+ * Use multiple threaded when the subsystem is running in the kernel.
+ *
+ * By default the model is single threaded if ACPI_APPLICATION is set,
+ * multi-threaded if ACPI_APPLICATION is not set.
+ */
+#define DEBUGGER_SINGLE_THREADED    0
+#define DEBUGGER_MULTI_THREADED     1
+
+#ifdef ACPI_APPLICATION
+#define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
+
+#else
+#define DEBUGGER_THREADING          DEBUGGER_MULTI_THREADED
+#endif
+
+
+/******************************************************************************
+ *
+ * C library configuration
+ *
+ *****************************************************************************/
+
+#ifdef ACPI_USE_SYSTEM_CLIBRARY
+/*
+ * Use the standard C library headers.
+ * We want to keep these to a minimum.
+ */
+
+#ifdef ACPI_USE_STANDARD_HEADERS
+/*
+ * Use the standard headers from the standard locations
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#endif /* ACPI_USE_STANDARD_HEADERS */
+
+/*
+ * We will be linking to the standard Clib functions
+ */
+
+#define ACPI_STRSTR(s1,s2)      strstr((s1), (s2))
+#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
+#define ACPI_STRLEN(s)          (acpi_size) strlen((s))
+#define ACPI_STRCPY(d,s)        (void) strcpy((d), (s))
+#define ACPI_STRNCPY(d,s,n)     (void) strncpy((d), (s), (acpi_size)(n))
+#define ACPI_STRNCMP(d,s,n)     strncmp((d), (s), (acpi_size)(n))
+#define ACPI_STRCMP(d,s)        strcmp((d), (s))
+#define ACPI_STRCAT(d,s)        (void) strcat((d), (s))
+#define ACPI_STRNCAT(d,s,n)     strncat((d), (s), (acpi_size)(n))
+#define ACPI_STRTOUL(d,s,n)     strtoul((d), (s), (acpi_size)(n))
+#define ACPI_MEMCPY(d,s,n)      (void) memcpy((d), (s), (acpi_size)(n))
+#define ACPI_MEMSET(d,s,n)      (void) memset((d), (s), (acpi_size)(n))
+
+#define ACPI_TOUPPER            toupper
+#define ACPI_TOLOWER            tolower
+#define ACPI_IS_XDIGIT          isxdigit
+#define ACPI_IS_DIGIT           isdigit
+#define ACPI_IS_SPACE           isspace
+#define ACPI_IS_UPPER           isupper
+#define ACPI_IS_PRINT           isprint
+#define ACPI_IS_ALPHA           isalpha
+#define ACPI_IS_ASCII           isascii
+
+/******************************************************************************
+ *
+ * Not using native C library, use local implementations
+ *
+ *****************************************************************************/
+#else
+
+/*
+ * Use local definitions of C library macros and functions
+ * NOTE: The function implementations may not be as efficient
+ * as an inline or assembly code implementation provided by a
+ * native C library.
+ */
+
+#ifndef va_arg
+
+#ifndef _VALIST
+#define _VALIST
+typedef char *va_list;
+#endif /* _VALIST */
+
+/*
+ * Storage alignment properties
+ */
+
+#define  _AUPBND                (sizeof (acpi_native_int) - 1)
+#define  _ADNBND                (sizeof (acpi_native_int) - 1)
+
+/*
+ * Variable argument list macro definitions
+ */
+
+#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))
+#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
+#define va_end(ap)              (void) 0
+#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
+
+#endif /* va_arg */
+
+
+#define ACPI_STRSTR(s1,s2)      acpi_ut_strstr ((s1), (s2))
+#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
+#define ACPI_STRLEN(s)          (acpi_size) acpi_ut_strlen ((s))
+#define ACPI_STRCPY(d,s)        (void) acpi_ut_strcpy ((d), (s))
+#define ACPI_STRNCPY(d,s,n)     (void) acpi_ut_strncpy ((d), (s), (acpi_size)(n))
+#define ACPI_STRNCMP(d,s,n)     acpi_ut_strncmp ((d), (s), (acpi_size)(n))
+#define ACPI_STRCMP(d,s)        acpi_ut_strcmp ((d), (s))
+#define ACPI_STRCAT(d,s)        (void) acpi_ut_strcat ((d), (s))
+#define ACPI_STRNCAT(d,s,n)     acpi_ut_strncat ((d), (s), (acpi_size)(n))
+#define ACPI_STRTOUL(d,s,n)     acpi_ut_strtoul ((d), (s), (acpi_size)(n))
+#define ACPI_MEMCPY(d,s,n)      (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n))
+#define ACPI_MEMSET(d,v,n)      (void) acpi_ut_memset ((d), (v), (acpi_size)(n))
+#define ACPI_TOUPPER            acpi_ut_to_upper
+#define ACPI_TOLOWER            acpi_ut_to_lower
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
+
+/******************************************************************************
+ *
+ * Assembly code macros
+ *
+ *****************************************************************************/
+
+/*
+ * Handle platform- and compiler-specific assembly language differences.
+ * These should already have been defined by the platform includes above.
+ *
+ * Notes:
+ * 1) Interrupt 3 is used to break into a debugger
+ * 2) Interrupts are turned off during ACPI register setup
+ */
+
+/* Unrecognized compiler, use defaults */
+
+#ifndef ACPI_ASM_MACROS
+
+/*
+ * Calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE      - External ACPI interfaces
+ * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
+ */
+#define ACPI_SYSTEM_XFACE
+#define ACPI_EXTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+
+#define ACPI_ASM_MACROS
+#define BREAKPOINT3
+#define ACPI_DISABLE_IRQS()
+#define ACPI_ENABLE_IRQS()
+#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
+#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
+
+#endif /* ACPI_ASM_MACROS */
+
+
+#ifdef ACPI_APPLICATION
+
+/* Don't want software interrupts within a ring3 application */
+
+#undef BREAKPOINT3
+#define BREAKPOINT3
+#endif
+
+
+/******************************************************************************
+ *
+ * Compiler-specific information is contained in the compiler-specific
+ * headers.
+ *
+ *****************************************************************************/
+#endif /* __ACENV_H__ */
diff -Nru a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/platform/acgcc.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ * Name: acgcc.h - GCC specific defines, etc.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACGCC_H__
+#define __ACGCC_H__
+
+/* This macro is used to tag functions as "printf-like" because
+ * some compilers (like GCC) can catch printf format string problems.
+ */
+#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5)))
+
+/* Some compilers complain about unused variables. Sometimes we don't want to
+ * use all the variables (most specifically for _THIS_MODULE). This allow us
+ * to to tell the compiler warning in a per-variable manner that a variable
+ * is unused.
+ */
+#define ACPI_UNUSED_VAR __attribute__ ((unused))
+
+#endif /* __ACGCC_H__ */
diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/platform/aclinux.h	Mon Feb 10 10:39:30 2003
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ * Name: aclinux.h - OS specific defines, etc.
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 - 2003, R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 __ACLINUX_H__
+#define __ACLINUX_H__
+
+#define ACPI_OS_NAME                "Linux"
+
+#define ACPI_USE_SYSTEM_CLIBRARY
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/div64.h>
+#include <asm/acpi.h>
+
+#define strtoul simple_strtoul
+
+#define ACPI_MACHINE_WIDTH  BITS_PER_LONG
+
+#else /* !__KERNEL__ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#if defined(__ia64__) || defined(__x86_64__)
+#define ACPI_MACHINE_WIDTH	    64
+#define COMPILER_DEPENDENT_INT64    long
+#define COMPILER_DEPENDENT_UINT64   unsigned long
+#else
+#define ACPI_MACHINE_WIDTH	    32
+#define COMPILER_DEPENDENT_INT64    long long
+#define COMPILER_DEPENDENT_UINT64   unsigned long long
+#define ACPI_USE_NATIVE_DIVIDE
+#endif
+
+#endif /* __KERNEL__ */
+
+/* Linux uses GCC */
+
+#include "acgcc.h"
+
+#endif /* __ACLINUX_H__ */
diff -Nru a/include/acpi/processor.h b/include/acpi/processor.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/acpi/processor.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,141 @@
+#ifndef __ACPI_PROCESSOR_H
+#define __ACPI_PROCESSOR_H
+
+#include <linux/kernel.h>
+
+#define ACPI_PROCESSOR_BUSY_METRIC	10
+
+#define ACPI_PROCESSOR_MAX_POWER	ACPI_C_STATE_COUNT
+#define ACPI_PROCESSOR_MAX_C2_LATENCY	100
+#define ACPI_PROCESSOR_MAX_C3_LATENCY	1000
+
+#define ACPI_PROCESSOR_MAX_PERFORMANCE	8
+
+#define ACPI_PROCESSOR_MAX_THROTTLING	16
+#define ACPI_PROCESSOR_MAX_THROTTLE	250	/* 25% */
+#define ACPI_PROCESSOR_MAX_DUTY_WIDTH	4
+
+/* Power Management */
+
+struct acpi_processor_cx_policy {
+	u32			count;
+	int			state;
+	struct {
+		u32			time;
+		u32			ticks;
+		u32			count;
+		u32			bm;
+	}			threshold;
+};
+
+struct acpi_processor_cx {
+	u8			valid;
+	u32			address;
+	u32			latency;
+	u32			latency_ticks;
+	u32			power;
+	u32			usage;
+	struct acpi_processor_cx_policy promotion;
+	struct acpi_processor_cx_policy demotion;
+};
+
+struct acpi_processor_power {
+	int			state;
+	int			default_state;
+	u32			bm_activity;
+	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
+};
+
+/* Performance Management */
+
+struct acpi_pct_register {
+	u8			descriptor;
+	u16			length;
+	u8			space_id;
+	u8			bit_width;
+	u8			bit_offset;
+	u8			reserved;
+	u64			address;
+} __attribute__ ((packed));
+
+struct acpi_processor_px {
+	acpi_integer		core_frequency;		/* megahertz */
+	acpi_integer		power;			/* milliWatts */
+	acpi_integer		transition_latency;	/* microseconds */
+	acpi_integer		bus_master_latency;	/* microseconds */
+	acpi_integer		control;		/* control value */
+	acpi_integer		status;			/* success indicator */
+};
+
+struct acpi_processor_performance {
+	int			state;
+	int			platform_limit;
+	u16			control_register;
+	u16			status_register;
+	int			state_count;
+	struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE];
+	struct cpufreq_frequency_table freq_table[ACPI_PROCESSOR_MAX_PERFORMANCE];
+	struct acpi_processor   *pr;
+};
+
+
+/* Throttling Control */
+
+struct acpi_processor_tx {
+	u16			power;
+	u16			performance;
+};
+
+struct acpi_processor_throttling {
+	int			state;
+	u32			address;
+	u8			duty_offset;
+	u8			duty_width;
+	int			state_count;
+	struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING];
+};
+
+/* Limit Interface */
+
+struct acpi_processor_lx {
+	int			px;		/* performace state */	
+	int			tx;		/* throttle level */
+};
+
+struct acpi_processor_limit {
+	struct acpi_processor_lx state;		/* current limit */
+	struct acpi_processor_lx thermal;	/* thermal limit */
+	struct acpi_processor_lx user;		/* user limit */
+};
+
+
+struct acpi_processor_flags {
+	u8			power:1;
+	u8			performance:1;
+	u8			throttling:1;
+	u8			limit:1;
+	u8			bm_control:1;
+	u8			bm_check:1;
+	u8			reserved:2;
+};
+
+struct acpi_processor {
+	acpi_handle		handle;
+	u32			acpi_id;
+	u32			id;
+	int			performance_platform_limit;
+	struct acpi_processor_flags flags;
+	struct acpi_processor_power power;
+	struct acpi_processor_performance *performance;
+	struct acpi_processor_throttling throttling;
+	struct acpi_processor_limit limit;
+};
+
+extern int acpi_processor_get_platform_limit (
+	struct acpi_processor*	pr);
+extern int acpi_processor_register_performance (
+	struct acpi_processor_performance * performance,
+	struct acpi_processor ** pr,
+	unsigned int cpu);
+
+#endif
diff -Nru a/include/asm-alpha/core_irongate.h b/include/asm-alpha/core_irongate.h
--- a/include/asm-alpha/core_irongate.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-alpha/core_irongate.h	Mon Feb 10 10:39:24 2003
@@ -50,13 +50,14 @@
 
 	igcsr32 bacsr10;		/* 0x40 - base address chip selects */
 	igcsr32 bacsr32;		/* 0x44 - base address chip selects */
-	igcsr32 bacsr54;		/* 0x48 - base address chip selects */
+	igcsr32 bacsr54_eccms761;	/* 0x48 - 751: base addr. chip selects
+						  761: ECC, mode/status */
 
 	igcsr32 rsrvd2[1];		/* 0x4C-0x4F reserved */
 
 	igcsr32 drammap;		/* 0x50 - address mapping control */
 	igcsr32 dramtm;			/* 0x54 - timing, driver strength */
-	igcsr32 dramms;			/* 0x58 - ECC, mode/status */
+	igcsr32 dramms;			/* 0x58 - DRAM mode/status */
 
 	igcsr32 rsrvd3[1];		/* 0x5C-0x5F reserved */
 
@@ -73,7 +74,10 @@
 	igcsr32 pciarb;			/* 0x84 - PCI arbitration control */
 	igcsr32 pcicfg;			/* 0x88 - PCI config status */
 
-	igcsr32 rsrvd6[5];		/* 0x8C-0x9F reserved */
+	igcsr32 rsrvd6[4];		/* 0x8C-0x9B reserved */
+
+	igcsr32 pci_mem;		/* 0x9C - PCI top of memory,
+						  761 only */
 
 	/* AGP (bus 1) control registers */
 	igcsr32 agpcap;			/* 0xA0 - AGP Capability Identifier */
@@ -102,6 +106,7 @@
 
 } Irongate1;
 
+extern igcsr32 *IronECC;
 
 /*
  * Memory spaces:
diff -Nru a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
--- a/include/asm-alpha/elf.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-alpha/elf.h	Mon Feb 10 10:39:27 2003
@@ -52,53 +52,25 @@
 
 #define ELF_PLAT_INIT(_r)       _r->r0 = 0
 
-/* Use the same format as the OSF/1 procfs interface.  The register
-   layout is sane.  However, since dump_thread() creates the funky
-   layout that ECOFF coredumps want, we need to undo that layout here.
-   Eventually, it would be nice if the ECOFF core-dump had to do the
-   translation, then ELF_CORE_COPY_REGS() would become trivial and
-   faster.  */
+/* The registers are layed out in pt_regs for PAL and syscall
+   convenience.  Re-order them for the linear elf_gregset_t.  */
 
-#define ELF_CORE_COPY_REGS(_dest,_regs)					\
-{									\
-	extern void dump_thread(struct pt_regs *, struct user *);	\
-	struct user _dump;						\
-									\
-	dump_thread(_regs, &_dump);					\
-	_dest[ 0] = _dump.regs[EF_V0];					\
-	_dest[ 1] = _dump.regs[EF_T0];					\
-	_dest[ 2] = _dump.regs[EF_T1];					\
-	_dest[ 3] = _dump.regs[EF_T2];					\
-	_dest[ 4] = _dump.regs[EF_T3];					\
-	_dest[ 5] = _dump.regs[EF_T4];					\
-	_dest[ 6] = _dump.regs[EF_T5];					\
-	_dest[ 7] = _dump.regs[EF_T6];					\
-	_dest[ 8] = _dump.regs[EF_T7];					\
-	_dest[ 9] = _dump.regs[EF_S0];					\
-	_dest[10] = _dump.regs[EF_S1];					\
-	_dest[11] = _dump.regs[EF_S2];					\
-	_dest[12] = _dump.regs[EF_S3];					\
-	_dest[13] = _dump.regs[EF_S4];					\
-	_dest[14] = _dump.regs[EF_S5];					\
-	_dest[15] = _dump.regs[EF_S6];					\
-	_dest[16] = _dump.regs[EF_A0];					\
-	_dest[17] = _dump.regs[EF_A1];					\
-	_dest[18] = _dump.regs[EF_A2];					\
-	_dest[19] = _dump.regs[EF_A3];					\
-	_dest[20] = _dump.regs[EF_A4];					\
-	_dest[21] = _dump.regs[EF_A5];					\
-	_dest[22] = _dump.regs[EF_T8];					\
-	_dest[23] = _dump.regs[EF_T9];					\
-	_dest[24] = _dump.regs[EF_T10];					\
-	_dest[25] = _dump.regs[EF_T11];					\
-	_dest[26] = _dump.regs[EF_RA];					\
-	_dest[27] = _dump.regs[EF_T12];					\
-	_dest[28] = _dump.regs[EF_AT];					\
-	_dest[29] = _dump.regs[EF_GP];					\
-	_dest[30] = _dump.regs[EF_SP];					\
-	_dest[31] = _dump.regs[EF_PC];	/* store PC here */		\
-	_dest[32] = _dump.regs[EF_PS];					\
-}
+extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt,
+			    struct thread_info *ti);
+#define ELF_CORE_COPY_REGS(DEST, REGS) \
+	dump_elf_thread(DEST, REGS, current_thread_info());
+
+/* Similar, but for a thread other than current.  */
+
+extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
+#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
+	dump_elf_task(*(DEST), TASK)
+
+/* Similar, but for the FP registers.  */
+
+extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
+#define ELF_CORE_COPY_FPREGS(TASK, DEST) \
+	dump_elf_task_fp(*(DEST), TASK)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports.  This is trivial on Alpha, 
diff -Nru a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h
--- a/include/asm-alpha/kmap_types.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-alpha/kmap_types.h	Mon Feb 10 10:39:33 2003
@@ -23,8 +23,8 @@
 D(8)	KM_PTE1,
 D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
-D(11)	KM_CRYPTO_USER,
-D(12)	KM_CRYPTO_SOFTIRQ,
+D(11)	KM_SOFTIRQ0,
+D(12)	KM_SOFTIRQ1,
 D(13)	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h	Mon Feb 10 10:39:22 2003
+++ b/include/asm-alpha/pci.h	Mon Feb 10 10:39:22 2003
@@ -68,16 +68,16 @@
    decisions.  */
 #define PCI_DMA_BUS_IS_PHYS  0
 
-/* Allocate and map kernel buffer using consistant mode DMA for PCI
+/* Allocate and map kernel buffer using consistent mode DMA for PCI
    device.  Returns non-NULL cpu-view pointer to the buffer if
    successful and sets *DMA_ADDRP to the pci side dma address as well,
    else DMA_ADDRP is undefined.  */
 
 extern void *pci_alloc_consistent(struct pci_dev *, size_t, dma_addr_t *);
 
-/* Free and unmap a consistant DMA buffer.  CPU_ADDR and DMA_ADDR must
-   be values that were returned from pci_alloc_consistant.  SIZE must
-   be the same as what as passed into pci_alloc_consistant.
+/* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+   be values that were returned from pci_alloc_consistent.  SIZE must
+   be the same as what as passed into pci_alloc_consistent.
    References to the memory and mappings assosciated with CPU_ADDR or
    DMA_ADDR past this call are illegal.  */
 
@@ -139,7 +139,7 @@
 
 extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int, int);
 
-/* Make physical memory consistant for a single streaming mode DMA
+/* Make physical memory consistent for a single streaming mode DMA
    translation after a transfer.
 
    If you perform a pci_map_single() but wish to interrogate the
@@ -155,7 +155,7 @@
 	/* Nothing to do.  */
 }
 
-/* Make physical memory consistant for a set of streaming mode DMA
+/* Make physical memory consistent for a set of streaming mode DMA
    translations after a transfer.  The same as pci_dma_sync_single but
    for a scatter-gather list, same rules and usage.  */
 
diff -Nru a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h
--- a/include/asm-alpha/signal.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-alpha/signal.h	Mon Feb 10 10:39:27 2003
@@ -93,7 +93,7 @@
 #define SA_NOCLDSTOP	0x00000004
 #define SA_NODEFER	0x00000008
 #define SA_RESETHAND	0x00000010
-#define SA_NOCLDWAIT	0x00000020 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000020
 #define SA_SIGINFO	0x00000040
 
 #define SA_ONESHOT	SA_RESETHAND
diff -Nru a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h
--- a/include/asm-alpha/topology.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-alpha/topology.h	Mon Feb 10 10:39:24 2003
@@ -6,7 +6,7 @@
 #include <asm/machvec.h>
 
 #ifdef CONFIG_NUMA
-static inline int __cpu_to_node(int cpu)
+static inline int cpu_to_node(int cpu)
 {
 	int node;
 	
@@ -23,13 +23,13 @@
 	return node;
 }
 
-static inline int __node_to_cpu_mask(int node)
+static inline int node_to_cpumask(int node)
 {
 	unsigned long node_cpu_mask = 0;
 	int cpu;
 
 	for(cpu = 0; cpu < NR_CPUS; cpu++) {
-		if (cpu_online(cpu) && (__cpu_to_node(cpu) == node))
+		if (cpu_online(cpu) && (cpu_to_node(cpu) == node))
 			node_cpu_mask |= 1UL << cpu;
 	}
 
@@ -40,8 +40,11 @@
 	return node_cpu_mask;
 }
 
-# define __node_to_memblk(node)		(node)
-# define __memblk_to_node(memblk)	(memblk)
+# define node_to_memblk(node)		(node)
+# define memblk_to_node(memblk)	(memblk)
+
+/* Cross-node load balancing interval. */
+# define NODE_BALANCE_RATE 10
 
 #else /* CONFIG_NUMA */
 # include <asm-generic/topology.h>
diff -Nru a/include/asm-arm/arch-ebsa110/param.h b/include/asm-arm/arch-ebsa110/param.h
--- a/include/asm-arm/arch-ebsa110/param.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-arm/arch-ebsa110/param.h	Mon Feb 10 10:39:23 2003
@@ -1,3 +1,4 @@
 /*
  *  linux/include/asm-arm/arch-ebsa110/param.h
  */
+#define __KERNEL_HZ	200
diff -Nru a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h
--- a/include/asm-arm/arch-ebsa110/time.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-arm/arch-ebsa110/time.h	Mon Feb 10 10:39:24 2003
@@ -17,17 +17,80 @@
  */
 
 #include <asm/leds.h>
+#include <asm/io.h>
 
-extern int  ebsa110_reset_timer(void);
-extern void ebsa110_setup_timer(void);
+extern unsigned long (*gettimeoffset)(void);
+
+#define PIT_CTRL		(PIT_BASE + 0x0d)
+#define PIT_T2			(PIT_BASE + 0x09)
+#define PIT_T1			(PIT_BASE + 0x05)
+#define PIT_T0			(PIT_BASE + 0x01)
+
+/*
+ * This is the rate at which your MCLK signal toggles (in Hz)
+ * This was measured on a 10 digit frequency counter sampling
+ * over 1 second.
+ */
+#define MCLK	47894000
+
+/*
+ * This is the rate at which the PIT timers get clocked
+ */
+#define CLKBY7	(MCLK / 7)
+
+/*
+ * This is the counter value.  We tick at 200Hz on this platform.
+ */
+#define COUNT	((CLKBY7 + (HZ / 2)) / HZ)
+
+/*
+ * Get the time offset from the system PIT.  Note that if we have missed an
+ * interrupt, then the PIT counter will roll over (ie, be negative).
+ * This actually works out to be convenient.
+ */
+static unsigned long ebsa110_gettimeoffset(void)
+{
+	unsigned long offset, count;
+
+	__raw_writeb(0x40, PIT_CTRL);
+	count = __raw_readb(PIT_T1);
+	count |= __raw_readb(PIT_T1) << 8;
+
+	/*
+	 * If count > COUNT, make the number negative.
+	 */
+	if (count > COUNT)
+		count |= 0xffff0000;
+
+	offset = COUNT;
+	offset -= count;
+
+	/*
+	 * `offset' is in units of timer counts.  Convert
+	 * offset to units of microseconds.
+	 */
+	offset = offset * (1000000 / HZ) / COUNT;
+
+	return offset;
+}
 
 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	if (ebsa110_reset_timer()) {
-		do_leds();
-		do_timer(regs);
-		do_profile(regs);
-	}
+	u32 count;
+
+	/* latch and read timer 1 */
+	__raw_writeb(0x40, PIT_CTRL);
+	count = __raw_readb(PIT_T1);
+	count |= __raw_readb(PIT_T1) << 8;
+
+	count += COUNT;
+
+	__raw_writeb(count & 0xff, PIT_T1);
+	__raw_writeb(count >> 8, PIT_T1);
+
+	do_leds();
+	do_timer(regs);
+	do_profile(regs);
 }
 
 /*
@@ -35,7 +98,14 @@
  */
 void __init time_init(void)
 {
-	ebsa110_setup_timer();
+	/*
+	 * Timer 1, mode 2, LSB/MSB
+	 */
+	__raw_writeb(0x70, PIT_CTRL);
+	__raw_writeb(COUNT & 0xff, PIT_T1);
+	__raw_writeb(COUNT >> 8, PIT_T1);
+
+	gettimeoffset = ebsa110_gettimeoffset;
 
 	timer_irq.handler = timer_interrupt;
 
diff -Nru a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h
--- a/include/asm-arm/arch-rpc/hardware.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-arm/arch-rpc/hardware.h	Mon Feb 10 10:39:33 2003
@@ -63,6 +63,17 @@
 #define IO_EC_MEMC8_BASE	0x8000ac00
 #define IO_EC_MEMC_BASE		0x80000000
 
+#define NETSLOT_BASE		0x0302b000
+#define NETSLOT_SIZE		0x00001000
+
+#define PODSLOT_IOC0_BASE	0x03240000
+#define PODSLOT_IOC4_BASE	0x03270000
+#define PODSLOT_IOC_SIZE	(1 << 14)
+#define PODSLOT_MEMC_BASE	0x03000000
+#define PODSLOT_MEMC_SIZE	(1 << 14)
+#define PODSLOT_EASI_BASE	0x08000000
+#define PODSLOT_EASI_SIZE	(1 << 24)
+
 #define	EXPMASK_STATUS		(EXPMASK_BASE + 0x00)
 #define EXPMASK_ENABLE		(EXPMASK_BASE + 0x04)
 
diff -Nru a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h
--- a/include/asm-arm/arch-rpc/io.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-arm/arch-rpc/io.h	Mon Feb 10 10:39:29 2003
@@ -247,4 +247,9 @@
 #define outsb(p,d,l)	__raw_writesb(__ioaddr(p),d,l)
 #define outsw(p,d,l)	__raw_writesw(__ioaddr(p),d,l)
 
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x)	(x)
+
 #endif
diff -Nru a/include/asm-arm/arch-sa1100/ide.h b/include/asm-arm/arch-sa1100/ide.h
--- a/include/asm-arm/arch-sa1100/ide.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-arm/arch-sa1100/ide.h	Mon Feb 10 10:39:23 2003
@@ -49,8 +49,9 @@
 		*irq = 0;
 }
 
-
-
+#ifdef CONFIG_SA1100_TRIZEPS
+#include <asm/arch/trizeps.h>
+#endif
 
 /*
  * This registers the standard ports for this architecture with the IDE
@@ -124,6 +125,23 @@
         ide_register_hw(&hw);
 #endif
     }
-}
+    else if( machine_is_trizeps() ){
+#ifdef CONFIG_SA1100_TRIZEPS
+	hw_regs_t hw;
 
+	/* Enable appropriate GPIOs as interrupt lines */
+	GPDR &= ~GPIO_GPIO(TRIZEPS_IRQ_IDE);
+	set_irq_type( TRIZEPS_IRQ_IDE, IRQT_RISING );
 
+	/* set the pcmcia interface timing */
+	//MECR = 0x00060006; // Done on trizeps init
+
+	/* Take hard drives out of reset */
+	GPSR = GPIO_GPIO(TRIZEPS_IRQ_IDE);
+
+	ide_init_hwif_ports(&hw, TRIZEPS_IDE_CS0 + 0, TRIZEPS_IDE_CS1 + 6, NULL);
+	hw.irq = TRIZEPS_IRQ_IDE;
+	ide_register_hw(&hw, NULL);
+#endif
+    }
+}
diff -Nru a/include/asm-arm/arch-sa1100/mftb2.h b/include/asm-arm/arch-sa1100/mftb2.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/arch-sa1100/mftb2.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,210 @@
+#ifndef _ARCH_ARM_MFTB2_h_
+#define _ARCH_ARM_MFTB2_h_
+
+// Defines for arch/arm/mm/mm-sa1100.h
+#define TRIZEPS_PHYS_VIRT_MAP_SIZE   0x00800000l
+
+// physical address (only for mm-sa1100.h)
+#define TRIZEPS_PHYS_IO_BASE         0x30000000l
+#define TRIZEPS_PHYS_MEM_BASE        0x38000000l
+
+// virtual
+#define TRIZEPS_IO_BASE		     0xF0000000l
+#define TRIZEPS_MEM_BASE             0xF2000000l
+
+// Offsets for phys and virtual
+#define TRIZEPS_OFFSET_REG0          0x00300000l
+#define TRIZEPS_OFFSET_REG1          0x00380000l
+#define TRIZEPS_OFFSET_IDE_CS0       0x00000000l
+#define TRIZEPS_OFFSET_IDE_CS1       0x00080000l
+#define TRIZEPS_OFFSET_UART5         0x00100000l
+#define TRIZEPS_OFFSET_UART6         0x00180000l
+#define TRIZEPS_PHYS_REG0            (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG0)
+#define TRIZEPS_PHYS_REG1            (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG1)
+#define TRIZEPS_PHYS_IDE_CS0         (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0)
+#define TRIZEPS_PHYS_IDE_CS1         (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1)
+#define TRIZEPS_PHYS_UART5           (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART5)
+#define TRIZEPS_PHYS_UART6           (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART6)
+
+// Use follow defines in devices
+// virtual address
+#define TRIZEPS_REG0    (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG0)
+#define TRIZEPS_REG1    (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG1)
+#define TRIZEPS_IDE_CS0 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0)
+#define TRIZEPS_IDE_CS1 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1)
+#define TRIZEPS_UART5   (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART5)
+#define TRIZEPS_UART6   (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART6)
+
+#define TRIZEPS_BAUD_BASE 1500000
+
+//#if 0 //temporarily disabled
+#ifndef __ASSEMBLY__
+struct tri_uart_cts_data_t {
+    int cts_gpio;
+    int cts_prev_state;
+    struct uart_info *info;
+    struct uart_port *port;
+    const char *name;
+};
+#endif /* __ASSEMBLY__ */
+
+/* Defines for MFTB2 serial_sa1100.c hardware handshaking lines */
+#define SERIAL_FULL
+#define NOT_CONNECTED	0
+#ifdef SERIAL_FULL
+#define TRIZEPS_GPIO_UART1_RTS	GPIO_GPIO14
+#define TRIZEPS_GPIO_UART1_DTR	NOT_CONNECTED //GPIO_GPIO9
+#define TRIZEPS_GPIO_UART1_CTS	GPIO_GPIO15
+#define TRIZEPS_GPIO_UART1_DCD	NOT_CONNECTED //GPIO_GPIO2
+#define TRIZEPS_GPIO_UART1_DSR	NOT_CONNECTED //GPIO_GPIO3
+#define TRIZEPS_GPIO_UART3_RTS	NOT_CONNECTED //GPIO_GPIO7
+#define TRIZEPS_GPIO_UART3_DTR	NOT_CONNECTED //GPIO_GPIO8
+#define TRIZEPS_GPIO_UART3_CTS	NOT_CONNECTED //GPIO_GPIO4
+#define TRIZEPS_GPIO_UART3_DCD	NOT_CONNECTED //GPIO_GPIO5
+#define TRIZEPS_GPIO_UART3_DSR	NOT_CONNECTED //GPIO_GPIO6
+
+#define TRIZEPS_GPIO_UART2_RTS	NOT_CONNECTED //GPIO_GPIO7
+#define TRIZEPS_GPIO_UART2_DTR	NOT_CONNECTED //GPIO_GPIO8
+#define TRIZEPS_GPIO_UART2_CTS	NOT_CONNECTED //GPIO_GPIO4
+#define TRIZEPS_GPIO_UART2_DCD	NOT_CONNECTED //GPIO_GPIO5
+#define TRIZEPS_GPIO_UART2_DSR	NOT_CONNECTED //GPIO_GPIO6
+
+#define TRIZEPS_IRQ_UART1_CTS	IRQ_GPIO15
+#define TRIZEPS_IRQ_UART1_DCD	NO_IRQ //IRQ_GPIO2
+#define TRIZEPS_IRQ_UART1_DSR	NO_IRQ //IRQ_GPIO3
+#define TRIZEPS_IRQ_UART3_CTS	NO_IRQ //IRQ_GPIO4
+#define TRIZEPS_IRQ_UART3_DCD	NO_IRQ //IRQ_GPIO5
+#define TRIZEPS_IRQ_UART3_DSR	NO_IRQ //IRQ_GPIO6
+
+#define TRIZEPS_IRQ_UART2_CTS	NO_IRQ //IRQ_GPIO4
+#define TRIZEPS_IRQ_UART2_DCD	NO_IRQ //IRQ_GPIO5
+#define TRIZEPS_IRQ_UART2_DSR	NO_IRQ //IRQ_GPIO6
+
+#endif /* SERIAL_FULL */
+//#endif //0
+
+/*
+ * This section contains the defines for the MFTB2 implementation
+ * of drivers/ide/hd.c. HD_IOBASE_0 and HD_IOBASE_1 have to be
+ * adjusted if hardware changes.
+ */
+#define TRIZEPS_IRQ_IDE 10		/* MFTB2 specific */
+
+/*---   ROOT   ---*/
+#define TRIZEPS_GPIO_ROOT_NFS       0
+#define TRIZEPS_GPIO_ROOT_HD        21
+/*---  PCMCIA  ---*/
+#define TRIZEPS_GPIO_PCMCIA_IRQ0 1
+#define TRIZEPS_GPIO_PCMCIA_CD0  24
+#define TRIZEPS_IRQ_PCMCIA_IRQ0  TRIZEPS_GPIO_PCMCIA_IRQ0
+#define TRIZEPS_IRQ_PCMCIA_CD0   TRIZEPS_GPIO_PCMCIA_CD0 + 32 - 11
+
+// REGISTER 0 -> 0x0XXXX (16bit access)
+// read only
+#define TRIZEPS_A_STAT             0x8000l
+#define TRIZEPS_F_STAT             0x4000l
+#define TRIZEPS_BATT_FAULT_EN      0x2000l
+#define TRIZEPS_nDQ                0x1000l
+#define TRIZEPS_MFT_OFF            0x0800l
+#define TRIZEPS_D_APWOFF           0x0400l
+#define TRIZEPS_F_CTRL             0x0200l
+#define TRIZEPS_F_STOP             0x0100l
+
+// read / write
+#define TRIZEPS_KP_IR_EN           0x0080l
+#define TRIZEPS_FIR                0x0040l
+#define TRIZEPS_BAR_ON             0x0020l
+#define TRIZEPS_VCI_ON             0x0010l
+#define TRIZEPS_LED4               0x0008l
+#define TRIZEPS_LED3               0x0004l
+#define TRIZEPS_LED2               0x0002l
+#define TRIZEPS_LED1               0x0001l
+
+// REGISTER 1 -> 0x1XXXX (16bit access)
+// read only
+#define TRIZEPS_nVCI2              0x8000l
+#define TRIZEPS_nAB_LOW            0x4000l
+#define TRIZEPS_nMB_DEAD           0x2000l
+#define TRIZEPS_nMB_LOW            0x1000l
+#define TRIZEPS_nPCM_VS2           0x0800l
+#define TRIZEPS_nPCM_VS1           0x0400l
+#define TRIZEPS_PCM_BVD2           0x0200l
+#define TRIZEPS_PCM_BVD1           0x0100l
+
+// read / write
+#define TRIZEPS_nROOT_NFS          0x0080l
+#define TRIZEPS_nROOT_HD           0x0040l
+#define TRIZEPS_nPCM_ENA_REG       0x0020l
+#define TRIZEPS_nPCM_RESET_DISABLE 0x0010l
+#define TRIZEPS_PCM_EN0_REG        0x0008l
+#define TRIZEPS_PCM_EN1_REG        0x0004l
+#define TRIZEPS_PCM_V3_EN_REG      0x0002l
+#define TRIZEPS_PCM_V5_EN_REG      0x0001l
+
+/* Access to Board Control Register */
+#define TRIZEPS_BCR0 (*(volatile unsigned short *)(TRIZEPS_REG0))
+#define TRIZEPS_BCR1 (*(volatile unsigned short *)(TRIZEPS_REG1))
+
+#define TRIZEPS_BCR_set( reg, x ) do { \
+	unsigned long flags; \
+	local_irq_save(flags); \
+	(reg) |= (x); \
+	local_irq_restore(flags); \
+} while (0)
+
+#define TRIZEPS_BCR_clear( reg, x ) do { \
+	unsigned long flags; \
+	local_irq_save(flags); \
+	(reg) &= ~(x); \
+	local_irq_restore(flags); \
+} while (0)
+
+#define TRIZEPS_OFFSET_KP_REG      0x00200000l
+#define TRIZEPS_OFFSET_VCI2        0x00280000l
+#define TRIZEPS_OFFSET_VCI4        0x00400000l
+
+#define TRIZEPS_OFFSET_VCI2_1_DPR  (TRIZEPS_OFFSET_VCI2 + 0x00010000l)
+#define TRIZEPS_OFFSET_VCI2_2_DPR  (TRIZEPS_OFFSET_VCI2 + 0x00018000l)
+#define TRIZEPS_OFFSET_VCI2_1_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00020000l)
+#define TRIZEPS_OFFSET_VCI2_2_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00028000l)
+
+#define TRIZEPS_OFFSET_VCI4_1_DPR  (TRIZEPS_OFFSET_VCI4 + 0x00000000l)
+#define TRIZEPS_OFFSET_VCI4_2_DPR  (TRIZEPS_OFFSET_VCI4 + 0x00008000l)
+#define TRIZEPS_OFFSET_VCI4_1_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000380l)
+#define TRIZEPS_OFFSET_VCI4_2_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000388l)
+#define TRIZEPS_OFFSET_VCI4_1_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000390l)
+#define TRIZEPS_OFFSET_VCI4_2_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000392l)
+
+#define TRIZEPS_PHYS_KP_REG        (PHYS_TRIZEPS_IO_BASE + TRIZEPS_OFFSET_KP_REG)
+
+// VCI address
+#define TRIZEPS_PHYS_VCI2_1_DPR    (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR)
+#define TRIZEPS_PHYS_VCI2_2_DPR    (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR)
+#define TRIZEPS_PHYS_VCI2_1_SEMA   (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA)
+#define TRIZEPS_PHYS_VCI2_2_SEMA   (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA)
+
+// VCI4 address
+#define TRIZEPS_PHYS_VCI4_1_DPR    (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR)
+#define TRIZEPS_PHYS_VCI4_2_DPR    (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR)
+#define TRIZEPS_PHYS_VCI4_1_SEMA   (TRIZEPS_PHYS_IO_BASE  + TRIZEPS_OFFSET_VCI4_1_SEMA)
+#define TRIZEPS_PHYS_VCI4_2_SEMA   (TRIZEPS_PHYS_IO_BASE  + TRIZEPS_OFFSET_VCI4_2_SEMA)
+#define TRIZEPS_PHYS_VCI4_1_CNTR   (TRIZEPS_PHYS_IO_BASE  + TRIZEPS_OFFSET_VCI4_1_CNTR)
+#define TRIZEPS_PHYS_VCI4_2_CNTR   (TRIZEPS_PHYS_IO_BASE  + TRIZEPS_OFFSET_VCI4_2_CNTR)
+
+#define TRIZEPS_KP_REG               (TRIZEPS_IO_BASE  + TRIZEPS_OFFSET_KP_REG)
+
+// VCI address
+#define TRIZEPS_VCI2_1_DPR           (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR)
+#define TRIZEPS_VCI2_2_DPR           (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR)
+#define TRIZEPS_VCI2_1_SEMA          (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA)
+#define TRIZEPS_VCI2_2_SEMA          (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA)
+
+// VCI4 address
+#define TRIZEPS_VCI4_1_DPR           (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR)
+#define TRIZEPS_VCI4_2_DPR           (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR)
+#define TRIZEPS_VCI4_1_SEMA          (TRIZEPS_IO_BASE  + TRIZEPS_OFFSET_VCI4_1_SEMA)
+#define TRIZEPS_VCI4_2_SEMA          (TRIZEPS_IO_BASE  + TRIZEPS_OFFSET_VCI4_2_SEMA)
+#define TRIZEPS_VCI4_1_CNTR          (TRIZEPS_IO_BASE  + TRIZEPS_OFFSET_VCI4_1_CNTR)
+#define TRIZEPS_VCI4_2_CNTR          (TRIZEPS_IO_BASE  + TRIZEPS_OFFSET_VCI4_2_CNTR)
+
+#endif
diff -Nru a/include/asm-arm/arch-sa1100/trizeps.h b/include/asm-arm/arch-sa1100/trizeps.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/arch-sa1100/trizeps.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-arm/arch-sa1100/trizeps.h
+ *
+ * This file contains the hardware specific definitions for Trizeps
+ *
+ * Authors:
+ * Andreas Hofer <ho@dsa-ac.de>,
+ * Peter Lueg <pl@dsa-ac.de>,
+ * Guennadi Liakhovetski <gl@dsa-ac.de>
+ *
+ */
+
+#ifndef _ASM_ARCH_TRIZEPS_H_
+#define _ASM_ARCH_TRIZEPS_H_
+
+#ifdef CONFIG_TRIZEPS_MFTB2
+#include "mftb2.h"
+#endif
+
+#endif // _INCLUDE_TRIZEPS_
diff -Nru a/include/asm-arm/bug.h b/include/asm-arm/bug.h
--- a/include/asm-arm/bug.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-arm/bug.h	Mon Feb 10 10:39:23 2003
@@ -18,3 +18,4 @@
 
 #endif
 
+#endif
diff -Nru a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
--- a/include/asm-arm/ecard.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-arm/ecard.h	Mon Feb 10 10:39:31 2003
@@ -130,6 +130,20 @@
 	int  (*fiqpending)(ecard_t *ec);
 } expansioncard_ops_t;
 
+#define ECARD_NUM_RESOURCES	(6)
+
+#define ECARD_RES_IOCSLOW	(0)
+#define ECARD_RES_IOCMEDIUM	(1)
+#define ECARD_RES_IOCFAST	(2)
+#define ECARD_RES_IOCSYNC	(3)
+#define ECARD_RES_MEMC		(4)
+#define ECARD_RES_EASI		(5)
+
+#define ecard_resource_start(ec,nr)	((ec)->resource[nr].start)
+#define ecard_resource_end(ec,nr)	((ec)->resource[nr].end)
+#define ecard_resource_len(ec,nr)	((ec)->resource[nr].end - \
+					 (ec)->resource[nr].start + 1)
+
 /*
  * This contains all the info needed on an expansion card
  */
@@ -137,6 +151,7 @@
 	struct expansion_card  *next;
 
 	struct device		dev;
+	struct resource		resource[ECARD_NUM_RESOURCES];
 
 	/* Public data */
 	volatile unsigned char *irqaddr;	/* address of IRQ register	*/
@@ -147,7 +162,7 @@
 
 	void			*irq_data;	/* Data for use for IRQ by card	*/
 	void			*fiq_data;	/* Data for use for FIQ by card	*/
-	expansioncard_ops_t	*ops;		/* Enable/Disable Ops for card	*/
+	const expansioncard_ops_t *ops;		/* Enable/Disable Ops for card	*/
 
 	CONST unsigned int	slot_no;	/* Slot number			*/
 	CONST unsigned int	dma;		/* DMA number (for request_dma)	*/
diff -Nru a/include/asm-arm/io.h b/include/asm-arm/io.h
--- a/include/asm-arm/io.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-arm/io.h	Mon Feb 10 10:39:24 2003
@@ -150,9 +150,17 @@
 #define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
 #define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
 
+#define readsb(p,d,l)		__raw_readsb((unsigned int)__mem_pci(p),d,l)
+#define readsw(p,d,l)		__raw_readsw((unsigned int)__mem_pci(p),d,l)
+#define readsl(p,d,l)		__raw_readsl((unsigned int)__mem_pci(p),d,l)
+
 #define writeb(v,c)		__raw_writeb(v,__mem_pci(c))
 #define writew(v,c)		__raw_writew(cpu_to_le16(v),__mem_pci(c))
 #define writel(v,c)		__raw_writel(cpu_to_le32(v),__mem_pci(c))
+
+#define writesb(p,d,l)		__raw_writesb((unsigned int)__mem_pci(p),d,l)
+#define writesw(p,d,l)		__raw_writesw((unsigned int)__mem_pci(p),d,l)
+#define writesl(p,d,l)		__raw_writesl((unsigned int)__mem_pci(p),d,l)
 
 #define memset_io(c,v,l)	_memset_io(__mem_pci(c),(v),(l))
 #define memcpy_fromio(a,c,l)	_memcpy_fromio((a),__mem_pci(c),(l))
diff -Nru a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h
--- a/include/asm-arm/mach/irq.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-arm/mach/irq.h	Mon Feb 10 10:39:24 2003
@@ -50,8 +50,8 @@
 	irq_handler_t	handle;
 	struct irqchip	*chip;
 	struct irqaction *action;
+	unsigned int	disable_depth;
 
-	unsigned int	enabled  : 1;		/* IRQ is currently enabled   */
 	unsigned int	triggered: 1;		/* IRQ has occurred	      */
 	unsigned int	running  : 1;		/* IRQ is running             */
 	unsigned int	pending  : 1;		/* IRQ is pending	      */
@@ -59,8 +59,7 @@
 	unsigned int	probe_ok : 1;		/* IRQ can be used for probe  */
 	unsigned int	valid    : 1;		/* IRQ claimable	      */
 	unsigned int	noautoenable : 1;	/* don't automatically enable IRQ */
-	unsigned int	unused   :23;
-	unsigned int	depth;			/* disable depth	      */
+	unsigned int	unused   :25;
 
 	/*
 	 * IRQ lock detection
diff -Nru a/include/asm-arm/module.h b/include/asm-arm/module.h
--- a/include/asm-arm/module.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-arm/module.h	Mon Feb 10 10:39:29 2003
@@ -10,4 +10,9 @@
 #define Elf_Sym		Elf32_Sym
 #define Elf_Ehdr	Elf32_Ehdr
 
+/*
+ * Include the ARM architecture version.
+ */
+#define MODULE_ARCH_VERMAGIC	"ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+
 #endif /* _ASM_ARM_MODULE_H */
diff -Nru a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h
--- a/include/asm-arm/proc-armv/processor.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-arm/proc-armv/processor.h	Mon Feb 10 10:39:33 2003
@@ -23,7 +23,7 @@
 #define KERNEL_STACK_SIZE	PAGE_SIZE
 
 #define INIT_EXTRA_THREAD_INFO						\
-	cpu_domain:	  domain_val(DOMAIN_USER, DOMAIN_CLIENT) |	\
+	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_CLIENT) |	\
 			  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |	\
 			  domain_val(DOMAIN_IO, DOMAIN_CLIENT)
 
@@ -45,7 +45,7 @@
 	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
 })
 
-#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
-#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)))[1017])
+#define KSTK_EIP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
+#define KSTK_ESP(tsk)	(((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017])
 
 #endif
diff -Nru a/include/asm-arm/signal.h b/include/asm-arm/signal.h
--- a/include/asm-arm/signal.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-arm/signal.h	Mon Feb 10 10:39:27 2003
@@ -90,7 +90,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_THIRTYTWO	0x02000000
 #define SA_RESTORER	0x04000000
diff -Nru a/include/asm-cris/io.h b/include/asm-cris/io.h
--- a/include/asm-cris/io.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-cris/io.h	Mon Feb 10 10:39:30 2003
@@ -246,7 +246,7 @@
 
 #define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void *)(b),(c),(d))
 
-/* The following is junk needed for the arch-independant code but which
+/* The following is junk needed for the arch-independent code but which
  * we never use in the CRIS port
  */
 
diff -Nru a/include/asm-cris/signal.h b/include/asm-cris/signal.h
--- a/include/asm-cris/signal.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-cris/signal.h	Mon Feb 10 10:39:31 2003
@@ -86,7 +86,7 @@
  */
 
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-generic/rmap.h b/include/asm-generic/rmap.h
--- a/include/asm-generic/rmap.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-generic/rmap.h	Mon Feb 10 10:39:29 2003
@@ -3,7 +3,7 @@
 /*
  * linux/include/asm-generic/rmap.h
  *
- * Architecture dependant parts of the reverse mapping code,
+ * Architecture dependent parts of the reverse mapping code,
  * this version should work for most architectures with a
  * 'normal' page table layout.
  *
diff -Nru a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
--- a/include/asm-generic/rtc.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-generic/rtc.h	Mon Feb 10 10:39:26 2003
@@ -147,7 +147,7 @@
 		yrs = 73;
 	}
 #endif
-	/* These limits and adjustments are independant of
+	/* These limits and adjustments are independent of
 	 * whether the chip is in binary mode or not.
 	 */
 	if (yrs > 169) {
diff -Nru a/include/asm-generic/topology.h b/include/asm-generic/topology.h
--- a/include/asm-generic/topology.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-generic/topology.h	Mon Feb 10 10:39:23 2003
@@ -29,23 +29,23 @@
 
 /* Other architectures wishing to use this simple topology API should fill
    in the below functions as appropriate in their own <asm/topology.h> file. */
-#ifndef __cpu_to_node
-#define __cpu_to_node(cpu)		(0)
+#ifndef cpu_to_node
+#define cpu_to_node(cpu)	(0)
 #endif
-#ifndef __memblk_to_node
-#define __memblk_to_node(memblk)	(0)
+#ifndef memblk_to_node
+#define memblk_to_node(memblk)	(0)
 #endif
-#ifndef __parent_node
-#define __parent_node(node)		(0)
+#ifndef parent_node
+#define parent_node(node)	(0)
 #endif
-#ifndef __node_to_first_cpu
-#define __node_to_first_cpu(node)	(0)
+#ifndef node_to_cpumask
+#define node_to_cpumask(node)	(cpu_online_map)
 #endif
-#ifndef __node_to_cpu_mask
-#define __node_to_cpu_mask(node)	(cpu_online_map)
+#ifndef node_to_first_cpu
+#define node_to_first_cpu(node)	(0)
 #endif
-#ifndef __node_to_memblk
-#define __node_to_memblk(node)		(0)
+#ifndef node_to_memblk
+#define node_to_memblk(node)	(0)
 #endif
 
 /* Cross-node load balancing interval. */
diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-generic/vmlinux.lds.h	Mon Feb 10 10:39:23 2003
@@ -13,18 +13,32 @@
 	}								\
 									\
 	/* Kernel symbol table: Normal symbols */			\
-	__start___ksymtab = .;						\
 	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
+		__start___ksymtab = .;					\
 		*(__ksymtab)						\
+		__stop___ksymtab = .;					\
 	}								\
-	__stop___ksymtab = .;						\
 									\
 	/* Kernel symbol table: GPL-only symbols */			\
-	__start___gpl_ksymtab = .;					\
-	__gpl_ksymtab     : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) {	\
-		*(__gpl_ksymtab)					\
+	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\
+		__start___ksymtab_gpl = .;				\
+		*(__ksymtab_gpl)					\
+		__stop___ksymtab_gpl = .;				\
+	}								\
+									\
+	/* Kernel symbol table: Normal symbols */			\
+	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {		\
+		__start___kcrctab = .;					\
+		*(__kcrctab)						\
+		__stop___kcrctab = .;					\
+	}								\
+									\
+	/* Kernel symbol table: GPL-only symbols */			\
+	__kcrctab_gpl     : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) {	\
+		__start___kcrctab_gpl = .;				\
+		*(__kcrctab_gpl)					\
+		__stop___kcrctab_gpl = .;				\
 	}								\
-	__stop___gpl_ksymtab = .;					\
 									\
 	/* Kernel symbol table: strings */				\
         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
--- a/include/asm-i386/apicdef.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-i386/apicdef.h	Mon Feb 10 10:39:27 2003
@@ -115,7 +115,7 @@
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
-#ifdef CONFIG_X86_NUMA
+#ifdef CONFIG_NUMA
  #define MAX_IO_APICS 32
 #else
  #define MAX_IO_APICS 8
diff -Nru a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
--- a/include/asm-i386/cpu.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-i386/cpu.h	Mon Feb 10 10:39:29 2003
@@ -17,7 +17,7 @@
 	struct node *parent = NULL;
 	
 #ifdef CONFIG_NUMA
-	parent = &node_devices[__cpu_to_node(num)].node;
+	parent = &node_devices[cpu_to_node(num)].node;
 #endif /* CONFIG_NUMA */
 
 	return register_cpu(&cpu_devices[num].cpu, num, parent);
diff -Nru a/include/asm-i386/edd.h b/include/asm-i386/edd.h
--- a/include/asm-i386/edd.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-i386/edd.h	Mon Feb 10 10:39:23 2003
@@ -165,7 +165,7 @@
 	struct edd_device_params params;
 } __attribute__ ((packed));
 
-extern struct edd_info edd[EDDNR];
+extern struct edd_info edd[EDDMAXNR];
 extern unsigned char eddnr;
 #endif				/*!__ASSEMBLY__ */
 
diff -Nru a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h
--- a/include/asm-i386/kmap_types.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-i386/kmap_types.h	Mon Feb 10 10:39:30 2003
@@ -22,8 +22,8 @@
 D(9)	KM_PTE2,
 D(10)	KM_IRQ0,
 D(11)	KM_IRQ1,
-D(12)	KM_CRYPTO_USER,
-D(13)	KM_CRYPTO_SOFTIRQ,
+D(12)	KM_SOFTIRQ0,
+D(13)	KM_SOFTIRQ1,
 D(14)	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-i386/memblk.h b/include/asm-i386/memblk.h
--- a/include/asm-i386/memblk.h	Mon Feb 10 10:39:28 2003
+++ b/include/asm-i386/memblk.h	Mon Feb 10 10:39:28 2003
@@ -14,7 +14,7 @@
 extern struct i386_memblk memblk_devices[MAX_NR_MEMBLKS];
 
 static inline int arch_register_memblk(int num){
-	int p_node = __memblk_to_node(num);
+	int p_node = memblk_to_node(num);
 
 	return register_memblk(&memblk_devices[num].memblk, num, 
 				&node_devices[p_node].node);
diff -Nru a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
--- a/include/asm-i386/mmzone.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-i386/mmzone.h	Mon Feb 10 10:39:27 2003
@@ -57,25 +57,47 @@
 
 #define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)       (NODE_DATA(nid)->node_start_pfn + \
-				 NODE_DATA(nid)->node_size)
+#define node_end_pfn(nid)						\
+({									\
+	pg_data_t *__pgdat = NODE_DATA(nid);				\
+	__pgdat->node_start_pfn + __pgdat->node_size;			\
+})
 
-#define local_mapnr(kvaddr) \
-	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
+#define local_mapnr(kvaddr)						\
+({									\
+	unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
+	(__pfn - node_start_pfn(pfn_to_nid(__pfn)));			\
+})
 
-#define kern_addr_valid(kaddr)	test_bit(local_mapnr(kaddr), \
-		 NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)
+#define kern_addr_valid(kaddr)						\
+({									\
+	unsigned long __kaddr = (unsigned long)(kaddr);			\
+	pg_data_t *__pgdat = NODE_DATA(kvaddr_to_nid(__kaddr));		\
+	test_bit(local_mapnr(__kaddr), __pgdat->valid_addr_bitmap);	\
+})
 
-#define pfn_to_page(pfn)	(node_mem_map(pfn_to_nid(pfn)) + node_localnr(pfn, pfn_to_nid(pfn)))
-#define page_to_pfn(page)	((page - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
+#define pfn_to_page(pfn)						\
+({									\
+	unsigned long __pfn = pfn;					\
+	int __node  = pfn_to_nid(__pfn);				\
+	&node_mem_map(__node)[node_localnr(__pfn,__node)];		\
+})
+
+#define page_to_pfn(pg)							\
+({									\
+	struct page *__page = pg;					\
+	struct zone *__zone = page_zone(__page);			\
+	(unsigned long)(__page - __zone->zone_mem_map)			\
+		+ __zone->zone_start_pfn;				\
+})
 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
 /*
  * pfn_valid should be made as fast as possible, and the current definition 
  * is valid for machines that are NUMA, but still contiguous, which is what
  * is currently supported. A more generalised, but slower definition would
  * be something like this - mbligh:
- * ( pfn_to_pgdat(pfn) && (pfn < node_end_pfn(pfn_to_nid(pfn))) ) 
+ * ( pfn_to_pgdat(pfn) && ((pfn) < node_end_pfn(pfn_to_nid(pfn))) ) 
  */ 
-#define pfn_valid(pfn)          (pfn < num_physpages)
+#define pfn_valid(pfn)          ((pfn) < num_physpages)
 #endif /* CONFIG_DISCONTIGMEM */
 #endif /* _ASM_MMZONE_H_ */
diff -Nru a/include/asm-i386/node.h b/include/asm-i386/node.h
--- a/include/asm-i386/node.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-i386/node.h	Mon Feb 10 10:39:24 2003
@@ -13,7 +13,7 @@
 extern struct i386_node node_devices[MAX_NUMNODES];
 
 static inline int arch_register_node(int num){
-	int p_node = __parent_node(num);
+	int p_node = parent_node(num);
 	struct node *parent = NULL;
 
 	if (p_node != num)
diff -Nru a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h
--- a/include/asm-i386/pgalloc.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-i386/pgalloc.h	Mon Feb 10 10:39:23 2003
@@ -20,11 +20,11 @@
  * Allocate and free page tables.
  */
 
-extern pgd_t *pgd_alloc(struct mm_struct *);
-extern void pgd_free(pgd_t *pgd);
+pgd_t *pgd_alloc(struct mm_struct *);
+void pgd_free(pgd_t *pgd);
 
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
-extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
+pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+struct page *pte_alloc_one(struct mm_struct *, unsigned long);
 
 static inline void pte_free_kernel(pte_t *pte)
 {
diff -Nru a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
--- a/include/asm-i386/pgtable-3level.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-i386/pgtable-3level.h	Mon Feb 10 10:39:31 2003
@@ -89,8 +89,17 @@
 }
 
 #define pte_page(x)	pfn_to_page(pte_pfn(x))
-#define pte_none(x)	(!(x).pte_low && !(x).pte_high)
-#define pte_pfn(x)	(((x).pte_low >> PAGE_SHIFT) | ((x).pte_high << (32 - PAGE_SHIFT)))
+
+static inline int pte_none(pte_t pte)
+{
+	return !pte.pte_low && !pte.pte_high;
+}
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+	return (pte.pte_low >> PAGE_SHIFT) |
+		(pte.pte_high << (32 - PAGE_SHIFT));
+}
 
 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 {
@@ -105,7 +114,5 @@
 {
 	return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
 }
-
-extern struct kmem_cache_s *pae_pgd_cachep;
 
 #endif /* _I386_PGTABLE_3LEVEL_H */
diff -Nru a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
--- a/include/asm-i386/pgtable.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-i386/pgtable.h	Mon Feb 10 10:39:30 2003
@@ -41,22 +41,13 @@
 #ifndef __ASSEMBLY__
 #if CONFIG_X86_PAE
 # include <asm/pgtable-3level.h>
-
-/*
- * Need to initialise the X86 PAE caches
- */
-extern void pgtable_cache_init(void);
-
 #else
 # include <asm/pgtable-2level.h>
+#endif
 
-/*
- * No page table caches to initialise
- */
-#define pgtable_cache_init()	do { } while (0)
+void pgtable_cache_init(void);
 
 #endif
-#endif
 
 #define __beep() asm("movb $0x3,%al; outb %al,$0x61")
 
@@ -242,7 +233,7 @@
 	((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
 
 /* to find an entry in a page-table-directory. */
-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 
 #define __pgd_offset(address) pgd_index(address)
 
diff -Nru a/include/asm-i386/signal.h b/include/asm-i386/signal.h
--- a/include/asm-i386/signal.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-i386/signal.h	Mon Feb 10 10:39:24 2003
@@ -86,7 +86,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-i386/topology.h b/include/asm-i386/topology.h
--- a/include/asm-i386/topology.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-i386/topology.h	Mon Feb 10 10:39:24 2003
@@ -34,32 +34,32 @@
 extern volatile int cpu_2_node[];
 
 /* Returns the number of the node containing CPU 'cpu' */
-static inline int __cpu_to_node(int cpu)
+static inline int cpu_to_node(int cpu)
 { 
 	return cpu_2_node[cpu];
 }
 
 /* Returns the number of the node containing MemBlk 'memblk' */
-#define __memblk_to_node(memblk) (memblk)
+#define memblk_to_node(memblk) (memblk)
 
 /* Returns the number of the node containing Node 'node'.  This architecture is flat, 
    so it is a pretty simple function! */
-#define __parent_node(node) (node)
+#define parent_node(node) (node)
 
 /* Returns a bitmask of CPUs on Node 'node'. */
-static inline unsigned long __node_to_cpu_mask(int node)
+static inline unsigned long node_to_cpumask(int node)
 {
 	return node_2_cpu_mask[node];
 }
 
 /* Returns the number of the first CPU on Node 'node'. */
-static inline int __node_to_first_cpu(int node)
+static inline int node_to_first_cpu(int node)
 { 
-	return __ffs(__node_to_cpu_mask(node));
+	return __ffs(node_to_cpumask(node));
 }
 
 /* Returns the number of the first MemBlk on Node 'node' */
-#define __node_to_memblk(node) (node)
+#define node_to_memblk(node) (node)
 
 /* Cross-node load balancing interval. */
 #define NODE_BALANCE_RATE 100
diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-i386/unistd.h	Mon Feb 10 10:39:29 2003
@@ -255,6 +255,8 @@
 #define __NR_io_getevents	247
 #define __NR_io_submit		248
 #define __NR_io_cancel		249
+#define __NR_fadvise64		250
+
 #define __NR_exit_group		252
 #define __NR_lookup_dcookie	253
 #define __NR_epoll_create	254
diff -Nru a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h
--- a/include/asm-ia64/asmmacro.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-ia64/asmmacro.h	Mon Feb 10 10:39:24 2003
@@ -2,15 +2,22 @@
 #define _ASM_IA64_ASMMACRO_H
 
 /*
- * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/config.h>
+
 #define ENTRY(name)				\
 	.align 32;				\
 	.proc name;				\
 name:
 
+#define ENTRY_MIN_ALIGN(name)			\
+	.align 16;				\
+	.proc name;				\
+name:
+
 #define GLOBAL_ENTRY(name)			\
 	.global name;				\
 	ENTRY(name)
@@ -37,19 +44,40 @@
 	.previous
 
 #if __GNUC__ >= 3
-# define EX(y,x...)					\
-	.xdata4 "__ex_table", @gprel(99f), @gprel(y);	\
+# define EX(y,x...)				\
+	.xdata4 "__ex_table", 99f-., y-.;	\
   [99:]	x
-# define EXCLR(y,x...)					\
-	.xdata4 "__ex_table", @gprel(99f), @gprel(y)+4;	\
+# define EXCLR(y,x...)				\
+	.xdata4 "__ex_table", 99f-., y-.+4;	\
   [99:]	x
 #else
-# define EX(y,x...)					\
-	.xdata4 "__ex_table", @gprel(99f), @gprel(y);	\
+# define EX(y,x...)				\
+	.xdata4 "__ex_table", 99f-., y-.;	\
   99:	x
-# define EXCLR(y,x...)					\
-	.xdata4 "__ex_table", @gprel(99f), @gprel(y)+4;	\
+# define EXCLR(y,x...)				\
+	.xdata4 "__ex_table", 99f-., y-.+4;	\
   99:	x
+#endif
+
+/*
+ * For now, we always put in the McKinley E9 workaround.  On CPUs that don't need it,
+ * we'll patch out the work-around bundles with NOPs, so their impact is minimal.
+ */
+#define DO_MCKINLEY_E9_WORKAROUND
+#ifdef DO_MCKINLEY_E9_WORKAROUND
+	.section "__mckinley_e9_bundles", "a"
+	.previous
+/* workaround for Itanium 2 Errata 9: */
+# define MCKINLEY_E9_WORKAROUND			\
+	.xdata4 "__mckinley_e9_bundles", 1f-.;	\
+1:{ .mib;					\
+	nop.m 0;				\
+	nop.i 0;				\
+	br.call.sptk.many b7=1f;;		\
+  };						\
+1:
+#else
+# define MCKINLEY_E9_WORKAROUND
 #endif
 
 #endif /* _ASM_IA64_ASMMACRO_H */
diff -Nru a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
--- a/include/asm-ia64/bitops.h	Mon Feb 10 10:39:32 2003
+++ b/include/asm-ia64/bitops.h	Mon Feb 10 10:39:32 2003
@@ -2,7 +2,7 @@
 #define _ASM_IA64_BITOPS_H
 
 /*
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 02/06/02 find_next_bit() and find_first_bit() added from Erich Focht's ia64 O(1)
@@ -320,7 +320,7 @@
 static inline unsigned long
 ia64_fls (unsigned long x)
 {
-	double d = x;
+	long double d = x;
 	long exp;
 
 	__asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
diff -Nru a/include/asm-ia64/bugs.h b/include/asm-ia64/bugs.h
--- a/include/asm-ia64/bugs.h	Mon Feb 10 10:39:32 2003
+++ b/include/asm-ia64/bugs.h	Mon Feb 10 10:39:32 2003
@@ -4,16 +4,14 @@
  * Needs:
  *	void check_bugs(void);
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
+#ifndef _ASM_IA64_BUGS_H
+#define _ASM_IA64_BUGS_H
 
 #include <asm/processor.h>
 
-/*
- * I don't know of any ia-64 bugs yet..
- */
-static void
-check_bugs (void)
-{
-}
+extern void check_bugs (void);
+
+#endif /* _ASM_IA64_BUGS_H */
diff -Nru a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
--- a/include/asm-ia64/compat.h	Mon Feb 10 10:39:32 2003
+++ b/include/asm-ia64/compat.h	Mon Feb 10 10:39:32 2003
@@ -14,11 +14,18 @@
 typedef s32		compat_pid_t;
 typedef u16		compat_uid_t;
 typedef u16		compat_gid_t;
+typedef u32		compat_uid32_t;
+typedef u32		compat_gid32_t;
 typedef u16		compat_mode_t;
 typedef u32		compat_ino_t;
 typedef u16		compat_dev_t;
 typedef s32		compat_off_t;
+typedef s64		compat_loff_t;
 typedef u16		compat_nlink_t;
+typedef u16		compat_ipc_pid_t;
+typedef s32		compat_daddr_t;
+typedef u32		compat_caddr_t;
+typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_timespec {
 	compat_time_t	tv_sec;
@@ -54,11 +61,31 @@
 };
 
 struct compat_flock {
-       short		l_type;
-       short		l_whence;
-       compat_off_t	l_start;
-       compat_off_t	l_len;
-       compat_pid_t	l_pid;
+	short		l_type;
+	short		l_whence;
+	compat_off_t	l_start;
+	compat_off_t	l_len;
+	compat_pid_t	l_pid;
 };
+
+struct compat_statfs {
+	int		f_type;
+	int		f_bsize;
+	int		f_blocks;
+	int		f_bfree;
+	int		f_bavail;
+	int		f_files;
+	int		f_ffree;
+	compat_fsid_t	f_fsid;
+	int		f_namelen;	/* SunOS ignores this field. */
+	int		f_spare[6];
+};
+
+typedef u32		compat_old_sigset_t;	/* at least 32 bits */
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32		compat_sigset_word;
 
 #endif /* _ASM_IA64_COMPAT_H */
diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
--- a/include/asm-ia64/elf.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-ia64/elf.h	Mon Feb 10 10:39:29 2003
@@ -4,10 +4,12 @@
 /*
  * ELF-specific definitions.
  *
- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
+ * Copyright (C) 1998-1999, 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/config.h>
+
 #include <asm/fpu.h>
 #include <asm/page.h>
 
@@ -88,6 +90,11 @@
    relevant until we have real hardware to play with... */
 #define ELF_PLATFORM	0
 
+/*
+ * This should go into linux/elf.h...
+ */
+#define AT_SYSINFO	32
+
 #ifdef __KERNEL__
 struct elf64_hdr;
 extern void ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter);
@@ -99,7 +106,14 @@
 #define ELF_CORE_COPY_TASK_REGS(tsk, elf_gregs) dump_task_regs(tsk, elf_gregs)
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 
-
+#ifdef CONFIG_FSYS
+#define ARCH_DLINFO									\
+do {											\
+	extern char syscall_via_epc[], __start_gate_section[];				\
+	NEW_AUX_ENT(AT_SYSINFO, GATE_ADDR + (syscall_via_epc - __start_gate_section));	\
+} while (0)
 #endif
+
+#endif /* __KERNEL__ */
 
 #endif /* _ASM_IA64_ELF_H */
diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h
--- a/include/asm-ia64/ia32.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-ia64/ia32.h	Mon Feb 10 10:39:33 2003
@@ -12,17 +12,6 @@
  * 32 bit structures for IA32 support.
  */
 
-/* 32bit compatibility types */
-typedef unsigned short	__kernel_ipc_pid_t32;
-typedef unsigned int	__kernel_uid32_t32;
-typedef unsigned int	__kernel_gid32_t32;
-typedef unsigned short	__kernel_umode_t32;
-typedef short		__kernel_nlink_t32;
-typedef int		__kernel_daddr_t32;
-typedef unsigned int	__kernel_caddr_t32;
-typedef long		__kernel_loff_t32;
-typedef __kernel_fsid_t	__kernel_fsid_t32;
-
 #define IA32_PAGE_SHIFT		12	/* 4KB pages */
 #define IA32_PAGE_SIZE		(1UL << IA32_PAGE_SHIFT)
 #define IA32_PAGE_MASK		(~(IA32_PAGE_SIZE - 1))
@@ -143,10 +132,6 @@
 };
 
 /* signal.h */
-#define _IA32_NSIG	       64
-#define _IA32_NSIG_BPW	       32
-#define _IA32_NSIG_WORDS	       (_IA32_NSIG / _IA32_NSIG_BPW)
-
 #define IA32_SET_SA_HANDLER(ka,handler,restorer)				\
 				((ka)->sa.sa_handler = (__sighandler_t)		\
 					(((unsigned long)(restorer) << 32)	\
@@ -154,23 +139,17 @@
 #define IA32_SA_HANDLER(ka)	((unsigned long) (ka)->sa.sa_handler & 0xffffffff)
 #define IA32_SA_RESTORER(ka)	((unsigned long) (ka)->sa.sa_handler >> 32)
 
-typedef struct {
-       unsigned int sig[_IA32_NSIG_WORDS];
-} sigset32_t;
-
 struct sigaction32 {
        unsigned int sa_handler;		/* Really a pointer, but need to deal with 32 bits */
        unsigned int sa_flags;
        unsigned int sa_restorer;	/* Another 32 bit pointer */
-       sigset32_t sa_mask;		/* A 32 bit mask */
+       compat_sigset_t sa_mask;		/* A 32 bit mask */
 };
 
-typedef unsigned int old_sigset32_t;	/* at least 32 bits */
-
 struct old_sigaction32 {
        unsigned int  sa_handler;	/* Really a pointer, but need to deal
 					     with 32 bits */
-       old_sigset32_t sa_mask;		/* A 32 bit mask */
+       compat_old_sigset_t sa_mask;		/* A 32 bit mask */
        unsigned int sa_flags;
        unsigned int sa_restorer;	/* Another 32 bit pointer */
 };
@@ -212,19 +191,6 @@
 	unsigned int	st_ctime_nsec;
 	unsigned int	st_ino_lo;
 	unsigned int	st_ino_hi;
-};
-
-struct statfs32 {
-       int f_type;
-       int f_bsize;
-       int f_blocks;
-       int f_bfree;
-       int f_bavail;
-       int f_files;
-       int f_ffree;
-       __kernel_fsid_t32 f_fsid;
-       int f_namelen;  /* SunOS ignores this field. */
-       int f_spare[6];
 };
 
 typedef union sigval32 {
diff -Nru a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h
--- a/include/asm-ia64/intrinsics.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-ia64/intrinsics.h	Mon Feb 10 10:39:27 2003
@@ -4,9 +4,11 @@
 /*
  * Compiler-dependent intrinsics.
  *
- * Copyright (C) 2002 Hewlett-Packard Co
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
+
+#include <linux/config.h>
 
 /*
  * Force an unresolved reference if someone tries to use
diff -Nru a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h
--- a/include/asm-ia64/kmap_types.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-ia64/kmap_types.h	Mon Feb 10 10:39:27 2003
@@ -21,8 +21,8 @@
 D(8)	KM_PTE1,
 D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
-D(11)	KM_CRYPTO_USER,
-D(12)	KM_CRYPTO_SOFTIRQ,
+D(11)	KM_SOFTIRQ0,
+D(12)	KM_SOFTIRQ1,
 D(13)	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
--- a/include/asm-ia64/mmu_context.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ia64/mmu_context.h	Mon Feb 10 10:39:23 2003
@@ -28,6 +28,36 @@
 
 #include <asm/processor.h>
 
+#define MMU_CONTEXT_DEBUG	0
+
+#if MMU_CONTEXT_DEBUG
+
+#include <ia64intrin.h>
+
+extern struct mmu_trace_entry {
+	char op;
+	u8 cpu;
+	u32 context;
+	void *mm;
+} mmu_tbuf[1024];
+
+extern volatile int mmu_tbuf_index;
+
+# define MMU_TRACE(_op,_cpu,_mm,_ctx)							\
+do {											\
+	int i = __sync_fetch_and_add(&mmu_tbuf_index, 1) % ARRAY_SIZE(mmu_tbuf);	\
+	struct mmu_trace_entry e;							\
+	e.op = (_op);									\
+	e.cpu = (_cpu);									\
+	e.mm = (_mm);									\
+	e.context = (_ctx);								\
+	mmu_tbuf[i] = e;								\
+} while (0)
+
+#else
+# define MMU_TRACE(op,cpu,mm,ctx)	do { ; } while (0)
+#endif
+
 struct ia64_ctx {
 	spinlock_t lock;
 	unsigned int next;	/* next context number to use */
@@ -91,6 +121,7 @@
 static inline int
 init_new_context (struct task_struct *p, struct mm_struct *mm)
 {
+	MMU_TRACE('N', smp_processor_id(), mm, 0);
 	mm->context = 0;
 	return 0;
 }
@@ -99,6 +130,7 @@
 destroy_context (struct mm_struct *mm)
 {
 	/* Nothing to do.  */
+	MMU_TRACE('D', smp_processor_id(), mm, mm->context);
 }
 
 static inline void
@@ -138,12 +170,17 @@
 
 	do {
 		context = get_mmu_context(mm);
+		MMU_TRACE('A', smp_processor_id(), mm, context);
 		reload_context(context);
+		MMU_TRACE('a', smp_processor_id(), mm, context);
 		/* in the unlikely event of a TLB-flush by another thread, redo the load: */
 	} while (unlikely(context != mm->context));
 }
 
-#define deactivate_mm(tsk,mm)	do { } while (0)
+#define deactivate_mm(tsk,mm)					\
+do {								\
+	MMU_TRACE('d', smp_processor_id(), mm, mm->context);	\
+} while (0)
 
 /*
  * Switch from address space PREV to address space NEXT.
diff -Nru a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h
--- a/include/asm-ia64/perfmon.h	Mon Feb 10 10:39:28 2003
+++ b/include/asm-ia64/perfmon.h	Mon Feb 10 10:39:28 2003
@@ -40,6 +40,7 @@
 #define PFM_FL_INHERIT_ALL	 0x02	/* always clone pfm_context across fork() */
 #define PFM_FL_NOTIFY_BLOCK    	 0x04	/* block task on user level notifications */
 #define PFM_FL_SYSTEM_WIDE	 0x08	/* create a system wide context */
+#define PFM_FL_EXCL_IDLE         0x20   /* exclude idle task from system wide session */
 
 /*
  * PMC flags
@@ -86,11 +87,12 @@
 	unsigned long	reg_long_reset;	/* reset after sampling buffer overflow (large) */
 	unsigned long	reg_short_reset;/* reset after counter overflow (small) */
 
-	unsigned long	reg_reset_pmds[4]; /* which other counters to reset on overflow */
-	unsigned long	reg_random_seed;   /* seed value when randomization is used */
-	unsigned long	reg_random_mask;   /* bitmask used to limit random value */
+	unsigned long	reg_reset_pmds[4];   /* which other counters to reset on overflow */
+	unsigned long	reg_random_seed;     /* seed value when randomization is used */
+	unsigned long	reg_random_mask;     /* bitmask used to limit random value */
+	unsigned long	reg_last_reset_value;/* last value used to reset the PMD (PFM_READ_PMDS) */
 
-	unsigned long   reserved[14];	/* for future use */
+	unsigned long   reserved[13];	/* for future use */
 } pfarg_reg_t;
 
 typedef struct {
@@ -123,7 +125,7 @@
  * Define the version numbers for both perfmon as a whole and the sampling buffer format.
  */
 #define PFM_VERSION_MAJ		1U
-#define PFM_VERSION_MIN		1U
+#define PFM_VERSION_MIN		3U
 #define PFM_VERSION		(((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
 
 #define PFM_SMPL_VERSION_MAJ	1U
@@ -156,13 +158,17 @@
 	unsigned long	stamp;			/* timestamp */
 	unsigned long	ip;			/* where did the overflow interrupt happened */
 	unsigned long	regs;			/* bitmask of which registers overflowed */
-	unsigned long   period;			/* unused */
+	unsigned long   reserved;		/* unused */
 } perfmon_smpl_entry_t;
 
-extern int perfmonctl(pid_t pid, int cmd, void *arg, int narg);
+extern long perfmonctl(pid_t pid, int cmd, void *arg, int narg);
 
 #ifdef __KERNEL__
 
+typedef struct {
+	void (*handler)(int irq, void *arg, struct pt_regs *regs);
+} pfm_intr_handler_desc_t;
+
 extern void pfm_save_regs (struct task_struct *);
 extern void pfm_load_regs (struct task_struct *);
 
@@ -174,9 +180,24 @@
 extern int  pfm_use_debug_registers(struct task_struct *);
 extern int  pfm_release_debug_registers(struct task_struct *);
 extern int  pfm_cleanup_smpl_buf(struct task_struct *);
-extern void pfm_syst_wide_update_task(struct task_struct *, int);
+extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin);
 extern void pfm_ovfl_block_reset(void);
-extern void perfmon_init_percpu(void);
+extern void pfm_init_percpu(void);
+
+/* 
+ * hooks to allow VTune/Prospect to cooperate with perfmon.
+ * (reserved for system wide monitoring modules only)
+ */
+extern int pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h);
+extern int pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h);
+
+/*
+ * describe the content of the local_cpu_date->pfm_syst_info field
+ */
+#define PFM_CPUINFO_SYST_WIDE	0x1	/* if set a system wide session exist */
+#define PFM_CPUINFO_DCR_PP	0x2	/* if set the system wide session has started */
+#define PFM_CPUINFO_EXCL_IDLE	0x4	/* the system wide session excludes the idle task */
+
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
--- a/include/asm-ia64/processor.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-ia64/processor.h	Mon Feb 10 10:39:24 2003
@@ -2,7 +2,7 @@
 #define _ASM_IA64_PROCESSOR_H
 
 /*
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
@@ -223,7 +223,10 @@
 struct siginfo;
 
 struct thread_struct {
-	__u64 flags;			/* various thread flags (see IA64_THREAD_*) */
+	__u32 flags;			/* various thread flags (see IA64_THREAD_*) */
+	/* writing on_ustack is performance-critical, so it's worth spending 8 bits on it... */
+	__u8 on_ustack;			/* executing on user-stacks? */
+	__u8 pad[3];
 	__u64 ksp;			/* kernel stack pointer */
 	__u64 map_base;			/* base address for get_unmapped_area() */
 	__u64 task_size;		/* limit for task size */
@@ -277,6 +280,7 @@
 
 #define INIT_THREAD {				\
 	.flags =	0,			\
+	.on_ustack =	0,			\
 	.ksp =		0,			\
 	.map_base =	DEFAULT_MAP_BASE,	\
 	.task_size =	DEFAULT_TASK_SIZE,	\
diff -Nru a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
--- a/include/asm-ia64/ptrace.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-ia64/ptrace.h	Mon Feb 10 10:39:29 2003
@@ -2,7 +2,7 @@
 #define _ASM_IA64_PTRACE_H
 
 /*
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -218,6 +218,13 @@
 # define ia64_task_regs(t)		(((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
 # define ia64_psr(regs)			((struct ia64_psr *) &(regs)->cr_ipsr)
 # define user_mode(regs)		(((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0)
+# define user_stack(task,regs)	((long) regs - (long) task == IA64_STK_OFFSET - sizeof(*regs))
+# define fsys_mode(task,regs)					\
+  ({								\
+	  struct task_struct *_task = (task);			\
+	  struct pt_regs *_regs = (regs);			\
+	  !user_mode(_regs) && user_stack(_task, _regs);	\
+  })
 
   struct task_struct;			/* forward decl */
 
diff -Nru a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h
--- a/include/asm-ia64/signal.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ia64/signal.h	Mon Feb 10 10:39:23 2003
@@ -67,7 +67,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-ia64/sn/sv.h b/include/asm-ia64/sn/sv.h
--- a/include/asm-ia64/sn/sv.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-ia64/sn/sv.h	Mon Feb 10 10:39:24 2003
@@ -99,7 +99,7 @@
  * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals.
  *
  * timeout is how long to wait before giving up, or 0 to wait
- * indefinately.  It is given in jiffies, and is relative.
+ * indefinitely.  It is given in jiffies, and is relative.
  *
  * The associated lock must be locked on entry.  It is unlocked on return.
  *
diff -Nru a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
--- a/include/asm-ia64/spinlock.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ia64/spinlock.h	Mon Feb 10 10:39:23 2003
@@ -74,6 +74,27 @@
 #define SPIN_LOCK_UNLOCKED			(spinlock_t) { 0 }
 #define spin_lock_init(x)			((x)->lock = 0)
 
+#define DEBUG_SPIN_LOCK	0
+
+#if DEBUG_SPIN_LOCK
+
+#include <ia64intrin.h>
+
+#define _raw_spin_lock(x)								\
+do {											\
+	unsigned long _timeout = 1000000000;						\
+	volatile unsigned int _old = 0, _new = 1, *_ptr = &((x)->lock);			\
+	do {										\
+		if (_timeout-- == 0) {							\
+			extern void dump_stack (void);					\
+			printk("kernel DEADLOCK at %s:%d?\n", __FILE__, __LINE__);	\
+			dump_stack();							\
+		}									\
+	} while (__sync_val_compare_and_swap(_ptr, _old, _new) != _old);		\
+} while (0)
+
+#else
+
 /*
  * Streamlined test_and_set_bit(0, (x)).  We use test-and-test-and-set
  * rather than a simple xchg to avoid writing the cache-line when
@@ -94,6 +115,8 @@
 	"(p7) br.cond.spnt.few 1b\n"				\
 	";;\n"							\
 	:: "r"(&(x)->lock) : "ar.ccv", "p7", "r2", "r29", "memory")
+
+#endif /* !DEBUG_SPIN_LOCK */
 
 #define spin_is_locked(x)	((x)->lock != 0)
 #define _raw_spin_unlock(x)	do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0)
diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-ia64/system.h	Mon Feb 10 10:39:26 2003
@@ -7,7 +7,7 @@
  * on information published in the Processor Abstraction Layer
  * and the System Abstraction Layer manual.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
@@ -17,6 +17,7 @@
 #include <asm/kregs.h>
 #include <asm/page.h>
 #include <asm/pal.h>
+#include <asm/percpu.h>
 
 #define KERNEL_START		(PAGE_OFFSET + 68*1024*1024)
 
@@ -26,7 +27,6 @@
 
 #ifndef __ASSEMBLY__
 
-#include <linux/percpu.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
@@ -117,62 +117,51 @@
  */
 /* For spinlocks etc */
 
+/* clearing psr.i is implicitly serialized (visible by next insn) */
+/* setting psr.i requires data serialization */
+#define __local_irq_save(x)	__asm__ __volatile__ ("mov %0=psr;;"			\
+						      "rsm psr.i;;"			\
+						      : "=r" (x) :: "memory")
+#define __local_irq_disable()	__asm__ __volatile__ (";; rsm psr.i;;" ::: "memory")
+#define __local_irq_restore(x)	__asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;"		\
+						      "(p6) ssm psr.i;"			\
+						      "(p7) rsm psr.i;;"		\
+						      "(p6) srlz.d"			\
+						      :: "r" ((x) & IA64_PSR_I)		\
+						      : "p6", "p7", "memory")
+
 #ifdef CONFIG_IA64_DEBUG_IRQ
 
   extern unsigned long last_cli_ip;
 
-# define local_irq_save(x)								\
-do {											\
-	unsigned long ip, psr;								\
-											\
-	__asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory");	\
-	if (psr & (1UL << 14)) {							\
-		__asm__ ("mov %0=ip" : "=r"(ip));					\
-		last_cli_ip = ip;							\
-	}										\
-	(x) = psr;									\
-} while (0)
+# define __save_ip()		__asm__ ("mov %0=ip" : "=r" (last_cli_ip))
 
-# define local_irq_disable()								\
-do {											\
-	unsigned long ip, psr;								\
-											\
-	__asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory");	\
-	if (psr & (1UL << 14)) {							\
-		__asm__ ("mov %0=ip" : "=r"(ip));					\
-		last_cli_ip = ip;							\
-	}										\
+# define local_irq_save(x)					\
+do {								\
+	unsigned long psr;					\
+								\
+	__local_irq_save(psr);					\
+	if (psr & IA64_PSR_I)					\
+		__save_ip();					\
+	(x) = psr;						\
 } while (0)
 
-# define local_irq_restore(x)							\
-do {										\
-	unsigned long ip, old_psr, psr = (x);					\
-										\
-	__asm__ __volatile__ ("mov %0=psr;"					\
-			      "cmp.ne p6,p7=%1,r0;;"				\
-			      "(p6) ssm psr.i;"					\
-			      "(p7) rsm psr.i;;"				\
-			      "(p6) srlz.d"					\
-			      : "=r" (old_psr) : "r"((psr) & IA64_PSR_I)	\
-			      : "p6", "p7", "memory");				\
-	if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) {			\
-		__asm__ ("mov %0=ip" : "=r"(ip));				\
-		last_cli_ip = ip;						\
-	}									\
+# define local_irq_disable()	do { unsigned long x; local_irq_save(x); } while (0)
+
+# define local_irq_restore(x)					\
+do {								\
+	unsigned long old_psr, psr = (x);			\
+								\
+	local_save_flags(old_psr);				\
+	__local_irq_restore(psr);				\
+	if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I))	\
+		__save_ip();					\
 } while (0)
 
 #else /* !CONFIG_IA64_DEBUG_IRQ */
-  /* clearing of psr.i is implicitly serialized (visible by next insn) */
-# define local_irq_save(x)	__asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;"	\
-						      : "=r" (x) :: "memory")
-# define local_irq_disable()	__asm__ __volatile__ (";; rsm psr.i;;" ::: "memory")
-/* (potentially) setting psr.i requires data serialization: */
-# define local_irq_restore(x)	__asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;"	\
-						      "(p6) ssm psr.i;"		\
-						      "(p7) rsm psr.i;;"	\
-						      "srlz.d"			\
-						      :: "r"((x) & IA64_PSR_I)	\
-						      : "p6", "p7", "memory")
+# define local_irq_save(x)	__local_irq_save(x)
+# define local_irq_disable()	__local_irq_disable()
+# define local_irq_restore(x)	__local_irq_restore(x)
 #endif /* !CONFIG_IA64_DEBUG_IRQ */
 
 #define local_irq_enable()	__asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory")
@@ -216,8 +205,8 @@
 extern void ia64_load_extra (struct task_struct *task);
 
 #ifdef CONFIG_PERFMON
-  DECLARE_PER_CPU(int, pfm_syst_wide);
-# define PERFMON_IS_SYSWIDE() (get_cpu_var(pfm_syst_wide) != 0)
+  DECLARE_PER_CPU(unsigned long, pfm_syst_info);
+# define PERFMON_IS_SYSWIDE() (get_cpu_var(pfm_syst_info) & 0x1)
 #else
 # define PERFMON_IS_SYSWIDE() (0)
 #endif
diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
--- a/include/asm-ia64/tlb.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-ia64/tlb.h	Mon Feb 10 10:39:26 2003
@@ -1,7 +1,7 @@
 #ifndef _ASM_IA64_TLB_H
 #define _ASM_IA64_TLB_H
 /*
- * Copyright (C) 2002 Hewlett-Packard Co
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * This file was derived from asm-generic/tlb.h.
@@ -70,8 +70,7 @@
  * freed pages that where gathered up to this point.
  */
 static inline void
-ia64_tlb_flush_mmu(struct mmu_gather *tlb,
-		unsigned long start, unsigned long end)
+ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
 	unsigned int nr;
 
@@ -197,8 +196,7 @@
  * PTE, not just those pointing to (normal) physical memory.
  */
 static inline void
-__tlb_remove_tlb_entry(struct mmu_gather *tlb,
-			pte_t *ptep, unsigned long address)
+__tlb_remove_tlb_entry (struct mmu_gather *tlb, pte_t *ptep, unsigned long address)
 {
 	if (tlb->start_addr == ~0UL)
 		tlb->start_addr = address;
diff -Nru a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
--- a/include/asm-ia64/tlbflush.h	Mon Feb 10 10:39:32 2003
+++ b/include/asm-ia64/tlbflush.h	Mon Feb 10 10:39:32 2003
@@ -47,19 +47,22 @@
 static inline void
 flush_tlb_mm (struct mm_struct *mm)
 {
+	MMU_TRACE('F', smp_processor_id(), mm, mm->context);
 	if (!mm)
-		return;
+		goto out;
 
 	mm->context = 0;
 
 	if (atomic_read(&mm->mm_users) == 0)
-		return;		/* happens as a result of exit_mmap() */
+		goto out;		/* happens as a result of exit_mmap() */
 
 #ifdef CONFIG_SMP
 	smp_flush_tlb_mm(mm);
 #else
 	local_finish_flush_tlb_mm(mm);
 #endif
+  out:
+	MMU_TRACE('f', smp_processor_id(), mm, mm->context);
 }
 
 extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end);
diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ia64/topology.h	Mon Feb 10 10:39:23 2003
@@ -21,25 +21,25 @@
 /*
  * Returns the number of the node containing CPU 'cpu'
  */
-#define __cpu_to_node(cpu) (int)(cpu_to_node_map[cpu])
+#define cpu_to_node(cpu) (int)(cpu_to_node_map[cpu])
 
 /*
  * Returns a bitmask of CPUs on Node 'node'.
  */
-#define __node_to_cpu_mask(node) (node_to_cpu_mask[node])
+#define node_to_cpumask(node) (node_to_cpumask[node])
 
 #else
-#define __cpu_to_node(cpu) (0)
-#define __node_to_cpu_mask(node) (phys_cpu_present_map)
+#define cpu_to_node(cpu) (0)
+#define node_to_cpumask(node) (phys_cpu_present_map)
 #endif
 
 /*
  * Returns the number of the node containing MemBlk 'memblk'
  */
 #ifdef CONFIG_ACPI_NUMA
-#define __memblk_to_node(memblk) (node_memblk[memblk].nid)
+#define memblk_to_node(memblk) (node_memblk[memblk].nid)
 #else
-#define __memblk_to_node(memblk) (memblk)
+#define memblk_to_node(memblk) (memblk)
 #endif
 
 /*
@@ -47,18 +47,18 @@
  * Not implemented here. Multi-level hierarchies detected with
  * the help of node_distance().
  */
-#define __parent_node(nid) (nid)
+#define parent_node(nid) (nid)
 
 /*
  * Returns the number of the first CPU on Node 'node'.
  */
-#define __node_to_first_cpu(node) (__ffs(__node_to_cpu_mask(node)))
+#define node_to_first_cpu(node) (__ffs(node_to_cpumask(node)))
 
 /*
  * Returns the number of the first MemBlk on Node 'node'
  * Should be fixed when IA64 discontigmem goes in.
  */
-#define __node_to_memblk(node) (node)
+#define node_to_memblk(node) (node)
 
 /* Cross-node load balancing interval. */
 #define NODE_BALANCE_RATE 10
diff -Nru a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h
--- a/include/asm-ia64/uaccess.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-ia64/uaccess.h	Mon Feb 10 10:39:24 2003
@@ -26,7 +26,7 @@
  * associated and, if so, sets r8 to -EFAULT and clears r9 to 0 and
  * then resumes execution at the continuation point.
  *
- * Copyright (C) 1998, 1999, 2001-2002 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -128,38 +128,28 @@
 /* We need to declare the __ex_table section before we can use it in .xdata.  */
 asm (".section \"__ex_table\", \"a\"\n\t.previous");
 
-#if __GNUC__ >= 3
-#  define GAS_HAS_LOCAL_TAGS	/* define if gas supports local tags a la [1:] */
-#endif
-
-#ifdef GAS_HAS_LOCAL_TAGS
-# define _LL	"[1:]"
-#else
-# define _LL	"1:"
-#endif
-
 #define __get_user_64(addr)									\
-	asm ("\n"_LL"\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
-	     _LL										\
+	asm ("\n[1:]\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n"						\
+	     "[1:]"										\
 	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_32(addr)									\
-	asm ("\n"_LL"\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
-	     _LL										\
+	asm ("\n[1:]\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n"						\
+	     "[1:]"										\
 	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_16(addr)									\
-	asm ("\n"_LL"\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
-	     _LL										\
+	asm ("\n[1:]\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n"						\
+	     "[1:]"										\
 	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_8(addr)									\
-	asm ("\n"_LL"\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
-	     _LL										\
+	asm ("\n[1:]\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n"						\
+	     "[1:]"										\
 	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 extern void __put_user_unknown (void);
@@ -201,30 +191,30 @@
  */
 #define __put_user_64(x,addr)								\
 	asm volatile (									\
-		"\n"_LL"\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
-		_LL									\
+		"\n[1:]\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", 1b-., 1f-.\n"				\
+		"[1:]"									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_32(x,addr)								\
 	asm volatile (									\
-		"\n"_LL"\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
-		_LL									\
+		"\n[1:]\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", 1b-., 1f-.\n"				\
+		"[1:]"									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_16(x,addr)								\
 	asm volatile (									\
-		"\n"_LL"\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
-		_LL									\
+		"\n[1:]\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", 1b-., 1f-.\n"				\
+		"[1:]"									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_8(x,addr)								\
 	asm volatile (									\
-		"\n"_LL"\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
-		_LL									\
+		"\n[1:]\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", 1b-., 1f-.\n"				\
+		"[1:]"									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 /*
@@ -314,26 +304,22 @@
 	int cont;	/* gp-relative continuation address; if bit 2 is set, r9 is set to 0 */
 };
 
-struct exception_fixup {
-	unsigned long cont;	/* continuation point (bit 2: clear r9 if set) */
-};
-
-extern struct exception_fixup search_exception_table (unsigned long addr);
-extern void handle_exception (struct pt_regs *regs, struct exception_fixup fixup);
+extern void handle_exception (struct pt_regs *regs, const struct exception_table_entry *e);
+extern const struct exception_table_entry *search_exception_tables (unsigned long addr);
 
 #ifdef GAS_HAS_LOCAL_TAGS
-#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
+# define SEARCH_EXCEPTION_TABLE(regs) search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri)
 #else
-#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip);
+# define SEARCH_EXCEPTION_TABLE(regs) search_exception_tables(regs->cr_iip)
 #endif
 
 static inline int
 done_with_exception (struct pt_regs *regs)
 {
-	struct exception_fixup fix;
-	fix = SEARCH_EXCEPTION_TABLE(regs);
-	if (fix.cont) {
-		handle_exception(regs, fix);
+	const struct exception_table_entry *e;
+	e = SEARCH_EXCEPTION_TABLE(regs);
+	if (e) {
+		handle_exception(regs, e);
 		return 1;
 	}
 	return 0;
diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
--- a/include/asm-ia64/unistd.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ia64/unistd.h	Mon Feb 10 10:39:23 2003
@@ -4,7 +4,7 @@
 /*
  * IA-64 Linux syscall numbers and inline-functions.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -223,8 +223,8 @@
 #define __NR_sched_setaffinity		1231
 #define __NR_sched_getaffinity		1232
 #define __NR_set_tid_address		1233
-/* #define __NR_alloc_hugepages		1234 reusable */
-/* #define __NR_free_hugepages		1235 reusable */
+/* 1234 available for reuse */
+/* 1235 available for reuse */
 #define __NR_exit_group			1236
 #define __NR_lookup_dcookie		1237
 #define __NR_io_setup			1238
diff -Nru a/include/asm-m68k/mac_psc.h b/include/asm-m68k/mac_psc.h
--- a/include/asm-m68k/mac_psc.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-m68k/mac_psc.h	Mon Feb 10 10:39:24 2003
@@ -158,7 +158,7 @@
 				 *                  0x3 = CD Audio
 				 *                  0x4 = External Audio
 				 *
-				 * The volume is definately not the general
+				 * The volume is definitely not the general
 				 * output volume as it doesn't affect the
 				 * alert sound volume.
 				 */
diff -Nru a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h
--- a/include/asm-m68k/signal.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-m68k/signal.h	Mon Feb 10 10:39:24 2003
@@ -85,7 +85,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h
--- a/include/asm-m68knommu/signal.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-m68knommu/signal.h	Mon Feb 10 10:39:27 2003
@@ -85,7 +85,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h
--- a/include/asm-mips/isadep.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-mips/isadep.h	Mon Feb 10 10:39:24 2003
@@ -1,5 +1,5 @@
 /*
- * Various ISA level dependant constants.
+ * Various ISA level dependent constants.
  * Most of the following constants reflect the different layout
  * of Coprocessor 0 registers.
  *
diff -Nru a/include/asm-mips/ng1hw.h b/include/asm-mips/ng1hw.h
--- a/include/asm-mips/ng1hw.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-mips/ng1hw.h	Mon Feb 10 10:39:29 2003
@@ -1,6 +1,6 @@
 /* $Id: ng1hw.h,v 1.4 1999/08/04 06:01:51 ulfc Exp $
  * 
- * ng1hw.h: Tweaks the newport.h structures and definations to be compatible
+ * ng1hw.h: Tweaks the newport.h structures and definitions to be compatible
  * 	    with IRIX.  Quite ugly, but it works.
  *
  * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com)
diff -Nru a/include/asm-mips/signal.h b/include/asm-mips/signal.h
--- a/include/asm-mips/signal.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-mips/signal.h	Mon Feb 10 10:39:24 2003
@@ -80,7 +80,7 @@
 #define SA_RESTART	0x10000000
 #define SA_SIGINFO	0x00000008
 #define SA_NODEFER	0x40000000
-#define SA_NOCLDWAIT	0x00010000	/* Not supported yet */
+#define SA_NOCLDWAIT	0x00010000
 #define SA_NOCLDSTOP	0x00000001
 
 #define SA_NOMASK	SA_NODEFER
diff -Nru a/include/asm-mips64/r10kcache.h b/include/asm-mips64/r10kcache.h
--- a/include/asm-mips64/r10kcache.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-mips64/r10kcache.h	Mon Feb 10 10:39:31 2003
@@ -25,7 +25,7 @@
 #define ic_lsize	64
 #define dc_lsize	32
 
-/* These are configuration dependant.  */
+/* These are configuration dependent.  */
 #define scache_size()	({						\
 	unsigned long __res;						\
 	__res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3;	\
diff -Nru a/include/asm-mips64/signal.h b/include/asm-mips64/signal.h
--- a/include/asm-mips64/signal.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-mips64/signal.h	Mon Feb 10 10:39:30 2003
@@ -80,7 +80,7 @@
 #define SA_RESTART	0x10000000
 #define SA_SIGINFO	0x00000008
 #define SA_NODEFER	0x40000000
-#define SA_NOCLDWAIT	0x00010000	/* Not supported yet */
+#define SA_NOCLDWAIT	0x00010000
 #define SA_NOCLDSTOP	0x00000001
 
 #define SA_NOMASK	SA_NODEFER
diff -Nru a/include/asm-mips64/topology.h b/include/asm-mips64/topology.h
--- a/include/asm-mips64/topology.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-mips64/topology.h	Mon Feb 10 10:39:23 2003
@@ -3,6 +3,6 @@
 
 #include <asm/mmzone.h>
 
-#define __cpu_to_node(cpu)		(cputocnode(cpu))
+#define cpu_to_node(cpu)	(cputocnode(cpu))
 
 #endif /* _ASM_MIPS64_TOPOLOGY_H */
diff -Nru a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
--- a/include/asm-parisc/bitops.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-parisc/bitops.h	Mon Feb 10 10:39:23 2003
@@ -257,7 +257,14 @@
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
-
+#define hweight64(x)						\
+({								\
+	unsigned long __x = (x);				\
+	unsigned int __w;					\
+	__w = generic_hweight32((unsigned int) __x);		\
+	__w += generic_hweight32((unsigned int) (__x>>32));	\
+	__w;							\
+})
 #define hweight32(x) generic_hweight32(x)
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
diff -Nru a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
--- a/include/asm-parisc/compat.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-parisc/compat.h	Mon Feb 10 10:39:33 2003
@@ -72,4 +72,24 @@
 	compat_pid_t		l_pid;
 };
 
+struct compat_statfs {
+	s32		f_type;
+	s32		f_bsize;
+	s32		f_blocks;
+	s32		f_bfree;
+	s32		f_bavail;
+	s32		f_files;
+	s32		f_ffree;
+	__kernel_fsid_t	f_fsid;
+	s32		f_namelen;
+	s32		f_spare[6];
+};
+
+typedef u32		compat_old_sigset_t;	/* at least 32 bits */
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	BITS_PER_LONG
+
+typedef u32		compat_sigset_word;
+
 #endif /* _ASM_PARISC_COMPAT_H */
diff -Nru a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
--- a/include/asm-parisc/dma-mapping.h	Mon Feb 10 10:39:25 2003
+++ b/include/asm-parisc/dma-mapping.h	Mon Feb 10 10:39:25 2003
@@ -203,7 +203,6 @@
 struct parisc_device;
 struct ioc;
 void * ccio_get_iommu(const struct parisc_device *dev);
-struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
 int ccio_request_resource(const struct parisc_device *dev,
 		struct resource *res);
 int ccio_allocate_resource(const struct parisc_device *dev,
@@ -213,7 +212,6 @@
 		void *alignf_data);
 #else /* !CONFIG_IOMMU_CCIO */
 #define ccio_get_iommu(dev) NULL
-#define ccio_get_fake(dev) NULL
 #define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
 #define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
 		allocate_resource(&iomem_resource, res, size, min, max, \
diff -Nru a/include/asm-parisc/module.h b/include/asm-parisc/module.h
--- a/include/asm-parisc/module.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-parisc/module.h	Mon Feb 10 10:39:23 2003
@@ -7,10 +7,14 @@
 #define Elf_Shdr Elf64_Shdr
 #define Elf_Sym Elf64_Sym
 #define Elf_Ehdr Elf64_Ehdr
+#define Elf_Addr Elf64_Addr
+#define Elf_Rela Elf64_Rela
 #else
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+#define Elf_Rela Elf32_Rela
 #endif
 
 #define module_map(x)		vmalloc(x)
@@ -20,6 +24,10 @@
 
 struct mod_arch_specific
 {
+	unsigned long got_offset;
+	unsigned long fdesc_offset, fdesc_count;
+	unsigned long stub_offset;
+	unsigned long stub_count;
 };
 
 #endif /* _ASM_PARISC_MODULE_H */
diff -Nru a/include/asm-parisc/signal.h b/include/asm-parisc/signal.h
--- a/include/asm-parisc/signal.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-parisc/signal.h	Mon Feb 10 10:39:33 2003
@@ -64,7 +64,7 @@
 #define SA_SIGINFO	0x00000010
 #define SA_NODEFER	0x00000020
 #define SA_RESTART	0x00000040
-#define SA_NOCLDWAIT	0x00000080 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000080
 #define _SA_SIGGFAULT	0x00000100 /* HPUX */
 
 #define SA_NOMASK	SA_NODEFER
diff -Nru a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h
--- a/include/asm-parisc/smp.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-parisc/smp.h	Mon Feb 10 10:39:30 2003
@@ -12,6 +12,7 @@
 #define PDC_OS_BOOT_RENDEZVOUS_HI  0x28
 
 #ifndef ASSEMBLY
+#include <linux/bitops.h>
 #include <linux/threads.h>	/* for NR_CPUS */
 typedef unsigned long address_t;
 
@@ -53,7 +54,7 @@
 #define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
 
 #define cpu_possible(cpu)       (cpu_present_mask & (1<<(cpu)))
-	
+
 extern inline unsigned int num_online_cpus(void)
 {
 	return hweight32(cpu_online_map);
diff -Nru a/include/asm-ppc/io.h b/include/asm-ppc/io.h
--- a/include/asm-ppc/io.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-ppc/io.h	Mon Feb 10 10:39:31 2003
@@ -36,7 +36,7 @@
 #define _IO_BASE	isa_io_base
 #define _ISA_MEM_BASE	isa_mem_base
 #define PCI_DRAM_OFFSET	pci_dram_offset
-#endif /* Platform-dependant I/O */
+#endif /* Platform-dependent I/O */
 
 extern unsigned long isa_io_base;
 extern unsigned long isa_mem_base;
diff -Nru a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h
--- a/include/asm-ppc/kmap_types.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-ppc/kmap_types.h	Mon Feb 10 10:39:30 2003
@@ -14,8 +14,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h
--- a/include/asm-ppc/signal.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ppc/signal.h	Mon Feb 10 10:39:23 2003
@@ -78,7 +78,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-ppc/system.h b/include/asm-ppc/system.h
--- a/include/asm-ppc/system.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-ppc/system.h	Mon Feb 10 10:39:26 2003
@@ -22,7 +22,7 @@
  * mb() prevents loads and stores being reordered across this point.
  * rmb() prevents loads being reordered across this point.
  * wmb() prevents stores being reordered across this point.
- * read_barrier_depends() prevents data-dependant loads being reordered
+ * read_barrier_depends() prevents data-dependent loads being reordered
  *	across this point (nop on PPC).
  *
  * We can use the eieio instruction for wmb, but since it doesn't
diff -Nru a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
--- a/include/asm-ppc64/compat.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-ppc64/compat.h	Mon Feb 10 10:39:24 2003
@@ -77,4 +77,11 @@
 	int		f_spare[6];
 };
 
+typedef u32		compat_old_sigset_t;
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32		compat_sigset_word;
+
 #endif /* _ASM_PPC64_COMPAT_H */
diff -Nru a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
--- a/include/asm-ppc64/elf.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-ppc64/elf.h	Mon Feb 10 10:39:30 2003
@@ -86,10 +86,15 @@
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2)				\
-do {	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
-		set_thread_flag(TIF_32BIT);			\
+do {								\
+	unsigned long new_flags = 0;				\
+	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
+		new_flags = _TIF_32BIT;				\
+	if ((current_thread_info()->flags & _TIF_32BIT)		\
+	    != new_flags)					\
+		set_thread_flag(TIF_ABI_PENDING);		\
 	else							\
-		clear_thread_flag(TIF_32BIT);			\
+		clear_thread_flag(TIF_ABI_PENDING);		\
 	if (ibcs2)						\
 		set_personality(PER_SVR4);			\
 	else if (current->personality != PER_LINUX32)		\
@@ -130,5 +135,77 @@
 	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
 	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
  } while (0)
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE    R_PPC_NONE
+#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
+#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
+#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
+#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
+#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
+#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16     R_PPC_GOT16
+#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
+
+#define R_PPC64_COPY      R_PPC_COPY
+#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE  R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32   R_PPC_UADDR32
+#define R_PPC64_UADDR16   R_PPC_UADDR16
+#define R_PPC64_REL32     R_PPC_REL32
+#define R_PPC64_PLT32     R_PPC_PLT32
+#define R_PPC64_PLTREL32  R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF     R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
+#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
+#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
+#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
+#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
+#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
+#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
+#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
+#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
+#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
+#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
+#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
+#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
+#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
+#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
+#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
+#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
+
+#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
+#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
+#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
+#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
+#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
+#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
+#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
+#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
+#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
+#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
+/* Keep this the last entry.  */
+#define R_PPC64_NUM		67
 
 #endif /* __PPC64_ELF_H */
diff -Nru a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h
--- a/include/asm-ppc64/kmap_types.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-ppc64/kmap_types.h	Mon Feb 10 10:39:27 2003
@@ -14,8 +14,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,	
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,	
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
--- a/include/asm-ppc64/ppc32.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-ppc64/ppc32.h	Mon Feb 10 10:39:26 2003
@@ -94,32 +94,22 @@
 	} _sifields;
 } siginfo_t32;
 
-#define __old_sigset_t32	old_sigset_t32
 #define __old_sigaction32	old_sigaction32
 
-typedef unsigned int __old_sigset_t32;
 struct __old_sigaction32 {
 	unsigned		sa_handler;
-	__old_sigset_t32  	sa_mask;
+	compat_old_sigset_t  	sa_mask;
 	unsigned int    	sa_flags;
 	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
 };
 
 
 
-#define _PPC32_NSIG	       64
-#define _PPC32_NSIG_BPW	       32
-#define _PPC32_NSIG_WORDS	       (_PPC32_NSIG / _PPC32_NSIG_BPW)
-
-typedef struct {
-       unsigned int sig[_PPC32_NSIG_WORDS];
-} sigset32_t;
-
 struct sigaction32 {
        unsigned int  sa_handler;	/* Really a pointer, but need to deal with 32 bits */
        unsigned int sa_flags;
        unsigned int sa_restorer;	/* Another 32 bit pointer */
-       sigset32_t sa_mask;		/* A 32 bit mask */
+       compat_sigset_t sa_mask;		/* A 32 bit mask */
 };
 
 typedef struct sigaltstack_32 {
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ppc64/processor.h	Mon Feb 10 10:39:23 2003
@@ -725,17 +725,17 @@
 
 #define spin_lock_prefetch(x)	prefetchw(x)
 
-#define cpu_has_largepage()	(__is_processor(PV_POWER4) || \
-				 __is_processor(PV_POWER4p))
+#define cpu_has_largepage()	(processor_type() == PV_POWER4 || \
+				 processor_type() == PV_POWER4p)
 
-#define cpu_has_slb()		(__is_processor(PV_POWER4) || \
-				 __is_processor(PV_POWER4p))
+#define cpu_has_slb()		(processor_type() == PV_POWER4 || \
+				 processor_type() == PV_POWER4p)
 
-#define cpu_has_tlbiel()	(__is_processor(PV_POWER4) || \
-				 __is_processor(PV_POWER4p))
+#define cpu_has_tlbiel()	(processor_type() == PV_POWER4 || \
+				 processor_type() == PV_POWER4p)
 
-#define cpu_has_noexecute()	(__is_processor(PV_POWER4) || \
-				 __is_processor(PV_POWER4p))
+#define cpu_has_noexecute()	(processor_type() == PV_POWER4 || \
+				 processor_type() == PV_POWER4p)
 
 #endif /* ASSEMBLY */
 
diff -Nru a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
--- a/include/asm-ppc64/signal.h	Mon Feb 10 10:39:26 2003
+++ b/include/asm-ppc64/signal.h	Mon Feb 10 10:39:26 2003
@@ -73,7 +73,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
--- a/include/asm-ppc64/system.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-ppc64/system.h	Mon Feb 10 10:39:33 2003
@@ -25,7 +25,7 @@
  * mb() prevents loads and stores being reordered across this point.
  * rmb() prevents loads being reordered across this point.
  * wmb() prevents stores being reordered across this point.
- * read_barrier_depends() prevents data-dependant loads being reordered
+ * read_barrier_depends() prevents data-dependent loads being reordered
  *	across this point (nop on PPC).
  *
  * We can use the eieio instruction for wmb, but since it doesn't
@@ -105,11 +105,18 @@
 	!(flags & MSR_EE);			\
 })
 
-static __inline__ int __is_processor(unsigned long pv)
+static inline int __is_processor(unsigned long pv)
 {
-      unsigned long pvr;
-      asm volatile("mfspr %0, 0x11F" : "=r" (pvr)); 
-      return(PVR_VER(pvr) == pv);
+	unsigned long pvr;
+	asm("mfspr %0, 0x11F" : "=r" (pvr)); 
+	return(PVR_VER(pvr) == pv);
+}
+
+static inline int processor_type(void)
+{
+	unsigned long pvr;
+	asm ("mfspr %0, 0x11F" : "=r" (pvr)); 
+	return(PVR_VER(pvr));
 }
 
 /*
@@ -189,7 +196,7 @@
 static __inline__ unsigned long
 __cmpxchg_u32(volatile int *p, int old, int new)
 {
-	int prev;
+	unsigned int prev;
 
 	__asm__ __volatile__ (
 	EIEIO_ON_SMP
@@ -211,7 +218,7 @@
 static __inline__ unsigned long
 __cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new)
 {
-	int prev;
+	unsigned long prev;
 
 	__asm__ __volatile__ (
 	EIEIO_ON_SMP
diff -Nru a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
--- a/include/asm-ppc64/thread_info.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ppc64/thread_info.h	Mon Feb 10 10:39:23 2003
@@ -85,6 +85,7 @@
 					   TIF_NEED_RESCHED */
 #define TIF_32BIT		5	/* 32 bit binary */
 #define TIF_RUN_LIGHT		6	/* iSeries run light */
+#define TIF_ABI_PENDING		7	/* 32/64 bit switch needed */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -94,6 +95,7 @@
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_32BIT		(1<<TIF_32BIT)
 #define _TIF_RUN_LIGHT		(1<<TIF_RUN_LIGHT)
+#define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 
 #define _TIF_USER_WORK_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
 				 _TIF_NEED_RESCHED)
diff -Nru a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-ppc64/topology.h	Mon Feb 10 10:39:33 2003
@@ -5,7 +5,7 @@
 
 #ifdef CONFIG_NUMA
 
-static inline int __cpu_to_node(int cpu)
+static inline int cpu_to_node(int cpu)
 {
 	int node;
 
@@ -19,7 +19,7 @@
 	return node;
 }
 
-static inline int __node_to_first_cpu(int node)
+static inline int node_to_first_cpu(int node)
 {
 	int cpu;
 
@@ -31,7 +31,7 @@
 	return -1;
 }
 
-static inline unsigned long __node_to_cpu_mask(int node)
+static inline unsigned long node_to_cpumask(int node)
 {
 	int cpu;
 	unsigned long mask = 0UL;
@@ -51,12 +51,7 @@
 
 #else /* !CONFIG_NUMA */
 
-#define __cpu_to_node(cpu)		(0)
-#define __memblk_to_node(memblk)	(0)
-#define __parent_node(nid)		(0)
-#define __node_to_first_cpu(node)	(0)
-#define __node_to_cpu_mask(node)	(cpu_online_map)
-#define __node_to_memblk(node)		(0)
+#include <asm-generic/topology.h>
 
 #endif /* CONFIG_NUMA */
 
diff -Nru a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h
--- a/include/asm-ppc64/uaccess.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-ppc64/uaccess.h	Mon Feb 10 10:39:27 2003
@@ -131,7 +131,7 @@
  */
 #define __put_user_asm(x, addr, err, op)			\
 	__asm__ __volatile__(					\
-		"1:	"op" %1,0(%2)\n"			\
+		"1:	"op" %1,0(%2)  	# put_user\n" 	 	\
 		"2:\n"						\
 		".section .fixup,\"ax\"\n"			\
 		"3:	li %0,%3\n"				\
@@ -179,7 +179,7 @@
 
 #define __get_user_asm(x, addr, err, op)		\
 	__asm__ __volatile__(				\
-		"1:	"op" %1,0(%2)\n"		\
+		"1:	"op" %1,0(%2)	# get_user\n"  	\
 		"2:\n"					\
 		".section .fixup,\"ax\"\n"		\
 		"3:	li %0,%3\n"			\
diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-ppc64/unistd.h	Mon Feb 10 10:39:23 2003
@@ -242,6 +242,7 @@
 #define __NR_io_getevents	229
 #define __NR_io_submit		230
 #define __NR_io_cancel		231
+/* 223 + 224 currently unused */
 #define __NR_exit_group		234
 #define __NR_lookup_dcookie	235
 #define __NR_sys_epoll_create	236
@@ -249,178 +250,6 @@
 #define __NR_sys_epoll_wait	238
 #define __NR_remap_file_pages	239
 
-#define __NR(n)	#n
-
-
-#define __syscall_return(type) \
-	return (__sc_err & 0x10000000 ? errno = __sc_ret, __sc_ret = -1 : 0), \
-	       (type) __sc_ret
-
-#define __syscall_clobbers \
-	"r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
-
-#define _syscall0(type,name)						\
-type name(void)								\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-									\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0)		\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-#define _syscall1(type,name,type1,arg1)					\
-type name(type1 arg1)							\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-									\
-		__sc_3 = (unsigned long) (arg1);			\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0)		\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2)			\
-type name(type1 arg1, type2 arg2)					\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-		register unsigned long __sc_4 __asm__ ("r4");		\
-									\
-		__sc_3 = (unsigned long) (arg1);			\
-		__sc_4 = (unsigned long) (arg2);			\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0),		\
-			  "r"   (__sc_4)				\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)		\
-type name(type1 arg1, type2 arg2, type3 arg3)				\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-		register unsigned long __sc_4 __asm__ ("r4");		\
-		register unsigned long __sc_5 __asm__ ("r5");		\
-									\
-		__sc_3 = (unsigned long) (arg1);			\
-		__sc_4 = (unsigned long) (arg2);			\
-		__sc_5 = (unsigned long) (arg3);			\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0),		\
-			  "r"   (__sc_4),				\
-			  "r"   (__sc_5)				\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)		\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-		register unsigned long __sc_4 __asm__ ("r4");		\
-		register unsigned long __sc_5 __asm__ ("r5");		\
-		register unsigned long __sc_6 __asm__ ("r6");		\
-									\
-		__sc_3 = (unsigned long) (arg1);			\
-		__sc_4 = (unsigned long) (arg2);			\
-		__sc_5 = (unsigned long) (arg3);			\
-		__sc_6 = (unsigned long) (arg4);			\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0),		\
-			  "r"   (__sc_4),				\
-			  "r"   (__sc_5),				\
-			  "r"   (__sc_6)				\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
-{									\
-	unsigned long __sc_ret, __sc_err;				\
-	{								\
-		register unsigned long __sc_0 __asm__ ("r0");		\
-		register unsigned long __sc_3 __asm__ ("r3");		\
-		register unsigned long __sc_4 __asm__ ("r4");		\
-		register unsigned long __sc_5 __asm__ ("r5");		\
-		register unsigned long __sc_6 __asm__ ("r6");		\
-		register unsigned long __sc_7 __asm__ ("r7");		\
-									\
-		__sc_3 = (unsigned long) (arg1);			\
-		__sc_4 = (unsigned long) (arg2);			\
-		__sc_5 = (unsigned long) (arg3);			\
-		__sc_6 = (unsigned long) (arg4);			\
-		__sc_7 = (unsigned long) (arg5);			\
-		__sc_0 = __NR_##name;					\
-		__asm__ __volatile__					\
-			("sc           \n\t"				\
-			 "mfcr %1      "				\
-			: "=&r" (__sc_3), "=&r" (__sc_0)		\
-			: "0"   (__sc_3), "1"   (__sc_0),		\
-			  "r"   (__sc_4),				\
-			  "r"   (__sc_5),				\
-			  "r"   (__sc_6),				\
-			  "r"   (__sc_7)				\
-			: __syscall_clobbers);				\
-		__sc_ret = __sc_3;					\
-		__sc_err = __sc_0;					\
-	}								\
-	__syscall_return (type);					\
-}
-
-
 #ifdef __KERNEL_SYSCALLS__
 
 /*
@@ -434,17 +263,15 @@
 /*
  * System call prototypes.
  */
-#define __NR__exit __NR_exit
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+extern pid_t setsid(void);
+extern int write(int fd, const char *buf, off_t count);
+extern int read(int fd, char *buf, off_t count);
+extern off_t lseek(int fd, off_t offset, int count);
+extern int dup(int fd);
+extern int execve(const char *file, char **argv, char **envp);
+extern int open(const char *file, int flag, int mode);
+extern int close(int fd);
+extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
 
 #endif /* __KERNEL_SYSCALLS__ */
 
diff -Nru a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h
--- a/include/asm-s390/kmap_types.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-s390/kmap_types.h	Mon Feb 10 10:39:23 2003
@@ -14,8 +14,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,	
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,	
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-s390/signal.h b/include/asm-s390/signal.h
--- a/include/asm-s390/signal.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-s390/signal.h	Mon Feb 10 10:39:30 2003
@@ -94,7 +94,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP    0x00000001
-#define SA_NOCLDWAIT    0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT    0x00000002
 #define SA_SIGINFO      0x00000004
 #define SA_ONSTACK      0x08000000
 #define SA_RESTART      0x10000000
diff -Nru a/include/asm-s390x/signal.h b/include/asm-s390x/signal.h
--- a/include/asm-s390x/signal.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-s390x/signal.h	Mon Feb 10 10:39:29 2003
@@ -94,7 +94,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP    0x00000001
-#define SA_NOCLDWAIT    0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT    0x00000002
 #define SA_SIGINFO      0x00000004
 #define SA_ONSTACK      0x08000000
 #define SA_RESTART      0x10000000
diff -Nru a/include/asm-sh/signal.h b/include/asm-sh/signal.h
--- a/include/asm-sh/signal.h	Mon Feb 10 10:39:28 2003
+++ b/include/asm-sh/signal.h	Mon Feb 10 10:39:28 2003
@@ -73,7 +73,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h
--- a/include/asm-sparc/delay.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc/delay.h	Mon Feb 10 10:39:24 2003
@@ -21,5 +21,6 @@
 
 /* This is too messy with inline asm on the Sparc. */
 extern void udelay(unsigned long usecs);
+extern void ndelay(unsigned long usecs);
 
 #endif /* defined(__SPARC_DELAY_H) */
diff -Nru a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
--- a/include/asm-sparc/ide.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-sparc/ide.h	Mon Feb 10 10:39:27 2003
@@ -83,7 +83,7 @@
 #define ide_ack_intr(hwif)		(1)
 
 /* XXX Known to be broken.  Axboe will fix the problems this
- * XXX has by making seperate IN/OUT macros for IDE_DATA
+ * XXX has by making separate IN/OUT macros for IDE_DATA
  * XXX register and rest of IDE regs and also using
  * XXX ide_ioreg_t instead of u32 for ports. -DaveM
  */
diff -Nru a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
--- a/include/asm-sparc/kmap_types.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc/kmap_types.h	Mon Feb 10 10:39:24 2003
@@ -13,8 +13,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
--- a/include/asm-sparc/mman.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-sparc/mman.h	Mon Feb 10 10:39:33 2003
@@ -21,7 +21,7 @@
 #define MAP_LOCKED      0x100           /* lock the mapping */
 #define _MAP_NEW        0x80000000      /* Binary compatibility is fun... */
 
-#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_GROWSDOWN	0x0200		/* stack-like segment */
 #define MAP_DENYWRITE	0x0800		/* ETXTBSY */
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 
diff -Nru a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
--- a/include/asm-sparc/signal.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-sparc/signal.h	Mon Feb 10 10:39:29 2003
@@ -140,7 +140,7 @@
 #define SA_INTERRUPT	0x10
 #define SA_NOMASK	0x20
 #define SA_SHIRQ	0x40
-#define SA_NOCLDWAIT	0x100	/* not supported yet */
+#define SA_NOCLDWAIT	0x100
 #define SA_SIGINFO	0x200
 
 #define SIG_BLOCK          0x01	/* for blocking signals */
diff -Nru a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
--- a/include/asm-sparc/smp.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc/smp.h	Mon Feb 10 10:39:24 2003
@@ -48,7 +48,6 @@
  *	Private routines/data
  */
  
-extern int smp_found_cpus;
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
 #define cpu_online_map cpu_present_map
diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
--- a/include/asm-sparc64/compat.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-sparc64/compat.h	Mon Feb 10 10:39:29 2003
@@ -77,4 +77,11 @@
 	int		f_spare[6];
 };
 
+typedef u32		compat_old_sigset_t;
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32		compat_sigset_word;
+
 #endif /* _ASM_SPARC64_COMPAT_H */
diff -Nru a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h
--- a/include/asm-sparc64/delay.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-sparc64/delay.h	Mon Feb 10 10:39:29 2003
@@ -45,6 +45,19 @@
 	__delay(usecs * HZ);
 }
 
+extern __inline__ void __ndelay(unsigned long usecs, unsigned long lps)
+{
+	usecs *= 0x0000000000000005UL;		/* 2**32 / 10000 */
+
+	__asm__ __volatile__(
+"	mulx	%1, %2, %0\n"
+"	srlx	%0, 32, %0\n"
+	: "=r" (usecs)
+	: "r" (usecs), "r" (lps));
+
+	__delay(usecs * HZ);
+}
+
 #ifdef CONFIG_SMP
 #define __udelay_val cpu_data[smp_processor_id()].udelay_val
 #else
@@ -52,6 +65,7 @@
 #endif
 
 #define udelay(usecs) __udelay((usecs),__udelay_val)
+#define ndelay(usecs) __ndelay((usecs),__udelay_val)
 
 #endif /* !__ASSEMBLY__ */
 
diff -Nru a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
--- a/include/asm-sparc64/elf.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc64/elf.h	Mon Feb 10 10:39:24 2003
@@ -111,6 +111,8 @@
 	if ((current_thread_info()->flags & _TIF_32BIT) \
 	    != new_flags)				\
 		set_thread_flag(TIF_ABI_PENDING);	\
+	else						\
+		clear_thread_flag(TIF_ABI_PENDING);	\
 	/* flush_thread will update pgd cache */	\
 	if (ibcs2)					\
 		set_personality(PER_SVR4);		\
diff -Nru a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
--- a/include/asm-sparc64/ide.h	Mon Feb 10 10:39:25 2003
+++ b/include/asm-sparc64/ide.h	Mon Feb 10 10:39:25 2003
@@ -80,7 +80,7 @@
 #define ide_ack_intr(hwif)		(1)
 
 /* XXX Known to be broken.  Axboe will fix the problems this
- * XXX has by making seperate IN/OUT macros for IDE_DATA
+ * XXX has by making separate IN/OUT macros for IDE_DATA
  * XXX register and rest of IDE regs and also using
  * XXX ide_ioreg_t instead of u32 for ports. -DaveM
  */
diff -Nru a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h
--- a/include/asm-sparc64/kmap_types.h	Mon Feb 10 10:39:32 2003
+++ b/include/asm-sparc64/kmap_types.h	Mon Feb 10 10:39:32 2003
@@ -17,8 +17,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
--- a/include/asm-sparc64/mman.h	Mon Feb 10 10:39:27 2003
+++ b/include/asm-sparc64/mman.h	Mon Feb 10 10:39:27 2003
@@ -21,7 +21,7 @@
 #define MAP_LOCKED      0x100           /* lock the mapping */
 #define _MAP_NEW        0x80000000      /* Binary compatibility is fun... */
 
-#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_GROWSDOWN	0x0200		/* stack-like segment */
 #define MAP_DENYWRITE	0x0800		/* ETXTBSY */
 #define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
 
diff -Nru a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
--- a/include/asm-sparc64/signal.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc64/signal.h	Mon Feb 10 10:39:24 2003
@@ -88,27 +88,21 @@
 #define _NSIG_BPW     	64
 #define _NSIG_WORDS   	(__NEW_NSIG / _NSIG_BPW)
 
-#define _NSIG_BPW32   	32
-#define _NSIG_WORDS32 	(__NEW_NSIG / _NSIG_BPW32)
-
 #define SIGRTMIN       32
 #define SIGRTMAX       (__NEW_NSIG - 1)
 
 #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
 #define _NSIG			__NEW_NSIG
 #define __new_sigset_t		sigset_t
-#define __new_sigset_t32	sigset_t32
 #define __new_sigaction		sigaction
 #define __new_sigaction32	sigaction32
 #define __old_sigset_t		old_sigset_t
-#define __old_sigset_t32	old_sigset_t32
 #define __old_sigaction		old_sigaction
 #define __old_sigaction32	old_sigaction32
 #else
 #define _NSIG			__OLD_NSIG
 #define NSIG			_NSIG
 #define __old_sigset_t		sigset_t
-#define __old_sigset_t32	sigset_t32
 #define __old_sigaction		sigaction
 #define __old_sigaction32	sigaction32
 #endif
@@ -116,16 +110,11 @@
 #ifndef __ASSEMBLY__
 
 typedef unsigned long __old_sigset_t;            /* at least 32 bits */
-typedef unsigned int __old_sigset_t32;
 
 typedef struct {
        unsigned long sig[_NSIG_WORDS];
 } __new_sigset_t;
 
-typedef struct {
-       unsigned int sig[_NSIG_WORDS32];
-} __new_sigset_t32;
-
 /* A SunOS sigstack */
 struct sigstack {
 	/* XXX 32-bit pointers pinhead XXX */
@@ -156,7 +145,7 @@
 #define SA_INTERRUPT	0x10
 #define SA_NOMASK	0x20
 #define SA_SHIRQ	0x40
-#define SA_NOCLDWAIT    0x100 /* not supported yet */
+#define SA_NOCLDWAIT    0x100
 #define SA_SIGINFO      0x200
 
 
@@ -213,14 +202,14 @@
 	__new_sigset_t		sa_mask;
 };
 
+#ifdef __KERNEL__
 struct __new_sigaction32 {
 	unsigned		sa_handler;
 	unsigned int    	sa_flags;
 	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
-	__new_sigset_t32 	sa_mask;
+	compat_sigset_t 	sa_mask;
 };
 
-#ifdef __KERNEL__
 struct k_sigaction {
 	struct __new_sigaction 	sa;
 	void			*ka_restorer;
@@ -234,12 +223,14 @@
 	void 			(*sa_restorer)(void);     /* not used by Linux/SPARC yet */
 };
 
+#ifdef __KERNEL__
 struct __old_sigaction32 {
 	unsigned		sa_handler;
-	__old_sigset_t32  	sa_mask;
+	compat_old_sigset_t  	sa_mask;
 	unsigned int    	sa_flags;
 	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
 };
+#endif
 
 typedef struct sigaltstack {
 	void			*ss_sp;
diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
--- a/include/asm-sparc64/unistd.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-sparc64/unistd.h	Mon Feb 10 10:39:24 2003
@@ -252,8 +252,8 @@
 #endif
 /* #define __NR_oldstat         232    Linux Specific                              */
 #define __NR_stime              233 /* Linux Specific                              */
-#define __NR_alloc_hugepages    234 /* Linux Specific                              */
-#define __NR_free_hugepages     235 /* Linux Specific                              */
+/* #define __NR_UNUSED          234 */
+/* #define __NR_UNUSED          235 */
 #define __NR__llseek            236 /* Linux Specific                              */
 #define __NR_mlock              237
 #define __NR_munlock            238
diff -Nru a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
--- a/include/asm-um/archparam-i386.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-um/archparam-i386.h	Mon Feb 10 10:39:31 2003
@@ -48,7 +48,7 @@
 	/* fake once used fs and gs selectors? */	\
 	pr_reg[9] = PT_REGS_DS(regs);		\
 	pr_reg[10] = PT_REGS_DS(regs);		\
-	pr_reg[11] = regs->regs.syscall;	\
+	pr_reg[11] = PT_REGS_SYSCALL_NR(regs);	\
 	pr_reg[12] = PT_REGS_IP(regs);		\
 	pr_reg[13] = PT_REGS_CS(regs);		\
 	pr_reg[14] = PT_REGS_EFLAGS(regs);	\
diff -Nru a/include/asm-um/bug.h b/include/asm-um/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-um/bug.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,18 @@
+#ifndef __UM_BUG_H
+#define __UM_BUG_H
+
+#ifndef __ASSEMBLY__
+
+#define BUG() do { \
+	panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+extern int foo;
+
+#endif
+
+#endif
diff -Nru a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-um/common.lds.S	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,86 @@
+  .fini      : { *(.fini)    } =0x9090
+  _etext = .;
+  PROVIDE (etext = .);
+
+  . = ALIGN(4096);
+  _sdata = .;
+  PROVIDE (sdata = .);
+
+  . = ALIGN(16);		/* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  RODATA
+
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
+  __gpl_ksymtab : { *(__gpl_ksymtab) }
+  __stop___gpl_ksymtab = .;
+
+  __start___kallsyms = .;       /* All kernel symbols */
+  __kallsyms : { *(__kallsyms) }
+  __stop___kallsyms = .;
+
+  .unprotected : { *(.unprotected) }
+  . = ALIGN(4096);
+  PROVIDE (_unprotected_end = .);
+
+  . = ALIGN(4096);
+  __uml_setup_start = .;
+  .uml.setup.init : { *(.uml.setup.init) }
+  __uml_setup_end = .;
+	
+  __uml_help_start = .;
+  .uml.help.init : { *(.uml.help.init) }
+  __uml_help_end = .;
+	
+  __uml_postsetup_start = .;
+  .uml.postsetup.init : { *(.uml.postsetup.init) }
+  __uml_postsetup_end = .;
+	
+  __setup_start = .;
+  .init.setup : { *(.init.setup) }
+  __setup_end = .;
+
+  __start___param = .;
+  __param : { *(__param) }
+  __stop___param = .;
+
+  . = ALIGN(32);
+  __per_cpu_start = . ; 
+  .data.percpu : { *(.data.percpu) }
+  __per_cpu_end = . ;
+	
+  __initcall_start = .;
+  .initcall.init : {
+	*(.initcall1.init) 
+	*(.initcall2.init) 
+	*(.initcall3.init) 
+	*(.initcall4.init) 
+	*(.initcall5.init) 
+	*(.initcall6.init) 
+	*(.initcall7.init)
+  }
+  __initcall_end = .;
+
+  __uml_initcall_start = .;
+  .uml.initcall.init : { *(.uml.initcall.init) }
+  __uml_initcall_end = .;
+  __init_end = .;
+
+  __exitcall_begin = .;
+  .exitcall : { *(.exitcall.exit) }
+  __exitcall_end = .;
+
+  __uml_exitcall_begin = .;
+  .uml.exitcall : { *(.uml.exitcall.exit) }
+  __uml_exitcall_end = .;
+
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
diff -Nru a/include/asm-um/current.h b/include/asm-um/current.h
--- a/include/asm-um/current.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-um/current.h	Mon Feb 10 10:39:23 2003
@@ -13,7 +13,8 @@
 #include "linux/config.h"
 #include "asm/page.h"
 
-#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & (PAGE_MASK << 2))
+#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
+			        (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
 
 #define current ({ int dummy; \
                    ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
diff -Nru a/include/asm-um/module.h b/include/asm-um/module.h
--- a/include/asm-um/module.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-um/module.h	Mon Feb 10 10:39:29 2003
@@ -1,6 +1,13 @@
 #ifndef __UM_MODULE_H
 #define __UM_MODULE_H
 
-#include "asm/arch/module.h"
+/* UML is simple */
+struct mod_arch_specific
+{
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
 
 #endif
diff -Nru a/include/asm-um/page.h b/include/asm-um/page.h
--- a/include/asm-um/page.h	Mon Feb 10 10:39:28 2003
+++ b/include/asm-um/page.h	Mon Feb 10 10:39:28 2003
@@ -4,9 +4,8 @@
 struct page;
 
 #include "asm/arch/page.h"
+#include "asm/bug.h"
 
-#undef BUG
-#undef PAGE_BUG
 #undef __pa
 #undef __va
 #undef pfn_to_page
@@ -22,20 +21,6 @@
 
 #define PAGE_OFFSET (uml_physmem)
 #define KERNELBASE PAGE_OFFSET
-
-#ifndef __ASSEMBLY__
-
-extern void stop(void);
-
-#define BUG() do { \
-	panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-} while (0)
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
-#endif /* __ASSEMBLY__ */
 
 #define __va_space (8*1024*1024)
 
diff -Nru a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
--- a/include/asm-um/pgtable.h	Mon Feb 10 10:39:33 2003
+++ b/include/asm-um/pgtable.h	Mon Feb 10 10:39:33 2003
@@ -14,6 +14,9 @@
 
 extern pgd_t swapper_pg_dir[1024];
 
+extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
+			     pte_t *pte_out);
+
 /* zero page used for uninitialized stuff */
 extern unsigned long *empty_zero_page;
 
diff -Nru a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
--- a/include/asm-um/processor-generic.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-um/processor-generic.h	Mon Feb 10 10:39:24 2003
@@ -80,21 +80,21 @@
 
 #define INIT_THREAD \
 { \
-	forking:		0, \
-	kernel_stack:		0, \
-	nsyscalls:		0, \
-        regs:		   	EMPTY_REGS, \
-	cr2:			0, \
-	err:			0, \
-	fault_addr:		NULL, \
-	prev_sched:		NULL, \
-	temp_stack:		0, \
-	exec_buf:		NULL, \
-	arch:			INIT_ARCH_THREAD, \
-	request:		{ 0 } \
+	.forking		= 0, \
+	.kernel_stack		= 0, \
+	.nsyscalls		= 0, \
+        .regs		   	= EMPTY_REGS, \
+	.cr2			= 0, \
+	.err			= 0, \
+	.fault_addr		= NULL, \
+	.prev_sched		= NULL, \
+	.temp_stack		= 0, \
+	.exec_buf		= NULL, \
+	.arch			= INIT_ARCH_THREAD, \
+	.request		= { 0 } \
 }
 
-#define INIT_THREAD_SIZE (4 * PAGE_SIZE)
+#define INIT_THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
 
 typedef struct {
 	unsigned long seg;
diff -Nru a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
--- a/include/asm-um/processor-i386.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-um/processor-i386.h	Mon Feb 10 10:39:23 2003
@@ -14,8 +14,8 @@
 	int debugregs_seq;
 };
 
-#define INIT_ARCH_THREAD { debugregs : 		{ [ 0 ... 7 ] = 0 }, \
-                           debugregs_seq :	0 }
+#define INIT_ARCH_THREAD { .debugregs  		= { [ 0 ... 7 ] = 0 }, \
+                           .debugregs_seq	= 0 }
 
 #include "asm/arch/user.h"
 
diff -Nru a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
--- a/include/asm-um/ptrace-generic.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-um/ptrace-generic.h	Mon Feb 10 10:39:30 2003
@@ -9,7 +9,7 @@
 #ifndef __ASSEMBLY__
 
 #include "linux/config.h"
-#include "skas_ptrace.h"
+
 #include "asm/current.h"
 
 #define pt_regs pt_regs_subarch
@@ -23,9 +23,10 @@
 #undef instruction_pointer
 
 #include "sysdep/ptrace.h"
+#include "skas_ptrace.h"
 
 struct pt_regs {
-	struct uml_pt_regs regs;
+	union uml_pt_regs regs;
 };
 
 #define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
diff -Nru a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
--- a/include/asm-um/ptrace-i386.h	Mon Feb 10 10:39:29 2003
+++ b/include/asm-um/ptrace-i386.h	Mon Feb 10 10:39:29 2003
@@ -6,6 +6,7 @@
 #ifndef __UM_PTRACE_I386_H
 #define __UM_PTRACE_I386_H
 
+#include "sysdep/ptrace.h"
 #include "asm/ptrace-generic.h"
 
 #define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
@@ -29,7 +30,7 @@
 #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
 #define PT_FIX_EXEC_STACK(sp) do ; while(0)
 
-#define user_mode(r) ((r)->regs.is_user)
+#define user_mode(r) UPT_IS_USER(&(r)->regs)
 
 #endif
 
diff -Nru a/include/asm-um/ucontext.h b/include/asm-um/ucontext.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-um/ucontext.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,6 @@
+#ifndef _ASM_UM_UCONTEXT_H
+#define _ASM_UM_UCONTEXT_H
+
+#include "asm/arch/ucontext.h"
+
+#endif
diff -Nru a/include/asm-v850/pci.h b/include/asm-v850/pci.h
--- a/include/asm-v850/pci.h	Mon Feb 10 10:39:24 2003
+++ b/include/asm-v850/pci.h	Mon Feb 10 10:39:24 2003
@@ -36,7 +36,7 @@
 pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
 		  int dir);
 
-/* Make physical memory consistant for a single streaming mode DMA
+/* Make physical memory consistent for a single streaming mode DMA
    translation after a transfer.
 
    If you perform a pci_map_single() but wish to interrogate the
diff -Nru a/include/asm-v850/signal.h b/include/asm-v850/signal.h
--- a/include/asm-v850/signal.h	Mon Feb 10 10:39:25 2003
+++ b/include/asm-v850/signal.h	Mon Feb 10 10:39:25 2003
@@ -88,7 +88,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
--- a/include/asm-x86_64/compat.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-x86_64/compat.h	Mon Feb 10 10:39:30 2003
@@ -81,4 +81,11 @@
 	int		f_spare[6];
 };
 
+typedef u32		compat_old_sigset_t;	/* at least 32 bits */
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32               compat_sigset_word;
+
 #endif /* _ASM_X86_64_COMPAT_H */
diff -Nru a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/dma-mapping.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,6 @@
+#ifndef _ASM_X8664_DMA_MAPPING_H
+#define _ASM_X8664_DMA_MAPPING_H
+
+#include <asm-generic/dma-mapping.h>
+
+#endif
diff -Nru a/include/asm-x86_64/kmap_types.h b/include/asm-x86_64/kmap_types.h
--- a/include/asm-x86_64/kmap_types.h	Mon Feb 10 10:39:30 2003
+++ b/include/asm-x86_64/kmap_types.h	Mon Feb 10 10:39:30 2003
@@ -11,8 +11,8 @@
 	KM_BIO_DST_IRQ,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h	Mon Feb 10 10:39:31 2003
+++ b/include/asm-x86_64/proto.h	Mon Feb 10 10:39:31 2003
@@ -1,6 +1,8 @@
 #ifndef _ASM_X8664_PROTO_H
 #define _ASM_X8664_PROTO_H 1
 
+#include <asm/ldt.h>
+
 /* misc architecture specific prototypes */
 
 struct cpuinfo_x86; 
diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
--- a/include/asm-x86_64/signal.h	Mon Feb 10 10:39:23 2003
+++ b/include/asm-x86_64/signal.h	Mon Feb 10 10:39:23 2003
@@ -93,7 +93,7 @@
  * Unix names RESETHAND and NODEFER respectively.
  */
 #define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_NOCLDWAIT	0x00000002
 #define SA_SIGINFO	0x00000004
 #define SA_ONSTACK	0x08000000
 #define SA_RESTART	0x10000000
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	Mon Feb 10 10:39:22 2003
+++ b/include/linux/acpi.h	Mon Feb 10 10:39:22 2003
@@ -31,11 +31,8 @@
 
 #include <linux/list.h>
 
-/*
- * Yes this is ugly, but moving all of ACPI's private headers to include/acpi 
- * isn't the right answer either.  Please just ignore it for now.
- */
-#include "../../drivers/acpi/include/acpi.h"
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
 #include <asm/acpi.h>
 
 
@@ -351,10 +348,10 @@
 
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 unsigned long acpi_find_rsdp (void);
-int acpi_boot_init (char *cmdline);
+int acpi_boot_init (void);
 int acpi_numa_init (void);
 
-int acpi_table_init (char *cmdline);
+int acpi_table_init (void);
 int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
 int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler);
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	Mon Feb 10 10:39:30 2003
+++ b/include/linux/agp_backend.h	Mon Feb 10 10:39:30 2003
@@ -160,7 +160,7 @@
  * an u32 argument of the type of memory to be allocated.  
  * Every agp bridge device will allow you to allocate 
  * AGP_NORMAL_MEMORY which maps to physical ram.  Any other
- * type is device dependant.
+ * type is device dependent.
  * 
  * It returns NULL whenever memory is unavailable.
  * 
diff -Nru a/include/linux/apm_bios.h b/include/linux/apm_bios.h
--- a/include/linux/apm_bios.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/apm_bios.h	Mon Feb 10 10:39:27 2003
@@ -45,7 +45,7 @@
 #define APM_BIOS_DISENGAGED     0x0010
 
 /*
- * Data for APM that is persistant across module unload/load
+ * Data for APM that is persistent across module unload/load
  */
 struct apm_info {
 	struct apm_bios_info	bios;
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/blkdev.h	Mon Feb 10 10:39:24 2003
@@ -4,6 +4,8 @@
 #include <linux/major.h>
 #include <linux/genhd.h>
 #include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
 #include <linux/pagemap.h>
 #include <linux/backing-dev.h>
 #include <linux/wait.h>
@@ -188,6 +190,14 @@
 	unplug_fn		*unplug_fn;
 	merge_bvec_fn		*merge_bvec_fn;
 
+	/*
+	 * Auto-unplugging state
+	 */
+	struct timer_list	unplug_timer;
+	int			unplug_thresh;	/* After this many requests */
+	unsigned long		unplug_delay;	/* After this many jiffies */
+	struct work_struct	unplug_work;
+
 	struct backing_dev_info	backing_dev_info;
 
 	/*
@@ -287,12 +297,12 @@
  * BLK_BOUNCE_ANY	: don't bounce anything
  * BLK_BOUNCE_ISA	: bounce pages above ISA DMA boundary
  */
-#define BLK_BOUNCE_HIGH		(blk_max_low_pfn << PAGE_SHIFT)
-#define BLK_BOUNCE_ANY		(blk_max_pfn << PAGE_SHIFT)
+#define BLK_BOUNCE_HIGH		((u64)blk_max_low_pfn << PAGE_SHIFT)
+#define BLK_BOUNCE_ANY		((u64)blk_max_pfn << PAGE_SHIFT)
 #define BLK_BOUNCE_ISA		(ISA_DMA_THRESHOLD)
 
 extern int init_emergency_isa_pool(void);
-inline void blk_queue_bounce(request_queue_t *q, struct bio **bio);
+extern void blk_queue_bounce(request_queue_t *q, struct bio **bio);
 
 #define rq_for_each_bio(bio, rq)	\
 	if ((rq->bio))			\
diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h
--- a/include/linux/buffer_head.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/buffer_head.h	Mon Feb 10 10:39:23 2003
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/linkage.h>
+#include <linux/wait.h>
 #include <asm/atomic.h>
 
 enum bh_state_bits {
@@ -154,7 +155,7 @@
 void __invalidate_buffers(kdev_t dev, int);
 int sync_blockdev(struct block_device *bdev);
 void __wait_on_buffer(struct buffer_head *);
-void sleep_on_buffer(struct buffer_head *bh);
+wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
 void wake_up_buffer(struct buffer_head *bh);
 int fsync_bdev(struct block_device *);
 int fsync_super(struct super_block *);
diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/crypto.h	Mon Feb 10 10:39:24 2003
@@ -131,9 +131,13 @@
 	int (*cit_setkey)(struct crypto_tfm *tfm,
 	                  const u8 *key, unsigned int keylen);
 	int (*cit_encrypt)(struct crypto_tfm *tfm,
-	                   struct scatterlist *sg, unsigned int nsg);
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
 	int (*cit_decrypt)(struct crypto_tfm *tfm,
-	                   struct scatterlist *sg, unsigned int nsg);
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
 	void (*cit_xor_block)(u8 *dst, const u8 *src);
 };
 
@@ -274,19 +278,21 @@
 }
 
 static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg)
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
 {
 	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_encrypt(tfm, sg, nsg);
+	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
 }                                        
 
 static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg)
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
 {
 	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_decrypt(tfm, sg, nsg);
+	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
 }
 
 static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/elf.h	Mon Feb 10 10:39:23 2003
@@ -519,6 +519,174 @@
 
 #define EF_ALPHA_32BIT		1	/* All addresses are below 2GB */
 
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indeces.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tenatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
 
 typedef struct elf32_rel {
   Elf32_Addr	r_offset;
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/ext3_jbd.h	Mon Feb 10 10:39:23 2003
@@ -28,7 +28,7 @@
  * indirection blocks, the group and superblock summaries, and the data
  * block to complete the transaction.  */
 
-#define EXT3_SINGLEDATA_TRANS_BLOCKS	8
+#define EXT3_SINGLEDATA_TRANS_BLOCKS	8U
 
 /* Extended attributes may touch two data buffers, two bitmap buffers,
  * and two group and summaries. */
@@ -58,7 +58,7 @@
  * start off at the maximum transaction size and grow the transaction
  * optimistically as we go. */
 
-#define EXT3_MAX_TRANS_DATA		64
+#define EXT3_MAX_TRANS_DATA		64U
 
 /* We break up a large truncate or write transaction once the handle's
  * buffer credits gets this low, we need either to extend the
@@ -67,7 +67,7 @@
  * one block, plus two quota updates.  Quota allocations are not
  * needed. */
 
-#define EXT3_RESERVE_TRANS_BLOCKS	12
+#define EXT3_RESERVE_TRANS_BLOCKS	12U
 
 #define EXT3_INDEX_EXTRA_TRANS_BLOCKS	8
 
diff -Nru a/include/linux/fadvise.h b/include/linux/fadvise.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/fadvise.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,11 @@
+#ifndef FADVISE_H_INCLUDED
+#define FADVISE_H_INCLUDED
+
+#define POSIX_FADV_NORMAL	0 /* No further special treatment.  */
+#define POSIX_FADV_RANDOM	1 /* Expect random page references.  */
+#define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.  */
+#define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */
+#define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */
+#define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */
+
+#endif	/* FADVISE_H_INCLUDED */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/fs.h	Mon Feb 10 10:39:24 2003
@@ -332,8 +332,6 @@
 	struct list_head	hash;
 	atomic_t		count;
 	dev_t			dev;
-	atomic_t		openers;
-	struct semaphore	sem;
 };
 
 struct block_device {
@@ -371,9 +369,10 @@
 	struct timespec		i_ctime;
 	unsigned int		i_blkbits;
 	unsigned long		i_blksize;
-	unsigned long		i_blocks;
 	unsigned long		i_version;
+	unsigned long		i_blocks;
 	unsigned short          i_bytes;
+	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
 	struct semaphore	i_sem;
 	struct inode_operations	*i_op;
 	struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
@@ -400,7 +399,7 @@
 	void			*i_security;
 	__u32			i_generation;
 	union {
-		void				*generic_ip;
+		void		*generic_ip;
 	} u;
 };
 
@@ -412,39 +411,6 @@
 	void *security;
 };
 
-static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
-{
-	inode->i_blocks += bytes >> 9;
-	bytes &= 511;
-	inode->i_bytes += bytes;
-	if (inode->i_bytes >= 512) {
-		inode->i_blocks++;
-		inode->i_bytes -= 512;
-	}
-}
-
-static inline void inode_sub_bytes(struct inode *inode, loff_t bytes)
-{
-	inode->i_blocks -= bytes >> 9;
-	bytes &= 511;
-	if (inode->i_bytes < bytes) {
-		inode->i_blocks--;
-		inode->i_bytes += 512;
-	}
-	inode->i_bytes -= bytes;
-}
-
-static inline loff_t inode_get_bytes(struct inode *inode)
-{
-	return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
-}
-
-static inline void inode_set_bytes(struct inode *inode, loff_t bytes)
-{
-	inode->i_blocks = bytes >> 9;
-	inode->i_bytes = bytes & 511;
-}
-
 /*
  * Track a single file's readahead state
  */
@@ -1134,7 +1100,9 @@
 extern int __check_disk_change(dev_t);
 extern int invalidate_inodes(struct super_block *);
 extern int invalidate_device(kdev_t, int);
-extern void invalidate_inode_pages(struct address_space *mapping);
+unsigned long invalidate_mapping_pages(struct address_space *mapping,
+					pgoff_t start, pgoff_t end);
+unsigned long invalidate_inode_pages(struct address_space *mapping);
 extern void invalidate_inode_pages2(struct address_space *mapping);
 extern void write_inode_now(struct inode *, int);
 extern int filemap_fdatawrite(struct address_space *);
@@ -1277,6 +1245,10 @@
 extern struct inode_operations page_symlink_inode_operations;
 extern void generic_fillattr(struct inode *, struct kstat *);
 extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+void inode_add_bytes(struct inode *inode, loff_t bytes);
+void inode_sub_bytes(struct inode *inode, loff_t bytes);
+loff_t inode_get_bytes(struct inode *inode);
+void inode_set_bytes(struct inode *inode, loff_t bytes);
 
 extern int vfs_readdir(struct file *, filldir_t, void *);
 
diff -Nru a/include/linux/gfp.h b/include/linux/gfp.h
--- a/include/linux/gfp.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/gfp.h	Mon Feb 10 10:39:24 2003
@@ -14,20 +14,17 @@
 /* Action modifiers - doesn't change the zoning */
 #define __GFP_WAIT	0x10	/* Can wait and reschedule? */
 #define __GFP_HIGH	0x20	/* Should access emergency pools? */
-#define __GFP_IO	0x40	/* Can start low memory physical IO? */
-#define __GFP_HIGHIO	0x80	/* Can start high mem physical IO? */
-#define __GFP_FS	0x100	/* Can call down to low-level FS? */
-#define __GFP_COLD	0x200	/* Cache-cold page required */
-#define __GFP_NOWARN	0x400	/* Suppress page allocation failure warning */
+#define __GFP_IO	0x40	/* Can start physical IO? */
+#define __GFP_FS	0x80	/* Can call down to low-level FS? */
+#define __GFP_COLD	0x100	/* Cache-cold page required */
+#define __GFP_NOWARN	0x200	/* Suppress page allocation failure warning */
 
-#define GFP_NOHIGHIO	(             __GFP_WAIT | __GFP_IO)
-#define GFP_NOIO	(             __GFP_WAIT)
-#define GFP_NOFS	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO)
 #define GFP_ATOMIC	(__GFP_HIGH)
-#define GFP_USER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
-#define GFP_HIGHUSER	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM)
-#define GFP_KERNEL	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
-#define GFP_KSWAPD	(             __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
+#define GFP_NOIO	(__GFP_WAIT)
+#define GFP_NOFS	(__GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL	(__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_USER	(__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_HIGHUSER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM)
 
 /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
    platforms, used as appropriate on others */
diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h
--- a/include/linux/hugetlb.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/hugetlb.h	Mon Feb 10 10:39:27 2003
@@ -18,19 +18,34 @@
 void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
 int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
 void huge_page_release(struct page *);
-void hugetlb_release_key(struct hugetlb_key *);
 int hugetlb_report_meminfo(char *);
 int is_hugepage_mem_enough(size_t);
+struct page *follow_huge_addr(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long address, int write);
+struct vm_area_struct *hugepage_vma(struct mm_struct *mm,
+					unsigned long address);
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+				pmd_t *pmd, int write);
+int pmd_huge(pmd_t pmd);
 
 extern int htlbpage_max;
 
+static inline void
+mark_mm_hugetlb(struct mm_struct *mm, struct vm_area_struct *vma)
+{
+	if (is_vm_hugetlb_page(vma))
+		mm->used_hugetlb = 1;
+}
+
 #else /* !CONFIG_HUGETLB_PAGE */
+
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 {
 	return 0;
 }
 
-#define follow_hugetlb_page(m,v,p,vs,a,b,i)		({ BUG(); 0; })
+#define follow_hugetlb_page(m,v,p,vs,a,b,i)	({ BUG(); 0; })
+#define follow_huge_addr(mm, vma, addr, write)	0
 #define copy_hugetlb_page_range(src, dst, vma)	({ BUG(); 0; })
 #define hugetlb_prefault(mapping, vma)		({ BUG(); 0; })
 #define zap_hugepage_range(vma, start, len)	BUG()
@@ -38,6 +53,14 @@
 #define huge_page_release(page)			BUG()
 #define is_hugepage_mem_enough(size)		0
 #define hugetlb_report_meminfo(buf)		0
+#define hugepage_vma(mm, addr)			0
+#define mark_mm_hugetlb(mm, vma)		do { } while (0)
+#define follow_huge_pmd(mm, addr, pmd, write)	0
+#define pmd_huge(x)	0
+
+#ifndef HPAGE_MASK
+#define HPAGE_MASK	0		/* Keep the compiler happy */
+#endif
 
 #endif /* !CONFIG_HUGETLB_PAGE */
 
diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h
--- a/include/linux/init_task.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/init_task.h	Mon Feb 10 10:39:23 2003
@@ -45,9 +45,13 @@
 
 #define INIT_SIGNALS(sig) {	\
 	.count		= ATOMIC_INIT(1), 		\
+	.shared_pending	= { NULL, &sig.shared_pending.head, {{0}}}, \
+}
+
+#define INIT_SIGHAND(sighand) {	\
+	.count		= ATOMIC_INIT(1), 		\
 	.action		= { {{0,}}, }, 			\
 	.siglock	= SPIN_LOCK_UNLOCKED, 		\
-	.shared_pending	= { NULL, &sig.shared_pending.head, {{0}}}, \
 }
 
 /*
@@ -90,7 +94,8 @@
 	.thread		= INIT_THREAD,					\
 	.fs		= &init_fs,					\
 	.files		= &init_files,					\
-	.sig		= &init_signals,				\
+	.signal		= &init_signals,				\
+	.sighand	= &init_sighand,				\
 	.pending	= { NULL, &tsk.pending.head, {{0}}},		\
 	.blocked	= {{0}},					\
 	.alloc_lock	= SPIN_LOCK_UNLOCKED,				\
diff -Nru a/include/linux/isdnif.h b/include/linux/isdnif.h
--- a/include/linux/isdnif.h	Mon Feb 10 10:39:22 2003
+++ b/include/linux/isdnif.h	Mon Feb 10 10:39:22 2003
@@ -62,7 +62,7 @@
 /*                                                                         */ 
 /* The proceed command holds a incoming call in a state to leave processes */
 /* enough time to check whether ist should be accepted.                    */
-/* The PROT_IO Command extends the interface to make protocol dependant    */
+/* The PROT_IO Command extends the interface to make protocol dependent    */
 /* features available (call diversion, call waiting...).                   */
 /*                                                                         */ 
 /* The PROT_IO Command is executed with the desired driver id and the arg  */
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Mon Feb 10 10:39:31 2003
+++ b/include/linux/jbd.h	Mon Feb 10 10:39:31 2003
@@ -63,7 +63,38 @@
 #define JFS_MIN_JOURNAL_BLOCKS 1024
 
 #ifdef __KERNEL__
+
+/**
+ * typedef handle_t - The handle_t type represents a single atomic update being performed by some process.
+ *
+ * All filesystem modifications made by the process go
+ * through this handle.  Recursive operations (such as quota operations)
+ * are gathered into a single update.
+ *
+ * The buffer credits field is used to account for journaled buffers
+ * being modified by the running process.  To ensure that there is
+ * enough log space for all outstanding operations, we need to limit the
+ * number of outstanding buffers possible at any time.  When the
+ * operation completes, any buffer credits not used are credited back to
+ * the transaction, so that at all times we know how many buffers the
+ * outstanding updates on a transaction might possibly touch. 
+ * 
+ * This is an opaque datatype.
+ **/
 typedef struct handle_s		handle_t;	/* Atomic operation type */
+
+
+/**
+ * typedef journal_t - The journal_t maintains all of the journaling state information for a single filesystem.
+ *
+ * journal_t is linked to from the fs superblock structure.
+ * 
+ * We use the journal_t to keep track of all outstanding transaction
+ * activity on the filesystem, and to manage the state of the log
+ * writing process.
+ *
+ * This is an opaque datatype.
+ **/
 typedef struct journal_s	journal_t;	/* Journal control structure */
 #endif
 
@@ -252,6 +283,20 @@
 }
 
 #define HAVE_JOURNAL_CALLBACK_STATUS
+/**
+ *   struct journal_callback - Base structure for callback information.
+ *   @jcb_list: list information for other callbacks attached to the same handle.
+ *   @jcb_func: Function to call with this callback structure. 
+ *
+ *   This struct is a 'seed' structure for a using with your own callback
+ *   structs. If you are using callbacks you must allocate one of these
+ *   or another struct of your own definition which has this struct 
+ *   as it's first element and pass it to journal_callback_set().
+ *
+ *   This is used internally by jbd to maintain callback information.
+ *
+ *   See journal_callback_set for more information.
+ **/
 struct journal_callback {
 	struct list_head jcb_list;
 	void (*jcb_func)(struct journal_callback *jcb, int error);
@@ -260,18 +305,21 @@
 
 struct jbd_revoke_table_s;
 
-/* The handle_t type represents a single atomic update being performed
- * by some process.  All filesystem modifications made by the process go
- * through this handle.  Recursive operations (such as quota operations)
- * are gathered into a single update.
- *
- * The buffer credits field is used to account for journaled buffers
- * being modified by the running process.  To ensure that there is
- * enough log space for all outstanding operations, we need to limit the
- * number of outstanding buffers possible at any time.  When the
- * operation completes, any buffer credits not used are credited back to
- * the transaction, so that at all times we know how many buffers the
- * outstanding updates on a transaction might possibly touch. */
+/**
+ * struct handle_s - The handle_s type is the concrete type associated with handle_t.
+ * @h_transaction: Which compound transaction is this update a part of?
+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
+ * @h_ref: Reference count on this handle
+ * @h_jcb: List of application registered callbacks for this handle.
+ * @h_err: Field for caller's use to track errors through large fs operations
+ * @h_sync: flag for sync-on-close
+ * @h_jdata: flag to force data journaling
+ * @h_aborted: flag indicating fatal error on handle
+ **/
+
+/* Docbook can't yet cope with the bit fields, but will leave the documentation
+ * in so it can be fixed later. 
+ */
 
 struct handle_s 
 {
@@ -284,8 +332,8 @@
 	/* Reference count on this handle */
 	int			h_ref;
 
-	/* Field for caller's use to track errors through large fs
-	   operations */
+	/* Field for caller's use to track errors through large fs */
+	/* operations */
 	int			h_err;
 
 	/* List of application registered callbacks for this handle.
@@ -412,21 +460,58 @@
 	struct list_head	t_jcb;
 };
 
-
-/* The journal_t maintains all of the journaling state information for a
- * single filesystem.  It is linked to from the fs superblock structure.
- * 
- * We use the journal_t to keep track of all outstanding transaction
- * activity on the filesystem, and to manage the state of the log
- * writing process. */
+/**
+ * struct journal_s - The journal_s type is the concrete type associated with journal_t.
+ * @j_flags:  General journaling state flags
+ * @j_errno:  Is there an outstanding uncleared error on the journal (from a prior abort)? 
+ * @j_sb_buffer: First part of superblock buffer
+ * @j_superblock: Second part of superblock buffer
+ * @j_format_version: Version of the superblock format
+ * @j_barrier_count:  Number of processes waiting to create a barrier lock
+ * @j_barrier: The barrier lock itself
+ * @j_running_transaction: The current running transaction..
+ * @j_committing_transaction: the transaction we are pushing to disk
+ * @j_checkpoint_transactions: a linked circular list of all transactions waiting for checkpointing
+ * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction to start committing, or for a barrier lock to be released
+ * @j_wait_logspace: Wait queue for waiting for checkpointing to complete
+ * @j_wait_done_commit: Wait queue for waiting for commit to complete 
+ * @j_wait_checkpoint:  Wait queue to trigger checkpointing
+ * @j_wait_commit: Wait queue to trigger commit
+ * @j_wait_updates: Wait queue to wait for updates to complete
+ * @j_checkpoint_sem: Semaphore for locking against concurrent checkpoints
+ * @j_sem: The main journal lock, used by lock_journal() 
+ * @j_head: Journal head - identifies the first unused block in the journal
+ * @j_tail: Journal tail - identifies the oldest still-used block in the journal.
+ * @j_free: Journal free - how many free blocks are there in the journal?
+ * @j_first: The block number of the first usable block 
+ * @j_last: The block number one beyond the last usable block
+ * @j_dev: Device where we store the journal
+ * @j_blocksize: blocksize for the location where we store the journal.
+ * @j_blk_offset: starting block offset for into the device where we store the journal
+ * @j_fs_dev: Device which holds the client fs.  For internal journal this will be equal to j_dev
+ * @j_maxlen: Total maximum capacity of the journal region on disk.
+ * @j_inode: Optional inode where we store the journal.  If present, all  journal block numbers are mapped into this inode via bmap().
+ * @j_tail_sequence:  Sequence number of the oldest transaction in the log 
+ * @j_transaction_sequence: Sequence number of the next transaction to grant
+ * @j_commit_sequence: Sequence number of the most recently committed transaction
+ * @j_commit_request: Sequence number of the most recent transaction wanting commit 
+ * @j_uuid: Uuid of client object.
+ * @j_task: Pointer to the current commit thread for this journal
+ * @j_max_transaction_buffers:  Maximum number of metadata buffers to allow in a single compound commit transaction
+ * @j_commit_interval: What is the maximum transaction lifetime before we begin a commit?
+ * @j_commit_timer:  The timer used to wakeup the commit thread
+ * @j_commit_timer_active: Timer flag
+ * @j_all_journals:  Link all journals together - system-wide 
+ * @j_revoke: The revoke table - maintains the list of revoked blocks in the current transaction.
+ **/
 
 struct journal_s
 {
 	/* General journaling state flags */
 	unsigned long		j_flags;
 
-	/* Is there an outstanding uncleared error on the journal (from
-	 * a prior abort)? */
+	/* Is there an outstanding uncleared error on the journal (from */
+	/* a prior abort)? */
 	int			j_errno;
 	
 	/* The superblock buffer */
@@ -448,13 +533,13 @@
 	/* ... the transaction we are pushing to disk ... */
 	transaction_t *		j_committing_transaction;
 	
-	/* ... and a linked circular list of all transactions waiting
-	 * for checkpointing. */
+	/* ... and a linked circular list of all transactions waiting */
+	/* for checkpointing. */
 	/* Protected by journal_datalist_lock */
 	transaction_t *		j_checkpoint_transactions;
 
-	/* Wait queue for waiting for a locked transaction to start
-           committing, or for a barrier lock to be released */
+	/* Wait queue for waiting for a locked transaction to start */
+        /*  committing, or for a barrier lock to be released */
 	wait_queue_head_t	j_wait_transaction_locked;
 	
 	/* Wait queue for waiting for checkpointing to complete */
@@ -481,33 +566,33 @@
 	/* Journal head: identifies the first unused block in the journal. */
 	unsigned long		j_head;
 	
-	/* Journal tail: identifies the oldest still-used block in the
-	 * journal. */
+	/* Journal tail: identifies the oldest still-used block in the */
+	/* journal. */
 	unsigned long		j_tail;
 
 	/* Journal free: how many free blocks are there in the journal? */
 	unsigned long		j_free;
 
-	/* Journal start and end: the block numbers of the first usable
-	 * block and one beyond the last usable block in the journal. */
+	/* Journal start and end: the block numbers of the first usable */
+	/* block and one beyond the last usable block in the journal.   */
 	unsigned long		j_first, j_last;
 
-	/* Device, blocksize and starting block offset for the location
-	 * where we store the journal. */
+	/* Device, blocksize and starting block offset for the location */
+	/* where we store the journal. */
 	struct block_device *	j_dev;
 	int			j_blocksize;
 	unsigned int		j_blk_offset;
 
-	/* Device which holds the client fs.  For internal journal this
-	 * will be equal to j_dev. */
+	/* Device which holds the client fs.  For internal journal this */
+	/* will be equal to j_dev. */
 	struct block_device *	j_fs_dev;
 
 	/* Total maximum capacity of the journal region on disk. */
 	unsigned int		j_maxlen;
 
-	/* Optional inode where we store the journal.  If present, all
-	 * journal block numbers are mapped into this inode via
-	 * bmap(). */
+	/* Optional inode where we store the journal.  If present, all */
+	/* journal block numbers are mapped into this inode via */
+	/* bmap(). */
 	struct inode *		j_inode;
 
 	/* Sequence number of the oldest transaction in the log */
@@ -519,23 +604,23 @@
 	/* Sequence number of the most recent transaction wanting commit */
 	tid_t			j_commit_request;
 
-	/* Journal uuid: identifies the object (filesystem, LVM volume
-	 * etc) backed by this journal.  This will eventually be
-	 * replaced by an array of uuids, allowing us to index multiple
-	 * devices within a single journal and to perform atomic updates
-	 * across them.  */
+	/* Journal uuid: identifies the object (filesystem, LVM volume   */
+	/* etc) backed by this journal.  This will eventually be         */
+	/* replaced by an array of uuids, allowing us to index multiple  */
+	/* devices within a single journal and to perform atomic updates */
+	/* across them.  */
 
 	__u8			j_uuid[16];
 
 	/* Pointer to the current commit thread for this journal */
 	struct task_struct *	j_task;
 
-	/* Maximum number of metadata buffers to allow in a single
-	 * compound commit transaction */
+	/* Maximum number of metadata buffers to allow in a single */
+	/* compound commit transaction */
 	int			j_max_transaction_buffers;
 
-	/* What is the maximum transaction lifetime before we begin a
-	 * commit? */
+	/* What is the maximum transaction lifetime before we begin a */
+	/* commit? */
 	unsigned long		j_commit_interval;
 
 	/* The timer used to wakeup the commit thread: */
@@ -545,8 +630,8 @@
 	/* Link all journals together - system-wide */
 	struct list_head	j_all_journals;
 
-	/* The revoke table: maintains the list of revoked blocks in the
-           current transaction. */
+	/* The revoke table: maintains the list of revoked blocks in the */
+        /*  current transaction. */
 	struct jbd_revoke_table_s *j_revoke;
 };
 
diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h
--- a/include/linux/jiffies.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/jiffies.h	Mon Feb 10 10:39:23 2003
@@ -2,14 +2,37 @@
 #define _LINUX_JIFFIES_H
 
 #include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/seqlock.h>
+#include <asm/system.h>
 #include <asm/param.h>			/* for HZ */
 
 /*
  * The 64-bit value is not volatile - you MUST NOT read it
- * without holding read_lock_irq(&xtime_lock)
+ * without holding read_lock_irq(&xtime_lock).
+ * get_jiffies_64() will do this for you as appropriate.
  */
 extern u64 jiffies_64;
 extern unsigned long volatile jiffies;
+
+static inline u64 get_jiffies_64(void)
+{
+#if BITS_PER_LONG < 64
+	extern seqlock_t xtime_lock;
+	unsigned long seq;
+	u64 tmp;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		tmp = jiffies_64;
+	} while (read_seqretry(&xtime_lock, seq));
+
+	return tmp;
+#else
+	return (u64)jiffies;
+#endif
+}
+
 
 /*
  *	These inlines deal with timer wrapping correctly. You are 
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/mm.h	Mon Feb 10 10:39:23 2003
@@ -208,24 +208,55 @@
  * Also, many kernel routines increase the page count before a critical
  * routine so they can be sure the page doesn't go away from under them.
  */
-#define get_page(p)		atomic_inc(&(p)->count)
-#define __put_page(p)		atomic_dec(&(p)->count)
 #define put_page_testzero(p)				\
 	({						\
 		BUG_ON(page_count(page) == 0);		\
 		atomic_dec_and_test(&(p)->count);	\
 	})
+
 #define page_count(p)		atomic_read(&(p)->count)
 #define set_page_count(p,v) 	atomic_set(&(p)->count, v)
+#define __put_page(p)		atomic_dec(&(p)->count)
 
 extern void FASTCALL(__page_cache_release(struct page *));
 
+#ifdef CONFIG_HUGETLB_PAGE
+
+static inline void get_page(struct page *page)
+{
+	if (PageCompound(page))
+		page = (struct page *)page->lru.next;
+	atomic_inc(&page->count);
+}
+
 static inline void put_page(struct page *page)
 {
+	if (PageCompound(page)) {
+		page = (struct page *)page->lru.next;
+		if (page->lru.prev) {	/* destructor? */
+			(*(void (*)(struct page *))page->lru.prev)(page);
+			return;
+		}
+	}
 	if (!PageReserved(page) && put_page_testzero(page))
 		__page_cache_release(page);
 }
 
+#else		/* CONFIG_HUGETLB_PAGE */
+
+static inline void get_page(struct page *page)
+{
+	atomic_inc(&page->count);
+}
+
+static inline void put_page(struct page *page)
+{
+	if (!PageReserved(page) && put_page_testzero(page))
+		__page_cache_release(page);
+}
+
+#endif		/* CONFIG_HUGETLB_PAGE */
+
 /*
  * Multiple processes may "see" the same page. E.g. for untouched
  * mappings of /dev/null, all processes see the same page full of
@@ -491,7 +522,9 @@
 
 extern unsigned long do_brk(unsigned long, unsigned long);
 
-static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
+static inline void
+__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
+		struct vm_area_struct *prev)
 {
 	prev->vm_next = vma->vm_next;
 	rb_erase(&vma->vm_rb, &mm->mm_rb);
@@ -499,7 +532,8 @@
 		mm->mmap_cache = prev;
 }
 
-static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
+static inline int
+can_vma_merge(struct vm_area_struct *vma, unsigned long vm_flags)
 {
 	if (!vma->vm_file && vma->vm_flags == vm_flags)
 		return 1;
diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h
--- a/include/linux/mmzone.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/mmzone.h	Mon Feb 10 10:39:23 2003
@@ -257,7 +257,7 @@
 
 #include <asm/topology.h>
 /* Returns the number of the current Node. */
-#define numa_node_id()		(__cpu_to_node(smp_processor_id()))
+#define numa_node_id()		(cpu_to_node(smp_processor_id()))
 
 #ifndef CONFIG_DISCONTIGMEM
 extern struct pglist_data contig_page_data;
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Mon Feb 10 10:39:30 2003
+++ b/include/linux/module.h	Mon Feb 10 10:39:30 2003
@@ -33,12 +33,19 @@
 #endif
 
 #define MODULE_NAME_LEN (64 - sizeof(unsigned long))
+
 struct kernel_symbol
 {
 	unsigned long value;
 	const char *name;
 };
 
+struct modversion_info
+{
+	unsigned long crc;
+	char name[MODULE_NAME_LEN];
+};
+
 /* These are either module local, or the kernel's dummy ones. */
 extern int init_module(void);
 extern void cleanup_module(void);
@@ -92,7 +99,7 @@
  */
 #define MODULE_LICENSE(license)					\
 	static const char __module_license[]			\
-		__attribute__((section(".init.license"))) = license
+		__attribute__((section(".init.license"), unused)) = license
 
 #else  /* !MODULE */
 
@@ -119,6 +126,7 @@
 
 	unsigned int num_syms;
 	const struct kernel_symbol *syms;
+	const unsigned long *crcs;
 };
 
 /* Given an address, look for it in the exception tables */
@@ -134,29 +142,52 @@
 
 
 #ifdef CONFIG_MODULES
+
 /* Get/put a kernel symbol (calls must be symmetric) */
 void *__symbol_get(const char *symbol);
 void *__symbol_get_gpl(const char *symbol);
 #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
 
+#ifdef __GENKSYMS__
+
+/* genksyms doesn't handle GPL-only symbols yet */
+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
+	
+#else
+
+#ifdef CONFIG_MODVERSIONS
+/* Mark the CRC weak since genksyms apparently decides not to
+ * generate a checksums for some symbols */
+#define __CRC_SYMBOL(sym, sec)					\
+	extern void *__crc_##sym __attribute__((weak));		\
+	static const unsigned long __kcrctab_##sym		\
+	__attribute__((section("__kcrctab" sec), unused))	\
+	= (unsigned long) &__crc_##sym;
+#else
+#define __CRC_SYMBOL(sym, sec)
+#endif
+
 /* For every exported symbol, place a struct in the __ksymtab section */
-#define EXPORT_SYMBOL(sym)					\
+#define __EXPORT_SYMBOL(sym, sec)				\
+	__CRC_SYMBOL(sym, sec)					\
 	static const char __kstrtab_##sym[]			\
 	__attribute__((section("__ksymtab_strings")))		\
 	= MODULE_SYMBOL_PREFIX #sym;                    	\
 	static const struct kernel_symbol __ksymtab_##sym	\
-	__attribute__((section("__ksymtab")))			\
+	__attribute__((section("__ksymtab" sec), unused))	\
 	= { (unsigned long)&sym, __kstrtab_##sym }
 
-#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL(sym)					\
+	__EXPORT_SYMBOL(sym, "")
 
 #define EXPORT_SYMBOL_GPL(sym)					\
-	static const char __kstrtab_##sym[]			\
-	__attribute__((section("__ksymtab_strings")))		\
-	= MODULE_SYMBOL_PREFIX #sym;                    	\
-	static const struct kernel_symbol __ksymtab_##sym	\
-	__attribute__((section("__gpl_ksymtab")))		\
-	= { (unsigned long)&sym, __kstrtab_##sym }
+	__EXPORT_SYMBOL(sym, "_gpl")
+
+#endif
+
+/* We don't mangle the actual symbol anymore, so no need for
+ * special casing EXPORT_SYMBOL_NOVERS */
+#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
 
 struct module_ref
 {
@@ -344,7 +375,7 @@
 }
 
 /* Get/put a kernel symbol (calls should be symmetric) */
-#define symbol_get(x) (&(x))
+#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); })
 #define symbol_put(x) do { } while(0)
 #define symbol_put_addr(x) do { } while(0)
 
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Mon Feb 10 10:39:29 2003
+++ b/include/linux/page-flags.h	Mon Feb 10 10:39:29 2003
@@ -72,7 +72,8 @@
 
 #define PG_direct		16	/* ->pte_chain points directly at pte */
 #define PG_mappedtodisk		17	/* Has blocks allocated on-disk */
-#define PG_reclaim		18	/* To be recalimed asap */
+#define PG_reclaim		18	/* To be reclaimed asap */
+#define PG_compound		19	/* Part of a compound page */
 
 /*
  * Global page accounting.  One instance per CPU.  Only unsigned longs are
@@ -97,15 +98,20 @@
 	unsigned long pswpin;		/* swap reads */
 	unsigned long pswpout;		/* swap writes */
 	unsigned long pgalloc;		/* page allocations */
+
 	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 pgscan;		/* pages scanned by page reclaim */
 	unsigned long pgrefill;		/* inspected in refill_inactive_zone */
 	unsigned long pgsteal;		/* total pages reclaimed */
+	unsigned long pginodesteal;	/* pages reclaimed via inode freeing */
 	unsigned long kswapd_steal;	/* pages reclaimed by kswapd */
+
+	unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */
 	unsigned long pageoutrun;	/* kswapd's calls to page reclaim */
 	unsigned long allocstall;	/* direct reclaim calls */
 	unsigned long pgrotated;	/* pages rotated to tail of the LRU */
@@ -245,6 +251,10 @@
 #define SetPageReclaim(page)	set_bit(PG_reclaim, &(page)->flags)
 #define ClearPageReclaim(page)	clear_bit(PG_reclaim, &(page)->flags)
 #define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags)
+
+#define PageCompound(page)	test_bit(PG_compound, &(page)->flags)
+#define SetPageCompound(page)	set_bit(PG_compound, &(page)->flags)
+#define ClearPageCompound(page)	clear_bit(PG_compound, &(page)->flags)
 
 /*
  * The PageSwapCache predicate doesn't use a PG_flag at this time,
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/pci.h	Mon Feb 10 10:39:27 2003
@@ -671,6 +671,37 @@
 extern struct pci_dev *isa_bridge;
 #endif
 
+/* Some worker functions that PCI Hotplug drivers find useful */
+struct pci_dev_wrapped {
+	struct pci_dev	*dev;
+	void		*data;
+};
+
+struct pci_bus_wrapped {
+	struct pci_bus	*bus;
+	void		*data;
+};
+
+struct pci_visit {
+	int (* pre_visit_pci_bus)	(struct pci_bus_wrapped *,
+					 struct pci_dev_wrapped *);
+	int (* post_visit_pci_bus)	(struct pci_bus_wrapped *,
+					 struct pci_dev_wrapped *);
+
+	int (* pre_visit_pci_dev)	(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+	int (* visit_pci_dev)		(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+	int (* post_visit_pci_dev)	(struct pci_dev_wrapped *,
+					 struct pci_bus_wrapped *);
+};
+
+extern int pci_visit_dev(struct pci_visit *fn,
+			 struct pci_dev_wrapped *wrapped_dev,
+			 struct pci_bus_wrapped *wrapped_parent);
+extern int pci_is_dev_in_use(struct pci_dev *dev);
+extern int pci_remove_device_safe(struct pci_dev *dev);
+
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Mon Feb 10 10:39:26 2003
+++ b/include/linux/pci_ids.h	Mon Feb 10 10:39:26 2003
@@ -582,7 +582,10 @@
 #define PCI_DEVICE_ID_SI_7016		0x7016
 
 #define PCI_VENDOR_ID_HP		0x103c
-#define PCI_DEVICE_ID_HP_DONNER_GFX	0x1008
+#define PCI_DEVICE_ID_HP_VISUALIZE_EG	0x1005
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX6	0x1006
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX4	0x1008
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX2	0x100a
 #define PCI_DEVICE_ID_HP_TACHYON	0x1028
 #define PCI_DEVICE_ID_HP_TACHLITE	0x1029
 #define PCI_DEVICE_ID_HP_J2585A		0x1030
@@ -591,6 +594,7 @@
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA1	0x1049
 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2	0x104A
 #define PCI_DEVICE_ID_HP_DIVA_MAESTRO	0x104B
+#define PCI_DEVICE_ID_HP_VISUALIZE_FXE	0x108b
 #define PCI_DEVICE_ID_HP_DIVA_HALFDOME	0x1223
 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE	0x1226
 #define PCI_DEVICE_ID_HP_DIVA_POWERBAR	0x1227
@@ -1661,6 +1665,9 @@
 #define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
 #define PCI_DEVICE_ID_TIGON3_5702X	0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
+#define PCI_DEVICE_ID_TIGON3_5704S	0x16a8
+#define PCI_DEVICE_ID_TIGON3_5702A3	0x16c6
+#define PCI_DEVICE_ID_TIGON3_5703A3	0x16c7
 #define PCI_DEVICE_ID_BCM4401		0x4401
 
 #define PCI_VENDOR_ID_SYBA		0x1592
diff -Nru a/include/linux/ptrace.h b/include/linux/ptrace.h
--- a/include/linux/ptrace.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/ptrace.h	Mon Feb 10 10:39:23 2003
@@ -26,6 +26,8 @@
 /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
 #define PTRACE_SETOPTIONS	0x4200
 #define PTRACE_GETEVENTMSG	0x4201
+#define PTRACE_GETSIGINFO	0x4202
+#define PTRACE_SETSIGINFO	0x4203
 
 /* options set using PTRACE_SETOPTIONS */
 #define PTRACE_O_TRACESYSGOOD	0x00000001
@@ -33,12 +35,16 @@
 #define PTRACE_O_TRACEVFORK	0x00000004
 #define PTRACE_O_TRACECLONE	0x00000008
 #define PTRACE_O_TRACEEXEC	0x00000010
+#define PTRACE_O_TRACEVFORKDONE	0x00000020
+#define PTRACE_O_TRACEEXIT	0x00000040
 
 /* Wait extended result codes for the above trace options.  */
 #define PTRACE_EVENT_FORK	1
 #define PTRACE_EVENT_VFORK	2
 #define PTRACE_EVENT_CLONE	3
 #define PTRACE_EVENT_EXEC	4
+#define PTRACE_EVENT_VFORK_DONE	5
+#define PTRACE_EVENT_EXIT	6
 
 #include <asm/ptrace.h>
 #include <linux/sched.h>
diff -Nru a/include/linux/quota.h b/include/linux/quota.h
--- a/include/linux/quota.h	Mon Feb 10 10:39:30 2003
+++ b/include/linux/quota.h	Mon Feb 10 10:39:30 2003
@@ -280,7 +280,8 @@
 struct quota_info {
 	unsigned int flags;			/* Flags for diskquotas on this device */
 	struct semaphore dqio_sem;		/* lock device while I/O in progress */
-	struct rw_semaphore dqoff_sem;		/* serialize quota_off() and quota_on() on device and ops using quota_info struct, pointers from inode to dquots */
+	struct semaphore dqonoff_sem;		/* Serialize quotaon & quotaoff */
+	struct rw_semaphore dqptr_sem;		/* serialize ops using quota_info struct, pointers from inode to dquots */
 	struct file *files[MAXQUOTAS];		/* fp's to quotafiles */
 	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
 	struct quota_format_ops *ops[MAXQUOTAS];	/* Operations for each type */
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/sched.h	Mon Feb 10 10:39:23 2003
@@ -201,7 +201,9 @@
 	unsigned long swap_address;
 
 	unsigned dumpable:1;
-
+#ifdef CONFIG_HUGETLB_PAGE
+	int used_hugetlb;
+#endif
 	/* Architecture-specific MM context */
 	mm_context_t context;
 
@@ -218,10 +220,21 @@
 
 extern int mmlist_nr;
 
-struct signal_struct {
+struct sighand_struct {
 	atomic_t		count;
 	struct k_sigaction	action[_NSIG];
 	spinlock_t		siglock;
+};
+
+/*
+ * NOTE! "signal_struct" does not have it's own
+ * locking, because a shared signal_struct always
+ * implies a shared sighand_struct, so locking
+ * sighand_struct is always a proper superset of
+ * the locking of signal_struct.
+ */
+struct signal_struct {
+	atomic_t		count;
 
 	/* current thread group signal load-balancing target: */
 	task_t			*curr_target;
@@ -233,6 +246,9 @@
 	int			group_exit;
 	int			group_exit_code;
 	struct task_struct	*group_exit_task;
+
+	/* thread group stop support, overloads group_exit_code too */
+	int			group_stop_count;
 };
 
 /*
@@ -343,7 +359,7 @@
 	unsigned long it_real_incr, it_prof_incr, it_virt_incr;
 	struct timer_list real_timer;
 	unsigned long utime, stime, cutime, cstime;
-	unsigned long start_time;
+	u64 start_time;
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
 /* process credentials */
@@ -373,7 +389,8 @@
 /* namespace */
 	struct namespace *namespace;
 /* signal handlers */
-	struct signal_struct *sig;
+	struct signal_struct *signal;
+	struct sighand_struct *sighand;
 
 	sigset_t blocked, real_blocked;
 	struct sigpending pending;
@@ -400,6 +417,7 @@
 	struct backing_dev_info *backing_dev_info;
 
 	unsigned long ptrace_message;
+	siginfo_t *last_siginfo; /* For ptrace use.  */
 };
 
 extern void __put_task_struct(struct task_struct *tsk);
@@ -440,6 +458,8 @@
 #define PT_TRACE_VFORK	0x00000020
 #define PT_TRACE_CLONE	0x00000040
 #define PT_TRACE_EXEC	0x00000080
+#define PT_TRACE_VFORK_DONE	0x00000100
+#define PT_TRACE_EXIT	0x00000200
 
 #if CONFIG_SMP
 extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
@@ -483,6 +503,8 @@
 extern struct   mm_struct init_mm;
 
 extern struct task_struct *find_task_by_pid(int pid);
+extern void set_special_pids(pid_t session, pid_t pgrp);
+extern void __set_special_pids(pid_t session, pid_t pgrp);
 
 /* per-UID process charging. */
 extern struct user_struct * alloc_uid(uid_t);
@@ -494,6 +516,7 @@
 extern unsigned long itimer_next;
 extern void do_timer(struct pt_regs *);
 
+extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
 extern void FASTCALL(sched_exit(task_t * p));
@@ -506,7 +529,6 @@
 extern void proc_caches_init(void);
 extern void flush_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *);
-extern void sig_exit(int, int, struct siginfo *);
 extern int dequeue_signal(sigset_t *mask, siginfo_t *info);
 extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 			      sigset_t *mask);
@@ -523,7 +545,7 @@
 extern void force_sig(int, struct task_struct *);
 extern void force_sig_specific(int, struct task_struct *);
 extern int send_sig(int, struct task_struct *, int);
-extern int __broadcast_thread_group(struct task_struct *p, int sig);
+extern void zap_other_threads(struct task_struct *p);
 extern int kill_pg(pid_t, int, int);
 extern int kill_sl(pid_t, int, int);
 extern int kill_proc(pid_t, int, int);
@@ -585,9 +607,13 @@
 
 extern void exit_mm(struct task_struct *);
 extern void exit_files(struct task_struct *);
+extern void exit_signal(struct task_struct *);
+extern void __exit_signal(struct task_struct *);
 extern void exit_sighand(struct task_struct *);
 extern void __exit_sighand(struct task_struct *);
 
+extern NORET_TYPE void do_group_exit(int);
+
 extern void reparent_to_init(void);
 extern void daemonize(void);
 extern task_t *child_reaper;
@@ -755,10 +781,12 @@
 
 /* Reevaluate whether the task has signals pending delivery.
    This is required every time the blocked sigset_t changes.
-   callers must hold sig->siglock.  */
+   callers must hold sighand->siglock.  */
 
 extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t));
 extern void recalc_sigpending(void);
+
+extern void signal_wake_up(struct task_struct *t, int resume_stopped);
 
 /*
  * Wrappers for p->thread_info->cpu access. No-op on UP.
diff -Nru a/include/linux/sdla_x25.h b/include/linux/sdla_x25.h
--- a/include/linux/sdla_x25.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/sdla_x25.h	Mon Feb 10 10:39:27 2003
@@ -157,7 +157,7 @@
 #define X25RES_PROTO_VIOLATION	0x41	/* protocol violation occured */
 #define X25RES_PKT_TIMEOUT	0x42	/* X.25 packet time out */
 #define X25RES_PKT_RETRY_LIMIT	0x43	/* X.25 packet retry limit exceeded */
-/*----- Command-dependant results -----*/
+/*----- Command-dependent results -----*/
 #define X25RES_LINK_DISC	0x00	/* HDLC_LINK_STATUS */
 #define X25RES_LINK_IN_ABM	0x01	/* HDLC_LINK_STATUS */
 #define X25RES_NO_DATA		0x01	/* HDLC_READ/READ_TRACE_DATA*/
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h	Mon Feb 10 10:39:30 2003
+++ b/include/linux/security.h	Mon Feb 10 10:39:30 2003
@@ -31,7 +31,8 @@
 #include <linux/shm.h>
 #include <linux/msg.h>
 #include <linux/sched.h>
-
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
 
 /*
  * These functions are in security/capability.c and are used
@@ -48,6 +49,20 @@
 extern void cap_task_kmod_set_label (void);
 extern void cap_task_reparent_to_init (struct task_struct *p);
 
+static inline int cap_netlink_send (struct sk_buff *skb)
+{
+	NETLINK_CB (skb).eff_cap = current->cap_effective;
+	return 0;
+}
+
+static inline int cap_netlink_recv (struct sk_buff *skb)
+{
+	if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
+		return -EPERM;
+	return 0;
+}
+
+
 /*
  * Values used in the task_security_ops calls
  */
@@ -63,16 +78,13 @@
 /* setfsuid or setfsgid, id0 == fsuid or fsgid */
 #define LSM_SETID_FS	8
 
-
-#ifdef CONFIG_SECURITY
-
 /* forward declares to avoid warnings */
-struct sk_buff;
-struct net_device;
 struct nfsctl_arg;
 struct sched_param;
 struct swap_info_struct;
 
+#ifdef CONFIG_SECURITY
+
 /**
  * struct security_operations - main security structure
  *
@@ -586,6 +598,149 @@
  * 	is being reparented to the init task.
  *	@p contains the task_struct for the kernel thread.
  *
+ * Security hooks for Netlink messaging.
+ *
+ * @netlink_send:
+ *	Save security information for a netlink message so that permission
+ *	checking can be performed when the message is processed.  The security
+ *	information can be saved using the eff_cap field of the
+ *      netlink_skb_parms structure.
+ *	@skb contains the sk_buff structure for the netlink message.
+ *	Return 0 if the information was successfully saved.
+ * @netlink_recv:
+ *	Check permission before processing the received netlink message in
+ *	@skb.
+ *	@skb contains the sk_buff structure for the netlink message.
+ *	Return 0 if permission is granted.
+ *
+ * Security hooks for Unix domain networking.
+ *
+ * @unix_stream_connect:
+ *	Check permissions before establishing a Unix domain stream connection
+ *	between @sock and @other.
+ *	@sock contains the socket structure.
+ *	@other contains the peer socket structure.
+ *	Return 0 if permission is granted.
+ * @unix_may_send:
+ *	Check permissions before connecting or sending datagrams from @sock to
+ *	@other.
+ *	@sock contains the socket structure.
+ *	@sock contains the peer socket structure.
+ *	Return 0 if permission is granted.
+ *
+ * The @unix_stream_connect and @unix_may_send hooks were necessary because
+ * Linux provides an alternative to the conventional file name space for Unix
+ * domain sockets.  Whereas binding and connecting to sockets in the file name
+ * space is mediated by the typical file permissions (and caught by the mknod
+ * and permission hooks in inode_security_ops), binding and connecting to
+ * sockets in the abstract name space is completely unmediated.  Sufficient
+ * control of Unix domain sockets in the abstract name space isn't possible
+ * using only the socket layer hooks, since we need to know the actual target
+ * socket, which is not looked up until we are inside the af_unix code.
+ *
+ * Security hooks for socket operations.
+ *
+ * @socket_create:
+ *	Check permissions prior to creating a new socket.
+ *	@family contains the requested protocol family.
+ *	@type contains the requested communications type.
+ *	@protocol contains the requested protocol.
+ *	Return 0 if permission is granted.
+ * @socket_post_create:
+ *	This hook allows a module to update or allocate a per-socket security
+ *	structure. Note that the security field was not added directly to the
+ *	socket structure, but rather, the socket security information is stored
+ *	in the associated inode.  Typically, the inode alloc_security hook will
+ *	allocate and and attach security information to
+ *	sock->inode->i_security.  This hook may be used to update the
+ *	sock->inode->i_security field with additional information that wasn't
+ *	available when the inode was allocated.
+ *	@sock contains the newly created socket structure.
+ *	@family contains the requested protocol family.
+ *	@type contains the requested communications type.
+ *	@protocol contains the requested protocol.
+ * @socket_bind:
+ *	Check permission before socket protocol layer bind operation is
+ *	performed and the socket @sock is bound to the address specified in the
+ *	@address parameter.
+ *	@sock contains the socket structure.
+ *	@address contains the address to bind to.
+ *	@addrlen contains the length of address.
+ *	Return 0 if permission is granted.  
+ * @socket_connect:
+ *	Check permission before socket protocol layer connect operation
+ *	attempts to connect socket @sock to a remote address, @address.
+ *	@sock contains the socket structure.
+ *	@address contains the address of remote endpoint.
+ *	@addrlen contains the length of address.
+ *	Return 0 if permission is granted.  
+ * @socket_listen:
+ *	Check permission before socket protocol layer listen operation.
+ *	@sock contains the socket structure.
+ *	@backlog contains the maximum length for the pending connection queue.
+ *	Return 0 if permission is granted.
+ * @socket_accept:
+ *	Check permission before accepting a new connection.  Note that the new
+ *	socket, @newsock, has been created and some information copied to it,
+ *	but the accept operation has not actually been performed.
+ *	@sock contains the listening socket structure.
+ *	@newsock contains the newly created server socket for connection.
+ *	Return 0 if permission is granted.
+ * @socket_post_accept:
+ *	This hook allows a security module to copy security
+ *	information into the newly created socket's inode.
+ *	@sock contains the listening socket structure.
+ *	@newsock contains the newly created server socket for connection.
+ * @socket_sendmsg:
+ *	Check permission before transmitting a message to another socket.
+ *	@sock contains the socket structure.
+ *	@msg contains the message to be transmitted.
+ *	@size contains the size of message.
+ *	Return 0 if permission is granted.
+ * @socket_recvmsg:
+ *	Check permission before receiving a message from a socket.
+ *	@sock contains the socket structure.
+ *	@msg contains the message structure.
+ *	@size contains the size of message structure.
+ *	@flags contains the operational flags.
+ *	Return 0 if permission is granted.  
+ * @socket_getsockname:
+ *	Check permission before the local address (name) of the socket object
+ *	@sock is retrieved.
+ *	@sock contains the socket structure.
+ *	Return 0 if permission is granted.
+ * @socket_getpeername:
+ *	Check permission before the remote address (name) of a socket object
+ *	@sock is retrieved.
+ *	@sock contains the socket structure.
+ *	Return 0 if permission is granted.
+ * @socket_getsockopt:
+ *	Check permissions before retrieving the options associated with socket
+ *	@sock.
+ *	@sock contains the socket structure.
+ *	@level contains the protocol level to retrieve option from.
+ *	@optname contains the name of option to retrieve.
+ *	Return 0 if permission is granted.
+ * @socket_setsockopt:
+ *	Check permissions before setting the options associated with socket
+ *	@sock.
+ *	@sock contains the socket structure.
+ *	@level contains the protocol level to set options for.
+ *	@optname contains the name of the option to set.
+ *	Return 0 if permission is granted.  
+ * @socket_shutdown:
+ *	Checks permission before all or part of a connection on the socket
+ *	@sock is shut down.
+ *	@sock contains the socket structure.
+ *	@how contains the flag indicating how future sends and receives are handled.
+ *	Return 0 if permission is granted.
+ * @socket_sock_rcv_skb:
+ *	Check permissions on incoming network packets.  This hook is distinct
+ *	from Netfilter's IP input hooks since it is the first time that the
+ *	incoming sk_buff @skb has been associated with a particular socket, @sk.
+ *	@sk contains the sock (not socket) associated with the incoming sk_buff.
+ *	@skb contains the incoming network data.
+ *
  * Security hooks affecting all System V IPC operations.
  *
  * @ipc_permission:
@@ -947,11 +1102,42 @@
 	int (*sem_semop) (struct sem_array * sma, 
 			  struct sembuf * sops, unsigned nsops, int alter);
 
+	int (*netlink_send) (struct sk_buff * skb);
+	int (*netlink_recv) (struct sk_buff * skb);
+
 	/* allow module stacking */
 	int (*register_security) (const char *name,
 	                          struct security_operations *ops);
 	int (*unregister_security) (const char *name,
 	                            struct security_operations *ops);
+
+#ifdef CONFIG_SECURITY_NETWORK
+	int (*unix_stream_connect) (struct socket * sock,
+				    struct socket * other, struct sock * newsk);
+	int (*unix_may_send) (struct socket * sock, struct socket * other);
+
+	int (*socket_create) (int family, int type, int protocol);
+	void (*socket_post_create) (struct socket * sock, int family,
+				    int type, int protocol);
+	int (*socket_bind) (struct socket * sock,
+			    struct sockaddr * address, int addrlen);
+	int (*socket_connect) (struct socket * sock,
+			       struct sockaddr * address, int addrlen);
+	int (*socket_listen) (struct socket * sock, int backlog);
+	int (*socket_accept) (struct socket * sock, struct socket * newsock);
+	void (*socket_post_accept) (struct socket * sock,
+				    struct socket * newsock);
+	int (*socket_sendmsg) (struct socket * sock,
+			       struct msghdr * msg, int size);
+	int (*socket_recvmsg) (struct socket * sock,
+			       struct msghdr * msg, int size, int flags);
+	int (*socket_getsockname) (struct socket * sock);
+	int (*socket_getpeername) (struct socket * sock);
+	int (*socket_getsockopt) (struct socket * sock, int level, int optname);
+	int (*socket_setsockopt) (struct socket * sock, int level, int optname);
+	int (*socket_shutdown) (struct socket * sock, int how);
+	int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
+#endif	/* CONFIG_SECURITY_NETWORK */
 };
 
 /* global variables */
@@ -1543,6 +1729,16 @@
 	return security_ops->sem_semop(sma, sops, nsops, alter);
 }
 
+static inline int security_netlink_send(struct sk_buff * skb)
+{
+	return security_ops->netlink_send(skb);
+}
+
+static inline int security_netlink_recv(struct sk_buff * skb)
+{
+	return security_ops->netlink_recv(skb);
+}
+
 /* prototypes */
 extern int security_scaffolding_startup	(void);
 extern int register_security	(struct security_operations *ops);
@@ -2104,7 +2300,228 @@
 	return 0;
 }
 
+/*
+ * The netlink capability defaults need to be used inline by default
+ * (rather than hooking into the capability module) to reduce overhead
+ * in the networking code.
+ */
+static inline int security_netlink_send (struct sk_buff *skb)
+{
+	return cap_netlink_send (skb);
+}
+
+static inline int security_netlink_recv (struct sk_buff *skb)
+{
+	return cap_netlink_recv (skb);
+}
+
 #endif	/* CONFIG_SECURITY */
+
+#ifdef CONFIG_SECURITY_NETWORK
+static inline int security_unix_stream_connect(struct socket * sock,
+					       struct socket * other, 
+					       struct sock * newsk)
+{
+	return security_ops->unix_stream_connect(sock, other, newsk);
+}
+
+
+static inline int security_unix_may_send(struct socket * sock, 
+					 struct socket * other)
+{
+	return security_ops->unix_may_send(sock, other);
+}
+
+static inline int security_socket_create (int family, int type, int protocol)
+{
+	return security_ops->socket_create(family, type, protocol);
+}
+
+static inline void security_socket_post_create(struct socket * sock, 
+					       int family,
+					       int type, 
+					       int protocol)
+{
+	security_ops->socket_post_create(sock, family, type, protocol);
+}
+
+static inline int security_socket_bind(struct socket * sock, 
+				       struct sockaddr * address, 
+				       int addrlen)
+{
+	return security_ops->socket_bind(sock, address, addrlen);
+}
+
+static inline int security_socket_connect(struct socket * sock, 
+					  struct sockaddr * address, 
+					  int addrlen)
+{
+	return security_ops->socket_connect(sock, address, addrlen);
+}
+
+static inline int security_socket_listen(struct socket * sock, int backlog)
+{
+	return security_ops->socket_listen(sock, backlog);
+}
+
+static inline int security_socket_accept(struct socket * sock, 
+					 struct socket * newsock)
+{
+	return security_ops->socket_accept(sock, newsock);
+}
+
+static inline void security_socket_post_accept(struct socket * sock, 
+					       struct socket * newsock)
+{
+	security_ops->socket_post_accept(sock, newsock);
+}
+
+static inline int security_socket_sendmsg(struct socket * sock, 
+					  struct msghdr * msg, int size)
+{
+	return security_ops->socket_sendmsg(sock, msg, size);
+}
+
+static inline int security_socket_recvmsg(struct socket * sock, 
+					  struct msghdr * msg, int size, 
+					  int flags)
+{
+	return security_ops->socket_recvmsg(sock, msg, size, flags);
+}
+
+static inline int security_socket_getsockname(struct socket * sock)
+{
+	return security_ops->socket_getsockname(sock);
+}
+
+static inline int security_socket_getpeername(struct socket * sock)
+{
+	return security_ops->socket_getpeername(sock);
+}
+
+static inline int security_socket_getsockopt(struct socket * sock, 
+					     int level, int optname)
+{
+	return security_ops->socket_getsockopt(sock, level, optname);
+}
+
+static inline int security_socket_setsockopt(struct socket * sock, 
+					     int level, int optname)
+{
+	return security_ops->socket_setsockopt(sock, level, optname);
+}
+
+static inline int security_socket_shutdown(struct socket * sock, int how)
+{
+	return security_ops->socket_shutdown(sock, how);
+}
+
+static inline int security_sock_rcv_skb (struct sock * sk, 
+					 struct sk_buff * skb)
+{
+	return security_ops->socket_sock_rcv_skb (sk, skb);
+}
+#else	/* CONFIG_SECURITY_NETWORK */
+static inline int security_unix_stream_connect(struct socket * sock,
+					       struct socket * other, 
+					       struct sock * newsk)
+{
+	return 0;
+}
+
+static inline int security_unix_may_send(struct socket * sock, 
+					 struct socket * other)
+{
+	return 0;
+}
+
+static inline int security_socket_create (int family, int type, int protocol)
+{
+	return 0;
+}
+
+static inline void security_socket_post_create(struct socket * sock, 
+					       int family,
+					       int type, 
+					       int protocol)
+{
+}
+
+static inline int security_socket_bind(struct socket * sock, 
+				       struct sockaddr * address, 
+				       int addrlen)
+{
+	return 0;
+}
+
+static inline int security_socket_connect(struct socket * sock, 
+					  struct sockaddr * address, 
+					  int addrlen)
+{
+	return 0;
+}
+
+static inline int security_socket_listen(struct socket * sock, int backlog)
+{
+	return 0;
+}
+
+static inline int security_socket_accept(struct socket * sock, 
+					 struct socket * newsock)
+{
+	return 0;
+}
+
+static inline void security_socket_post_accept(struct socket * sock, 
+					       struct socket * newsock)
+{
+}
+
+static inline int security_socket_sendmsg(struct socket * sock, 
+					  struct msghdr * msg, int size)
+{
+	return 0;
+}
+
+static inline int security_socket_recvmsg(struct socket * sock, 
+					  struct msghdr * msg, int size, 
+					  int flags)
+{
+	return 0;
+}
+
+static inline int security_socket_getsockname(struct socket * sock)
+{
+	return 0;
+}
+
+static inline int security_socket_getpeername(struct socket * sock)
+{
+	return 0;
+}
+
+static inline int security_socket_getsockopt(struct socket * sock, 
+					     int level, int optname)
+{
+	return 0;
+}
+
+static inline int security_socket_setsockopt(struct socket * sock, 
+					     int level, int optname)
+{
+	return 0;
+}
+
+static inline int security_socket_shutdown(struct socket * sock, int how)
+{
+	return 0;
+}
+static inline int security_sock_rcv_skb (struct sock * sk, 
+					 struct sk_buff * skb)
+{
+	return 0;
+}
+#endif	/* CONFIG_SECURITY_NETWORK */
 
 #endif /* ! __LINUX_SECURITY_H */
 
diff -Nru a/include/linux/seqlock.h b/include/linux/seqlock.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/seqlock.h	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,124 @@
+#ifndef __LINUX_SEQLOCK_H
+#define __LINUX_SEQLOCK_H
+/*
+ * Reader/writer consistent mechanism without starving writers. This type of
+ * lock for data where the reader wants a consitent set of information
+ * and is willing to retry if the information changes.  Readers never
+ * block but they may have to retry if a writer is in
+ * progress. Writers do not wait for readers. 
+ *
+ * This is not as cache friendly as brlock. Also, this will not work
+ * for data that contains pointers, because any writer could
+ * invalidate a pointer that a reader was following.
+ *
+ * Expected reader usage:
+ * 	do {
+ *	    seq = read_seqbegin(&foo);
+ * 	...
+ *      } while (read_seqretry(&foo, seq));
+ *
+ *
+ * On non-SMP the spin locks disappear but the writer still needs
+ * to increment the sequence variables because an interrupt routine could
+ * change the state of the data.
+ *
+ * Based on x86_64 vsyscall gettimeofday 
+ * by Keith Owens and Andrea Arcangeli
+ */
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/preempt.h>
+
+typedef struct {
+	unsigned sequence;
+	spinlock_t lock;
+} seqlock_t;
+
+/*
+ * These macros triggered gcc-3.x compile-time problems.  We think these are
+ * OK now.  Be cautious.
+ */
+#define SEQLOCK_UNLOCKED { 0, SPIN_LOCK_UNLOCKED }
+#define seqlock_init(x)	do { *(x) = (seqlock_t) SEQLOCK_UNLOCKED; } while (0)
+
+
+/* Lock out other writers and update the count.
+ * Acts like a normal spin_lock/unlock.
+ * Don't need preempt_disable() because that is in the spin_lock already.
+ */
+static inline void write_seqlock(seqlock_t *sl)
+{
+	spin_lock(&sl->lock);
+	++sl->sequence;
+	smp_wmb();			
+}	
+
+static inline void write_sequnlock(seqlock_t *sl) 
+{
+	smp_wmb();
+	sl->sequence++;
+	spin_unlock(&sl->lock);
+}
+
+static inline int write_tryseqlock(seqlock_t *sl)
+{
+	int ret = spin_trylock(&sl->lock);
+
+	if (ret) {
+		++sl->sequence;
+		smp_wmb();			
+	}
+	return ret;
+}
+
+/* Start of read calculation -- fetch last complete writer token */
+static inline unsigned read_seqbegin(const seqlock_t *sl)
+{
+	unsigned ret = sl->sequence;
+	smp_rmb();
+	return ret;
+}
+
+/* Test if reader processed invalid data.
+ * If initial values is odd, 
+ *	then writer had already started when section was entered
+ * If sequence value changed
+ *	then writer changed data while in section
+ *    
+ * Using xor saves one conditional branch.
+ */
+static inline int read_seqretry(const seqlock_t *sl, unsigned iv)
+{
+	smp_rmb();
+	return (iv & 1) | (sl->sequence ^ iv);
+}
+
+/*
+ * Possible sw/hw IRQ protected versions of the interfaces.
+ */
+#define write_seqlock_irqsave(lock, flags)				\
+	do { local_irq_save(flags); write_seqlock(lock); } while (0)
+#define write_seqlock_irq(lock)						\
+	do { local_irq_disable();   write_seqlock(lock); } while (0)
+#define write_seqlock_bh(lock)						\
+        do { local_bh_disable();    write_seqlock(lock); } while (0)
+
+#define write_sequnlock_irqrestore(lock, flags)				\
+	do { write_sequnlock(lock); local_irq_restore(flags); } while(0)
+#define write_sequnlock_irq(lock)					\
+	do { write_sequnlock(lock); local_irq_enable(); } while(0)
+#define write_sequnlock_bh(lock)					\
+	do { write_sequnlock(lock); local_bh_enable(); } while(0)
+
+#define read_seqbegin_irqsave(lock, flags)				\
+	({ local_irq_save(flags);   read_seqbegin(lock); })
+
+#define read_seqretry_irqrestore(lock, iv, flags)			\
+	({								\
+		int ret = read_seqretry(lock, iv);			\
+		local_irq_restore(flags);				\
+		ret;							\
+	})
+
+#endif /* __LINUX_SEQLOCK_H */
diff -Nru a/include/linux/signal.h b/include/linux/signal.h
--- a/include/linux/signal.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/signal.h	Mon Feb 10 10:39:24 2003
@@ -204,6 +204,7 @@
 }
 
 extern long do_sigpending(void *, unsigned long);
+extern int sigprocmask(int, sigset_t *, sigset_t *);
 
 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 struct pt_regs;
diff -Nru a/include/linux/slab.h b/include/linux/slab.h
--- a/include/linux/slab.h	Mon Feb 10 10:39:33 2003
+++ b/include/linux/slab.h	Mon Feb 10 10:39:33 2003
@@ -17,13 +17,12 @@
 /* flags for kmem_cache_alloc() */
 #define	SLAB_NOFS		GFP_NOFS
 #define	SLAB_NOIO		GFP_NOIO
-#define SLAB_NOHIGHIO		GFP_NOHIGHIO
 #define	SLAB_ATOMIC		GFP_ATOMIC
 #define	SLAB_USER		GFP_USER
 #define	SLAB_KERNEL		GFP_KERNEL
 #define	SLAB_DMA		GFP_DMA
 
-#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS|__GFP_COLD|__GFP_NOWARN)
+#define SLAB_LEVEL_MASK		(__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|__GFP_COLD|__GFP_NOWARN)
 #define	SLAB_NO_GROW		0x00001000UL	/* don't grow a cache */
 
 /* flags to pass to kmem_cache_create().
@@ -72,7 +71,8 @@
 extern kmem_cache_t	*filp_cachep;
 extern kmem_cache_t	*dquot_cachep;
 extern kmem_cache_t	*fs_cachep;
-extern kmem_cache_t	*sigact_cachep;
+extern kmem_cache_t	*signal_cachep;
+extern kmem_cache_t	*sighand_cachep;
 extern kmem_cache_t	*bio_cachep;
 
 #endif	/* __KERNEL__ */
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/spinlock.h	Mon Feb 10 10:39:27 2003
@@ -37,30 +37,120 @@
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
 
-/*
- * !CONFIG_SMP and spin_lock_init not previously defined
- * (e.g. by including include/asm/spinlock.h)
- */
-#elif !defined(spin_lock_init)
+#else
 
-#ifndef CONFIG_PREEMPT
+#if !defined(CONFIG_PREEMPT) && !defined(CONFIG_DEBUG_SPINLOCK)
 # define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
 # define ATOMIC_DEC_AND_LOCK
 #endif
 
+#ifdef CONFIG_DEBUG_SPINLOCK
+ 
+#define SPINLOCK_MAGIC	0x1D244B3C
+typedef struct {
+	unsigned long magic;
+	volatile unsigned long lock;
+	volatile unsigned int babble;
+	const char *module;
+	char *owner;
+	int oline;
+} spinlock_t;
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0}
+
+#define spin_lock_init(x) \
+	do { \
+		(x)->magic = SPINLOCK_MAGIC; \
+		(x)->lock = 0; \
+		(x)->babble = 5; \
+		(x)->module = __FILE__; \
+		(x)->owner = NULL; \
+		(x)->oline = 0; \
+	} while (0)
+
+#define CHECK_LOCK(x) \
+	do { \
+	 	if ((x)->magic != SPINLOCK_MAGIC) { \
+			printk(KERN_ERR "%s:%d: spin_is_locked on uninitialized spinlock %p.\n", \
+					__FILE__, __LINE__, (x)); \
+		} \
+	} while(0)
+
+#define _raw_spin_lock(x)		\
+	do { \
+	 	CHECK_LOCK(x); \
+		if ((x)->lock&&(x)->babble) { \
+			printk("%s:%d: spin_lock(%s:%p) already locked by %s/%d\n", \
+					__FILE__,__LINE__, (x)->module, \
+					(x), (x)->owner, (x)->oline); \
+			(x)->babble--; \
+		} \
+		(x)->lock = 1; \
+		(x)->owner = __FILE__; \
+		(x)->oline = __LINE__; \
+	} while (0)
+
+/* without debugging, spin_is_locked on UP always says
+ * FALSE. --> printk if already locked. */
+#define spin_is_locked(x) \
+	({ \
+	 	CHECK_LOCK(x); \
+		if ((x)->lock&&(x)->babble) { \
+			printk("%s:%d: spin_is_locked(%s:%p) already locked by %s/%d\n", \
+					__FILE__,__LINE__, (x)->module, \
+					(x), (x)->owner, (x)->oline); \
+			(x)->babble--; \
+		} \
+		0; \
+	})
+
+/* without debugging, spin_trylock on UP always says
+ * TRUE. --> printk if already locked. */
+#define _raw_spin_trylock(x) \
+	({ \
+	 	CHECK_LOCK(x); \
+		if ((x)->lock&&(x)->babble) { \
+			printk("%s:%d: spin_trylock(%s:%p) already locked by %s/%d\n", \
+					__FILE__,__LINE__, (x)->module, \
+					(x), (x)->owner, (x)->oline); \
+			(x)->babble--; \
+		} \
+		(x)->lock = 1; \
+		(x)->owner = __FILE__; \
+		(x)->oline = __LINE__; \
+		1; \
+	})
+
+#define spin_unlock_wait(x)	\
+	do { \
+	 	CHECK_LOCK(x); \
+		if ((x)->lock&&(x)->babble) { \
+			printk("%s:%d: spin_unlock_wait(%s:%p) owned by %s/%d\n", \
+					__FILE__,__LINE__, (x)->module, (x), \
+					(x)->owner, (x)->oline); \
+			(x)->babble--; \
+		}\
+	} while (0)
+
+#define _raw_spin_unlock(x) \
+	do { \
+	 	CHECK_LOCK(x); \
+		if (!(x)->lock&&(x)->babble) { \
+			printk("%s:%d: spin_unlock(%s:%p) not locked\n", \
+					__FILE__,__LINE__, (x)->module, (x));\
+			(x)->babble--; \
+		} \
+		(x)->lock = 0; \
+	} while (0)
+#else
 /*
  * gcc versions before ~2.95 have a nasty bug with empty initializers.
  */
 #if (__GNUC__ > 2)
   typedef struct { } spinlock_t;
-  typedef struct { } rwlock_t;
   #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
-  #define RW_LOCK_UNLOCKED (rwlock_t) { }
 #else
   typedef struct { int gcc_is_buggy; } spinlock_t;
-  typedef struct { int gcc_is_buggy; } rwlock_t;
   #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-  #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 #endif
 
 /*
@@ -72,6 +162,18 @@
 #define _raw_spin_trylock(lock)	((void)(lock), 1)
 #define spin_unlock_wait(lock)	do { (void)(lock); } while(0)
 #define _raw_spin_unlock(lock)	do { (void)(lock); } while(0)
+#endif /* CONFIG_DEBUG_SPINLOCK */
+
+/* RW spinlocks: No debug version */
+
+#if (__GNUC__ > 2)
+  typedef struct { } rwlock_t;
+  #define RW_LOCK_UNLOCKED (rwlock_t) { }
+#else
+  typedef struct { int gcc_is_buggy; } rwlock_t;
+  #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+#endif
+
 #define rwlock_init(lock)	do { (void)(lock); } while(0)
 #define _raw_read_lock(lock)	do { (void)(lock); } while(0)
 #define _raw_read_unlock(lock)	do { (void)(lock); } while(0)
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h	Mon Feb 10 10:39:27 2003
+++ b/include/linux/sysctl.h	Mon Feb 10 10:39:27 2003
@@ -305,7 +305,8 @@
 	NET_IPV4_ICMP_RATELIMIT=89,
 	NET_IPV4_ICMP_RATEMASK=90,
 	NET_TCP_TW_REUSE=91,
-	NET_TCP_FRTO=92
+	NET_TCP_FRTO=92,
+	NET_TCP_LOW_LATENCY=93
 };
 
 enum {
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	Mon Feb 10 10:39:25 2003
+++ b/include/linux/sysfs.h	Mon Feb 10 10:39:25 2003
@@ -30,6 +30,9 @@
 extern int
 sysfs_create_file(struct kobject *, struct attribute *);
 
+extern int
+sysfs_update_file(struct kobject *, struct attribute *);
+
 extern void
 sysfs_remove_file(struct kobject *, struct attribute *);
 
diff -Nru a/include/linux/time.h b/include/linux/time.h
--- a/include/linux/time.h	Mon Feb 10 10:39:29 2003
+++ b/include/linux/time.h	Mon Feb 10 10:39:29 2003
@@ -25,6 +25,7 @@
 #ifdef __KERNEL__
 
 #include <linux/spinlock.h>
+#include <linux/seqlock.h>
 
 /*
  * Change timeval to jiffies, trying to avoid the
@@ -120,7 +121,7 @@
 }
 
 extern struct timespec xtime;
-extern rwlock_t xtime_lock;
+extern seqlock_t xtime_lock;
 
 static inline unsigned long get_seconds(void)
 { 
diff -Nru a/include/linux/times.h b/include/linux/times.h
--- a/include/linux/times.h	Mon Feb 10 10:39:23 2003
+++ b/include/linux/times.h	Mon Feb 10 10:39:23 2003
@@ -2,7 +2,30 @@
 #define _LINUX_TIMES_H
 
 #ifdef __KERNEL__
+#include <asm/div64.h>
+#include <asm/types.h>
+
+#if (HZ % USER_HZ)==0
 # define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ))
+#else
+# define jiffies_to_clock_t(x) ((clock_t) jiffies_64_to_clock_t((u64) x))
+#endif
+
+static inline u64 jiffies_64_to_clock_t(u64 x)
+{
+#if (HZ % USER_HZ)==0
+	do_div(x, HZ / USER_HZ);
+#else
+	/*
+	 * There are better ways that don't overflow early,
+	 * but even this doesn't overflow in hundreds of years
+	 * in 64 bits, so..
+	 */
+	x *= USER_HZ;
+	do_div(x, HZ);
+#endif
+	return x;
+}
 #endif
 
 struct tms {
diff -Nru a/include/linux/types.h b/include/linux/types.h
--- a/include/linux/types.h	Mon Feb 10 10:39:31 2003
+++ b/include/linux/types.h	Mon Feb 10 10:39:31 2003
@@ -4,10 +4,12 @@
 #ifdef	__KERNEL__
 #include <linux/config.h>
 
+#define BITS_TO_LONGS(bits) \
+	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 #define DECLARE_BITMAP(name,bits) \
-	unsigned long name[((bits)+BITS_PER_LONG-1)/BITS_PER_LONG]
+	unsigned long name[BITS_TO_LONGS(bits)]
 #define CLEAR_BITMAP(name,bits) \
-	memset(name, 0, ((bits)+BITS_PER_LONG-1)/8)
+	memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long))
 #endif
 
 #include <linux/posix_types.h>
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Mon Feb 10 10:39:26 2003
+++ b/include/linux/usb.h	Mon Feb 10 10:39:26 2003
@@ -554,7 +554,6 @@
 #define URB_NO_FSBR		0x0020	/* UHCI-specific */
 #define URB_ZERO_PACKET		0x0040	/* Finish bulk OUTs with short packet */
 #define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt needed */
-#define URB_TIMEOUT_KILLED	0x1000	/* only set by HCD! */
 
 struct usb_iso_packet_descriptor {
 	unsigned int offset;
diff -Nru a/include/linux/xfrm.h b/include/linux/xfrm.h
--- a/include/linux/xfrm.h	Mon Feb 10 10:39:24 2003
+++ b/include/linux/xfrm.h	Mon Feb 10 10:39:24 2003
@@ -163,6 +163,7 @@
 struct xfrm_usersa_id {
 	xfrm_address_t			saddr;
 	__u32				spi;
+	__u16				family;
 	__u8				proto;
 };
 
diff -Nru a/include/net/ip.h b/include/net/ip.h
--- a/include/net/ip.h	Mon Feb 10 10:39:29 2003
+++ b/include/net/ip.h	Mon Feb 10 10:39:29 2003
@@ -96,7 +96,7 @@
 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);
+extern int		ip_queue_xmit(struct sk_buff *skb, int ipfragok);
 extern void		ip_init(void);
 extern int		ip_append_data(struct sock *sk,
 				       int getfrag(void *from, char *to, int offset, int len,
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	Mon Feb 10 10:39:30 2003
+++ b/include/net/sock.h	Mon Feb 10 10:39:30 2003
@@ -44,6 +44,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>	/* struct sk_buff */
+#include <linux/security.h>
 
 #ifdef CONFIG_FILTER
 #include <linux/filter.h>
@@ -458,28 +459,45 @@
 #ifdef CONFIG_FILTER
 
 /**
- *	sk_filter - run a packet through a socket filter
+ *	__sk_filter - run a packet through a socket filter
+ *	@sk: sock associated with &sk_buff
  *	@skb: buffer to filter
- *	@filter: filter to apply
+ *	@needlock: set to 1 if the sock is not locked by caller.
  *
  * Run the filter code and then cut skb->data to correct size returned by
  * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller
  * than pkt_len we keep whole skb->data. This is the socket level
  * wrapper to sk_run_filter. It returns 0 if the packet should
- * be accepted or 1 if the packet should be tossed.
+ * be accepted or -EPERM if the packet should be tossed.
+ *
+ * This function should not be called directly, use sk_filter instead
+ * to ensure that the LSM security check is also performed.
  */
- 
-static inline int sk_filter(struct sk_buff *skb, struct sk_filter *filter)
+
+static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock)
 {
-	int pkt_len;
+	int err = 0;
 
-        pkt_len = sk_run_filter(skb, filter->insns, filter->len);
-        if(!pkt_len)
-                return 1;	/* Toss Packet */
-        else
-                skb_trim(skb, pkt_len);
+	if (sk->filter) {
+		struct sk_filter *filter;
+		
+		if (needlock)
+			bh_lock_sock(sk);
+		
+		filter = sk->filter;
+		if (filter) {
+			int pkt_len = sk_run_filter(skb, filter->insns,
+						    filter->len);
+			if (!pkt_len)
+				err = -EPERM;
+			else
+				skb_trim(skb, pkt_len);
+		}
 
-	return 0;
+		if (needlock)
+			bh_unlock_sock(sk);
+	}
+	return err;
 }
 
 /**
@@ -506,8 +524,26 @@
 	atomic_add(sk_filter_len(fp), &sk->omem_alloc);
 }
 
+#else
+
+static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock)
+{
+	return 0;
+}
+
 #endif /* CONFIG_FILTER */
 
+static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock)
+{
+	int err;
+	
+	err = security_sock_rcv_skb(sk, skb);
+	if (err)
+		return err;
+	
+	return __sk_filter(sk, skb, needlock);
+}
+
 /*
  * Socket reference counting postulates.
  *
@@ -712,36 +748,31 @@
 
 static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
+	int err = 0;
+
 	/* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
 	   number of warnings when compiling with -W --ANK
 	 */
-	if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf)
-                return -ENOMEM;
-
-#ifdef CONFIG_FILTER
-	if (sk->filter) {
-		int err = 0;
-		struct sk_filter *filter;
-
-		/* It would be deadlock, if sock_queue_rcv_skb is used
-		   with socket lock! We assume that users of this
-		   function are lock free.
-		 */
-		bh_lock_sock(sk);
-		if ((filter = sk->filter) != NULL && sk_filter(skb, filter))
-			err = -EPERM;
-		bh_unlock_sock(sk);
-		if (err)
-			return err;	/* Toss packet */
+	if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) {
+		err = -ENOMEM;
+		goto out;
 	}
-#endif /* CONFIG_FILTER */
+
+	/* It would be deadlock, if sock_queue_rcv_skb is used
+	   with socket lock! We assume that users of this
+	   function are lock free.
+	*/
+	err = sk_filter(sk, skb, 1);
+	if (err)
+		goto out;
 
 	skb->dev = NULL;
 	skb_set_owner_r(skb, sk);
 	skb_queue_tail(&sk->receive_queue, skb);
 	if (!sk->dead)
 		sk->data_ready(sk,skb->len);
-	return 0;
+out:
+	return err;
 }
 
 static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Mon Feb 10 10:39:23 2003
+++ b/include/net/tcp.h	Mon Feb 10 10:39:23 2003
@@ -474,6 +474,7 @@
 extern int sysctl_tcp_adv_win_scale;
 extern int sysctl_tcp_tw_reuse;
 extern int sysctl_tcp_frto;
+extern int sysctl_tcp_low_latency;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
@@ -566,7 +567,8 @@
  */
 
 struct tcp_func {
-	int			(*queue_xmit)		(struct sk_buff *skb);
+	int			(*queue_xmit)		(struct sk_buff *skb,
+							 int ipfragok);
 
 	void			(*send_check)		(struct sock *sk,
 							 struct tcphdr *th,
@@ -1348,7 +1350,7 @@
 {
 	struct tcp_opt *tp = tcp_sk(sk);
 
-	if (tp->ucopy.task) {
+	if (!sysctl_tcp_low_latency && tp->ucopy.task) {
 		__skb_queue_tail(&tp->ucopy.prequeue, skb);
 		tp->ucopy.memory += skb->truesize;
 		if (tp->ucopy.memory > sk->rcvbuf) {
diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h	Mon Feb 10 10:39:24 2003
+++ b/include/net/xfrm.h	Mon Feb 10 10:39:24 2003
@@ -105,7 +105,6 @@
 		u16		family;
 		xfrm_address_t	saddr;
 		int		header_len;
-		int		trailer_len;
 	} props;
 
 	struct xfrm_lifetime_cfg lft;
diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h
--- a/include/scsi/scsi.h	Mon Feb 10 10:39:33 2003
+++ b/include/scsi/scsi.h	Mon Feb 10 10:39:33 2003
@@ -104,7 +104,26 @@
 
 
 /*
- *  Status codes
+ *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
+ *  T10/1561-D Revision 4 Draft dated 7th November 2002.
+ */
+#define SAM_STAT_GOOD            0x00
+#define SAM_STAT_CHECK_CONDITION 0x02
+#define SAM_STAT_CONDITION_MET   0x04
+#define SAM_STAT_BUSY            0x08
+#define SAM_STAT_IMMEDIATE       0x10
+#define SAM_STAT_IMMEDIATE_CONDITION_MET 0x14
+#define SAM_STAT_RESERVATION_CONFLICT 0x18
+#define SAM_STAT_COMMAND_TERMINATED 0x22	/* obsolete in SAM-3 */
+#define SAM_STAT_TASK_SET_FULL   0x28
+#define SAM_STAT_ACA_ACTIVE      0x30
+#define SAM_STAT_TASK_ABORTED    0x40
+
+/*
+ *  Status codes. These are deprecated as they are shifted 1 bit right
+ *  from those found in the SCSI standards. This causes confusion for
+ *  applications that are ported to several OSes. Prefer SAM Status codes
+ *  above.
  */
 
 #define GOOD                 0x00
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	Mon Feb 10 10:39:27 2003
+++ b/include/sound/ac97_codec.h	Mon Feb 10 10:39:27 2003
@@ -196,6 +196,8 @@
 #define AC97_CXR_SPDIF_AC3	0x2
 
 /* specific - ALC */
+#define AC97_ALC650_SURR_DAC_VOL	0x64
+#define AC97_ALC650_LFE_DAC_VOL		0x66
 #define AC97_ALC650_MULTICH	0x6a
 #define AC97_ALC650_CLOCK	0x7a
 
@@ -235,8 +237,6 @@
 	unsigned short (*read) (ac97_t *ac97, unsigned short reg);
 	void (*wait) (ac97_t *ac97);
 	void (*init) (ac97_t *ac97);
-	snd_info_entry_t *proc_entry;
-	snd_info_entry_t *proc_regs_entry;
 	void *private_data;
 	void (*private_free) (ac97_t *ac97);
 	/* --- */
diff -Nru a/include/sound/ad1848.h b/include/sound/ad1848.h
--- a/include/sound/ad1848.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/ad1848.h	Mon Feb 10 10:39:24 2003
@@ -22,7 +22,6 @@
  *
  */
 
-#include "control.h"
 #include "pcm.h"
 
 /* IO ports */
@@ -162,28 +161,44 @@
 		      ad1848_t ** 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);
 void snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
+/* exported mixer stuffs */
+enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
+
+#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \
+	((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
+#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);
+
+/* for ease of use */
+struct ad1848_mix_elem {
+	const char *name;
+	int index;
+	int type;
+	unsigned long private_value;
+};
+
 #define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_ad1848_info_single, \
-  .get = snd_ad1848_get_single, .put = snd_ad1848_put_single, \
-  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+{ .name = xname, \
+  .index = xindex, \
+  .type = AD1848_MIX_SINGLE, \
+  .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
 
 #define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
-  .info = snd_ad1848_info_double, \
-  .get = snd_ad1848_get_double, .put = snd_ad1848_put_double, \
-  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
-
-int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+{ .name = xname, \
+  .index = xindex, \
+  .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)
+{
+	return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value);
+}
 
 #ifdef CONFIG_SND_DEBUG
 void snd_ad1848_debug(ad1848_t *chip);
diff -Nru a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
--- a/include/sound/ak4531_codec.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/ak4531_codec.h	Mon Feb 10 10:39:24 2003
@@ -68,7 +68,6 @@
 
 struct _snd_ak4531 {
 	void (*write) (ak4531_t *ak4531, unsigned short reg, unsigned short val);
-	snd_info_entry_t *proc_entry;
 	void *private_data;
 	void (*private_free) (ak4531_t *ak4531);
 	/* --- */
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	Mon Feb 10 10:39:33 2003
+++ b/include/sound/core.h	Mon Feb 10 10:39:33 2003
@@ -55,6 +55,7 @@
 	SNDRV_DEV_TIMER,
 	SNDRV_DEV_SEQUENCER,
 	SNDRV_DEV_HWDEP,
+	SNDRV_DEV_INFO,
 	SNDRV_DEV_LOWLEVEL =		(2*SNDRV_DEV_TYPE_RANGE_SIZE)
 } snd_device_type_t;
 
@@ -281,6 +282,8 @@
 void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr);
 void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
 void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, dma_addr_t dma_addr);
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *dma_addr);
+#define snd_free_pci_page(pci,ptr,addr) snd_free_pci_pages(pci,PAGE_SIZE,ptr,addr)
 #endif
 #ifdef CONFIG_SBUS
 void *snd_malloc_sbus_pages(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr);
@@ -343,7 +346,7 @@
 
 void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
 void snd_dma_disable(unsigned long dma);
-unsigned int snd_dma_residue(unsigned long dma);
+unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
 
 /* misc.c */
 
@@ -354,13 +357,17 @@
 #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
 void snd_verbose_printd(const char *file, int line, const char *format, ...);
 #endif
-#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK)
-void snd_printd(const char *format, ...);
-#endif
 
 /* --- */
 
 #ifdef CONFIG_SND_VERBOSE_PRINTK
+/**
+ * snd_printk - printk wrapper
+ * @fmt: format string
+ *
+ * Works like print() but prints the file and the line of the caller
+ * when configured with CONFIG_SND_VERBOSE_PRINTK.
+ */
 #define snd_printk(fmt, args...) \
 	snd_verbose_printk(__FILE__, __LINE__, fmt ,##args)
 #else
@@ -373,15 +380,45 @@
 #define __ASTRING__(x) #x
 
 #ifdef CONFIG_SND_VERBOSE_PRINTK
+/**
+ * snd_printd - debug printk
+ * @format: format string
+ *
+ * Compiled only when Works like snd_printk() for debugging purpose.
+ * Ignored when CONFIG_SND_DEBUG is not set.
+ */
 #define snd_printd(fmt, args...) \
 	snd_verbose_printd(__FILE__, __LINE__, fmt ,##args)
+#else
+#define snd_printd(fmt, args...) \
+	printk(fmt ,##args)
 #endif
+/**
+ * snd_assert - run-time assersion macro
+ * @expr: expression
+ * @args...: the action
+ *
+ * This macro checks the expression in run-time and invokes the commands
+ * given in the rest arguments if the assertion is failed.
+ * When CONFIG_SND_DEBUG is not set, the expression is executed but
+ * not checked.
+ */
 #define snd_assert(expr, args...) do {\
 	if (!(expr)) {\
 		snd_printk("BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
 		args;\
 	}\
 } while (0)
+/**
+ * snd_runtime_check - run-time assersion macro
+ * @expr: expression
+ * @args...: the action
+ *
+ * This macro checks the expression in run-time and invokes the commands
+ * given in the rest arguments if the assertion is failed.
+ * Unlike snd_assert(), the action commands are executed even if
+ * CONFIG_SND_DEBUG is not set but without any error messages.
+ */
 #define snd_runtime_check(expr, args...) do {\
 	if (!(expr)) {\
 		snd_printk("ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
@@ -398,6 +435,13 @@
 #endif /* CONFIG_SND_DEBUG */
 
 #ifdef CONFIG_SND_DEBUG_DETECT
+/**
+ * snd_printdd - debug printk
+ * @format: format string
+ *
+ * Compiled only when Works like snd_printk() for debugging purpose.
+ * Ignored when CONFIG_SND_DEBUG_DETECT is not set.
+ */
 #define snd_printdd(format, args...) snd_printk(format, ##args)
 #else
 #define snd_printdd(format, args...) /* nothing */
diff -Nru a/include/sound/cs46xx.h b/include/sound/cs46xx.h
--- a/include/sound/cs46xx.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/cs46xx.h	Mon Feb 10 10:39:24 2003
@@ -1673,7 +1673,6 @@
 	unsigned long remap_addr;
 	unsigned long size;
 	struct resource *resource;
-	void *proc_entry;
 } snd_cs46xx_region_t;
 
 struct _snd_cs46xx {
@@ -1726,7 +1725,6 @@
 	spinlock_t reg_lock;
 	unsigned int midcr;
 	unsigned int uartm;
-	snd_info_entry_t *proc_entry;
 
 	int amplifier;
 	void (*amplifier_ctrl)(cs46xx_t *, int);
diff -Nru a/include/sound/cs46xx_dsp_scb_types.h b/include/sound/cs46xx_dsp_scb_types.h
--- a/include/sound/cs46xx_dsp_scb_types.h	Mon Feb 10 10:39:27 2003
+++ b/include/sound/cs46xx_dsp_scb_types.h	Mon Feb 10 10:39:27 2003
@@ -248,12 +248,12 @@
 	   insure that the fractional error is always
 	   positive)
 	*/
-	long outTripletsPerFrame;
+	u32 outTripletsPerFrame;
 
 	/* 16b.16b integer.frac accumulated number of
 	   output triplets since the start of group 
 	*/
-	long accumOutTriplets;  
+	u32 accumOutTriplets;  
 } mix2_ostream_spb_t;
 
 /* SCB for Timing master algorithm */
@@ -569,10 +569,10 @@
 	u32  vdec_input_buf_strm_config;
 	/* inputBufStrmConfig: rsConfig for the input buffer to the decimator
 	   (buffer size = 64 dwords) */
-	long  vdec_coef_increment;
+	u32  vdec_coef_increment;
 	/* coefIncrement = - 128.0 / decimationFactor (as a 32Q15 number) */
 
-	long  vdec_accumphi;
+	u32  vdec_accumphi;
 	/* accumPhi: accumulated fractional phase increment (6.26) */
 
 	u16 vdec_exp_vol_change_rate;
diff -Nru a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
--- a/include/sound/cs46xx_dsp_spos.h	Mon Feb 10 10:39:29 2003
+++ b/include/sound/cs46xx_dsp_spos.h	Mon Feb 10 10:39:29 2003
@@ -196,8 +196,8 @@
 	u16 spdif_input_volume_left;
 	/* spdif channel status,
 	   left right and user validity bits */
-	int spdif_csuv_default;
-	int spdif_csuv_stream;
+	unsigned int spdif_csuv_default;
+	unsigned int spdif_csuv_stream;
 
 	/* SPDIF input sample rate converter */
 	dsp_scb_descriptor_t * spdif_in_src;
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/emu10k1.h	Mon Feb 10 10:39:24 2003
@@ -25,12 +25,11 @@
 
 #ifdef __KERNEL__
 
-#include "pcm.h"
-#include "pcm_sgbuf.h"
-#include "rawmidi.h"
-#include "hwdep.h"
-#include "ac97_codec.h"
-#include "util_mem.h"
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/hwdep.h>
+#include <sound/ac97_codec.h>
+#include <sound/util_mem.h>
 #include <asm/io.h>
 
 #ifndef PCI_VENDOR_ID_CREATIVE
@@ -232,7 +231,7 @@
 #define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
 #define A_GPINPUT_MASK		0xff00
 #define A_GPOUTPUT_MASK		0x00ff
-#define A_IOCFG_GPOUT0		0x0040		/* analog/digital? */
+#define A_IOCFG_GPOUT0		0x0044		/* analog/digital? */
 
 #define TIMER			0x1a		/* Timer terminal count register		*/
 						/* NOTE: After the rate is changed, a maximum	*/
@@ -993,13 +992,6 @@
 	emu10k1_midi_t midi2; /* for audigy */
 
 	unsigned int efx_voices_mask[2];
-
-	snd_info_entry_t *proc_entry;
-	snd_info_entry_t *proc_entry_fx8010_gpr;
-	snd_info_entry_t *proc_entry_fx8010_tram_data;
-	snd_info_entry_t *proc_entry_fx8010_tram_addr;
-	snd_info_entry_t *proc_entry_fx8010_code;
-	snd_info_entry_t *proc_entry_fx8010_iblocks;
 };
 
 int snd_emu10k1_create(snd_card_t * card,
@@ -1045,7 +1037,7 @@
 unsigned char snd_emu10k1_sum_vol_attn(unsigned int value);
 
 /* memory allocation */
-snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, struct snd_sg_buf *sgbuf);
+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);
@@ -1063,7 +1055,6 @@
 
 /* proc interface */
 int snd_emu10k1_proc_init(emu10k1_t * emu);
-int snd_emu10k1_proc_done(emu10k1_t * emu);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/sound/gus.h b/include/sound/gus.h
--- a/include/sound/gus.h	Mon Feb 10 10:39:23 2003
+++ b/include/sound/gus.h	Mon Feb 10 10:39:23 2003
@@ -210,7 +210,6 @@
 	snd_gf1_bank_info_t banks_16[4];
 	snd_gf1_mem_block_t *first;
 	snd_gf1_mem_block_t *last;
-	snd_info_entry_t *info_entry;
 	struct semaphore memory_mutex;
 } snd_gf1_mem_t;
 
@@ -332,8 +331,6 @@
 	unsigned int rom_banks;		/* GUS's ROM banks */
 
 	snd_gf1_mem_t mem_alloc;
-	snd_info_entry_t *ram_entries[4];
-	snd_info_entry_t *rom_entries[4];
 
 	/* registers */
 	unsigned short reg_page;
@@ -452,9 +449,6 @@
 	int timer_dev;			/* timer device */
 
 	struct _snd_gf1 gf1;	/* gf1 specific variables */
-#ifdef CONFIG_SND_DEBUG
-	snd_info_entry_t *irq_entry;
-#endif
 	snd_pcm_t *pcm;
 	snd_pcm_substream_t *pcm_cap_substream;
 	unsigned int c_dma_size;
@@ -601,7 +595,6 @@
 /* gus_mem_proc.c */
 
 int snd_gf1_mem_proc_init(snd_gus_card_t * gus);
-int snd_gf1_mem_proc_done(snd_gus_card_t * gus);
 
 /* gus_dma.c */
 
@@ -676,7 +669,6 @@
 void 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_done(snd_gus_card_t *gus);
 #endif
 
 /* gus_uart.c */
diff -Nru a/include/sound/info.h b/include/sound/info.h
--- a/include/sound/info.h	Mon Feb 10 10:39:30 2003
+++ b/include/sound/info.h	Mon Feb 10 10:39:30 2003
@@ -141,6 +141,19 @@
 void snd_remove_proc_entry(struct proc_dir_entry *parent,
 			   struct proc_dir_entry *de);
 
+/* for card drivers */
+int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp);
+
+inline static void snd_info_set_text_ops(snd_info_entry_t *entry, 
+					 void *private_data,
+					 void (*read)(snd_info_entry_t *, snd_info_buffer_t *))
+{
+	entry->private_data = private_data;
+	entry->c.text.read_size = 1024;
+	entry->c.text.read = read;
+}
+
+
 #else
 
 #define snd_seq_root NULL
@@ -160,14 +173,18 @@
 						       unsigned int mode) { return NULL; }
 static inline void snd_info_free_device(snd_info_entry_t * 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_unregister(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 struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { return NULL; }
 static inline void snd_remove_proc_entry(struct proc_dir_entry *parent,
 					 struct proc_dir_entry *de) { ; }
+
+#define snd_card_proc_new(card,name,entryp)  0 /* always success */
+#define snd_info_set_text_ops(entry,private_data,read) /*NOP*/
 
 #endif
 
diff -Nru a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h
--- a/include/sound/mixer_oss.h	Mon Feb 10 10:39:28 2003
+++ b/include/sound/mixer_oss.h	Mon Feb 10 10:39:28 2003
@@ -31,8 +31,8 @@
 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, int *active_index);
-typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, int active_index);
+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
 
diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h	Mon Feb 10 10:39:27 2003
+++ b/include/sound/pcm.h	Mon Feb 10 10:39:27 2003
@@ -50,7 +50,7 @@
 typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
 typedef struct sndrv_mask snd_mask_t;
 
-#define _snd_pcm_substream_chip(substream) ((substream)->pcm->private_data)
+#define _snd_pcm_substream_chip(substream) ((substream)->private_data)
 #define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
 #define _snd_pcm_chip(pcm) ((pcm)->private_data)
 #define snd_pcm_chip(pcm) snd_magic_cast1(chip_t, _snd_pcm_chip(pcm), return -ENXIO)
@@ -120,10 +120,12 @@
 #define SNDRV_PCM_TRIGGER_SUSPEND	5
 #define SNDRV_PCM_TRIGGER_RESUME	6
 
-#define SNDRV_PCM_DMA_TYPE_CONTINUOUS	0	/* continuous no-DMA memory */
-#define SNDRV_PCM_DMA_TYPE_ISA		1	/* ISA continuous */
-#define SNDRV_PCM_DMA_TYPE_PCI		2	/* PCI continuous */
-#define SNDRV_PCM_DMA_TYPE_SBUS		3	/* SBUS continuous */
+#define SNDRV_PCM_DMA_TYPE_UNKNOWN	0	/* not defined */
+#define SNDRV_PCM_DMA_TYPE_CONTINUOUS	1	/* continuous no-DMA memory */
+#define SNDRV_PCM_DMA_TYPE_ISA		2	/* ISA continuous */
+#define SNDRV_PCM_DMA_TYPE_PCI		3	/* PCI continuous */
+#define SNDRV_PCM_DMA_TYPE_SBUS		4	/* SBUS continuous */
+#define SNDRV_PCM_DMA_TYPE_PCI_SG	5	/* PCI SG-buffer */
 
 /* If you change this don't forget to change rates[] table in pcm_native.c */
 #define SNDRV_PCM_RATE_5512		(1<<0)		/* 5512Hz */
@@ -363,6 +365,7 @@
 struct _snd_pcm_substream {
 	snd_pcm_t *pcm;
 	snd_pcm_str_t *pstr;
+	void *private_data;		/* copied from pcm->private_data */
 	int number;
 	char name[32];			/* substream name */
 	int stream;			/* stream (direction) */
@@ -741,6 +744,10 @@
 			  snd_pcm_hw_params_t *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,
+			 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_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
diff -Nru a/include/sound/pcm_params.h b/include/sound/pcm_params.h
--- a/include/sound/pcm_params.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/pcm_params.h	Mon Feb 10 10:39:24 2003
@@ -129,7 +129,7 @@
 
 INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
 {
-	int i;
+	unsigned int i;
 	assert(to <= SNDRV_MASK_BITS && from <= to);
 	for (i = from; i <= to; i++)
 		mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
@@ -137,7 +137,7 @@
 
 INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
 {
-	int i;
+	unsigned int i;
 	assert(to <= SNDRV_MASK_BITS && from <= to);
 	for (i = from; i <= to; i++)
 		mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
diff -Nru a/include/sound/pcm_sgbuf.h b/include/sound/pcm_sgbuf.h
--- a/include/sound/pcm_sgbuf.h	Mon Feb 10 10:39:30 2003
+++ b/include/sound/pcm_sgbuf.h	Mon Feb 10 10:39:30 2003
@@ -32,6 +32,7 @@
 	int pages;	/* allocated pages */
 	int tblsize;	/* allocated table size */
 	struct snd_sg_page *table;
+	struct page **page_table;
 	struct pci_dev *pci;
 };
 
@@ -53,15 +54,17 @@
 	return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
 }
 
-int snd_pcm_sgbuf_init(snd_pcm_substream_t *substream, struct pci_dev *pci, int tblsize);
-int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream);
-int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size);
-int snd_pcm_sgbuf_free(snd_pcm_substream_t *substream);
-
-int snd_pcm_sgbuf_ops_copy_playback(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count);
-int snd_pcm_sgbuf_ops_copy_capture(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count);
-int snd_pcm_sgbuf_ops_silence(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, snd_pcm_uframes_t count);
-struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
+struct snd_sg_buf *snd_pcm_sgbuf_init(struct pci_dev *pci);
+void snd_pcm_sgbuf_delete(struct snd_sg_buf *sgbuf);
+void *snd_pcm_sgbuf_alloc_pages(struct snd_sg_buf *sgbuf, size_t size);
+int snd_pcm_sgbuf_free_pages(struct snd_sg_buf *sgbuf, void *vmaddr);
+
+int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci, snd_pcm_substream_t *substream);
+int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci, snd_pcm_t *pcm);
 
+#define _snd_pcm_substream_sgbuf(substream) ((substream)->dma_private)
+#define snd_pcm_substream_sgbuf(substream) snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return -ENXIO)
+
+struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
 
 #endif /* __SOUND_PCM_SGBUF_H */
diff -Nru a/include/sound/sb.h b/include/sound/sb.h
--- a/include/sound/sb.h	Mon Feb 10 10:39:26 2003
+++ b/include/sound/sb.h	Mon Feb 10 10:39:26 2003
@@ -305,6 +305,7 @@
 
 /* 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);
 /* sb16.c */
 void snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -312,5 +313,50 @@
 int snd_sb16_capture_open(snd_pcm_substream_t *substream);
 int snd_sb16_playback_close(snd_pcm_substream_t *substream);
 int snd_sb16_capture_close(snd_pcm_substream_t *substream);
+
+/* exported mixer stuffs */
+enum {
+	SB_MIX_SINGLE,
+	SB_MIX_DOUBLE,
+	SB_MIX_INPUT_SW,
+	SB_MIX_CAPTURE_PRO,
+	SB_MIX_CAPTURE_DT019X
+};
+
+#define SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) \
+  ((left_reg) | ((right_reg) << 8) | ((left_shift) << 16) | ((right_shift) << 19) | ((mask) << 24))
+#define SB_MIXVAL_SINGLE(reg, shift, mask) \
+  ((reg) | ((shift) << 16) | ((mask) << 24))
+#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);
+
+/* for ease of use */
+struct sbmix_elem {
+	const char *name;
+	int type;
+	unsigned long private_value;
+};
+
+#define SB_SINGLE(xname, reg, shift, mask) \
+{ .name = xname, \
+  .type = SB_MIX_SINGLE, \
+  .private_value = SB_MIXVAL_SINGLE(reg, shift, mask) }
+
+#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \
+{ .name = xname, \
+  .type = SB_MIX_DOUBLE, \
+  .private_value = SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) }
+
+#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \
+{ .name = xname, \
+  .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)
+{
+	return snd_sbmixer_add_ctl(chip, c->name, 0, c->type, c->private_value);
+}
 
 #endif /* __SOUND_SB_H */
diff -Nru a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h
--- a/include/sound/sb16_csp.h	Mon Feb 10 10:39:33 2003
+++ b/include/sound/sb16_csp.h	Mon Feb 10 10:39:33 2003
@@ -159,7 +159,6 @@
 	snd_kcontrol_t *qsound_space;
 
 	struct semaphore access_mutex;	/* locking */
-	snd_info_entry_t *proc;	/* proc interface */
 };
 
 int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep);
diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
--- a/include/sound/seq_kernel.h	Mon Feb 10 10:39:33 2003
+++ b/include/sound/seq_kernel.h	Mon Feb 10 10:39:33 2003
@@ -174,7 +174,7 @@
 
 /* port attach/detach */
 int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *pcbp,
-			      int cap, int type, char *portname);
+			      int cap, int type, int midi_channels, char *portname);
 int snd_seq_event_port_detach(int client, int port);
 
 #endif /* __SOUND_SEQ_KERNEL_H */
diff -Nru a/include/sound/sndmagic.h b/include/sound/sndmagic.h
--- a/include/sound/sndmagic.h	Mon Feb 10 10:39:24 2003
+++ b/include/sound/sndmagic.h	Mon Feb 10 10:39:24 2003
@@ -27,14 +27,49 @@
 
 void *_snd_magic_kcalloc(unsigned long magic, size_t size, int flags);
 void *_snd_magic_kmalloc(unsigned long magic, size_t size, int flags);
-void snd_magic_kfree(void *ptr);
 
-#define snd_magic_kcalloc(type, extra, flags) (type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags)
-#define snd_magic_kmalloc(type, extra, flags) (type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags)
+/**
+ * snd_magic_kmalloc - allocate a record with a magic-prefix
+ * @type: the type to allocate a record (like xxx_t)
+ * @extra: the extra size to allocate in bytes
+ * @flags: the allocation condition (GFP_XXX)
+ *
+ * Allocates a record of the given type with the extra space and
+ * returns its pointer.  The allocated record has a secret magic-key
+ * to be checked via snd_magic_cast() for safe casts.
+ *
+ * The allocated pointer must be released via snd_magic_kfree().
+ *
+ * The "struct xxx" style cannot be used as the type argument
+ * because the magic-key constant is generated from the type-name
+ * string.
+ */
+#define snd_magic_kmalloc(type, extra, flags) \
+	(type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags)
+/**
+ * snd_magic_kcalloc - allocate a record with a magic-prefix and initialize
+ * @type: the type to allocate a record (like xxx_t)
+ * @extra: the extra size to allocate in bytes
+ * @flags: the allocation condition (GFP_XXX)
+ *
+ * Works like snd_magic_kmalloc() but this clears the area with zero
+ * automatically.
+ */
+#define snd_magic_kcalloc(type, extra, flags) \
+	(type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags)
+
+/**
+ * snd_magic_kfree - release the allocated area
+ * @ptr: the pointer allocated via snd_magic_kmalloc() or snd_magic_kcalloc()
+ *
+ * Releases the memory area allocated via snd_magic_kmalloc() or
+ * snd_magic_kcalloc() function.
+ */
+void snd_magic_kfree(void *ptr);
 
 static inline unsigned long _snd_magic_value(void *obj)
 {
-	return obj == NULL ? -1 : *(((unsigned long *)obj) - 1);
+	return obj == NULL ? (unsigned long)-1 : *(((unsigned long *)obj) - 1);
 }
 
 static inline int _snd_magic_bad(void *obj, unsigned long magic)
@@ -44,7 +79,19 @@
 
 #define snd_magic_cast1(t, expr, cmd) snd_magic_cast(t, expr, cmd)
 
-#define snd_magic_cast(type, ptr, action...) (type *) ({\
+/**
+ * snd_magic_cast - check and cast the magic-allocated pointer
+ * @type: the type of record to cast
+ * @ptr: the magic-allocated pointer
+ * @action...: the action to do if failed
+ *
+ * This macro provides a safe cast for the given type, which was
+ * allocated via snd_magic_kmalloc() or snd_magic_kcallc().
+ * If the pointer is invalid, i.e. the cast-type doesn't match,
+ * the action arguments are called with a debug message.
+ */
+#define snd_magic_cast(type, ptr, action...) \
+	(type *) ({\
 	void *__ptr = ptr;\
 	unsigned long __magic = _snd_magic_value(__ptr);\
 	if (__magic != type##_magic) {\
@@ -64,6 +111,7 @@
 #define snd_pcm_sgbuf_t_magic			0xa15a0107
 
 #define snd_info_private_data_t_magic		0xa15a0201
+#define snd_info_entry_t_magic			0xa15a0202
 #define snd_ctl_file_t_magic			0xa15a0301
 #define snd_kcontrol_t_magic			0xa15a0302
 #define snd_rawmidi_t_magic			0xa15a0401
diff -Nru a/include/sound/timer.h b/include/sound/timer.h
--- a/include/sound/timer.h	Mon Feb 10 10:39:27 2003
+++ b/include/sound/timer.h	Mon Feb 10 10:39:27 2003
@@ -23,6 +23,7 @@
  */
 
 #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;
@@ -45,17 +46,19 @@
 #define SNDRV_TIMER_HW_STOP	0x00000002	/* call stop before start */
 #define SNDRV_TIMER_HW_SLAVE	0x00000004	/* only slave timer (variable resolution) */
 #define SNDRV_TIMER_HW_FIRST	0x00000008	/* first tick can be incomplete */
+#define SNDRV_TIMER_HW_TASKLET	0x00000010	/* timer is called from tasklet */
 
-#define SNDRV_TIMER_IFLG_SLAVE	0x00000001
-#define SNDRV_TIMER_IFLG_RUNNING	0x00000002
-#define SNDRV_TIMER_IFLG_START	0x00000004
-#define SNDRV_TIMER_IFLG_AUTO	0x00000008	/* auto restart */
-
-#define SNDRV_TIMER_FLG_SYSTEM	0x00000001	/* system timer */
-#define SNDRV_TIMER_FLG_CHANGE	0x00000002
-#define SNDRV_TIMER_FLG_RESCHED	0x00000004	/* need reschedule */
+#define SNDRV_TIMER_IFLG_SLAVE	  0x00000001
+#define SNDRV_TIMER_IFLG_RUNNING  0x00000002
+#define SNDRV_TIMER_IFLG_START	  0x00000004
+#define SNDRV_TIMER_IFLG_AUTO	  0x00000008	/* auto restart */
+#define SNDRV_TIMER_IFLG_FAST	  0x00000010	/* fast callback (do not use tasklet) */
+#define SNDRV_TIMER_IFLG_CALLBACK 0x00000020	/* timer callback is active */
 
-typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution, void *data);
+#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);
 
 struct _snd_timer_hardware {
 	/* -- must be filled with low-level driver */
@@ -87,6 +90,9 @@
 	struct list_head device_list;
 	struct list_head open_list_head;
 	struct list_head active_list_head;
+	struct list_head ack_list_head;
+	struct list_head sack_list_head; /* slow ack list head */
+	struct tasklet_struct task_queue;
 };
 
 struct _snd_timer_instance {
@@ -97,17 +103,19 @@
 	void (*private_free) (snd_timer_instance_t *ti);
 	snd_timer_callback_t callback;
 	void *callback_data;
-	unsigned long ticks;
-	unsigned long cticks;
+	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;
 	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;
-	atomic_t in_use;		/* don't free */
 };
 
 /*
@@ -128,7 +136,6 @@
 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_del(snd_timer_instance_t * timeri);
 extern int snd_timer_continue(snd_timer_instance_t * timeri);
 
 extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left);
diff -Nru a/include/sound/trident.h b/include/sound/trident.h
--- a/include/sound/trident.h	Mon Feb 10 10:39:29 2003
+++ b/include/sound/trident.h	Mon Feb 10 10:39:29 2003
@@ -431,7 +431,8 @@
         int ChanPCM;			/* max number of PCM channels */
 	int ChanPCMcnt;			/* actual number of PCM channels */
 
-	int ac97_detect;		/* 1 = AC97 in detection phase */
+	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 */
 
@@ -452,7 +453,6 @@
 	snd_trident_pcm_mixer_t pcm_mixer[32];
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
 
 	struct snd_trident_gameport *gameport;
 };
@@ -479,7 +479,7 @@
 void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
 
 /* TLB memory allocation */
-snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, void *pages, dma_addr_t addr, unsigned long size);
+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);
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	Mon Feb 10 10:39:25 2003
+++ b/include/sound/version.h	Mon Feb 10 10:39:25 2003
@@ -1,3 +1,3 @@
-/* include/version.h.  Generated automatically by configure.  */
-#define CONFIG_SND_VERSION "0.9.0rc6"
-#define CONFIG_SND_DATE " (Tue Dec 17 19:01:13 2002 UTC)"
+/* include/version.h.  Generated by configure.  */
+#define CONFIG_SND_VERSION "0.9.0rc7"
+#define CONFIG_SND_DATE " (Sun Feb 09 18:00:12 2003 UTC)"
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/init/Kconfig	Mon Feb 10 10:39:31 2003
@@ -144,6 +144,18 @@
 	  have not been converted to the new module parameter system yet.
 	  If unsure, say Y.
 
+config MODVERSIONS
+	bool "Module versioning support (EXPERIMENTAL)"
+	depends on MODULES && EXPERIMENTAL
+	help
+	  Usually, you have to use modules compiled with your kernel.
+	  Saying Y here makes it sometimes possible to use modules
+	  compiled for different kernels, by adding enough information
+	  to the modules to (hopefully) spot any changes which would
+	  make them incompatible with the kernel you are running.  If
+	  you say Y here, you will need a copy of genksyms.  If
+	  unsure, say N.
+
 config KMOD
 	bool "Kernel module loader"
 	depends on MODULES
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Mon Feb 10 10:39:25 2003
+++ b/init/do_mounts.c	Mon Feb 10 10:39:25 2003
@@ -653,12 +653,6 @@
 	/*
 	 * OK, time to copy in the data
 	 */
-	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
-	if (buf == 0) {
-		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
-		goto done;
-	}
-
 	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
 		devblocks = 0;
 	else
@@ -669,6 +663,12 @@
 
 	if (devblocks == 0) {
 		printk(KERN_ERR "RAMDISK: could not determine device size\n");
+		goto done;
+	}
+
+	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
+	if (buf == 0) {
+		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
 		goto done;
 	}
 
diff -Nru a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile	Mon Feb 10 10:39:24 2003
+++ b/kernel/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,10 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \
-		printk.o suspend.o dma.o module.o cpufreq.o \
-		profile.o rcupdate.o intermodule.o params.o
-
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
 	    exit.o itimer.o time.o softirq.o resource.o \
 	    sysctl.o capability.o ptrace.o timer.o user.o \
diff -Nru a/kernel/acct.c b/kernel/acct.c
--- a/kernel/acct.c	Mon Feb 10 10:39:27 2003
+++ b/kernel/acct.c	Mon Feb 10 10:39:27 2003
@@ -51,7 +51,9 @@
 #include <linux/tty.h>
 #include <linux/security.h>
 #include <linux/vfs.h>
+#include <linux/jiffies.h>
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 
 /*
  * These constants control the amount of freespace that suspend and
@@ -306,6 +308,7 @@
 	mm_segment_t fs;
 	unsigned long vsize;
 	unsigned long flim;
+	u64 elapsed;
 
 	/*
 	 * First check to see if there is enough free_space to continue
@@ -323,9 +326,11 @@
 	strncpy(ac.ac_comm, current->comm, ACCT_COMM);
 	ac.ac_comm[ACCT_COMM - 1] = '\0';
 
-	ac.ac_btime = CT_TO_SECS(current->start_time) +
-		(xtime.tv_sec - (jiffies / HZ));
-	ac.ac_etime = encode_comp_t(jiffies - current->start_time);
+	elapsed = get_jiffies_64() - current->start_time;
+	ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
+	                       (unsigned long) elapsed : (unsigned long) -1l);
+	do_div(elapsed, HZ);
+	ac.ac_btime = xtime.tv_sec - elapsed;
 	ac.ac_utime = encode_comp_t(current->utime);
 	ac.ac_stime = encode_comp_t(current->stime);
 	ac.ac_uid = current->uid;
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Mon Feb 10 10:39:31 2003
+++ b/kernel/exit.c	Mon Feb 10 10:39:31 2003
@@ -76,6 +76,7 @@
 	if (unlikely(p->ptrace))
 		__ptrace_unlink(p);
 	BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
+	__exit_signal(p);
 	__exit_sighand(p);
 	proc_dentry = __unhash_process(p);
 
@@ -156,7 +157,7 @@
  *
  * "I ask you, have you ever known what it is to be an orphan?"
  */
-static int __will_become_orphaned_pgrp(int pgrp, task_t *ignored_task)
+static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task)
 {
 	struct task_struct *p;
 	struct list_head *l;
@@ -177,22 +178,17 @@
 	return ret;	/* (sighing) "Often!" */
 }
 
-static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task)
+int is_orphaned_pgrp(int pgrp)
 {
 	int retval;
 
 	read_lock(&tasklist_lock);
-	retval = __will_become_orphaned_pgrp(pgrp, ignored_task);
+	retval = will_become_orphaned_pgrp(pgrp, NULL);
 	read_unlock(&tasklist_lock);
 
 	return retval;
 }
 
-int is_orphaned_pgrp(int pgrp)
-{
-	return will_become_orphaned_pgrp(pgrp, 0);
-}
-
 static inline int has_stopped_jobs(int pgrp)
 {
 	int retval = 0;
@@ -203,6 +199,17 @@
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
 		if (p->state != TASK_STOPPED)
 			continue;
+
+		/* If p is stopped by a debugger on a signal that won't
+		   stop it, then don't count p as stopped.  This isn't
+		   perfect but it's a good approximation.  */
+		if (unlikely (p->ptrace)
+		    && p->exit_code != SIGSTOP
+		    && p->exit_code != SIGTSTP
+		    && p->exit_code != SIGTTOU
+		    && p->exit_code != SIGTTIN)
+			continue;
+
 		retval = 1;
 		break;
 	}
@@ -247,6 +254,29 @@
 	write_unlock_irq(&tasklist_lock);
 }
 
+void __set_special_pids(pid_t session, pid_t pgrp)
+{
+	struct task_struct *curr = current;
+
+	if (curr->session != session) {
+		detach_pid(curr, PIDTYPE_SID);
+		curr->session = session;
+		attach_pid(curr, PIDTYPE_SID, session);
+	}
+	if (curr->pgrp != pgrp) {
+		detach_pid(curr, PIDTYPE_PGID);
+		curr->pgrp = pgrp;
+		attach_pid(curr, PIDTYPE_PGID, pgrp);
+	}
+}
+
+void set_special_pids(pid_t session, pid_t pgrp)
+{
+	write_lock_irq(&tasklist_lock);
+	__set_special_pids(session, pgrp);
+	write_unlock_irq(&tasklist_lock);
+}
+
 /*
  *	Put all the gunge required to become a kernel thread without
  *	attached user resources in one place where it belongs.
@@ -264,8 +294,7 @@
 	 */
 	exit_mm(current);
 
-	current->session = 1;
-	current->pgrp = 1;
+	set_special_pids(1, 1);
 	current->tty = NULL;
 
 	/* Become as one with the init task */
@@ -495,7 +524,7 @@
 	    (p->session == father->session)) {
 		int pgrp = p->pgrp;
 
-		if (__will_become_orphaned_pgrp(pgrp, 0) && has_stopped_jobs(pgrp)) {
+		if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
 			__kill_pg_info(SIGHUP, (void *)1, pgrp);
 			__kill_pg_info(SIGCONT, (void *)1, pgrp);
 		}
@@ -547,10 +576,33 @@
  * Send signals to all our closest relatives so that they know
  * to properly mourn us..
  */
-static void exit_notify(void)
+static void exit_notify(struct task_struct *tsk)
 {
 	struct task_struct *t;
 
+	if (signal_pending(tsk) && !tsk->signal->group_exit
+	    && !thread_group_empty(tsk)) {
+		/*
+		 * This occurs when there was a race between our exit
+		 * syscall and a group signal choosing us as the one to
+		 * wake up.  It could be that we are the only thread
+		 * alerted to check for pending signals, but another thread
+		 * should be woken now to take the signal since we will not.
+		 * Now we'll wake all the threads in the group just to make
+		 * sure someone gets all the pending signals.
+		 */
+		read_lock(&tasklist_lock);
+		spin_lock_irq(&tsk->sighand->siglock);
+		for (t = next_thread(tsk); t != tsk; t = next_thread(t))
+			if (!signal_pending(t) && !(t->flags & PF_EXITING)) {
+				recalc_sigpending_tsk(t);
+				if (signal_pending(t))
+					signal_wake_up(t, 0);
+			}
+		spin_unlock_irq(&tsk->sighand->siglock);
+		read_unlock(&tasklist_lock);
+	}
+
 	write_lock_irq(&tasklist_lock);
 
 	/*
@@ -562,8 +614,8 @@
 	 *	jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
 	 */
 
-	forget_original_parent(current);
-	BUG_ON(!list_empty(&current->children));
+	forget_original_parent(tsk);
+	BUG_ON(!list_empty(&tsk->children));
 
 	/*
 	 * Check to see if any process groups have become orphaned
@@ -575,14 +627,14 @@
 	 * is about to become orphaned.
 	 */
 	 
-	t = current->parent;
+	t = tsk->real_parent;
 	
-	if ((t->pgrp != current->pgrp) &&
-	    (t->session == current->session) &&
-	    __will_become_orphaned_pgrp(current->pgrp, current) &&
-	    has_stopped_jobs(current->pgrp)) {
-		__kill_pg_info(SIGHUP, (void *)1, current->pgrp);
-		__kill_pg_info(SIGCONT, (void *)1, current->pgrp);
+	if ((t->pgrp != tsk->pgrp) &&
+	    (t->session == tsk->session) &&
+	    will_become_orphaned_pgrp(tsk->pgrp, tsk) &&
+	    has_stopped_jobs(tsk->pgrp)) {
+		__kill_pg_info(SIGHUP, (void *)1, tsk->pgrp);
+		__kill_pg_info(SIGCONT, (void *)1, tsk->pgrp);
 	}
 
 	/* Let father know we died 
@@ -601,17 +653,25 @@
 	 *	
 	 */
 	
-	if (current->exit_signal != SIGCHLD && current->exit_signal != -1 &&
-	    ( current->parent_exec_id != t->self_exec_id  ||
-	      current->self_exec_id != current->parent_exec_id) 
+	if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 &&
+	    ( tsk->parent_exec_id != t->self_exec_id  ||
+	      tsk->self_exec_id != tsk->parent_exec_id)
 	    && !capable(CAP_KILL))
-		current->exit_signal = SIGCHLD;
+		tsk->exit_signal = SIGCHLD;
 
 
-	if (current->exit_signal != -1)
-		do_notify_parent(current, current->exit_signal);
+	/* If something other than our normal parent is ptracing us, then
+	 * send it a SIGCHLD instead of honoring exit_signal.  exit_signal
+	 * only has special meaning to our real parent.
+	 */
+	if (tsk->exit_signal != -1) {
+		if (tsk->parent == tsk->real_parent)
+			do_notify_parent(tsk, tsk->exit_signal);
+		else
+			do_notify_parent(tsk, SIGCHLD);
+	}
 
-	current->state = TASK_ZOMBIE;
+	tsk->state = TASK_ZOMBIE;
 	/*
 	 * No need to unlock IRQs, we'll schedule() immediately
 	 * anyway. In the preemption case this also makes it
@@ -642,7 +702,9 @@
 
 	profile_exit_task(tsk);
  
-fake_volatile:
+	if (unlikely(current->ptrace & PT_TRACE_EXIT))
+		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
+
 	acct_process(code);
 	__exit_mm(tsk);
 
@@ -652,7 +714,7 @@
 	exit_namespace(tsk);
 	exit_thread();
 
-	if (current->leader)
+	if (tsk->leader)
 		disassociate_ctty(1);
 
 	module_put(tsk->thread_info->exec_domain->module);
@@ -660,26 +722,16 @@
 		module_put(tsk->binfmt->module);
 
 	tsk->exit_code = code;
-	exit_notify();
+	exit_notify(tsk);
 	preempt_disable();
-	if (current->exit_signal == -1)
-		release_task(current);
+
+	if (tsk->exit_signal == -1)
+		release_task(tsk);
+
 	schedule();
 	BUG();
-/*
- * In order to get rid of the "volatile function does return" message
- * I did this little loop that confuses gcc to think do_exit really
- * is volatile. In fact it's schedule() that is volatile in some
- * circumstances: when current->state = ZOMBIE, schedule() never
- * returns.
- *
- * In fact the natural way to do all this is to have the label and the
- * goto right after each other, but I put the fake_volatile label at
- * the start of the function just in case something /really/ bad
- * happens, and the schedule returns. This way we can try again. I'm
- * not paranoid: it's just that everybody is out to get me.
- */
-	goto fake_volatile;
+	/* Avoid "noreturn function does return".  */
+	for (;;) ;
 }
 
 NORET_TYPE void complete_and_exit(struct completion *comp, long code)
@@ -701,9 +753,9 @@
 	struct list_head *tmp, *head = &link->pidptr->task_list;
 
 #if CONFIG_SMP
-	if (!p->sig)
+	if (!p->sighand)
 		BUG();
-	if (!spin_is_locked(&p->sig->siglock) &&
+	if (!spin_is_locked(&p->sighand->siglock) &&
 				!rwlock_is_locked(&tasklist_lock))
 		BUG();
 #endif
@@ -715,31 +767,45 @@
 }
 
 /*
- * this kills every thread in the thread group. Note that any externally
- * wait4()-ing process will get the correct exit code - even if this 
- * thread is not the thread group leader.
+ * Take down every thread in the group.  This is called by fatal signals
+ * as well as by sys_exit_group (below).
  */
-asmlinkage long sys_exit_group(int error_code)
+NORET_TYPE void
+do_group_exit(int exit_code)
 {
-	unsigned int exit_code = (error_code & 0xff) << 8;
-
-	if (!thread_group_empty(current)) {
-		struct signal_struct *sig = current->sig;
+	BUG_ON(exit_code & 0x80); /* core dumps don't get here */
 
-		spin_lock_irq(&sig->siglock);
-		if (sig->group_exit) {
-			spin_unlock_irq(&sig->siglock);
-
-			/* another thread was faster: */
-			do_exit(sig->group_exit_code);
+	if (current->signal->group_exit)
+		exit_code = current->signal->group_exit_code;
+	else if (!thread_group_empty(current)) {
+		struct signal_struct *const sig = current->signal;
+		struct sighand_struct *const sighand = current->sighand;
+		read_lock(&tasklist_lock);
+		spin_lock_irq(&sighand->siglock);
+		if (sig->group_exit)
+			/* Another thread got here before we took the lock.  */
+			exit_code = sig->group_exit_code;
+		else {
+			sig->group_exit = 1;
+			sig->group_exit_code = exit_code;
+			zap_other_threads(current);
 		}
-		sig->group_exit = 1;
-		sig->group_exit_code = exit_code;
-		__broadcast_thread_group(current, SIGKILL);
-		spin_unlock_irq(&sig->siglock);
+		spin_unlock_irq(&sighand->siglock);
+		read_unlock(&tasklist_lock);
 	}
 
 	do_exit(exit_code);
+	/* NOTREACHED */
+}
+
+/*
+ * this kills every thread in the thread group. Note that any externally
+ * wait4()-ing process will get the correct exit code - even if this
+ * thread is not the thread group leader.
+ */
+asmlinkage void sys_exit_group(int error_code)
+{
+	do_group_exit((error_code & 0xff) << 8);
 }
 
 static int eligible_child(pid_t pid, int options, task_t *p)
@@ -783,11 +849,149 @@
 	return 1;
 }
 
+/*
+ * Handle sys_wait4 work for one task in state TASK_ZOMBIE.  We hold
+ * read_lock(&tasklist_lock) on entry.  If we return zero, we still hold
+ * the lock and this task is uninteresting.  If we return nonzero, we have
+ * released the lock and the system call should return.
+ */
+static int wait_task_zombie(task_t *p, unsigned int *stat_addr, struct rusage *ru)
+{
+	unsigned long state;
+	int retval;
+
+	/*
+	 * Try to move the task's state to DEAD
+	 * only one thread is allowed to do this:
+	 */
+	state = xchg(&p->state, TASK_DEAD);
+	if (state != TASK_ZOMBIE) {
+		BUG_ON(state != TASK_DEAD);
+		return 0;
+	}
+	if (unlikely(p->exit_signal == -1))
+		/*
+		 * This can only happen in a race with a ptraced thread
+		 * dying on another processor.
+		 */
+		return 0;
+
+	/*
+	 * Now we are sure this task is interesting, and no other
+	 * thread can reap it because we set its state to TASK_DEAD.
+	 */
+	read_unlock(&tasklist_lock);
+
+	retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+	if (!retval && stat_addr) {
+		if (p->signal->group_exit)
+			retval = put_user(p->signal->group_exit_code, stat_addr);
+		else
+			retval = put_user(p->exit_code, stat_addr);
+	}
+	if (retval) {
+		p->state = TASK_ZOMBIE;
+		return retval;
+	}
+	retval = p->pid;
+	if (p->real_parent != p->parent) {
+		write_lock_irq(&tasklist_lock);
+		/* Double-check with lock held.  */
+		if (p->real_parent != p->parent) {
+			__ptrace_unlink(p);
+			do_notify_parent(p, p->exit_signal);
+			p->state = TASK_ZOMBIE;
+			p = NULL;
+		}
+		write_unlock_irq(&tasklist_lock);
+	}
+	if (p != NULL)
+		release_task(p);
+	BUG_ON(!retval);
+	return retval;
+}
+
+/*
+ * Handle sys_wait4 work for one task in state TASK_STOPPED.  We hold
+ * read_lock(&tasklist_lock) on entry.  If we return zero, we still hold
+ * the lock and this task is uninteresting.  If we return nonzero, we have
+ * released the lock and the system call should return.
+ */
+static int wait_task_stopped(task_t *p, int delayed_group_leader,
+			     unsigned int *stat_addr, struct rusage *ru)
+{
+	int retval, exit_code;
+
+	if (!p->exit_code)
+		return 0;
+	if (delayed_group_leader && !(p->ptrace & PT_PTRACED) &&
+	    p->signal && p->signal->group_stop_count > 0)
+		/*
+		 * A group stop is in progress and this is the group leader.
+		 * We won't report until all threads have stopped.
+		 */
+		return 0;
+
+	/*
+	 * Now we are pretty sure this task is interesting.
+	 * Make sure it doesn't get reaped out from under us while we
+	 * give up the lock and then examine it below.  We don't want to
+	 * keep holding onto the tasklist_lock while we call getrusage and
+	 * possibly take page faults for user memory.
+	 */
+	get_task_struct(p);
+	read_unlock(&tasklist_lock);
+	write_lock_irq(&tasklist_lock);
+
+	/*
+	 * This uses xchg to be atomic with the thread resuming and setting
+	 * it.  It must also be done with the write lock held to prevent a
+	 * race with the TASK_ZOMBIE case.
+	 */
+	exit_code = xchg(&p->exit_code, 0);
+	if (unlikely(p->state > TASK_STOPPED)) {
+		/*
+		 * The task resumed and then died.  Let the next iteration
+		 * catch it in TASK_ZOMBIE.  Note that exit_code might
+		 * already be zero here if it resumed and did _exit(0).
+		 * The task itself is dead and won't touch exit_code again;
+		 * other processors in this function are locked out.
+		 */
+		p->exit_code = exit_code;
+		exit_code = 0;
+	}
+	if (unlikely(exit_code == 0)) {
+		/*
+		 * Another thread in this function got to it first, or it
+		 * resumed, or it resumed and then died.
+		 */
+		write_unlock_irq(&tasklist_lock);
+		put_task_struct(p);
+		read_lock(&tasklist_lock);
+		return 0;
+	}
+
+	/* move to end of parent's list to avoid starvation */
+	remove_parent(p);
+	add_parent(p, p->parent);
+
+	write_unlock_irq(&tasklist_lock);
+
+	retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+	if (!retval && stat_addr)
+		retval = put_user((exit_code << 8) | 0x7f, stat_addr);
+	if (!retval)
+		retval = p->pid;
+	put_task_struct(p);
+
+	BUG_ON(!retval);
+	return retval;
+}
+
 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct task_struct *tsk;
-	unsigned long state;
 	int flag, retval;
 
 	if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL))
@@ -814,63 +1018,24 @@
 
 			switch (p->state) {
 			case TASK_STOPPED:
-				if (!p->exit_code)
-					continue;
-				if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))
+				if (!(options & WUNTRACED) &&
+				    !(p->ptrace & PT_PTRACED))
 					continue;
-				read_unlock(&tasklist_lock);
-
-				/* move to end of parent's list to avoid starvation */
-				write_lock_irq(&tasklist_lock);
-				remove_parent(p);
-				add_parent(p, p->parent);
-				write_unlock_irq(&tasklist_lock);
-				retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; 
-				if (!retval && stat_addr) 
-					retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
-				if (!retval) {
-					p->exit_code = 0;
-					retval = p->pid;
-				}
-				goto end_wait4;
+				retval = wait_task_stopped(p, ret == 2,
+							   stat_addr, ru);
+				if (retval != 0) /* He released the lock.  */
+					goto end_wait4;
+				break;
 			case TASK_ZOMBIE:
 				/*
 				 * Eligible but we cannot release it yet:
 				 */
 				if (ret == 2)
 					continue;
-				/*
-				 * Try to move the task's state to DEAD
-				 * only one thread is allowed to do this:
-				 */
-				state = xchg(&p->state, TASK_DEAD);
-				if (state != TASK_ZOMBIE)
-					continue;
-				read_unlock(&tasklist_lock);
-
-				retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
-				if (!retval && stat_addr) {
-					if (p->sig->group_exit)
-						retval = put_user(p->sig->group_exit_code, stat_addr);
-					else
-						retval = put_user(p->exit_code, stat_addr);
-				}
-				if (retval) {
-					p->state = TASK_ZOMBIE;
+				retval = wait_task_zombie(p, stat_addr, ru);
+				if (retval != 0) /* He released the lock.  */
 					goto end_wait4;
-				}
-				retval = p->pid;
-				if (p->real_parent != p->parent) {
-					write_lock_irq(&tasklist_lock);
-					__ptrace_unlink(p);
-					do_notify_parent(p, SIGCHLD);
-					p->state = TASK_ZOMBIE;
-					write_unlock_irq(&tasklist_lock);
-				} else
-					release_task(p);
-				goto end_wait4;
-			default:
-				continue;
+				break;
 			}
 		}
 		if (!flag) {
@@ -885,7 +1050,7 @@
 		if (options & __WNOTHREAD)
 			break;
 		tsk = next_thread(tsk);
-		if (tsk->sig != current->sig)
+		if (tsk->signal != current->signal)
 			BUG();
 	} while (tsk != current);
 	read_unlock(&tasklist_lock);
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Mon Feb 10 10:39:23 2003
+++ b/kernel/fork.c	Mon Feb 10 10:39:23 2003
@@ -26,6 +26,7 @@
 #include <linux/mman.h>
 #include <linux/fs.h>
 #include <linux/security.h>
+#include <linux/jiffies.h>
 #include <linux/futex.h>
 #include <linux/ptrace.h>
 #include <linux/mount.h>
@@ -664,22 +665,39 @@
 
 static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
 {
-	struct signal_struct *sig;
+	struct sighand_struct *sig;
 
-	if (clone_flags & CLONE_SIGHAND) {
-		atomic_inc(&current->sig->count);
+	if (clone_flags & (CLONE_SIGHAND | CLONE_THREAD)) {
+		atomic_inc(&current->sighand->count);
 		return 0;
 	}
-	sig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL);
-	tsk->sig = sig;
+	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
+	tsk->sighand = sig;
 	if (!sig)
 		return -1;
 	spin_lock_init(&sig->siglock);
 	atomic_set(&sig->count, 1);
+	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
+	return 0;
+}
+
+static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk)
+{
+	struct signal_struct *sig;
+
+	if (clone_flags & CLONE_THREAD) {
+		atomic_inc(&current->signal->count);
+		return 0;
+	}
+	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
+	tsk->signal = sig;
+	if (!sig)
+		return -1;
+	atomic_set(&sig->count, 1);
 	sig->group_exit = 0;
 	sig->group_exit_code = 0;
 	sig->group_exit_task = NULL;
-	memcpy(sig->action, current->sig->action, sizeof(sig->action));
+	sig->group_stop_count = 0;
 	sig->curr_target = NULL;
 	init_sigpending(&sig->shared_pending);
 
@@ -800,7 +818,7 @@
 	spin_lock_init(&p->alloc_lock);
 	spin_lock_init(&p->switch_lock);
 
-	clear_tsk_thread_flag(p,TIF_SIGPENDING);
+	clear_tsk_thread_flag(p, TIF_SIGPENDING);
 	init_sigpending(&p->pending);
 
 	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
@@ -814,7 +832,7 @@
 	p->cutime = p->cstime = 0;
 	p->array = NULL;
 	p->lock_depth = -1;		/* -1 = no lock */
-	p->start_time = jiffies;
+	p->start_time = get_jiffies_64();
 	p->security = NULL;
 
 	retval = -ENOMEM;
@@ -829,8 +847,10 @@
 		goto bad_fork_cleanup_files;
 	if (copy_sighand(clone_flags, p))
 		goto bad_fork_cleanup_fs;
-	if (copy_mm(clone_flags, p))
+	if (copy_signal(clone_flags, p))
 		goto bad_fork_cleanup_sighand;
+	if (copy_mm(clone_flags, p))
+		goto bad_fork_cleanup_signal;
 	if (copy_namespace(clone_flags, p))
 		goto bad_fork_cleanup_mm;
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
@@ -909,6 +929,7 @@
 	 */
 	if (sigismember(&current->pending.signal, SIGKILL)) {
 		write_unlock_irq(&tasklist_lock);
+		retval = -EINTR;
 		goto bad_fork_cleanup_namespace;
 	}
 
@@ -920,20 +941,31 @@
 	p->parent = p->real_parent;
 
 	if (clone_flags & CLONE_THREAD) {
-		spin_lock(&current->sig->siglock);
+		spin_lock(&current->sighand->siglock);
 		/*
 		 * Important: if an exit-all has been started then
 		 * do not create this new thread - the whole thread
 		 * group is supposed to exit anyway.
 		 */
-		if (current->sig->group_exit) {
-			spin_unlock(&current->sig->siglock);
+		if (current->signal->group_exit) {
+			spin_unlock(&current->sighand->siglock);
 			write_unlock_irq(&tasklist_lock);
 			goto bad_fork_cleanup_namespace;
 		}
 		p->tgid = current->tgid;
 		p->group_leader = current->group_leader;
-		spin_unlock(&current->sig->siglock);
+
+		if (current->signal->group_stop_count > 0) {
+			/*
+			 * There is an all-stop in progress for the group.
+			 * We ourselves will stop as soon as we check signals.
+			 * Make the new thread part of that group stop too.
+			 */
+			current->signal->group_stop_count++;
+			set_tsk_thread_flag(p, TIF_SIGPENDING);
+		}
+
+		spin_unlock(&current->sighand->siglock);
 	}
 
 	SET_LINKS(p);
@@ -963,6 +995,8 @@
 	exit_namespace(p);
 bad_fork_cleanup_mm:
 	exit_mm(p);
+bad_fork_cleanup_signal:
+	exit_signal(p);
 bad_fork_cleanup_sighand:
 	exit_sighand(p);
 bad_fork_cleanup_fs:
@@ -1035,8 +1069,13 @@
 			init_completion(&vfork);
 		}
 
-		if (p->ptrace & PT_PTRACED)
-			send_sig(SIGSTOP, p, 1);
+		if (p->ptrace & PT_PTRACED) {
+			/*
+			 * We'll start up with an immediate SIGSTOP.
+			 */
+			sigaddset(&p->pending.signal, SIGSTOP);
+			set_tsk_thread_flag(p, TIF_SIGPENDING);
+		}
 
 		wake_up_forked_process(p);		/* do this last */
 		++total_forks;
@@ -1046,9 +1085,11 @@
 			ptrace_notify ((trace << 8) | SIGTRAP);
 		}
 
-		if (clone_flags & CLONE_VFORK)
+		if (clone_flags & CLONE_VFORK) {
 			wait_for_completion(&vfork);
-		else
+			if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
+				ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
+		} else
 			/*
 			 * Let the child process run first, to avoid most of the
 			 * COW overhead when the child exec()s afterwards.
@@ -1058,8 +1099,11 @@
 	return p;
 }
 
-/* SLAB cache for signal_struct structures (tsk->sig) */
-kmem_cache_t *sigact_cachep;
+/* SLAB cache for signal_struct structures (tsk->signal) */
+kmem_cache_t *signal_cachep;
+
+/* SLAB cache for sighand_struct structures (tsk->sighand) */
+kmem_cache_t *sighand_cachep;
 
 /* SLAB cache for files_struct structures (tsk->files) */
 kmem_cache_t *files_cachep;
@@ -1075,11 +1119,17 @@
 
 void __init proc_caches_init(void)
 {
-	sigact_cachep = kmem_cache_create("signal_act",
+	sighand_cachep = kmem_cache_create("sighand_cache",
+			sizeof(struct sighand_struct), 0,
+			SLAB_HWCACHE_ALIGN, NULL, NULL);
+	if (!sighand_cachep)
+		panic("Cannot create sighand SLAB cache");
+
+	signal_cachep = kmem_cache_create("signal_cache",
 			sizeof(struct signal_struct), 0,
 			SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (!sigact_cachep)
-		panic("Cannot create signal action SLAB cache");
+	if (!signal_cachep)
+		panic("Cannot create signal SLAB cache");
 
 	files_cachep = kmem_cache_create("files_cache", 
 			 sizeof(struct files_struct), 0, 
diff -Nru a/kernel/kmod.c b/kernel/kmod.c
--- a/kernel/kmod.c	Mon Feb 10 10:39:24 2003
+++ b/kernel/kmod.c	Mon Feb 10 10:39:24 2003
@@ -100,8 +100,7 @@
 	int i;
 	struct task_struct *curtask = current;
 
-	curtask->session = 1;
-	curtask->pgrp = 1;
+	set_special_pids(1, 1);
 
 	use_init_fs_context();
 
@@ -111,12 +110,12 @@
 	   as the super user right after the execve fails if you time
 	   the signal just right.
 	*/
-	spin_lock_irq(&curtask->sig->siglock);
+	spin_lock_irq(&curtask->sighand->siglock);
 	sigemptyset(&curtask->blocked);
 	flush_signals(curtask);
 	flush_signal_handlers(curtask);
 	recalc_sigpending();
-	spin_unlock_irq(&curtask->sig->siglock);
+	spin_unlock_irq(&curtask->sighand->siglock);
 
 	for (i = 0; i < curtask->files->max_fds; i++ ) {
 		if (curtask->files->fd[i]) close(i);
@@ -239,20 +238,20 @@
 	}
 
 	/* Block everything but SIGKILL/SIGSTOP */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	tmpsig = current->blocked;
 	siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	waitpid_result = waitpid(pid, NULL, __WCLONE);
 	atomic_dec(&kmod_concurrent);
 
 	/* Allow signals again.. */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	current->blocked = tmpsig;
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (waitpid_result != pid) {
 		printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Mon Feb 10 10:39:23 2003
+++ b/kernel/ksyms.c	Mon Feb 10 10:39:23 2003
@@ -55,6 +55,7 @@
 #include <linux/dnotify.h>
 #include <linux/mount.h>
 #include <linux/ptrace.h>
+#include <linux/time.h>
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -68,13 +69,6 @@
 
 extern int panic_timeout;
 
-#ifdef CONFIG_MODVERSIONS
-const struct module_symbol __export_Using_Versions
-__attribute__((section("__ksymtab"))) = {
-	1 /* Version version */, "Using_Versions"
-};
-#endif
-
 /* process memory management */
 EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
@@ -272,6 +266,10 @@
 EXPORT_SYMBOL(vfs_stat);
 EXPORT_SYMBOL(vfs_lstat);
 EXPORT_SYMBOL(vfs_getattr);
+EXPORT_SYMBOL(inode_add_bytes);
+EXPORT_SYMBOL(inode_sub_bytes);
+EXPORT_SYMBOL(inode_get_bytes);
+EXPORT_SYMBOL(inode_set_bytes);
 EXPORT_SYMBOL(lock_rename);
 EXPORT_SYMBOL(unlock_rename);
 EXPORT_SYMBOL(generic_read_dir);
@@ -488,6 +486,7 @@
 EXPORT_SYMBOL(jiffies);
 EXPORT_SYMBOL(jiffies_64);
 EXPORT_SYMBOL(xtime);
+EXPORT_SYMBOL(xtime_lock);
 EXPORT_SYMBOL(do_gettimeofday);
 EXPORT_SYMBOL(do_settimeofday);
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Mon Feb 10 10:39:30 2003
+++ b/kernel/module.c	Mon Feb 10 10:39:30 2003
@@ -78,6 +78,7 @@
 /* Find a symbol, return value and the symbol group */
 static unsigned long __find_symbol(const char *name,
 				   struct kernel_symbol_group **group,
+				   unsigned int *symidx,
 				   int gplok)
 {
 	struct kernel_symbol_group *ks;
@@ -90,6 +91,8 @@
 		for (i = 0; i < ks->num_syms; i++) {
 			if (strcmp(ks->syms[i].name, name) == 0) {
 				*group = ks;
+				if (symidx)
+					*symidx = i;
 				return ks->syms[i].value;
 			}
 		}
@@ -520,7 +523,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&modlist_lock, flags);
-	if (!__find_symbol(symbol, &ksg, 1))
+	if (!__find_symbol(symbol, &ksg, NULL, 1))
 		BUG();
 	module_put(ksg->owner);
 	spin_unlock_irqrestore(&modlist_lock, flags);
@@ -722,22 +725,91 @@
 }
 #endif /* CONFIG_OBSOLETE_MODPARM */
 
+#ifdef CONFIG_MODVERSIONS
+static int check_version(Elf_Shdr *sechdrs,
+			 unsigned int versindex,
+			 const char *symname,
+			 struct module *mod, 
+			 struct kernel_symbol_group *ksg,
+			 unsigned int symidx)
+{
+	unsigned long crc;
+	unsigned int i, num_versions;
+	struct modversion_info *versions;
+
+	/* Exporting module didn't supply crcs?  OK, we're already tainted. */
+	if (!ksg->crcs)
+		return 1;
+
+	crc = ksg->crcs[symidx];
+
+	versions = (void *) sechdrs[versindex].sh_addr;
+	num_versions = sechdrs[versindex].sh_size
+		/ sizeof(struct modversion_info);
+
+	for (i = 0; i < num_versions; i++) {
+		if (strcmp(versions[i].name, symname) != 0)
+			continue;
+
+		if (versions[i].crc == crc)
+			return 1;
+		printk("%s: disagrees about version of symbol %s\n",
+		       mod->name, symname);
+		DEBUGP("Found checksum %lX vs module %lX\n",
+		       crc, versions[i].crc);
+		return 0;
+	}
+	/* Not in module's version table.  OK, but that taints the kernel. */
+	if (!(tainted & TAINT_FORCED_MODULE)) {
+		printk("%s: no version for \"%s\" found: kernel tainted.\n",
+		       mod->name, symname);
+		tainted |= TAINT_FORCED_MODULE;
+	}
+	return 1;
+}
+
+/* First part is kernel version, which we ignore. */
+static inline int same_magic(const char *amagic, const char *bmagic)
+{
+	amagic += strcspn(amagic, " ");
+	bmagic += strcspn(bmagic, " ");
+	return strcmp(amagic, bmagic) == 0;
+}
+#else
+static inline int check_version(Elf_Shdr *sechdrs,
+				unsigned int versindex,
+				const char *symname,
+				struct module *mod, 
+				struct kernel_symbol_group *ksg,
+				unsigned int symidx)
+{
+	return 1;
+}
+
+static inline int same_magic(const char *amagic, const char *bmagic)
+{
+	return strcmp(amagic, bmagic) == 0;
+}
+#endif /* CONFIG_MODVERSIONS */
+
 /* Resolve a symbol for this module.  I.e. if we find one, record usage.
    Must be holding module_mutex. */
 static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
-				    unsigned int symindex,
-				    const char *strtab,
+				    unsigned int versindex,
 				    const char *name,
 				    struct module *mod)
 {
 	struct kernel_symbol_group *ksg;
 	unsigned long ret;
+	unsigned int symidx;
 
 	spin_lock_irq(&modlist_lock);
-	ret = __find_symbol(name, &ksg, mod->license_gplok);
+	ret = __find_symbol(name, &ksg, &symidx, mod->license_gplok);
 	if (ret) {
-		/* This can fail due to OOM, or module unloading */
-		if (!use_module(mod, ksg->owner))
+		/* use_module can fail due to OOM, or module unloading */
+		if (!check_version(sechdrs, versindex, name, mod,
+				   ksg, symidx) ||
+		    !use_module(mod, ksg->owner))
 			ret = 0;
 	}
 	spin_unlock_irq(&modlist_lock);
@@ -772,7 +844,7 @@
 	unsigned long value, flags;
 
 	spin_lock_irqsave(&modlist_lock, flags);
-	value = __find_symbol(symbol, &ksg, 1);
+	value = __find_symbol(symbol, &ksg, NULL, 1);
 	if (value && !strong_try_module_get(ksg->owner))
 		value = 0;
 	spin_unlock_irqrestore(&modlist_lock, flags);
@@ -824,6 +896,7 @@
 static int simplify_symbols(Elf_Shdr *sechdrs,
 			    unsigned int symindex,
 			    unsigned int strindex,
+			    unsigned int versindex,
 			    struct module *mod)
 {
 	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
@@ -848,7 +921,7 @@
 
 		case SHN_UNDEF:
 			sym[i].st_value
-			  = resolve_symbol(sechdrs, symindex, strtab,
+			  = resolve_symbol(sechdrs, versindex,
 					   strtab + sym[i].st_name, mod);
 
 			/* Ok if resolved.  */
@@ -916,7 +989,7 @@
 			    || strstr(secstrings + s->sh_name, ".init"))
 				continue;
 			s->sh_entsize = get_offset(&mod->core_size, s);
-			DEBUGP("\t%s\n", name);
+			DEBUGP("\t%s\n", secstrings + s->sh_name);
 		}
 	}
 
@@ -932,7 +1005,7 @@
 				continue;
 			s->sh_entsize = (get_offset(&mod->init_size, s)
 					 | INIT_OFFSET_MASK);
-			DEBUGP("\t%s\n", name);
+			DEBUGP("\t%s\n", secstrings + s->sh_name);
 		}
 	}
 }
@@ -976,7 +1049,8 @@
 	Elf_Shdr *sechdrs;
 	char *secstrings, *args;
 	unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
-		modindex, obsparmindex, licenseindex, gplindex, vmagindex;
+		modindex, obsparmindex, licenseindex, gplindex, vmagindex,
+		crcindex, gplcrcindex, versindex;
 	long arglen;
 	struct module *mod;
 	long err = 0;
@@ -1012,7 +1086,8 @@
 
 	/* May not export symbols, or have setup params, so these may
            not exist */
-	exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0;
+	exportindex = setupindex = obsparmindex = gplindex = licenseindex 
+		= crcindex = gplcrcindex = versindex = 0;
 
 	/* And these should exist, but gcc whinges if we don't init them */
 	symindex = strindex = exindex = modindex = vmagindex = 0;
@@ -1040,6 +1115,21 @@
 			/* Exported symbols. */
 			DEBUGP("EXPORT table in section %u\n", i);
 			exportindex = i;
+		} else if (strcmp(secstrings+sechdrs[i].sh_name,
+				  "__ksymtab_gpl") == 0) {
+			/* Exported symbols. (GPL) */
+			DEBUGP("GPL symbols found in section %u\n", i);
+			gplindex = i;
+		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab")
+			   == 0) {
+			/* Exported symbols CRCs. */
+			DEBUGP("CRC table in section %u\n", i);
+			crcindex = i;
+		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab_gpl")
+			   == 0) {
+			/* Exported symbols CRCs. (GPL)*/
+			DEBUGP("CRC table in section %u\n", i);
+			gplcrcindex = i;
 		} else if (strcmp(secstrings+sechdrs[i].sh_name, "__param")
 			   == 0) {
 			/* Setup parameter info */
@@ -1060,16 +1150,21 @@
 			/* MODULE_LICENSE() */
 			DEBUGP("Licence found in section %u\n", i);
 			licenseindex = i;
+			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  "__gpl_ksymtab") == 0) {
-			/* EXPORT_SYMBOL_GPL() */
-			DEBUGP("GPL symbols found in section %u\n", i);
-			gplindex = i;
-		} else if (strcmp(secstrings+sechdrs[i].sh_name,
-				  "__vermagic") == 0) {
+				  "__vermagic") == 0 &&
+			   (sechdrs[i].sh_flags & SHF_ALLOC)) {
 			/* Version magic. */
 			DEBUGP("Version magic found in section %u\n", i);
 			vmagindex = i;
+			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
+		} else if (strcmp(secstrings+sechdrs[i].sh_name,
+				  "__versions") == 0 &&
+			   (sechdrs[i].sh_flags & SHF_ALLOC)) {
+			/* Module version info (both exported and needed) */
+			DEBUGP("Versions found in section %u\n", i);
+			versindex = i;
+			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 		}
 #ifdef CONFIG_KALLSYMS
 		/* symbol and string tables for decoding later. */
@@ -1090,12 +1185,12 @@
 	}
 	mod = (void *)sechdrs[modindex].sh_addr;
 
-	/* This is allowed: modprobe --force will strip it. */
+	/* This is allowed: modprobe --force will invalidate it. */
 	if (!vmagindex) {
 		tainted |= TAINT_FORCED_MODULE;
 		printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
 		       mod->name);
-	} else if (strcmp((char *)sechdrs[vmagindex].sh_addr, vermagic) != 0) {
+	} else if (!same_magic((char *)sechdrs[vmagindex].sh_addr, vermagic)) {
 		printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
 		       mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic);
 		err = -ENOEXEC;
@@ -1181,7 +1276,7 @@
 	set_license(mod, sechdrs, licenseindex);
 
 	/* Fix up syms, so that st_value is a pointer to location. */
-	err = simplify_symbols(sechdrs, symindex, strindex, mod);
+	err = simplify_symbols(sechdrs, symindex, strindex, versindex, mod);
 	if (err < 0)
 		goto cleanup;
 
@@ -1189,9 +1284,23 @@
 	mod->symbols.num_syms = (sechdrs[exportindex].sh_size
 				 / sizeof(*mod->symbols.syms));
 	mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr;
+	if (crcindex)
+		mod->symbols.crcs = (void *)sechdrs[crcindex].sh_addr;
+
 	mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size
 				 / sizeof(*mod->symbols.syms));
 	mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr;
+	if (gplcrcindex)
+		mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr;
+
+#ifdef CONFIG_MODVERSIONS
+	if ((mod->symbols.num_syms && !crcindex)
+	    || (mod->gpl_symbols.num_syms && !gplcrcindex)) {
+		printk(KERN_WARNING "%s: No versions for exported symbols."
+		       " Tainting kernel.\n", mod->name);
+		tainted |= TAINT_FORCED_MODULE;
+	}
+#endif
 
 	/* Set up exception table */
 	if (exindex) {
@@ -1442,7 +1551,7 @@
 	return 0;
 }
 
-/* Format: modulename size refcount deps
+/* Format: modulename size refcount deps address
 
    Where refcount is a number or -, and deps is a comma-separated list
    of depends or -.
@@ -1492,8 +1601,12 @@
 /* Provided by the linker */
 extern const struct kernel_symbol __start___ksymtab[];
 extern const struct kernel_symbol __stop___ksymtab[];
-extern const struct kernel_symbol __start___gpl_ksymtab[];
-extern const struct kernel_symbol __stop___gpl_ksymtab[];
+extern const struct kernel_symbol __start___ksymtab_gpl[];
+extern const struct kernel_symbol __stop___ksymtab_gpl[];
+extern const unsigned long __start___kcrctab[];
+extern const unsigned long __stop___kcrctab[];
+extern const unsigned long __start___kcrctab_gpl[];
+extern const unsigned long __stop___kcrctab_gpl[];
 
 static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols;
 
@@ -1502,11 +1615,14 @@
 	/* Add kernel symbols to symbol table */
 	kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab);
 	kernel_symbols.syms = __start___ksymtab;
+	kernel_symbols.crcs = __start___kcrctab;
 	kernel_symbols.gplonly = 0;
 	list_add(&kernel_symbols.list, &symbols);
-	kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab
-				       - __start___gpl_ksymtab);
-	kernel_gpl_symbols.syms = __start___gpl_ksymtab;
+
+	kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl
+				       - __start___ksymtab_gpl);
+	kernel_gpl_symbols.syms = __start___ksymtab_gpl;
+	kernel_gpl_symbols.crcs = __start___kcrctab_gpl;
 	kernel_gpl_symbols.gplonly = 1;
 	list_add(&kernel_gpl_symbols.list, &symbols);
 
diff -Nru a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c	Mon Feb 10 10:39:31 2003
+++ b/kernel/params.c	Mon Feb 10 10:39:31 2003
@@ -27,6 +27,22 @@
 #define DEBUGP(fmt, a...)
 #endif
 
+static inline int dash2underscore(char c)
+{
+	if (c == '-')
+		return '_';
+	return c;
+}
+
+static inline int parameq(const char *input, const char *paramname)
+{
+	unsigned int i;
+	for (i = 0; dash2underscore(input[i]) == paramname[i]; i++)
+		if (input[i] == '\0')
+			return 1;
+	return 0;
+}
+
 static int parse_one(char *param,
 		     char *val,
 		     struct kernel_param *params, 
@@ -37,7 +53,7 @@
 
 	/* Find parameter */
 	for (i = 0; i < num_params; i++) {
-		if (strcmp(param, params[i].name) == 0) {
+		if (parameq(param, params[i].name)) {
 			DEBUGP("They are equal!  Calling %p\n",
 			       params[i].set);
 			return params[i].set(val, &params[i]);
@@ -69,8 +85,6 @@
 		if (equals == 0) {
 			if (args[i] == '=')
 				equals = i;
-			else if (args[i] == '-')
-				args[i] = '_';
 		}
 		if (args[i] == '"')
 			in_quote = !in_quote;
diff -Nru a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c	Mon Feb 10 10:39:33 2003
+++ b/kernel/printk.c	Mon Feb 10 10:39:33 2003
@@ -243,19 +243,13 @@
 
 		break;
 	case 5:		/* Clear ring buffer */
-		spin_lock_irq(&logbuf_lock);
 		logged_chars = 0;
-		spin_unlock_irq(&logbuf_lock);
 		break;
 	case 6:		/* Disable logging to console */
-		spin_lock_irq(&logbuf_lock);
 		console_loglevel = minimum_console_loglevel;
-		spin_unlock_irq(&logbuf_lock);
 		break;
 	case 7:		/* Enable logging to console */
-		spin_lock_irq(&logbuf_lock);
 		console_loglevel = default_console_loglevel;
-		spin_unlock_irq(&logbuf_lock);
 		break;
 	case 8:		/* Set level of messages printed to console */
 		error = -EINVAL;
@@ -263,15 +257,11 @@
 			goto out;
 		if (len < minimum_console_loglevel)
 			len = minimum_console_loglevel;
-		spin_lock_irq(&logbuf_lock);
 		console_loglevel = len;
-		spin_unlock_irq(&logbuf_lock);
 		error = 0;
 		break;
 	case 9:		/* Number of chars in the log buffer */
-		spin_lock_irq(&logbuf_lock);
 		error = log_end - log_start;
-		spin_unlock_irq(&logbuf_lock);
 		break;
 	default:
 		error = -EINVAL;
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Mon Feb 10 10:39:33 2003
+++ b/kernel/ptrace.c	Mon Feb 10 10:39:33 2003
@@ -277,15 +277,43 @@
 	else
 		child->ptrace &= ~PT_TRACE_EXEC;
 
+	if (data & PTRACE_O_TRACEVFORKDONE)
+		child->ptrace |= PT_TRACE_VFORK_DONE;
+	else
+		child->ptrace &= ~PT_TRACE_VFORK_DONE;
+
+	if (data & PTRACE_O_TRACEEXIT)
+		child->ptrace |= PT_TRACE_EXIT;
+	else
+		child->ptrace &= ~PT_TRACE_EXIT;
+
 	if ((data & (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK
 		    | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE
-		    | PTRACE_O_TRACEEXEC))
+		    | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT
+		    | PTRACE_O_TRACEVFORKDONE))
 	    != data)
 		return -EINVAL;
 
 	return 0;
 }
 
+static int ptrace_getsiginfo(struct task_struct *child, long data)
+{
+	if (child->last_siginfo == NULL)
+		return -EINVAL;
+	return copy_siginfo_to_user ((siginfo_t *) data, child->last_siginfo);
+}
+
+static int ptrace_setsiginfo(struct task_struct *child, long data)
+{
+	if (child->last_siginfo == NULL)
+		return -EINVAL;
+	if (copy_from_user (child->last_siginfo, (siginfo_t *) data,
+			    sizeof (siginfo_t)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
 int ptrace_request(struct task_struct *child, long request,
 		   long addr, long data)
 {
@@ -300,6 +328,12 @@
 		break;
 	case PTRACE_GETEVENTMSG:
 		ret = put_user(child->ptrace_message, (unsigned long *) data);
+		break;
+	case PTRACE_GETSIGINFO:
+		ret = ptrace_getsiginfo(child, data);
+		break;
+	case PTRACE_SETSIGINFO:
+		ret = ptrace_setsiginfo(child, data);
 		break;
 	default:
 		break;
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Mon Feb 10 10:39:30 2003
+++ b/kernel/sched.c	Mon Feb 10 10:39:30 2003
@@ -213,7 +213,7 @@
 	int i;
 
 	for (i = 0; i < NR_CPUS; i++)
-		cpu_rq(i)->node_nr_running = &node_nr_running[__cpu_to_node(i)];
+		cpu_rq(i)->node_nr_running = &node_nr_running[cpu_to_node(i)];
 }
 
 #else /* !CONFIG_NUMA */
@@ -438,6 +438,7 @@
 /***
  * try_to_wake_up - wake up a thread
  * @p: the to-be-woken-up thread
+ * @state: the mask of task states that can be woken
  * @sync: do a synchronous wakeup?
  *
  * Put it on the run-queue if it's not already there. The "current"
@@ -448,7 +449,7 @@
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(task_t * p, int sync)
+static int try_to_wake_up(task_t * p, unsigned int state, int sync)
 {
 	unsigned long flags;
 	int success = 0;
@@ -458,28 +459,30 @@
 repeat_lock_task:
 	rq = task_rq_lock(p, &flags);
 	old_state = p->state;
-	if (!p->array) {
-		/*
-		 * Fast-migrate the task if it's not running or runnable
-		 * currently. Do not violate hard affinity.
-		 */
-		if (unlikely(sync && !task_running(rq, p) &&
-			(task_cpu(p) != smp_processor_id()) &&
-			(p->cpus_allowed & (1UL << smp_processor_id())))) {
-
-			set_task_cpu(p, smp_processor_id());
-			task_rq_unlock(rq, &flags);
-			goto repeat_lock_task;
+	if (old_state & state) {
+		if (!p->array) {
+			/*
+			 * Fast-migrate the task if it's not running or runnable
+			 * currently. Do not violate hard affinity.
+			 */
+			if (unlikely(sync && !task_running(rq, p) &&
+				(task_cpu(p) != smp_processor_id()) &&
+				(p->cpus_allowed & (1UL << smp_processor_id())))) {
+
+				set_task_cpu(p, smp_processor_id());
+				task_rq_unlock(rq, &flags);
+				goto repeat_lock_task;
+			}
+			if (old_state == TASK_UNINTERRUPTIBLE)
+				rq->nr_uninterruptible--;
+			activate_task(p, rq);
+	
+			if (p->prio < rq->curr->prio)
+				resched_task(rq->curr);
+			success = 1;
 		}
-		if (old_state == TASK_UNINTERRUPTIBLE)
-			rq->nr_uninterruptible--;
-		activate_task(p, rq);
-
-		if (p->prio < rq->curr->prio)
-			resched_task(rq->curr);
-		success = 1;
+		p->state = TASK_RUNNING;
 	}
-	p->state = TASK_RUNNING;
 	task_rq_unlock(rq, &flags);
 
 	return success;
@@ -487,7 +490,12 @@
 
 int wake_up_process(task_t * p)
 {
-	return try_to_wake_up(p, 0);
+	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
+}
+
+int wake_up_state(task_t *p, unsigned int state)
+{
+	return try_to_wake_up(p, state, 0);
 }
 
 /*
@@ -715,7 +723,7 @@
 	}
 
 	minload = 10000000;
-	cpumask = __node_to_cpu_mask(node);
+	cpumask = node_to_cpumask(node);
 	for (i = 0; i < NR_CPUS; ++i) {
 		if (!(cpumask & (1UL << i)))
 			continue;
@@ -767,7 +775,7 @@
 
 static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq)
 {
-	int this_node = __cpu_to_node(this_cpu);
+	int this_node = cpu_to_node(this_cpu);
 	/*
 	 * Avoid rebalancing between nodes too often.
 	 * We rebalance globally once every NODE_BALANCE_RATE load balances.
@@ -776,9 +784,9 @@
 		int node = find_busiest_node(this_node);
 		this_rq->nr_balanced = 0;
 		if (node >= 0)
-			return (__node_to_cpu_mask(node) | (1UL << this_cpu));
+			return (node_to_cpumask(node) | (1UL << this_cpu));
 	}
-	return __node_to_cpu_mask(this_node);
+	return node_to_cpumask(this_node);
 }
 
 #else /* !CONFIG_NUMA */
@@ -1263,7 +1271,7 @@
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
 {
 	task_t *p = curr->task;
-	return ((p->state & mode) && try_to_wake_up(p, sync));
+	return try_to_wake_up(p, mode, sync);
 }
 
 /*
@@ -2037,7 +2045,7 @@
 	unsigned long free = 0;
 	task_t *relative;
 	int state;
-	static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
+	static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
 
 	printk("%-13.13s ", p->comm);
 	state = p->state ? __ffs(p->state) + 1 : 0;
@@ -2057,7 +2065,7 @@
 		printk(" %016lx ", thread_saved_pc(p));
 #endif
 	{
-		unsigned long * n = (unsigned long *) (p+1);
+		unsigned long * n = (unsigned long *) (p->thread_info+1);
 		while (!*n)
 			n++;
 		free = (unsigned long) n - (unsigned long)(p+1);
@@ -2418,7 +2426,7 @@
 	rq->curr = current;
 	rq->idle = current;
 	set_task_cpu(current, smp_processor_id());
-	wake_up_process(current);
+	wake_up_forked_process(current);
 
 	init_timers();
 
@@ -2465,15 +2473,12 @@
 		_raw_spin_lock(lock);
 		return;
 	}
-
-	while (!_raw_spin_trylock(lock)) {
-		if (need_resched()) {
-			preempt_enable_no_resched();
-			__cond_resched();
-			preempt_disable();
-		}
-		cpu_relax();
-	}
+	do {
+		preempt_enable();
+		while (spin_is_locked(lock))
+			cpu_relax();
+		preempt_disable();
+	} while (!_raw_spin_trylock(lock));
 }
 
 void __preempt_write_lock(rwlock_t *lock)
@@ -2483,13 +2488,11 @@
 		return;
 	}
 
-	while (!_raw_write_trylock(lock)) {
-		if (need_resched()) {
-			preempt_enable_no_resched();
-			__cond_resched();
-			preempt_disable();
-		}
-		cpu_relax();
-	}
+	do {
+		preempt_enable();
+		while (rwlock_is_locked(lock))
+			cpu_relax();
+		preempt_disable();
+	} while (!_raw_write_trylock(lock));
 }
 #endif
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Mon Feb 10 10:39:25 2003
+++ b/kernel/signal.c	Mon Feb 10 10:39:25 2003
@@ -55,7 +55,7 @@
 |  SIGALRM           |  load-balance    |  kill-all      |
 |  SIGTERM           |  load-balance    |  kill-all      |
 |  SIGCHLD           |  load-balance    |  ignore        |
-|  SIGCONT           |  specific        |  continue-all  |
+|  SIGCONT           |  load-balance    |  ignore        |
 |  SIGSTOP           |  n/a             |  stop-all      |
 |  SIGTSTP           |  load-balance    |  stop-all      |
 |  SIGTTIN           |  load-balance    |  stop-all      |
@@ -98,26 +98,11 @@
 #endif
 
 #if SIGRTMIN > BITS_PER_LONG
-#define M(sig) (1ULL << (sig))
+#define M(sig) (1ULL << ((sig)-1))
 #else
-#define M(sig) (1UL << (sig))
+#define M(sig) (1UL << ((sig)-1))
 #endif
-#define T(sig, mask) (M(sig) & mask)
-
-#define SIG_USER_SPECIFIC_MASK (\
-	M(SIGILL)    |  M(SIGTRAP)   |  M(SIGABRT)   |  M(SIGBUS)    | \
-	M(SIGFPE)    |  M(SIGSEGV)   |  M(SIGPIPE)   |  M(SIGXFSZ)   | \
-	M(SIGPROF)   |  M(SIGSYS)    |  M_SIGSTKFLT  |  M(SIGCONT)   | \
-        M_SIGEMT )
-
-#define SIG_USER_LOAD_BALANCE_MASK (\
-        M(SIGHUP)    |  M(SIGINT)    |  M(SIGQUIT)   |  M(SIGUSR1)   | \
-        M(SIGUSR2)   |  M(SIGALRM)   |  M(SIGTERM)   |  M(SIGCHLD)   | \
-        M(SIGURG)    |  M(SIGVTALRM) |  M(SIGPOLL)   |  M(SIGWINCH)  | \
-        M(SIGPWR)    |  M(SIGTSTP)   |  M(SIGTTIN)   |  M(SIGTTOU)   )
-
-#define SIG_KERNEL_SPECIFIC_MASK (\
-        M(SIGCHLD)   |   M(SIGURG)   |  M(SIGWINCH)                  )
+#define T(sig, mask) (M(sig) & (mask))
 
 #define SIG_KERNEL_BROADCAST_MASK (\
 	M(SIGHUP)    |  M(SIGINT)    |  M(SIGQUIT)   |  M(SIGILL)    | \
@@ -132,34 +117,37 @@
 #define SIG_KERNEL_ONLY_MASK (\
 	M(SIGKILL)   |  M(SIGSTOP)                                   )
 
+#define SIG_KERNEL_STOP_MASK (\
+	M(SIGSTOP)   |  M(SIGTSTP)   |  M(SIGTTIN)   |  M(SIGTTOU)   )
+
 #define SIG_KERNEL_COREDUMP_MASK (\
         M(SIGQUIT)   |  M(SIGILL)    |  M(SIGTRAP)   |  M(SIGABRT)   | \
         M(SIGFPE)    |  M(SIGSEGV)   |  M(SIGBUS)    |  M(SIGSYS)    | \
         M(SIGXCPU)   |  M(SIGXFSZ)   |  M_SIGEMT                     )
 
-#define sig_user_specific(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_USER_SPECIFIC_MASK))
-#define sig_user_load_balance(sig) \
-		(((sig) >= SIGRTMIN) || T(sig, SIG_USER_LOAD_BALANCE_MASK))
-#define sig_kernel_specific(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_SPECIFIC_MASK))
-#define sig_kernel_broadcast(sig) \
-		(((sig) >= SIGRTMIN) || T(sig, SIG_KERNEL_BROADCAST_MASK))
+#define SIG_KERNEL_IGNORE_MASK (\
+        M(SIGCONT)   |  M(SIGCHLD)   |  M(SIGWINCH)  |  M(SIGURG)    )
+
 #define sig_kernel_only(sig) \
 		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_ONLY_MASK))
 #define sig_kernel_coredump(sig) \
 		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_COREDUMP_MASK))
-
-#define sig_user_defined(t, sig) \
-	(((t)->sig->action[(sig)-1].sa.sa_handler != SIG_DFL) &&	\
-	 ((t)->sig->action[(sig)-1].sa.sa_handler != SIG_IGN))
-
-#define sig_ignored(t, sig) \
-	(((sig) != SIGCHLD) && \
-		((t)->sig->action[(sig)-1].sa.sa_handler == SIG_IGN))
-
-static int
-__send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
+#define sig_kernel_ignore(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_IGNORE_MASK))
+#define sig_kernel_stop(sig) \
+		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_STOP_MASK))
+
+#define sig_user_defined(t, signr) \
+	(((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&	\
+	 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
+
+#define sig_ignored(t, signr) \
+	(!((t)->ptrace & PT_PTRACED) && \
+	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_IGN)
+
+#define sig_fatal(t, signr) \
+	(!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
+	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
 
 /*
  * Re-calculate pending state from the set of locally pending
@@ -193,10 +181,11 @@
 
 #define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
 
-void recalc_sigpending_tsk(struct task_struct *t)
+inline void recalc_sigpending_tsk(struct task_struct *t)
 {
-	if (PENDING(&t->pending, &t->blocked) ||
-			PENDING(&t->sig->shared_pending, &t->blocked))
+	if (t->signal->group_stop_count > 0 ||
+	    PENDING(&t->pending, &t->blocked) ||
+	    PENDING(&t->signal->shared_pending, &t->blocked))
 		set_tsk_thread_flag(t, TIF_SIGPENDING);
 	else
 		clear_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -204,11 +193,7 @@
 
 void recalc_sigpending(void)
 {
-	if (PENDING(&current->pending, &current->blocked) ||
-		    PENDING(&current->sig->shared_pending, &current->blocked))
-		set_thread_flag(TIF_SIGPENDING);
-	else
-		clear_thread_flag(TIF_SIGPENDING);
+	recalc_sigpending_tsk(current);
 }
 
 /* Given the mask, find the first available signal that should be serviced. */
@@ -280,20 +265,41 @@
  */
 void __exit_sighand(struct task_struct *tsk)
 {
-	struct signal_struct * sig = tsk->sig;
+	struct sighand_struct * sighand = tsk->sighand;
+
+	/* Ok, we're done with the signal handlers */
+	tsk->sighand = NULL;
+	if (atomic_dec_and_test(&sighand->count))
+		kmem_cache_free(sighand_cachep, sighand);
+}
+
+void exit_sighand(struct task_struct *tsk)
+{
+	write_lock_irq(&tasklist_lock);
+	__exit_sighand(tsk);
+	write_unlock_irq(&tasklist_lock);
+}
+
+/*
+ * This function expects the tasklist_lock write-locked.
+ */
+void __exit_signal(struct task_struct *tsk)
+{
+	struct signal_struct * sig = tsk->signal;
+	struct sighand_struct * sighand = tsk->sighand;
 
 	if (!sig)
 		BUG();
 	if (!atomic_read(&sig->count))
 		BUG();
-	spin_lock(&sig->siglock);
+	spin_lock(&sighand->siglock);
 	if (atomic_dec_and_test(&sig->count)) {
 		if (tsk == sig->curr_target)
 			sig->curr_target = next_thread(tsk);
-		tsk->sig = NULL;
-		spin_unlock(&sig->siglock);
+		tsk->signal = NULL;
+		spin_unlock(&sighand->siglock);
 		flush_sigqueue(&sig->shared_pending);
-		kmem_cache_free(sigact_cachep, sig);
+		kmem_cache_free(signal_cachep, sig);
 	} else {
 		/*
 		 * If there is any task waiting for the group exit
@@ -305,17 +311,17 @@
 		}
 		if (tsk == sig->curr_target)
 			sig->curr_target = next_thread(tsk);
-		tsk->sig = NULL;
-		spin_unlock(&sig->siglock);
+		tsk->signal = NULL;
+		spin_unlock(&sighand->siglock);
 	}
 	clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
 	flush_sigqueue(&tsk->pending);
 }
 
-void exit_sighand(struct task_struct *tsk)
+void exit_signal(struct task_struct *tsk)
 {
 	write_lock_irq(&tasklist_lock);
-	__exit_sighand(tsk);
+	__exit_signal(tsk);
 	write_unlock_irq(&tasklist_lock);
 }
 
@@ -327,7 +333,7 @@
 flush_signal_handlers(struct task_struct *t)
 {
 	int i;
-	struct k_sigaction *ka = &t->sig->action[0];
+	struct k_sigaction *ka = &t->sighand->action[0];
 	for (i = _NSIG ; i != 0 ; i--) {
 		if (ka->sa.sa_handler != SIG_IGN)
 			ka->sa.sa_handler = SIG_DFL;
@@ -337,23 +343,6 @@
 	}
 }
 
-/*
- * sig_exit - cause the current task to exit due to a signal.
- */
-
-void
-sig_exit(int sig, int exit_code, struct siginfo *info)
-{
-	sigaddset(&current->pending.signal, sig);
-	recalc_sigpending();
-	current->flags |= PF_SIGNALED;
-
-	if (current->sig->group_exit)
-		exit_code = current->sig->group_exit_code;
-
-	do_exit(exit_code);
-	/* NOTREACHED */
-}
 
 /* Notify the system that a driver wants to block all signals for this
  * process, and wants to be notified if any signals at all were to be
@@ -368,11 +357,11 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	current->notifier_mask = mask;
 	current->notifier_data = priv;
 	current->notifier = notifier;
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
 /* Notify the system that blocking has ended. */
@@ -382,11 +371,11 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	current->notifier = NULL;
 	current->notifier_data = NULL;
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
 static inline int collect_signal(int sig, struct sigpending *list, siginfo_t *info)
@@ -473,32 +462,78 @@
  */
 int dequeue_signal(sigset_t *mask, siginfo_t *info)
 {
+	int signr = __dequeue_signal(&current->pending, mask, info);
+	if (!signr)
+		signr = __dequeue_signal(&current->signal->shared_pending,
+					 mask, info);
+	return signr;
+}
+
+/*
+ * Tell a process that it has a new active signal..
+ *
+ * NOTE! we rely on the previous spin_lock to
+ * lock interrupts for us! We can only be called with
+ * "siglock" held, and the local interrupt must
+ * have been disabled when that got acquired!
+ *
+ * No need to set need_resched since signal event passing
+ * goes through ->blocked
+ */
+inline void signal_wake_up(struct task_struct *t, int resume)
+{
+	unsigned int mask;
+
+	set_tsk_thread_flag(t,TIF_SIGPENDING);
+
 	/*
-	 * Here we handle shared pending signals. To implement the full
-	 * semantics we need to unqueue and resend them. It will likely
-	 * get into our own pending queue.
+	 * If the task is running on a different CPU
+	 * force a reschedule on the other CPU to make
+	 * it notice the new signal quickly.
+	 *
+	 * The code below is a tad loose and might occasionally
+	 * kick the wrong CPU if we catch the process in the
+	 * process of changing - but no harm is done by that
+	 * other than doing an extra (lightweight) IPI interrupt.
+	 */
+	if (t->state == TASK_RUNNING)
+		kick_if_running(t);
+	/*
+	 * If resume is set, we want to wake it up in the TASK_STOPPED case.
+	 * We don't check for TASK_STOPPED because there is a race with it
+	 * executing another processor and just now entering stopped state.
+	 * By calling wake_up_process any time resume is set, we ensure
+	 * the process will wake up and handle its stop or death signal.
 	 */
-	if (current->sig->shared_pending.head) {
-		int signr = __dequeue_signal(&current->sig->shared_pending, mask, info);
-		if (signr)
-			__send_sig_info(signr, info, current);
+	mask = TASK_INTERRUPTIBLE;
+	if (resume)
+		mask |= TASK_STOPPED;
+	if (t->state & mask) {
+		wake_up_process(t);
+		return;
 	}
-	return __dequeue_signal(&current->pending, mask, info);
 }
 
-static int rm_from_queue(int sig, struct sigpending *s)
+/*
+ * 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)
 {
 	struct sigqueue *q, **pp;
 
-	if (!sigismember(&s->signal, sig))
+	if (!sigtestsetmask(&s->signal, mask))
 		return 0;
 
-	sigdelset(&s->signal, sig);
+	sigdelsetmask(&s->signal, mask);
 
 	pp = &s->head;
 
 	while ((q = *pp) != NULL) {
-		if (q->info.si_signo == sig) {
+		if (q->info.si_signo < SIGRTMIN &&
+		    (mask & sigmask (q->info.si_signo))) {
 			if ((*pp = q->next) == NULL)
 				s->tail = pp;
 			kmem_cache_free(sigqueue_cachep,q);
@@ -511,111 +546,101 @@
 }
 
 /*
- * Remove signal sig from t->pending.
- * Returns 1 if sig was found.
- *
- * All callers must be holding the siglock.
- */
-static int rm_sig_from_queue(int sig, struct task_struct *t)
-{
-	return rm_from_queue(sig, &t->pending);
-}
-
-/*
  * Bad permissions for sending the signal
  */
-static inline int bad_signal(int sig, struct siginfo *info, struct task_struct *t)
+static inline int check_kill_permission(int sig, struct siginfo *info,
+					struct task_struct *t)
 {
-	return (!info || ((unsigned long)info != 1 &&
+	int error = -EINVAL;
+	if (sig < 0 || sig > _NSIG)
+		return error;
+	error = -EPERM;
+	if ((!info || ((unsigned long)info != 1 &&
 			(unsigned long)info != 2 && SI_FROMUSER(info)))
 	    && ((sig != SIGCONT) || (current->session != t->session))
 	    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
-	    && !capable(CAP_KILL);
+	    && !capable(CAP_KILL))
+		return error;
+	return security_task_kill(t, info, sig);
 }
 
-/*
- * Signal type:
- *    < 0 : global action (kill - spread to all non-blocked threads)
- *    = 0 : ignored
- *    > 0 : wake up.
- */
-static int signal_type(int sig, struct signal_struct *signals)
-{
-	unsigned long handler;
-
-	if (!signals)
-		return 0;
-	
-	handler = (unsigned long) signals->action[sig-1].sa.sa_handler;
-	if (handler > 1)
-		return 1;
-
-	/* "Ignore" handler.. Illogical, but that has an implicit handler for SIGCHLD */
-	if (handler == 1)
-		return sig == SIGCHLD;
-
-	/* Default handler. Normally lethal, but.. */
-	switch (sig) {
-
-	/* Ignored */
-	case SIGCONT: case SIGWINCH:
-	case SIGCHLD: case SIGURG:
-		return 0;
-
-	/* Implicit behaviour */
-	case SIGTSTP: case SIGTTIN: case SIGTTOU:
-		return 1;
-
-	/* Implicit actions (kill or do special stuff) */
-	default:
-		return -1;
-	}
-}
-		
+/* forward decl */
+static void do_notify_parent_cldstop(struct task_struct *tsk,
+				     struct task_struct *parent);
 
 /*
- * Determine whether a signal should be posted or not.
- *
- * Signals with SIG_IGN can be ignored, except for the
- * special case of a SIGCHLD. 
- *
- * Some signals with SIG_DFL default to a non-action.
+ * Handle magic process-wide effects of stop/continue signals, and SIGKILL.
+ * Unlike the signal actions, these happen immediately at signal-generation
+ * time regardless of blocking, ignoring, or handling.  This does the
+ * actual continuing for SIGCONT, but not the actual stopping for stop
+ * signals.  The process stop is done as a signal action for SIG_DFL.
  */
-static int ignored_signal(int sig, struct task_struct *t)
+static void handle_stop_signal(int sig, struct task_struct *p)
 {
-	/* Don't ignore traced or blocked signals */
-	if ((t->ptrace & PT_PTRACED) || sigismember(&t->blocked, sig))
-		return 0;
-
-	return signal_type(sig, t->sig) == 0;
-}
+	struct task_struct *t;
 
-/*
- * Handle TASK_STOPPED cases etc implicit behaviour
- * of certain magical signals.
- *
- * SIGKILL gets spread out to every thread. 
- */
-static void handle_stop_signal(int sig, struct task_struct *t)
-{
-	switch (sig) {
-	case SIGKILL: case SIGCONT:
-		/* Wake up the process if stopped.  */
-		if (t->state == TASK_STOPPED)
-			wake_up_process(t);
-		t->exit_code = 0;
-		rm_sig_from_queue(SIGSTOP, t);
-		rm_sig_from_queue(SIGTSTP, t);
-		rm_sig_from_queue(SIGTTOU, t);
-		rm_sig_from_queue(SIGTTIN, t);
-		break;
+	if (sig_kernel_stop(sig)) {
+		/*
+		 * This is a stop signal.  Remove SIGCONT from all queues.
+		 */
+		rm_from_queue(sigmask(SIGCONT), &p->signal->shared_pending);
+		t = p;
+		do {
+			rm_from_queue(sigmask(SIGCONT), &t->pending);
+			t = next_thread(t);
+		} while (t != p);
+	} else if (sig == SIGCONT) {
+		/*
+		 * Remove all stop signals from all queues,
+		 * and wake all threads.
+		 */
+		if (unlikely(p->signal->group_stop_count > 0)) {
+			/*
+			 * There was a group stop in progress.  We'll
+			 * pretend it finished before we got here.  We are
+			 * obliged to report it to the parent: if the
+			 * SIGSTOP happened "after" this SIGCONT, then it
+			 * would have cleared this pending SIGCONT.  If it
+			 * happened "before" this SIGCONT, then the parent
+			 * got the SIGCHLD about the stop finishing before
+			 * the continue happened.  We do the notification
+			 * now, and it's as if the stop had finished and
+			 * the SIGCHLD was pending on entry to this kill.
+			 */
+			p->signal->group_stop_count = 0;
+			if (p->ptrace & PT_PTRACED)
+				do_notify_parent_cldstop(p, p->parent);
+			else
+				do_notify_parent_cldstop(
+					p->group_leader,
+					p->group_leader->real_parent);
+		}
+		rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
+		t = p;
+		do {
+			rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
+			
+			/*
+			 * If there is a handler for SIGCONT, we must make
+			 * sure that no thread returns to user mode before
+			 * we post the signal, in case it was the only
+			 * thread eligible to run the signal handler--then
+			 * it must not do anything between resuming and
+			 * running the handler.  With the TIF_SIGPENDING
+			 * flag set, the thread will pause and acquire the
+			 * siglock that we hold now and until we've queued
+			 * the pending signal. 
+			 *
+			 * Wake up the stopped thread _after_ setting
+			 * TIF_SIGPENDING
+			 */
+			if (!sigismember(&t->blocked, SIGCONT))
+				set_tsk_thread_flag(t, TIF_SIGPENDING);
+			wake_up_state(t, TASK_STOPPED);
 
-	case SIGSTOP: case SIGTSTP:
-	case SIGTTIN: case SIGTTOU:
-		/* If we're stopping again, cancel SIGCONT */
-		rm_sig_from_queue(SIGCONT, t);
-		break;
+			t = next_thread(t);
+		} while (t != p);
 	}
 }
 
@@ -647,23 +672,23 @@
 		*signals->tail = q;
 		signals->tail = &q->next;
 		switch ((unsigned long) info) {
-			case 0:
-				q->info.si_signo = sig;
-				q->info.si_errno = 0;
-				q->info.si_code = SI_USER;
-				q->info.si_pid = current->pid;
-				q->info.si_uid = current->uid;
-				break;
-			case 1:
-				q->info.si_signo = sig;
-				q->info.si_errno = 0;
-				q->info.si_code = SI_KERNEL;
-				q->info.si_pid = 0;
-				q->info.si_uid = 0;
-				break;
-			default:
-				copy_siginfo(&q->info, info);
-				break;
+		case 0:
+			q->info.si_signo = sig;
+			q->info.si_errno = 0;
+			q->info.si_code = SI_USER;
+			q->info.si_pid = current->pid;
+			q->info.si_uid = current->uid;
+			break;
+		case 1:
+			q->info.si_signo = sig;
+			q->info.si_errno = 0;
+			q->info.si_code = SI_KERNEL;
+			q->info.si_pid = 0;
+			q->info.si_uid = 0;
+			break;
+		default:
+			copy_siginfo(&q->info, info);
+			break;
 		}
 	} else if (sig >= SIGRTMIN && info && (unsigned long)info != 1
 		   && info->si_code != SI_USER)
@@ -678,103 +703,36 @@
 	return 0;
 }
 
-/*
- * Tell a process that it has a new active signal..
- *
- * NOTE! we rely on the previous spin_lock to
- * lock interrupts for us! We can only be called with
- * "siglock" held, and the local interrupt must
- * have been disabled when that got acquired!
- *
- * No need to set need_resched since signal event passing
- * goes through ->blocked
- */
-inline void signal_wake_up(struct task_struct *t)
-{
-	set_tsk_thread_flag(t,TIF_SIGPENDING);
-
-	/*
-	 * If the task is running on a different CPU 
-	 * force a reschedule on the other CPU to make
-	 * it notice the new signal quickly.
-	 *
-	 * The code below is a tad loose and might occasionally
-	 * kick the wrong CPU if we catch the process in the
-	 * process of changing - but no harm is done by that
-	 * other than doing an extra (lightweight) IPI interrupt.
-	 */
-	if (t->state == TASK_RUNNING)
-		kick_if_running(t);
-	if (t->state & TASK_INTERRUPTIBLE) {
-		wake_up_process(t);
-		return;
-	}
-}
-
-static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t)
-{
-	int retval = send_signal(sig, info, &t->pending);
-
-	if (!retval && !sigismember(&t->blocked, sig))
-		signal_wake_up(t);
+#define LEGACY_QUEUE(sigptr, sig) \
+	(((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
 
-	return retval;
-}
 
 static int
-specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t, int shared)
+specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
 {
 	int ret;
 
 	if (!irqs_disabled())
 		BUG();
 #if CONFIG_SMP
-	if (!spin_is_locked(&t->sig->siglock))
+	if (!spin_is_locked(&t->sighand->siglock))
 		BUG();
 #endif
-	ret = -EINVAL;
-	if (sig < 0 || sig > _NSIG)
-		goto out;
-	/* The somewhat baroque permissions check... */
-	ret = -EPERM;
-	if (bad_signal(sig, info, t))
-		goto out;
-	ret = security_task_kill(t, info, sig);
-	if (ret)
-		goto out;
 
-	/* The null signal is a permissions and process existence probe.
-	   No signal is actually delivered.  Same goes for zombies. */
-	ret = 0;
-	if (!sig || !t->sig)
-		goto out;
-
-	handle_stop_signal(sig, t);
-
-	/* Optimize away the signal, if it's a signal that can be
-	   handled immediately (ie non-blocked and untraced) and
-	   that is ignored (either explicitly or by default).  */
-
-	if (ignored_signal(sig, t))
-		goto out;
+	/* Short-circuit ignored signals.  */
+	if (sig_ignored(t, sig))
+		return 0;
 
-#define LEGACY_QUEUE(sigptr, sig) \
-	(((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
+	/* Support queueing exactly one non-rt signal, so that we
+	   can get more detailed information about the cause of
+	   the signal. */
+	if (LEGACY_QUEUE(&t->pending, sig))
+		return 0;
 
-	if (!shared) {
-		/* Support queueing exactly one non-rt signal, so that we
-		   can get more detailed information about the cause of
-		   the signal. */
-		if (LEGACY_QUEUE(&t->pending, sig))
-			goto out;
+	ret = send_signal(sig, info, &t->pending);
+	if (!ret && !sigismember(&t->blocked, sig))
+		signal_wake_up(t, sig == SIGKILL);
 
-		ret = deliver_signal(sig, info, t);
-	} else {
-		if (LEGACY_QUEUE(&t->sig->shared_pending, sig))
-			goto out;
-		ret = send_signal(sig, info, &t->sig->shared_pending);
-	}
-out:
 	return ret;
 }
 
@@ -789,192 +747,214 @@
 	unsigned long int flags;
 	int ret;
 
-	spin_lock_irqsave(&t->sig->siglock, flags);
-	if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
-		t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
+	spin_lock_irqsave(&t->sighand->siglock, flags);
+	if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
+		t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
 	sigdelset(&t->blocked, sig);
 	recalc_sigpending_tsk(t);
-	ret = __send_sig_info(sig, info, t);
-	spin_unlock_irqrestore(&t->sig->siglock, flags);
+	ret = specific_send_sig_info(sig, info, t);
+	spin_unlock_irqrestore(&t->sighand->siglock, flags);
 
 	return ret;
 }
 
-static int
-__specific_force_sig_info(int sig, struct task_struct *t)
-{
-	if (!t->sig)
-		return -ESRCH;
-
-	if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
-		t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
-	sigdelset(&t->blocked, sig);
-	recalc_sigpending_tsk(t);
-
-	return specific_send_sig_info(sig, (void *)2, t, 0);
-}
-
 void
 force_sig_specific(int sig, struct task_struct *t)
 {
 	unsigned long int flags;
 
-	spin_lock_irqsave(&t->sig->siglock, flags);
-	if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
-		t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
+	spin_lock_irqsave(&t->sighand->siglock, flags);
+	if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
+		t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
 	sigdelset(&t->blocked, sig);
 	recalc_sigpending_tsk(t);
-	specific_send_sig_info(sig, (void *)2, t, 0);
-	spin_unlock_irqrestore(&t->sig->siglock, flags);
+	specific_send_sig_info(sig, (void *)2, t);
+	spin_unlock_irqrestore(&t->sighand->siglock, flags);
 }
 
-#define can_take_signal(p, sig)	\
-	(((unsigned long) p->sig->action[sig-1].sa.sa_handler > 1) && \
-	!sigismember(&p->blocked, sig) && (task_curr(p) || !signal_pending(p)))
+/*
+ * Test if P wants to take SIG.  After we've checked all threads with this,
+ * it's equivalent to finding no threads not blocking SIG.  Any threads not
+ * blocking SIG were ruled out because they are not running and already
+ * have pending signals.  Such threads will dequeue from the shared queue
+ * as soon as they're available, so putting the signal on the shared queue
+ * will be equivalent to sending it to one such thread.
+ */
+#define wants_signal(sig, p, mask) 			\
+	(!sigismember(&(p)->blocked, sig)		\
+	 && !((p)->state & mask)			\
+	 && !((p)->flags & PF_EXITING)			\
+	 && (task_curr(p) || !signal_pending(p)))
 
-static inline
-int load_balance_thread_group(struct task_struct *p, int sig,
-				struct siginfo *info)
+static inline int
+__group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-	struct task_struct *tmp;
+	struct task_struct *t;
+	unsigned int mask;
 	int ret;
 
+#if CONFIG_SMP
+	if (!spin_is_locked(&p->sighand->siglock))
+		BUG();
+#endif
+	handle_stop_signal(sig, p);
+
+	/* Short-circuit ignored signals.  */
+	if (sig_ignored(p, sig))
+		return 0;
+
+	if (LEGACY_QUEUE(&p->signal->shared_pending, sig))
+		/* This is a non-RT signal and we already have one queued.  */
+		return 0;
+
 	/*
-	 * if the specified thread is not blocking this signal
-	 * then deliver it.
+	 * Don't bother zombies and stopped tasks (but
+	 * SIGKILL will punch through stopped state)
 	 */
-	if (can_take_signal(p, sig))
-		return specific_send_sig_info(sig, info, p, 0);
+	mask = TASK_DEAD | TASK_ZOMBIE;
+	if (sig != SIGKILL)
+		mask |= TASK_STOPPED;
 
 	/*
-	 * Otherwise try to find a suitable thread.
-	 * If no such thread is found then deliver to
-	 * the original thread.
+	 * Put this signal on the shared-pending queue, or fail with EAGAIN.
+	 * We always use the shared queue for process-wide signals,
+	 * to avoid several races.
 	 */
+	ret = send_signal(sig, info, &p->signal->shared_pending);
+	if (unlikely(ret))
+		return ret;
 
-	tmp = p->sig->curr_target;
-
-	if (!tmp || tmp->tgid != p->tgid)
-		/* restart balancing at this thread */
-		p->sig->curr_target = p;
-
-	else for (;;) {
-		if (thread_group_empty(p))
-			BUG();
-		if (!tmp || tmp->tgid != p->tgid)
-			BUG();
-
+	/*
+	 * Now find a thread we can wake up to take the signal off the queue.
+	 *
+	 * If the main thread wants the signal, it gets first crack.
+	 * Probably the least surprising to the average bear.
+	 */
+	if (wants_signal(sig, p, mask))
+		t = p;
+	else if (thread_group_empty(p))
 		/*
-		 * Do not send signals that are ignored or blocked,
-		 * or to not-running threads that are overworked:
+		 * There is just one thread and it does not need to be woken.
+		 * It will dequeue unblocked signals before it runs again.
 		 */
-		if (!can_take_signal(tmp, sig)) {
-			tmp = next_thread(tmp);
-			p->sig->curr_target = tmp;
-			if (tmp == p)
-				break;
-			continue;
+		return 0;
+	else {
+		/*
+		 * Otherwise try to find a suitable thread.
+		 */
+		t = p->signal->curr_target;
+		if (t == NULL)
+			/* restart balancing at this thread */
+			t = p->signal->curr_target = p;
+		BUG_ON(t->tgid != p->tgid);
+
+		while (!wants_signal(sig, t, mask)) {
+			t = next_thread(t);
+			if (t == p->signal->curr_target)
+				/*
+				 * No thread needs to be woken.
+				 * Any eligible threads will see
+				 * the signal in the queue soon.
+				 */
+				return 0;
 		}
-		ret = specific_send_sig_info(sig, info, tmp, 0);
-		return ret;
+		p->signal->curr_target = t;
 	}
+
 	/*
-	 * No suitable thread was found - put the signal
-	 * into the shared-pending queue.
+	 * Found a killable thread.  If the signal will be fatal,
+	 * then start taking the whole group down immediately.
 	 */
-	return specific_send_sig_info(sig, info, p, 1);
-}
-
-int __broadcast_thread_group(struct task_struct *p, int sig)
-{
-	struct task_struct *tmp;
-	struct list_head *l;
-	struct pid *pid;
-	int err = 0;
-
-	for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid)
-		err = __specific_force_sig_info(sig, tmp);
-
-	return err;
-}
+	if (sig_fatal(p, sig) && !p->signal->group_exit &&
+	    !sigismember(&t->real_blocked, sig) &&
+	    (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) {
+		/*
+		 * This signal will be fatal to the whole group.
+		 */
+		if (!sig_kernel_coredump(sig)) {
+			/*
+			 * Start a group exit and wake everybody up.
+			 * This way we don't have other threads
+			 * running and doing things after a slower
+			 * thread has the fatal signal pending.
+			 */
+			p->signal->group_exit = 1;
+			p->signal->group_exit_code = sig;
+			p->signal->group_stop_count = 0;
+			t = p;
+			do {
+				sigaddset(&t->pending.signal, SIGKILL);
+				signal_wake_up(t, 1);
+				t = next_thread(t);
+			} while (t != p);
+			return 0;
+		}
 
-struct task_struct * find_unblocked_thread(struct task_struct *p, int signr)
-{
-	struct task_struct *tmp;
-	struct list_head *l;
-	struct pid *pid;
+		/*
+		 * There will be a core dump.  We make all threads other
+		 * than the chosen one go into a group stop so that nothing
+		 * happens until it gets scheduled, takes the signal off
+		 * the shared queue, and does the core dump.  This is a
+		 * little more complicated than strictly necessary, but it
+		 * keeps the signal state that winds up in the core dump
+		 * unchanged from the death state, e.g. which thread had
+		 * the core-dump signal unblocked.
+		 */
+		rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
+		rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
+		p->signal->group_stop_count = 0;
+		p->signal->group_exit_task = t;
+		t = p;
+		do {
+			p->signal->group_stop_count++;
+			signal_wake_up(t, 0);
+			t = next_thread(t);
+		} while (t != p);
+		wake_up_process(p->signal->group_exit_task);
+		return 0;
+	}
 
-	for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid)
-		if (!sigismember(&tmp->blocked, signr))
-			return tmp;
-	return NULL;
+	/*
+	 * The signal is already in the shared-pending queue.
+	 * Tell the chosen thread to wake up and dequeue it.
+	 */
+	signal_wake_up(t, sig == SIGKILL);
+	return 0;
 }
 
-static int
-__send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+/*
+ * Nuke all other threads in the group.
+ */
+void zap_other_threads(struct task_struct *p)
 {
 	struct task_struct *t;
-	int ret = 0;
 
-#if CONFIG_SMP
-	if (!spin_is_locked(&p->sig->siglock))
-		BUG();
-#endif
-	/* not a thread group - normal signal behavior */
-	if (thread_group_empty(p) || !sig)
-		goto out_send;
-
-	if (sig_user_defined(p, sig)) {
-		if (sig_user_specific(sig))
-			goto out_send;
-		if (sig_user_load_balance(sig)) {
-			ret = load_balance_thread_group(p, sig, info);
-			goto out_unlock;
-		}
+	p->signal->group_stop_count = 0;
 
-		/* must not happen */
-		BUG();
-	}
-	/* optimize away ignored signals: */
-	if (sig_ignored(p, sig))
-		goto out_unlock;
+	if (thread_group_empty(p))
+		return;
 
-	if (sig_kernel_specific(sig) ||
-		       ((p->ptrace & PT_PTRACED) && !sig_kernel_only(sig)))
-		goto out_send;
-
-	/* Does any of the threads unblock the signal? */
-	t = find_unblocked_thread(p, sig);
-	if (!t) {
-		ret = specific_send_sig_info(sig, info, p, 1);
-		goto out_unlock;
-	}
-	if (sigismember(&t->real_blocked,sig)) {
-		ret = specific_send_sig_info(sig, info, t, 0);
-		goto out_unlock;
-	}
-	if (sig_kernel_broadcast(sig) || sig_kernel_coredump(sig)) {
-		ret = __broadcast_thread_group(p, sig);
-		goto out_unlock;
-	}
-
-	/* must not happen */
-	BUG();
-out_send:
-	ret = specific_send_sig_info(sig, info, p, 0);
-out_unlock:
-	return ret;
+	for (t = next_thread(p); t != p; t = next_thread(t)) {
+		sigaddset(&t->pending.signal, SIGKILL);
+		rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
+		signal_wake_up(t, 1);
+	}
 }
 
-int
-send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+/*
+ * Must be called with the tasklist_lock held for reading!
+ */
+int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&p->sig->siglock, flags);
-	ret = __send_sig_info(sig, info, p);
-	spin_unlock_irqrestore(&p->sig->siglock, flags);
+	ret = check_kill_permission(sig, info, p);
+	if (!ret && sig && p->sighand) {
+		spin_lock_irqsave(&p->sighand->siglock, flags);
+		ret = __group_send_sig_info(sig, info, p);
+		spin_unlock_irqrestore(&p->sighand->siglock, flags);
+	}
 
 	return ret;
 }
@@ -995,7 +975,7 @@
 		return -EINVAL;
 
 	for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
-		err = send_sig_info(sig, info, p);
+		err = group_send_sig_info(sig, info, p);
 		if (retval)
 			retval = err;
 	}
@@ -1037,7 +1017,7 @@
 	for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) {
 		if (!p->leader)
 			continue;
-		err = send_sig_info(sig, info, p);
+		err = group_send_sig_info(sig, info, p);
 		if (retval)
 			retval = err;
 	}
@@ -1056,7 +1036,7 @@
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
 	if (p)
-		error = send_sig_info(sig, info, p);
+		error = group_send_sig_info(sig, info, p);
 	read_unlock(&tasklist_lock);
 	return error;
 }
@@ -1079,8 +1059,8 @@
 
 		read_lock(&tasklist_lock);
 		for_each_process(p) {
-			if (p->pid > 1 && p != current) {
-				int err = send_sig_info(sig, info, p);
+			if (p->pid > 1 && p->tgid != current->tgid) {
+				int err = group_send_sig_info(sig, info, p);
 				++count;
 				if (err != -EPERM)
 					retval = err;
@@ -1100,6 +1080,24 @@
  */
 
 int
+send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+{
+	int ret;
+
+	/* XXX should nix these interfaces and update the kernel */
+	if (T(sig, SIG_KERNEL_BROADCAST_MASK)) {
+		read_lock(&tasklist_lock);
+		ret = group_send_sig_info(sig, info, p);
+		read_unlock(&tasklist_lock);
+	} else {
+		spin_lock_irq(&p->sighand->siglock);
+		ret = specific_send_sig_info(sig, info, p);
+		spin_unlock_irq(&p->sighand->siglock);
+	}
+	return ret;
+}
+
+int
 send_sig(int sig, struct task_struct *p, int priv)
 {
 	return send_sig_info(sig, (void*)(long)(priv != 0), p);
@@ -1133,9 +1131,10 @@
  * Joy. Or not. Pthread wants us to wake up every thread
  * in our parent group.
  */
-static inline void __wake_up_parent(struct task_struct *p)
+static inline void __wake_up_parent(struct task_struct *p,
+				    struct task_struct *parent)
 {
-	struct task_struct *parent = p->parent, *tsk = parent;
+	struct task_struct *tsk = parent;
 
 	/*
 	 * Fortunately this is not necessary for thread groups:
@@ -1148,7 +1147,7 @@
 	do {
 		wake_up_interruptible(&tsk->wait_chldexit);
 		tsk = next_thread(tsk);
-		if (tsk->sig != parent->sig)
+		if (tsk->signal != parent->signal)
 			BUG();
 	} while (tsk != parent);
 }
@@ -1162,6 +1161,7 @@
 	struct siginfo info;
 	unsigned long flags;
 	int why, status;
+	struct sighand_struct *psig;
 
 	if (sig == -1)
 		BUG();
@@ -1200,10 +1200,34 @@
 	info.si_code = why;
 	info.si_status = status;
 
-	spin_lock_irqsave(&tsk->parent->sig->siglock, flags);
-	__send_sig_info(sig, &info, tsk->parent);
-	__wake_up_parent(tsk);
-	spin_unlock_irqrestore(&tsk->parent->sig->siglock, flags);
+	psig = tsk->parent->sighand;
+	spin_lock_irqsave(&psig->siglock, flags);
+	if (sig == SIGCHLD && tsk->state != TASK_STOPPED &&
+	    (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
+	     (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
+		/*
+		 * We are exiting and our parent doesn't care.  POSIX.1
+		 * defines special semantics for setting SIGCHLD to SIG_IGN
+		 * or setting the SA_NOCLDWAIT flag: we should be reaped
+		 * automatically and not left for our parent's wait4 call.
+		 * Rather than having the parent do it as a magic kind of
+		 * signal handler, we just set this to tell do_exit that we
+		 * can be cleaned up without becoming a zombie.  Note that
+		 * we still call __wake_up_parent in this case, because a
+		 * blocked sys_wait4 might now return -ECHILD.
+		 *
+		 * Whether we send SIGCHLD or not for SA_NOCLDWAIT
+		 * is implementation-defined: we do (if you don't want
+		 * it, just use SIG_IGN instead).
+		 */
+		tsk->exit_signal = -1;
+		if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
+			sig = 0;
+	}
+	if (sig > 0 && sig <= _NSIG)
+		__group_send_sig_info(sig, &info, tsk->parent);
+	__wake_up_parent(tsk, tsk->parent);
+	spin_unlock_irqrestore(&psig->siglock, flags);
 }
 
 
@@ -1224,6 +1248,152 @@
 	}
 }
 
+static void
+do_notify_parent_cldstop(struct task_struct *tsk, struct task_struct *parent)
+{
+	struct siginfo info;
+	unsigned long flags;
+	struct sighand_struct *sighand;
+
+	info.si_signo = SIGCHLD;
+	info.si_errno = 0;
+	info.si_pid = tsk->pid;
+	info.si_uid = tsk->uid;
+
+	/* FIXME: find out whether or not this is supposed to be c*time. */
+	info.si_utime = tsk->utime;
+	info.si_stime = tsk->stime;
+
+	info.si_status = tsk->exit_code & 0x7f;
+	info.si_code = CLD_STOPPED;
+
+	sighand = parent->sighand;
+	spin_lock_irqsave(&sighand->siglock, flags);
+	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
+	    !(sighand->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+		__group_send_sig_info(SIGCHLD, &info, parent);
+	/*
+	 * Even if SIGCHLD is not generated, we must wake up wait4 calls.
+	 */
+	__wake_up_parent(tsk, parent);
+	spin_unlock_irqrestore(&sighand->siglock, flags);
+}
+
+static void
+finish_stop(int stop_count)
+{
+	/*
+	 * If there are no other threads in the group, or if there is
+	 * a group stop in progress and we are the last to stop,
+	 * report to the parent.  When ptraced, every thread reports itself.
+	 */
+	if (stop_count < 0 || (current->ptrace & PT_PTRACED)) {
+		read_lock(&tasklist_lock);
+		do_notify_parent_cldstop(current, current->parent);
+		read_unlock(&tasklist_lock);
+	}
+	else if (stop_count == 0) {
+		read_lock(&tasklist_lock);
+		do_notify_parent_cldstop(current->group_leader,
+					 current->group_leader->real_parent);
+		read_unlock(&tasklist_lock);
+	}
+
+	schedule();
+	/*
+	 * Now we don't run again until continued.
+	 */
+	current->exit_code = 0;
+}
+
+/*
+ * This performs the stopping for SIGSTOP and other stop signals.
+ * We have to stop all threads in the thread group.
+ */
+static void
+do_signal_stop(int signr)
+{
+	struct signal_struct *sig = current->signal;
+	struct sighand_struct *sighand = current->sighand;
+	int stop_count = -1;
+
+	if (sig->group_stop_count > 0) {
+		/*
+		 * There is a group stop in progress.  We don't need to
+		 * start another one.
+		 */
+		spin_lock_irq(&sighand->siglock);
+		if (unlikely(sig->group_stop_count == 0)) {
+			BUG_ON(!sig->group_exit);
+			spin_unlock_irq(&sighand->siglock);
+			return;
+		}
+		signr = sig->group_exit_code;
+		stop_count = --sig->group_stop_count;
+		current->exit_code = signr;
+		set_current_state(TASK_STOPPED);
+		spin_unlock_irq(&sighand->siglock);
+	}
+	else if (thread_group_empty(current)) {
+		/*
+		 * No locks needed in this case.
+		 */
+		current->exit_code = signr;
+		set_current_state(TASK_STOPPED);
+	}
+	else {
+		/*
+		 * There is no group stop already in progress.
+		 * We must initiate one now.
+		 */
+		struct task_struct *t;
+		read_lock(&tasklist_lock);
+		spin_lock_irq(&sighand->siglock);
+
+		if (unlikely(sig->group_exit)) {
+			/*
+			 * There is a group exit in progress now.
+			 * We'll just ignore the stop and process the
+			 * associated fatal signal.
+			 */
+			spin_unlock_irq(&sighand->siglock);
+			read_unlock(&tasklist_lock);
+			return;
+		}
+
+		if (sig->group_stop_count == 0) {
+			sig->group_exit_code = signr;
+			stop_count = 0;
+			for (t = next_thread(current); t != current;
+			     t = next_thread(t))
+				/*
+				 * Setting state to TASK_STOPPED for a group
+				 * stop is always done with the siglock held,
+				 * so this check has no races.
+				 */
+				if (t->state < TASK_STOPPED) {
+					stop_count++;
+					signal_wake_up(t, 0);
+				}
+			sig->group_stop_count = stop_count;
+		}
+		else {
+			/* A race with another thread while unlocked.  */
+			signr = sig->group_exit_code;
+			stop_count = --sig->group_stop_count;
+		}
+
+		current->exit_code = signr;
+		set_current_state(TASK_STOPPED);
+
+		spin_unlock_irq(&sighand->siglock);
+		read_unlock(&tasklist_lock);
+	}
+
+	finish_stop(stop_count);
+}
+
+
 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 
 int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
@@ -1234,31 +1404,65 @@
 		unsigned long signr = 0;
 		struct k_sigaction *ka;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
+		if (unlikely(current->signal->group_stop_count > 0)) {
+			int stop_count;
+			if (current->signal->group_exit_task == current) {
+				/*
+				 * Group stop is so we can do a core dump.
+				 */
+				current->signal->group_exit_task = NULL;
+				goto dequeue;
+			}
+			/*
+			 * There is a group stop in progress.  We stop
+			 * without any associated signal being in our queue.
+			 */
+			stop_count = --current->signal->group_stop_count;
+			signr = current->signal->group_exit_code;
+			current->exit_code = signr;
+			set_current_state(TASK_STOPPED);
+			spin_unlock_irq(&current->sighand->siglock);
+			finish_stop(stop_count);
+			continue;
+		}
+	dequeue:
 		signr = dequeue_signal(mask, info);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 		if (!signr)
 			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/*
+			 * If there is a group stop in progress,
+			 * we must participate in the bookkeeping.
+			 */
+			if (current->signal->group_stop_count > 0) {
+				spin_lock_irq(&current->sighand->siglock);
+				--current->signal->group_stop_count;
+				spin_unlock_irq(&current->sighand->siglock);
+			}
+
 			/* Let the debugger run.  */
 			current->exit_code = signr;
+			current->last_siginfo = info;
 			set_current_state(TASK_STOPPED);
 			notify_parent(current, SIGCHLD);
 			schedule();
 
+			current->last_siginfo = NULL;
+
 			/* We're back.  Did the debugger cancel the sig?  */
 			signr = current->exit_code;
 			if (signr == 0)
 				continue;
 			current->exit_code = 0;
 
-			/* The debugger continued.  Ignore SIGSTOP.  */
-			if (signr == SIGSTOP)
-				continue;
-
-			/* Update the siginfo structure.  Is this good?  */
+			/* Update the siginfo structure if the signal has
+			   changed.  If the debugger wanted something
+			   specific in the siginfo structure then it should
+			   have updated *info via PTRACE_SETSIGINFO.  */
 			if (signr != info->si_signo) {
 				info->si_signo = signr;
 				info->si_errno = 0;
@@ -1269,61 +1473,69 @@
 
 			/* If the (new) signal is now blocked, requeue it.  */
 			if (sigismember(&current->blocked, signr)) {
-				send_sig_info(signr, info, current);
+				spin_lock_irq(&current->sighand->siglock);
+				specific_send_sig_info(signr, info, current);
+				spin_unlock_irq(&current->sighand->siglock);
 				continue;
 			}
 		}
 
-		ka = &current->sig->action[signr-1];
-		if (ka->sa.sa_handler == SIG_IGN) {
-			if (signr != SIGCHLD)
-				continue;
-			/* Check for SIGCHLD: it's special.  */
-			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
-				/* nothing */;
+		ka = &current->sighand->action[signr-1];
+		if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
 			continue;
-		}
-
-		if (ka->sa.sa_handler == SIG_DFL) {
-			int exit_code = signr;
-
-			/* Init gets no signals it doesn't want.  */
-			if (current->pid == 1)
-				continue;
+		if (ka->sa.sa_handler != SIG_DFL) /* Run the handler.  */
+			return signr;
 
-			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
-				continue;
+		/*
+		 * Now we are doing the default action for this signal.
+		 */
+		if (sig_kernel_ignore(signr)) /* Default is nothing. */
+			continue;
 
-			case SIGTSTP: case SIGTTIN: case SIGTTOU:
-				if (is_orphaned_pgrp(current->pgrp))
-					continue;
-				/* FALLTHRU */
-
-			case SIGSTOP: {
-				struct signal_struct *sig;
-				set_current_state(TASK_STOPPED);
-				current->exit_code = signr;
-				sig = current->parent->sig;
-				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
-					notify_parent(current, SIGCHLD);
-				schedule();
-				continue;
-			}
+		/* Init gets no signals it doesn't want.  */
+		if (current->pid == 1)
+			continue;
 
-			case SIGQUIT: case SIGILL: case SIGTRAP:
-			case SIGABRT: case SIGFPE: case SIGSEGV:
-			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-				if (do_coredump(signr, exit_code, regs))
-					exit_code |= 0x80;
-				/* FALLTHRU */
+		if (sig_kernel_stop(signr)) {
+			/*
+			 * The default action is to stop all threads in
+			 * the thread group.  The job control signals
+			 * do nothing in an orphaned pgrp, but SIGSTOP
+			 * always works.
+			 */
+			if (signr == SIGSTOP ||
+			    !is_orphaned_pgrp(current->pgrp))
+				do_signal_stop(signr);
+			continue;
+		}
 
-			default:
-				sig_exit(signr, exit_code, info);
+		/*
+		 * Anything else is fatal, maybe with a core dump.
+		 */
+		current->flags |= PF_SIGNALED;
+		if (sig_kernel_coredump(signr) &&
+		    do_coredump(signr, signr, regs)) {
+			/*
+			 * That killed all other threads in the group and
+			 * synchronized with their demise, so there can't
+			 * be any more left to kill now.  The group_exit
+			 * flags are set by do_coredump.  Note that
+			 * thread_group_empty won't always be true yet,
+			 * because those threads were blocked in __exit_mm
+			 * and we just let them go to finish dying.
+			 */
+			const int code = signr | 0x80;
+			BUG_ON(!current->signal->group_exit);
+			BUG_ON(current->signal->group_exit_code != code);
+			do_exit(code);
 				/* NOTREACHED */
 			}
-		}
-		return signr;
+
+		/*
+		 * Death signals, no core dump.
+		 */
+		do_group_exit(signr);
+		/* NOTREACHED */
 	}
 	return 0;
 }
@@ -1344,6 +1556,7 @@
 EXPORT_SYMBOL(notify_parent);
 EXPORT_SYMBOL(send_sig);
 EXPORT_SYMBOL(send_sig_info);
+EXPORT_SYMBOL(sigprocmask);
 EXPORT_SYMBOL(block_all_signals);
 EXPORT_SYMBOL(unblock_all_signals);
 
@@ -1370,6 +1583,42 @@
  * used by various programs)
  */
 
+/*
+ * This is also useful for kernel threads that want to temporarily
+ * (or permanently) block certain signals.
+ *
+ * NOTE! Unlike the user-mode sys_sigprocmask(), the kernel
+ * interface happily blocks "unblockable" signals like SIGKILL
+ * and friends.
+ */
+int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
+{
+	int error;
+	sigset_t old_block;
+
+	spin_lock_irq(&current->sighand->siglock);
+	old_block = current->blocked;
+	error = 0;
+	switch (how) {
+	case SIG_BLOCK:
+		sigorsets(&current->blocked, &current->blocked, set);
+		break;
+	case SIG_UNBLOCK:
+		signandsets(&current->blocked, &current->blocked, set);
+		break;
+	case SIG_SETMASK:
+		current->blocked = *set;
+		break;
+	default:
+		error = -EINVAL;
+	}
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+	if (oldset)
+		*oldset = old_block;
+	return error;
+}
+
 asmlinkage long
 sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize)
 {
@@ -1386,35 +1635,15 @@
 			goto out;
 		sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
 
-		spin_lock_irq(&current->sig->siglock);
-		old_set = current->blocked;
-
-		error = 0;
-		switch (how) {
-		default:
-			error = -EINVAL;
-			break;
-		case SIG_BLOCK:
-			sigorsets(&new_set, &old_set, &new_set);
-			break;
-		case SIG_UNBLOCK:
-			signandsets(&new_set, &old_set, &new_set);
-			break;
-		case SIG_SETMASK:
-			break;
-		}
-
-		current->blocked = new_set;
-		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		error = sigprocmask(how, &new_set, &old_set);
 		if (error)
 			goto out;
 		if (oset)
 			goto set_old;
 	} else if (oset) {
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		old_set = current->blocked;
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 
 	set_old:
 		error = -EFAULT;
@@ -1434,13 +1663,18 @@
 	if (sigsetsize > sizeof(sigset_t))
 		goto out;
 
-	spin_lock_irq(&current->sig->siglock);
-	sigandsets(&pending, &current->blocked, &current->pending.signal);
-	spin_unlock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
+	sigorsets(&pending, &current->pending.signal,
+		  &current->signal->shared_pending.signal);
+	spin_unlock_irq(&current->sighand->siglock);
+
+	/* Outside the lock because only this thread touches it.  */
+	sigandsets(&pending, &current->blocked, &pending);
 
 	error = -EFAULT;
 	if (!copy_to_user(set, &pending, sigsetsize))
 		error = 0;
+
 out:
 	return error;
 }	
@@ -1546,7 +1780,7 @@
 			return -EINVAL;
 	}
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	sig = dequeue_signal(&these, &info);
 	if (!sig) {
 		timeout = MAX_SCHEDULE_TIMEOUT;
@@ -1561,19 +1795,19 @@
 			current->real_blocked = current->blocked;
 			sigandsets(&current->blocked, &current->blocked, &these);
 			recalc_sigpending();
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 
 			current->state = TASK_INTERRUPTIBLE;
 			timeout = schedule_timeout(timeout);
 
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			sig = dequeue_signal(&these, &info);
 			current->blocked = current->real_blocked;
 			siginitset(&current->real_blocked, 0);
 			recalc_sigpending();
 		}
 	}
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	if (sig) {
 		ret = sig;
@@ -1628,9 +1862,17 @@
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
 	if (p) {
-		spin_lock_irq(&p->sig->siglock);
-		error = specific_send_sig_info(sig, &info, p, 0);
-		spin_unlock_irq(&p->sig->siglock);
+		error = check_kill_permission(sig, &info, p);
+		/*
+		 * The null signal is a permissions and process existence
+		 * probe.  No signal is actually delivered.
+		 */
+		if (!error && sig && p->sighand) {
+			spin_lock_irq(&p->sighand->siglock);
+			handle_stop_signal(sig, p);
+			error = specific_send_sig_info(sig, &info, p);
+			spin_unlock_irq(&p->sighand->siglock);
+		}
 	}
 	read_unlock(&tasklist_lock);
 	return error;
@@ -1662,17 +1904,22 @@
 	if (sig < 1 || sig > _NSIG || (act && sig_kernel_only(sig)))
 		return -EINVAL;
 
-	k = &current->sig->action[sig-1];
+	k = &current->sighand->action[sig-1];
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
+	if (signal_pending(current)) {
+		/*
+		 * If there might be a fatal signal pending on multiple
+		 * threads, make sure we take it before changing the action.
+		 */
+		spin_unlock_irq(&current->sighand->siglock);
+		return -ERESTARTNOINTR;
+	}
 
 	if (oact)
 		*oact = *k;
 
 	if (act) {
-		*k = *act;
-		sigdelsetmask(&k->sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
-
 		/*
 		 * POSIX 3.3.1.3:
 		 *  "Setting a signal action to SIG_IGN for a signal that is
@@ -1683,25 +1930,40 @@
 		 *   pending and whose default action is to ignore the signal
 		 *   (for example, SIGCHLD), shall cause the pending signal to
 		 *   be discarded, whether or not it is blocked"
-		 *
-		 * Note the silly behaviour of SIGCHLD: SIG_IGN means that the
-		 * signal isn't actually ignored, but does automatic child
-		 * reaping, while SIG_DFL is explicitly said by POSIX to force
-		 * the signal to be ignored.
 		 */
-
-		if (k->sa.sa_handler == SIG_IGN
-		    || (k->sa.sa_handler == SIG_DFL
-			&& (sig == SIGCONT ||
-			    sig == SIGCHLD ||
-			    sig == SIGWINCH ||
-			    sig == SIGURG))) {
-			if (rm_sig_from_queue(sig, current))
-				recalc_sigpending();
+		if (act->sa.sa_handler == SIG_IGN ||
+		    (act->sa.sa_handler == SIG_DFL &&
+		     sig_kernel_ignore(sig))) {
+			/*
+			 * This is a fairly rare case, so we only take the
+			 * tasklist_lock once we're sure we'll need it.
+			 * Now we must do this little unlock and relock
+			 * dance to maintain the lock hierarchy.
+			 */
+			struct task_struct *t = current;
+			spin_unlock_irq(&t->sighand->siglock);
+			read_lock(&tasklist_lock);
+			spin_lock_irq(&t->sighand->siglock);
+			*k = *act;
+			sigdelsetmask(&k->sa.sa_mask,
+				      sigmask(SIGKILL) | sigmask(SIGSTOP));
+			rm_from_queue(sigmask(sig), &t->signal->shared_pending);
+			do {
+				rm_from_queue(sigmask(sig), &t->pending);
+				recalc_sigpending_tsk(t);
+				t = next_thread(t);
+			} while (t != current);
+			spin_unlock_irq(&current->sighand->siglock);
+			read_unlock(&tasklist_lock);
+			return 0;
 		}
+
+		*k = *act;
+		sigdelsetmask(&k->sa.sa_mask,
+			      sigmask(SIGKILL) | sigmask(SIGSTOP));
 	}
 
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 	return 0;
 }
 
@@ -1730,7 +1992,7 @@
 			goto out;
 
 		error = -EPERM;
-		if (on_sig_stack (sp))
+		if (on_sig_stack(sp))
 			goto out;
 
 		error = -EINVAL;
@@ -1788,9 +2050,9 @@
 		error = -EFAULT;
 		if (copy_from_user(&new_set, set, sizeof(*set)))
 			goto out;
-		new_set &= ~(sigmask(SIGKILL)|sigmask(SIGSTOP));
+		new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		old_set = current->blocked.sig[0];
 
 		error = 0;
@@ -1810,7 +2072,7 @@
 		}
 
 		recalc_sigpending();
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 		if (error)
 			goto out;
 		if (oset)
@@ -1872,13 +2134,13 @@
 {
 	int old;
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	old = current->blocked.sig[0];
 
 	siginitset(&current->blocked, newmask & ~(sigmask(SIGKILL)|
 						  sigmask(SIGSTOP)));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	return old;
 }
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Mon Feb 10 10:39:24 2003
+++ b/kernel/suspend.c	Mon Feb 10 10:39:24 2003
@@ -65,7 +65,6 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
-extern void signal_wake_up(struct task_struct *t);
 extern int sys_sync(void);
 
 unsigned char software_suspend_enabled = 0;
@@ -219,9 +218,9 @@
 			/* FIXME: smp problem here: we may not access other process' flags
 			   without locking */
 			p->flags |= PF_FREEZE;
-			spin_lock_irqsave(&p->sig->siglock, flags);
-			signal_wake_up(p);
-			spin_unlock_irqrestore(&p->sig->siglock, flags);
+			spin_lock_irqsave(&p->sighand->siglock, flags);
+			signal_wake_up(p, 0);
+			spin_unlock_irqrestore(&p->sighand->siglock, flags);
 			todo++;
 		} while_each_thread(g, p);
 		read_unlock(&tasklist_lock);
@@ -1085,12 +1084,12 @@
 	else if (!memcmp("S2",cur->swh.magic.magic,2))
 		memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
 	else {
+		if (noresume)
+			return -EINVAL;
 		panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
 			name_resume, cur->swh.magic.magic);
-		/* We want to panic even with noresume -- we certainly don't want to add
-		   out signature into your ext2 filesystem ;-) */
 	}
-	if(noresume) {
+	if (noresume) {
 		/* We don't do a sanity check here: we want to restore the swap
 		   whatever version of kernel made the suspend image;
 		   We need to write swap, but swap is *not* enabled so
@@ -1208,11 +1207,11 @@
 	/* We enable the possibility of machine suspend */
 	software_suspend_enabled = 1;
 #endif
-	if(!resume_status)
+	if (!resume_status)
 		return;
 
 	printk( "%s", name_resume );
-	if(resume_status == NORESUME) {
+	if (resume_status == NORESUME) {
 		if(resume_file[0])
 			read_suspend_image(resume_file, 1);
 		printk( "disabled\n" );
@@ -1241,7 +1240,7 @@
 
 static int __init resume_setup(char *str)
 {
-	if(resume_status)
+	if (resume_status == NORESUME)
 		return 1;
 
 	strncpy( resume_file, str, 255 );
@@ -1250,16 +1249,13 @@
 	return 1;
 }
 
-static int __init software_noresume(char *str)
+static int __init noresume_setup(char *str)
 {
-	if(!resume_status)
-		printk(KERN_WARNING "noresume option lacks a resume= option\n");
 	resume_status = NORESUME;
-	
 	return 1;
 }
 
-__setup("noresume", software_noresume);
+__setup("noresume", noresume_setup);
 __setup("resume=", resume_setup);
 
 EXPORT_SYMBOL(software_suspend);
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Mon Feb 10 10:39:23 2003
+++ b/kernel/sys.c	Mon Feb 10 10:39:23 2003
@@ -1021,16 +1021,7 @@
 		goto out;
 
 	current->leader = 1;
-	if (current->session != current->pid) {
-		detach_pid(current, PIDTYPE_SID);
-		current->session = current->pid;
-		attach_pid(current, PIDTYPE_SID, current->pid);
-	}
-	if (current->pgrp != current->pid) {
-		detach_pid(current, PIDTYPE_PGID);
-		current->pgrp = current->pid;
-		attach_pid(current, PIDTYPE_PGID, current->pid);
-	}
+	__set_special_pids(current->pid, current->pid);
 	current->tty = NULL;
 	current->tty_old_pgrp = 0;
 	err = current->pgrp;
@@ -1317,7 +1308,7 @@
 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
 			  unsigned long arg4, unsigned long arg5)
 {
-	int error = 0;
+	int error;
 	int sig;
 
 	error = security_task_prctl(option, arg2, arg3, arg4, arg5);
diff -Nru a/kernel/time.c b/kernel/time.c
--- a/kernel/time.c	Mon Feb 10 10:39:24 2003
+++ b/kernel/time.c	Mon Feb 10 10:39:24 2003
@@ -36,9 +36,6 @@
  */
 struct timezone sys_tz;
 
-/* The xtime_lock is not only serializing the xtime read/writes but it's also
-   serializing all accesses to the global NTP variables now. */
-extern rwlock_t xtime_lock;
 extern unsigned long last_time_offset;
 
 #if !defined(__alpha__) && !defined(__ia64__)
@@ -80,7 +77,7 @@
 		return -EPERM;
 	if (get_user(value, tptr))
 		return -EFAULT;
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime.tv_sec = value;
 	xtime.tv_nsec = 0;
 	last_time_offset = 0;
@@ -88,7 +85,7 @@
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 	return 0;
 }
 
@@ -96,13 +93,13 @@
 
 asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz)
 {
-	if (tv) {
+	if (likely(tv != NULL)) {
 		struct timeval ktv;
 		do_gettimeofday(&ktv);
 		if (copy_to_user(tv, &ktv, sizeof(ktv)))
 			return -EFAULT;
 	}
-	if (tz) {
+	if (unlikely(tz != NULL)) {
 		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
 			return -EFAULT;
 	}
@@ -127,10 +124,10 @@
  */
 inline static void warp_clock(void)
 {
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	xtime.tv_sec += sys_tz.tz_minuteswest * 60;
 	last_time_offset = 0;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 }
 
 /*
@@ -235,7 +232,7 @@
 		    txc->tick > 1100000/USER_HZ)
 			return -EINVAL;
 
-	write_lock_irq(&xtime_lock);
+	write_seqlock_irq(&xtime_lock);
 	result = time_state;	/* mostly `TIME_OK' */
 
 	/* Save for later - semantics of adjtime is to return old value */
@@ -386,7 +383,7 @@
 	txc->errcnt	   = pps_errcnt;
 	txc->stbcnt	   = pps_stbcnt;
 	last_time_offset = 0;
-	write_unlock_irq(&xtime_lock);
+	write_sequnlock_irq(&xtime_lock);
 	do_gettimeofday(&txc->time);
 	return(result);
 }
@@ -409,9 +406,13 @@
 struct timespec current_kernel_time(void)
 {
         struct timespec now;
-        unsigned long flags;
-        read_lock_irqsave(&xtime_lock,flags);
-	now = xtime;
-        read_unlock_irqrestore(&xtime_lock,flags);
+        unsigned long seq;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		
+		now = xtime;
+	} while (read_seqretry(&xtime_lock, seq));
+
 	return now; 
 }
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Mon Feb 10 10:39:24 2003
+++ b/kernel/timer.c	Mon Feb 10 10:39:24 2003
@@ -26,8 +26,11 @@
 #include <linux/mm.h>
 #include <linux/notifier.h>
 #include <linux/thread_info.h>
+#include <linux/time.h>
+#include <linux/jiffies.h>
 
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 
 /*
  * per-CPU timer vector definitions:
@@ -758,7 +761,7 @@
  * This read-write spinlock protects us from races in SMP while
  * playing with xtime and avenrun.
  */
-rwlock_t xtime_lock __cacheline_aligned_in_smp = RW_LOCK_UNLOCKED;
+seqlock_t xtime_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED;
 unsigned long last_time_offset;
 
 /*
@@ -799,7 +802,7 @@
   
 /*
  * The 64-bit jiffies value is not atomic - you MUST NOT read it
- * without holding read_lock_irq(&xtime_lock).
+ * without sampling the sequence number in xtime_lock.
  * jiffies is defined in the linker script...
  */
 
@@ -1085,20 +1088,26 @@
 asmlinkage long sys_sysinfo(struct sysinfo *info)
 {
 	struct sysinfo val;
+	u64 uptime;
 	unsigned long mem_total, sav_total;
 	unsigned int mem_unit, bitcount;
+	unsigned long seq;
 
 	memset((char *)&val, 0, sizeof(struct sysinfo));
 
-	read_lock_irq(&xtime_lock);
-	val.uptime = jiffies / HZ;
+	do {
+		seq = read_seqbegin(&xtime_lock);
 
-	val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
-	val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
-	val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
+		uptime = jiffies_64;
+		do_div(uptime, HZ);
+		val.uptime = (unsigned long) uptime;
+
+		val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
+		val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
+		val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
 
-	val.procs = nr_threads;
-	read_unlock_irq(&xtime_lock);
+		val.procs = nr_threads;
+	} while (read_seqretry(&xtime_lock, seq));
 
 	si_meminfo(&val);
 	si_swapinfo(&val);
@@ -1143,7 +1152,7 @@
 	val.totalhigh <<= bitcount;
 	val.freehigh <<= bitcount;
 
-out:
+ out:
 	if (copy_to_user(info, &val, sizeof(struct sysinfo)))
 		return -EFAULT;
 
diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c
--- a/kernel/workqueue.c	Mon Feb 10 10:39:33 2003
+++ b/kernel/workqueue.c	Mon Feb 10 10:39:33 2003
@@ -177,12 +177,13 @@
 	current->flags |= PF_IOTHREAD;
 	cwq->thread = current;
 
+	set_user_nice(current, -10);
 	set_cpus_allowed(current, 1UL << cpu);
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked, sigmask(SIGCHLD));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	complete(&startup->done);
 
@@ -212,10 +213,10 @@
 				/* SIGCHLD - auto-reaping */ ;
 
 			/* zap all other signals */
-			spin_lock_irq(&current->sig->siglock);
+			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
 			recalc_sigpending();
-			spin_unlock_irq(&current->sig->siglock);
+			spin_unlock_irq(&current->sighand->siglock);
 		}
 	}
 	remove_wait_queue(&cwq->more_work, &wait);
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile	Mon Feb 10 10:39:23 2003
+++ b/lib/Makefile	Mon Feb 10 10:39:23 2003
@@ -8,9 +8,6 @@
 
 L_TARGET := lib.a
 
-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
-	       crc32.o rbtree.o radix-tree.o kobject.o
-
 obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \
 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
 	 kobject.o
diff -Nru a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile
--- a/lib/zlib_deflate/Makefile	Mon Feb 10 10:39:29 2003
+++ b/lib/zlib_deflate/Makefile	Mon Feb 10 10:39:29 2003
@@ -6,8 +6,6 @@
 # decompression code.
 #
 
-export-objs := deflate_syms.o
-
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o
 
 zlib_deflate-objs := deflate.o deftree.o deflate_syms.o
diff -Nru a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
--- a/lib/zlib_inflate/Makefile	Mon Feb 10 10:39:31 2003
+++ b/lib/zlib_inflate/Makefile	Mon Feb 10 10:39:31 2003
@@ -13,8 +13,6 @@
 # uncompression can be done without blocking on allocation).
 #
 
-export-objs := inflate_syms.o
-
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
 
 zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \
diff -Nru a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile	Mon Feb 10 10:39:29 2003
+++ b/mm/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,14 +2,12 @@
 # Makefile for the linux memory manager.
 #
 
-export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o
-
 mmu-y			:= nommu.o
 mmu-$(CONFIG_MMU)	:= fremap.o highmem.o madvise.o memory.o mincore.o \
 			   mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
 			   shmem.o vmalloc.o
 
-obj-y			:= bootmem.o filemap.o mempool.o oom_kill.o \
+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 vcache.o vmscan.o $(mmu-y)
 
diff -Nru a/mm/fadvise.c b/mm/fadvise.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/mm/fadvise.c	Mon Feb 10 10:39:33 2003
@@ -0,0 +1,72 @@
+/*
+ * mm/fadvise.c
+ *
+ * Copyright (C) 2002, Linus Torvalds
+ *
+ * 11Jan2003	akpm@digeo.com
+ *		Initial version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/backing-dev.h>
+#include <linux/pagevec.h>
+#include <linux/fadvise.h>
+
+/*
+ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
+ * deactivate the pages and clear PG_Referenced.
+ */
+int sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
+{
+	struct file *file = fget(fd);
+	struct inode *inode;
+	struct address_space *mapping;
+	struct backing_dev_info *bdi;
+	int ret = 0;
+
+	if (!file)
+		return -EBADF;
+
+	inode = file->f_dentry->d_inode;
+	mapping = inode->i_mapping;
+	if (!mapping)
+		return -EINVAL;
+
+	bdi = mapping->backing_dev_info;
+
+	switch (advice) {
+	case POSIX_FADV_NORMAL:
+		file->f_ra.ra_pages = bdi->ra_pages;
+		break;
+	case POSIX_FADV_RANDOM:
+		file->f_ra.ra_pages = 0;
+		break;
+	case POSIX_FADV_SEQUENTIAL:
+		file->f_ra.ra_pages = bdi->ra_pages * 2;
+		break;
+	case POSIX_FADV_WILLNEED:
+	case POSIX_FADV_NOREUSE:
+		if (!mapping->a_ops->readpage) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = do_page_cache_readahead(mapping, file,
+				offset >> PAGE_CACHE_SHIFT,
+				max_sane_readahead(len >> PAGE_CACHE_SHIFT));
+		if (ret > 0)
+			ret = 0;
+		break;
+	case POSIX_FADV_DONTNEED:
+		invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT,
+				(len >> PAGE_CACHE_SHIFT) + 1);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	fput(file);
+	return ret;
+}
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Mon Feb 10 10:39:24 2003
+++ b/mm/filemap.c	Mon Feb 10 10:39:24 2003
@@ -259,9 +259,10 @@
 
 	do {
 		prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
-		sync_page(page);
-		if (test_bit(bit_nr, &page->flags))
+		if (test_bit(bit_nr, &page->flags)) {
+			sync_page(page);
 			io_schedule();
+		}
 	} while (test_bit(bit_nr, &page->flags));
 	finish_wait(waitqueue, &wait);
 }
@@ -326,9 +327,10 @@
 
 	while (TestSetPageLocked(page)) {
 		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-		sync_page(page);
-		if (PageLocked(page))
+		if (PageLocked(page)) {
+			sync_page(page);
 			io_schedule();
+		}
 	}
 	finish_wait(wqh, &wait);
 }
@@ -1306,11 +1308,13 @@
 	return 0;
 }
 
+/*
+ * This is for filesystems which do not implement ->writepage.
+ */
 int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE))
+	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
 		return -EINVAL;
-	vma->vm_flags &= ~VM_MAYWRITE;
 	return generic_file_mmap(file, vma);
 }
 #else
@@ -1553,7 +1557,7 @@
 	struct page	*page;
 	struct page	*cached_page = NULL;
 	ssize_t		written;
-	int		err;
+	ssize_t		err;
 	size_t		bytes;
 	struct pagevec	lru_pvec;
 	const struct iovec *cur_iov = iov; /* current iovec */
@@ -1813,7 +1817,7 @@
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
-	int err;
+	ssize_t err;
 	struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
 
 	BUG_ON(iocb->ki_pos != pos);
@@ -1832,7 +1836,7 @@
 			   size_t count, loff_t *ppos)
 {
 	struct inode	*inode = file->f_dentry->d_inode->i_mapping->host;
-	int		err;
+	ssize_t		err;
 	struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
 
 	down(&inode->i_sem);
diff -Nru a/mm/fremap.c b/mm/fremap.c
--- a/mm/fremap.c	Mon Feb 10 10:39:23 2003
+++ b/mm/fremap.c	Mon Feb 10 10:39:23 2003
@@ -53,8 +53,11 @@
 	pte_t *pte, entry;
 	pgd_t *pgd;
 	pmd_t *pmd;
-	struct pte_chain *pte_chain = NULL;
+	struct pte_chain *pte_chain;
 
+	pte_chain = pte_chain_alloc(GFP_KERNEL);
+	if (!pte_chain)
+		goto err;
 	pgd = pgd_offset(mm, addr);
 	spin_lock(&mm->page_table_lock);
 
@@ -62,7 +65,6 @@
 	if (!pmd)
 		goto err_unlock;
 
-	pte_chain = pte_chain_alloc(GFP_KERNEL);
 	pte = pte_alloc_map(mm, pmd, addr);
 	if (!pte)
 		goto err_unlock;
@@ -87,6 +89,7 @@
 err_unlock:
 	spin_unlock(&mm->page_table_lock);
 	pte_chain_free(pte_chain);
+err:
 	return err;
 }
 
diff -Nru a/mm/highmem.c b/mm/highmem.c
--- a/mm/highmem.c	Mon Feb 10 10:39:29 2003
+++ b/mm/highmem.c	Mon Feb 10 10:39:29 2003
@@ -366,7 +366,7 @@
 	return 0;
 }
 
-void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, int bio_gfp,
+static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig,
 			mempool_t *pool)
 {
 	struct page *page;
@@ -387,7 +387,7 @@
 		 * irk, bounce it
 		 */
 		if (!bio)
-			bio = bio_alloc(bio_gfp, (*bio_orig)->bi_vcnt);
+			bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt);
 
 		to = bio->bi_io_vec + i;
 
@@ -447,10 +447,9 @@
 	*bio_orig = bio;
 }
 
-inline void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig)
+void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig)
 {
 	mempool_t *pool;
-	int bio_gfp;
 
 	/*
 	 * for non-isa bounce case, just check if the bounce pfn is equal
@@ -460,20 +459,16 @@
 	if (!(q->bounce_gfp & GFP_DMA)) {
 		if (q->bounce_pfn >= blk_max_pfn)
 			return;
-
-		bio_gfp = GFP_NOHIGHIO;
 		pool = page_pool;
 	} else {
 		BUG_ON(!isa_page_pool);
-
-		bio_gfp = GFP_NOIO;
 		pool = isa_page_pool;
 	}
 
 	/*
 	 * slow path
 	 */
-	__blk_queue_bounce(q, bio_orig, bio_gfp, pool);
+	__blk_queue_bounce(q, bio_orig, pool);
 }
 
 #if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_HIGHMEM)
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Mon Feb 10 10:39:26 2003
+++ b/mm/memory.c	Mon Feb 10 10:39:26 2003
@@ -607,13 +607,22 @@
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 	unsigned long pfn;
+	struct vm_area_struct *vma;
+
+	vma = hugepage_vma(mm, address);
+	if (vma)
+		return follow_huge_addr(mm, vma, address, write);
 
 	pgd = pgd_offset(mm, address);
 	if (pgd_none(*pgd) || pgd_bad(*pgd))
 		goto out;
 
 	pmd = pmd_offset(pgd, address);
-	if (pmd_none(*pmd) || pmd_bad(*pmd))
+	if (pmd_none(*pmd))
+		goto out;
+	if (pmd_huge(*pmd))
+		return follow_huge_pmd(mm, address, pmd, write);
+	if (pmd_bad(*pmd))
 		goto out;
 
 	ptep = pte_offset_map(pmd, address);
@@ -926,9 +935,19 @@
 	struct page *old_page, *new_page;
 	unsigned long pfn = pte_pfn(pte);
 	struct pte_chain *pte_chain = NULL;
+	int ret;
 
-	if (!pfn_valid(pfn))
-		goto bad_wp_page;
+	if (unlikely(!pfn_valid(pfn))) {
+		/*
+		 * This should really halt the system so it can be debugged or
+		 * at least the kernel stops what it's doing before it corrupts
+		 * data, but for the moment just pretend this is OOM.
+		 */
+		pte_unmap(page_table);
+		printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
+				address);
+		goto oom;
+	}
 	old_page = pfn_to_page(pfn);
 
 	if (!TestSetPageLocked(old_page)) {
@@ -936,10 +955,11 @@
 		unlock_page(old_page);
 		if (reuse) {
 			flush_cache_page(vma, address);
-			establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
+			establish_pte(vma, address, page_table,
+				pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
 			pte_unmap(page_table);
-			spin_unlock(&mm->page_table_lock);
-			return VM_FAULT_MINOR;
+			ret = VM_FAULT_MINOR;
+			goto out;
 		}
 	}
 	pte_unmap(page_table);
@@ -950,11 +970,13 @@
 	page_cache_get(old_page);
 	spin_unlock(&mm->page_table_lock);
 
+	pte_chain = pte_chain_alloc(GFP_KERNEL);
+	if (!pte_chain)
+		goto no_mem;
 	new_page = alloc_page(GFP_HIGHUSER);
 	if (!new_page)
 		goto no_mem;
 	copy_cow_page(old_page,new_page,address);
-	pte_chain = pte_chain_alloc(GFP_KERNEL);
 
 	/*
 	 * Re-check the pte - we dropped the lock
@@ -973,25 +995,19 @@
 		new_page = old_page;
 	}
 	pte_unmap(page_table);
-	spin_unlock(&mm->page_table_lock);
 	page_cache_release(new_page);
 	page_cache_release(old_page);
-	pte_chain_free(pte_chain);
-	return VM_FAULT_MINOR;
+	ret = VM_FAULT_MINOR;
+	goto out;
 
-bad_wp_page:
-	pte_unmap(page_table);
-	spin_unlock(&mm->page_table_lock);
-	printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n", address);
-	/*
-	 * This should really halt the system so it can be debugged or
-	 * at least the kernel stops what it's doing before it corrupts
-	 * data, but for the moment just pretend this is OOM.
-	 */
-	return VM_FAULT_OOM;
 no_mem:
 	page_cache_release(old_page);
-	return VM_FAULT_OOM;
+oom:
+	ret = VM_FAULT_OOM;
+out:
+	spin_unlock(&mm->page_table_lock);
+	pte_chain_free(pte_chain);
+	return ret;
 }
 
 static void vmtruncate_list(struct list_head *head, unsigned long pgoff)
@@ -1286,6 +1302,7 @@
 	struct page * new_page;
 	pte_t entry;
 	struct pte_chain *pte_chain;
+	int ret;
 
 	if (!vma->vm_ops || !vma->vm_ops->nopage)
 		return do_anonymous_page(mm, vma, page_table,
@@ -1301,6 +1318,10 @@
 	if (new_page == NOPAGE_OOM)
 		return VM_FAULT_OOM;
 
+	pte_chain = pte_chain_alloc(GFP_KERNEL);
+	if (!pte_chain)
+		goto oom;
+
 	/*
 	 * Should we do an early C-O-W break?
 	 */
@@ -1308,7 +1329,7 @@
 		struct page * page = alloc_page(GFP_HIGHUSER);
 		if (!page) {
 			page_cache_release(new_page);
-			return VM_FAULT_OOM;
+			goto oom;
 		}
 		copy_user_highpage(page, new_page, address);
 		page_cache_release(new_page);
@@ -1316,7 +1337,6 @@
 		new_page = page;
 	}
 
-	pte_chain = pte_chain_alloc(GFP_KERNEL);
 	spin_lock(&mm->page_table_lock);
 	page_table = pte_offset_map(pmd, address);
 
@@ -1346,15 +1366,20 @@
 		pte_unmap(page_table);
 		page_cache_release(new_page);
 		spin_unlock(&mm->page_table_lock);
-		pte_chain_free(pte_chain);
-		return VM_FAULT_MINOR;
+		ret = VM_FAULT_MINOR;
+		goto out;
 	}
 
 	/* no need to invalidate: a not-present page shouldn't be cached */
 	update_mmu_cache(vma, address, entry);
 	spin_unlock(&mm->page_table_lock);
+	ret = VM_FAULT_MAJOR;
+	goto out;
+oom:
+	ret = VM_FAULT_OOM;
+out:
 	pte_chain_free(pte_chain);
-	return VM_FAULT_MAJOR;
+	return ret;
 }
 
 /*
@@ -1422,6 +1447,10 @@
 	pgd = pgd_offset(mm, address);
 
 	inc_page_state(pgfault);
+
+	if (is_vm_hugetlb_page(vma))
+		return VM_FAULT_SIGBUS;	/* mapping truncation does this. */
+
 	/*
 	 * We need the page table lock to synchronize with kswapd
 	 * and the SMP-safe atomic PTE updates.
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Mon Feb 10 10:39:29 2003
+++ b/mm/mmap.c	Mon Feb 10 10:39:29 2003
@@ -124,6 +124,19 @@
 }
 
 /*
+ * Requires inode->i_mapping->i_shared_sem
+ */
+static inline void
+__remove_shared_vm_struct(struct vm_area_struct *vma, struct inode *inode)
+{
+	if (inode) {
+		if (vma->vm_flags & VM_DENYWRITE)
+			atomic_inc(&inode->i_writecount);
+		list_del_init(&vma->shared);
+	}
+}
+
+/*
  * Remove one vm structure from the inode's i_mapping address space.
  */
 static void remove_shared_vm_struct(struct vm_area_struct *vma)
@@ -134,9 +147,7 @@
 		struct inode *inode = file->f_dentry->d_inode;
 
 		down(&inode->i_mapping->i_shared_sem);
-		if (vma->vm_flags & VM_DENYWRITE)
-			atomic_inc(&inode->i_writecount);
-		list_del_init(&vma->shared);
+		__remove_shared_vm_struct(vma, inode);
 		up(&inode->i_mapping->i_shared_sem);
 	}
 }
@@ -194,7 +205,8 @@
  * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits
  * into "VM_xxx".
  */
-static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags)
+static inline unsigned long
+calc_vm_flags(unsigned long prot, unsigned long flags)
 {
 #define _trans(x,bit1,bit2) \
 ((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
@@ -243,10 +255,10 @@
 #define validate_mm(mm) do { } while (0)
 #endif
 
-static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr,
-						struct vm_area_struct ** pprev,
-						struct rb_node *** rb_link,
-						struct rb_node ** rb_parent)
+static struct vm_area_struct *
+find_vma_prepare(struct mm_struct *mm, unsigned long addr,
+		struct vm_area_struct **pprev, struct rb_node ***rb_link,
+		struct rb_node ** rb_parent)
 {
 	struct vm_area_struct * vma;
 	struct rb_node ** __rb_link, * __rb_parent, * rb_prev;
@@ -280,8 +292,9 @@
 	return vma;
 }
 
-static inline void __vma_link_list(struct mm_struct * mm, struct vm_area_struct * vma,
-				   struct vm_area_struct * prev, struct rb_node * rb_parent)
+static inline void
+__vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma,
+		struct vm_area_struct *prev, struct rb_node *rb_parent)
 {
 	if (prev) {
 		vma->vm_next = prev->vm_next;
@@ -289,20 +302,21 @@
 	} else {
 		mm->mmap = vma;
 		if (rb_parent)
-			vma->vm_next = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
+			vma->vm_next = rb_entry(rb_parent,
+					struct vm_area_struct, vm_rb);
 		else
 			vma->vm_next = NULL;
 	}
 }
 
-static void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma,
-				 struct rb_node ** rb_link, struct rb_node * rb_parent)
+static void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
+			struct rb_node **rb_link, struct rb_node *rb_parent)
 {
 	rb_link_node(&vma->vm_rb, rb_parent, rb_link);
 	rb_insert_color(&vma->vm_rb, &mm->mm_rb);
 }
 
-static inline void __vma_link_file(struct vm_area_struct * vma)
+static inline void __vma_link_file(struct vm_area_struct *vma)
 {
 	struct file * file;
 
@@ -321,8 +335,10 @@
 	}
 }
 
-static void __vma_link(struct mm_struct * mm, struct vm_area_struct * vma,  struct vm_area_struct * prev,
-		       struct rb_node ** rb_link, struct rb_node * rb_parent)
+static void
+__vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
+	struct vm_area_struct *prev, struct rb_node **rb_link,
+	struct rb_node *rb_parent)
 {
 	__vma_link_list(mm, vma, prev, rb_parent);
 	__vma_link_rb(mm, vma, rb_link, rb_parent);
@@ -346,46 +362,124 @@
 	if (mapping)
 		up(&mapping->i_shared_sem);
 
+	mark_mm_hugetlb(mm, vma);
 	mm->map_count++;
 	validate_mm(mm);
 }
 
-static int vma_merge(struct mm_struct * mm, struct vm_area_struct * prev,
-		     struct rb_node * rb_parent, unsigned long addr, 
-		     unsigned long end, unsigned long vm_flags)
+/*
+ * Return true if we can merge this (vm_flags,file,vm_pgoff,size)
+ * in front of (at a lower virtual address and file offset than) the vma.
+ *
+ * We don't check here for the merged mmap wrapping around the end of pagecache
+ * indices (16TB on ia32) because do_mmap_pgoff() does not permit mmap's which
+ * wrap, nor mmaps which cover the final page at index -1UL.
+ */
+static int
+can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
+	struct file *file, unsigned long vm_pgoff, unsigned long size)
+{
+	if (vma->vm_file == file && vma->vm_flags == vm_flags) {
+		if (!file)
+			return 1;	/* anon mapping */
+		if (vma->vm_pgoff == vm_pgoff + size)
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * Return true if we can merge this (vm_flags,file,vm_pgoff)
+ * beyond (at a higher virtual address and file offset than) the vma.
+ */
+static int
+can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
+	struct file *file, unsigned long vm_pgoff)
+{
+	if (vma->vm_file == file && vma->vm_flags == vm_flags) {
+		unsigned long vma_size;
+
+		if (!file)
+			return 1;	/* anon mapping */
+
+		vma_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+		if (vma->vm_pgoff + vma_size == vm_pgoff)
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * Given a new mapping request (addr,end,vm_flags,file,pgoff), figure out
+ * whether that can be merged with its predecessor or its successor.  Or
+ * both (it neatly fills a hole).
+ */
+static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev,
+			struct rb_node *rb_parent, unsigned long addr, 
+			unsigned long end, unsigned long vm_flags,
+			struct file *file, unsigned long pgoff)
 {
 	spinlock_t * lock = &mm->page_table_lock;
+
 	if (!prev) {
 		prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
 		goto merge_next;
 	}
-	if (prev->vm_end == addr && can_vma_merge(prev, vm_flags)) {
-		struct vm_area_struct * next;
 
+	/*
+	 * Can it merge with the predecessor?
+	 */
+	if (prev->vm_end == addr &&
+			can_vma_merge_after(prev, vm_flags, file, pgoff)) {
+		struct vm_area_struct *next;
+		struct inode *inode = file ? file->f_dentry->d_inode : NULL;
+		int need_up = 0;
+
+		if (unlikely(file && prev->vm_next &&
+				prev->vm_next->vm_file == file)) {
+			down(&inode->i_mapping->i_shared_sem);
+			need_up = 1;
+		}
 		spin_lock(lock);
 		prev->vm_end = end;
+
+		/*
+		 * OK, it did.  Can we now merge in the successor as well?
+		 */
 		next = prev->vm_next;
-		if (next && prev->vm_end == next->vm_start && can_vma_merge(next, vm_flags)) {
+		if (next && prev->vm_end == next->vm_start &&
+				can_vma_merge_before(next, vm_flags, file,
+					pgoff, (end - addr) >> PAGE_SHIFT)) {
 			prev->vm_end = next->vm_end;
 			__vma_unlink(mm, next, prev);
+			__remove_shared_vm_struct(next, inode);
 			spin_unlock(lock);
+			if (need_up)
+				up(&inode->i_mapping->i_shared_sem);
 
 			mm->map_count--;
 			kmem_cache_free(vm_area_cachep, next);
 			return 1;
 		}
 		spin_unlock(lock);
+		if (need_up)
+			up(&inode->i_mapping->i_shared_sem);
 		return 1;
 	}
 
+	/*
+	 * Can this new request be merged in front of prev->vm_next?
+	 */
 	prev = prev->vm_next;
 	if (prev) {
  merge_next:
-		if (!can_vma_merge(prev, vm_flags))
+		if (!can_vma_merge_before(prev, vm_flags, file,
+				pgoff, (end - addr) >> PAGE_SHIFT))
 			return 0;
 		if (end == prev->vm_start) {
 			spin_lock(lock);
 			prev->vm_start = addr;
+			prev->vm_pgoff -= (end - addr) >> PAGE_SHIFT;
 			spin_unlock(lock);
 			return 1;
 		}
@@ -404,7 +498,7 @@
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma, * prev;
-	struct inode *inode = NULL;
+	struct inode *inode;
 	unsigned int vm_flags;
 	int correct_wcount = 0;
 	int error;
@@ -441,7 +535,8 @@
 	 * to. we assume access permissions have been handled by the open
 	 * of the memory object, so we don't do any here.
 	 */
-	vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+	vm_flags = calc_vm_flags(prot,flags) | mm->def_flags |
+			VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 
 	if (flags & MAP_LOCKED) {
 		if (!capable(CAP_IPC_LOCK))
@@ -456,18 +551,24 @@
 			return -EAGAIN;
 	}
 
+	inode = file ? file->f_dentry->d_inode : NULL;
+
 	if (file) {
-		inode = file->f_dentry->d_inode;
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
-			if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE))
+			if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
 				return -EACCES;
 
-			/* Make sure we don't allow writing to an append-only file.. */
+			/*
+			 * Make sure we don't allow writing to an append-only
+			 * file..
+			 */
 			if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE))
 				return -EACCES;
 
-			/* make sure there are no mandatory locks on the file. */
+			/*
+			 * Make sure there are no mandatory locks on the file.
+			 */
 			if (locks_verify_locked(inode))
 				return -EAGAIN;
 
@@ -521,7 +622,9 @@
 			/* Check memory availability in shmem_file_setup? */
 			vm_flags |= VM_ACCOUNT;
 		} else if (vm_flags & VM_WRITE) {
-			/* Private writable mapping: check memory availability */
+			/*
+			 * Private writable mapping: check memory availability
+			 */
 			charged = len >> PAGE_SHIFT;
 			if (!vm_enough_memory(charged))
 				return -ENOMEM;
@@ -531,10 +634,12 @@
 
 	/* Can we just expand an old anonymous mapping? */
 	if (!file && !(vm_flags & VM_SHARED) && rb_parent)
-		if (vma_merge(mm, prev, rb_parent, addr, addr + len, vm_flags))
+		if (vma_merge(mm, prev, rb_parent, addr, addr + len,
+					vm_flags, NULL, 0))
 			goto out;
 
-	/* Determine the object being mapped and call the appropriate
+	/*
+	 * Determine the object being mapped and call the appropriate
 	 * specific mapper. the address has already been validated, but
 	 * not unmapped, but the maps are removed from the list.
 	 */
@@ -590,10 +695,19 @@
 	 */
 	addr = vma->vm_start;
 
-	vma_link(mm, vma, prev, rb_link, rb_parent);
-	if (correct_wcount)
-		atomic_inc(&inode->i_writecount);
-
+	if (!file || !rb_parent || !vma_merge(mm, prev, rb_parent, addr,
+				addr + len, vma->vm_flags, file, pgoff)) {
+		vma_link(mm, vma, prev, rb_link, rb_parent);
+		if (correct_wcount)
+			atomic_inc(&inode->i_writecount);
+	} else {
+		if (file) {
+			if (correct_wcount)
+				atomic_inc(&inode->i_writecount);
+			fput(file);
+		}
+		kmem_cache_free(vm_area_cachep, vma);
+	}
 out:	
 	mm->total_vm += len >> PAGE_SHIFT;
 	if (vm_flags & VM_LOCKED) {
@@ -636,7 +750,9 @@
  * This function "knows" that -ENOMEM has the bits set.
  */
 #ifndef HAVE_ARCH_UNMAPPED_AREA
-static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+static inline unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
@@ -671,10 +787,14 @@
 	}
 }
 #else
-extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+extern unsigned long
+arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
+			unsigned long, unsigned long);
 #endif	
 
-unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+unsigned long
+get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
+		unsigned long pgoff, unsigned long flags)
 {
 	if (flags & MAP_FIXED) {
 		if (addr > TASK_SIZE - len)
@@ -685,7 +805,8 @@
 	}
 
 	if (file && file->f_op && file->f_op->get_unmapped_area)
-		return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags);
+		return file->f_op->get_unmapped_area(file, addr, len,
+						pgoff, flags);
 
 	return arch_get_unmapped_area(file, addr, len, pgoff, flags);
 }
@@ -708,7 +829,8 @@
 			while (rb_node) {
 				struct vm_area_struct * vma_tmp;
 
-				vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb);
+				vma_tmp = rb_entry(rb_node,
+						struct vm_area_struct, vm_rb);
 
 				if (vma_tmp->vm_end > addr) {
 					vma = vma_tmp;
@@ -726,8 +848,9 @@
 }
 
 /* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */
-struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
-				      struct vm_area_struct **pprev)
+struct vm_area_struct *
+find_vma_prev(struct mm_struct *mm, unsigned long addr,
+			struct vm_area_struct **pprev)
 {
 	struct vm_area_struct *vma = NULL, *prev = NULL;
 	struct rb_node * rb_node;
@@ -754,7 +877,7 @@
 		}
 	}
 
- out:
+out:
 	*pprev = prev;
 	return prev ? prev->vm_next : vma;
 }
@@ -801,7 +924,8 @@
 	return 0;
 }
 
-struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
+struct vm_area_struct *
+find_extend_vma(struct mm_struct *mm, unsigned long addr)
 {
 	struct vm_area_struct *vma, *prev;
 
@@ -820,7 +944,7 @@
 /*
  * vma is the first one with address < vma->vm_start.  Have to extend vma.
  */
-int expand_stack(struct vm_area_struct * vma, unsigned long address)
+int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
 	unsigned long grow;
 
@@ -855,7 +979,8 @@
 	return 0;
 }
 
-struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
+struct vm_area_struct *
+find_extend_vma(struct mm_struct * mm, unsigned long addr)
 {
 	struct vm_area_struct * vma;
 	unsigned long start;
@@ -925,7 +1050,7 @@
 		break;
 	}
 no_mmaps:
-	if (last < first)	/* needed for arches with discontiguous pgd indices */
+	if (last < first)	/* for arches with discontiguous pgd indices */
 		return;
 	/*
 	 * If the PGD bits are not consecutive in the virtual address, the
@@ -1098,6 +1223,11 @@
 		return 0;
 	/* we have  start < mpnt->vm_end  */
 
+	if (is_vm_hugetlb_page(mpnt)) {
+		if ((start & ~HPAGE_MASK) || (len & ~HPAGE_MASK))
+			return -EINVAL;
+	}
+
 	/* if it doesn't overlap, we have nothing.. */
 	end = start + len;
 	if (mpnt->vm_start >= end)
@@ -1200,7 +1330,8 @@
 	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
 
 	/* Can we just expand an old anonymous mapping? */
-	if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
+	if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len,
+					flags, NULL, 0))
 		goto out;
 
 	/*
@@ -1265,8 +1396,9 @@
 
 	tlb = tlb_gather_mmu(mm, 1);
 	flush_cache_mm(mm);
+	/* Use ~0UL here to ensure all VMAs in the mm are unmapped */
 	mm->map_count -= unmap_vmas(&tlb, mm, mm->mmap, 0,
-					TASK_SIZE, &nr_accounted);
+					~0UL, &nr_accounted);
 	vm_unacct_memory(nr_accounted);
 	BUG_ON(mm->map_count);	/* This is just debugging */
 	clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
@@ -1297,7 +1429,6 @@
 		kmem_cache_free(vm_area_cachep, vma);
 		vma = next;
 	}
-		
 }
 
 /* Insert vm structure into process list sorted by address
@@ -1309,7 +1440,7 @@
 	struct vm_area_struct * __vma, * prev;
 	struct rb_node ** rb_link, * rb_parent;
 
-	__vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent);
+	__vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent);
 	if (__vma && __vma->vm_start < vma->vm_end)
 		BUG();
 	vma_link(mm, vma, prev, rb_link, rb_parent);
diff -Nru a/mm/mremap.c b/mm/mremap.c
--- a/mm/mremap.c	Mon Feb 10 10:39:27 2003
+++ b/mm/mremap.c	Mon Feb 10 10:39:27 2003
@@ -24,9 +24,9 @@
 
 static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr)
 {
-	pgd_t * pgd;
-	pmd_t * pmd;
-	pte_t * pte = NULL;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte = NULL;
 
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd))
@@ -73,8 +73,8 @@
 
 static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr)
 {
-	pmd_t * pmd;
-	pte_t * pte = NULL;
+	pmd_t *pmd;
+	pte_t *pte = NULL;
 
 	pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr);
 	if (pmd)
@@ -88,7 +88,7 @@
 {
 	int error = 0;
 	pte_t pte;
-	struct page * page = NULL;
+	struct page *page = NULL;
 
 	if (pte_present(*src))
 		page = pte_page(*src);
@@ -183,12 +183,12 @@
 	return -1;
 }
 
-static unsigned long move_vma(struct vm_area_struct * vma,
+static unsigned long move_vma(struct vm_area_struct *vma,
 	unsigned long addr, unsigned long old_len, unsigned long new_len,
 	unsigned long new_addr)
 {
-	struct mm_struct * mm = vma->vm_mm;
-	struct vm_area_struct * new_vma, * next, * prev;
+	struct mm_struct *mm = vma->vm_mm;
+	struct vm_area_struct *new_vma, *next, *prev;
 	int allocated_vma;
 	int split = 0;
 
@@ -196,14 +196,16 @@
 	next = find_vma_prev(mm, new_addr, &prev);
 	if (next) {
 		if (prev && prev->vm_end == new_addr &&
-		    can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+		    can_vma_merge(prev, vma->vm_flags) && !vma->vm_file &&
+					!(vma->vm_flags & VM_SHARED)) {
 			spin_lock(&mm->page_table_lock);
 			prev->vm_end = new_addr + new_len;
 			spin_unlock(&mm->page_table_lock);
 			new_vma = prev;
 			if (next != prev->vm_next)
 				BUG();
-			if (prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags)) {
+			if (prev->vm_end == next->vm_start &&
+					can_vma_merge(next, prev->vm_flags)) {
 				spin_lock(&mm->page_table_lock);
 				prev->vm_end = next->vm_end;
 				__vma_unlink(mm, next, prev);
@@ -214,7 +216,8 @@
 				kmem_cache_free(vm_area_cachep, next);
 			}
 		} else if (next->vm_start == new_addr + new_len &&
-			   can_vma_merge(next, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+			  	can_vma_merge(next, vma->vm_flags) &&
+				!vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
 			spin_lock(&mm->page_table_lock);
 			next->vm_start = new_addr;
 			spin_unlock(&mm->page_table_lock);
@@ -223,7 +226,8 @@
 	} else {
 		prev = find_vma(mm, new_addr-1);
 		if (prev && prev->vm_end == new_addr &&
-		    can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+		    can_vma_merge(prev, vma->vm_flags) && !vma->vm_file &&
+				!(vma->vm_flags & VM_SHARED)) {
 			spin_lock(&mm->page_table_lock);
 			prev->vm_end = new_addr + new_len;
 			spin_unlock(&mm->page_table_lock);
@@ -249,7 +253,7 @@
 			INIT_LIST_HEAD(&new_vma->shared);
 			new_vma->vm_start = new_addr;
 			new_vma->vm_end = new_addr+new_len;
-			new_vma->vm_pgoff += (addr - vma->vm_start) >> PAGE_SHIFT;
+			new_vma->vm_pgoff += (addr-vma->vm_start) >> PAGE_SHIFT;
 			if (new_vma->vm_file)
 				get_file(new_vma->vm_file);
 			if (new_vma->vm_ops && new_vma->vm_ops->open)
@@ -428,7 +432,8 @@
 			if (vma->vm_flags & VM_SHARED)
 				map_flags |= MAP_SHARED;
 
-			new_addr = get_unmapped_area(vma->vm_file, 0, new_len, vma->vm_pgoff, map_flags);
+			new_addr = get_unmapped_area(vma->vm_file, 0, new_len,
+						vma->vm_pgoff, map_flags);
 			ret = new_addr;
 			if (new_addr & ~PAGE_MASK)
 				goto out;
diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c	Mon Feb 10 10:39:27 2003
+++ b/mm/oom_kill.c	Mon Feb 10 10:39:27 2003
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/swap.h>
 #include <linux/timex.h>
+#include <linux/jiffies.h>
 
 /* #define DEBUG */
 
@@ -68,11 +69,10 @@
 	/*
 	 * CPU time is in seconds and run time is in minutes. There is no
 	 * particular reason for this other than that it turned out to work
-	 * very well in practice. This is not safe against jiffie wraps
-	 * but we don't care _that_ much...
+	 * very well in practice.
 	 */
 	cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
-	run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10);
+	run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10);
 
 	points /= int_sqrt(cpu_time);
 	points /= int_sqrt(int_sqrt(run_time));
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c	Mon Feb 10 10:39:29 2003
+++ b/mm/page-writeback.c	Mon Feb 10 10:39:29 2003
@@ -237,7 +237,6 @@
 				break;
 		}
 	}
-	blk_run_queues();
 }
 
 /*
@@ -308,7 +307,6 @@
 		}
 		nr_to_write -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
 	}
-	blk_run_queues();
 	if (time_before(next_jif, jiffies + HZ))
 		next_jif = jiffies + HZ;
 	mod_timer(&wb_timer, next_jif);
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Mon Feb 10 10:39:23 2003
+++ b/mm/page_alloc.c	Mon Feb 10 10:39:23 2003
@@ -85,6 +85,62 @@
 	page->mapping = NULL;
 }
 
+#ifndef CONFIG_HUGETLB_PAGE
+#define prep_compound_page(page, order) do { } while (0)
+#define destroy_compound_page(page, order) do { } while (0)
+#else
+/*
+ * Higher-order pages are called "compound pages".  They are structured thusly:
+ *
+ * The first PAGE_SIZE page is called the "head page".
+ *
+ * The remaining PAGE_SIZE pages are called "tail pages".
+ *
+ * All pages have PG_compound set.  All pages have their lru.next pointing at
+ * the head page (even the head page has this).
+ *
+ * The head page's lru.prev, if non-zero, holds the address of the compound
+ * page's put_page() function.
+ *
+ * The order of the allocation is stored in the first tail page's lru.prev.
+ * This is only for debug at present.  This usage means that zero-order pages
+ * may not be compound.
+ */
+static void prep_compound_page(struct page *page, int order)
+{
+	int i;
+	int nr_pages = 1 << order;
+
+	page->lru.prev = NULL;
+	page[1].lru.prev = (void *)order;
+	for (i = 0; i < nr_pages; i++) {
+		struct page *p = page + i;
+
+		SetPageCompound(p);
+		p->lru.next = (void *)page;
+	}
+}
+
+static void destroy_compound_page(struct page *page, int order)
+{
+	int i;
+	int nr_pages = 1 << order;
+
+	if (page[1].lru.prev != (void *)order)
+		bad_page(__FUNCTION__, page);
+
+	for (i = 0; i < nr_pages; i++) {
+		struct page *p = page + i;
+
+		if (!PageCompound(p))
+			bad_page(__FUNCTION__, page);
+		if (p->lru.next != (void *)page)
+			bad_page(__FUNCTION__, page);
+		ClearPageCompound(p);
+	}
+}
+#endif		/* CONFIG_HUGETLB_PAGE */
+
 /*
  * Freeing function for a buddy system allocator.
  *
@@ -114,6 +170,8 @@
 {
 	unsigned long page_idx, index;
 
+	if (order)
+		destroy_compound_page(page, order);
 	page_idx = page - base;
 	if (page_idx & ~mask)
 		BUG();
@@ -409,6 +467,12 @@
 	free_hot_cold_page(page, 1);
 }
 
+/*
+ * Really, prep_compound_page() should be called from __rmqueue_bulk().  But
+ * 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, int cold)
 {
 	unsigned long flags;
@@ -435,6 +499,8 @@
 		spin_lock_irqsave(&zone->lock, flags);
 		page = __rmqueue(zone, order);
 		spin_unlock_irqrestore(&zone->lock, flags);
+		if (order && page)
+			prep_compound_page(page, order);
 	}
 
 	if (page != NULL) {
@@ -1269,7 +1335,7 @@
 	pgdat->node_mem_map = node_mem_map;
 
 	free_area_init_core(pgdat, zones_size, zholes_size);
-	memblk_set_online(__node_to_memblk(nid));
+	memblk_set_online(node_to_memblk(nid));
 
 	calculate_zone_bitmap(pgdat, zones_size);
 }
@@ -1379,15 +1445,20 @@
 	"pswpin",
 	"pswpout",
 	"pgalloc",
+
 	"pgfree",
 	"pgactivate",
 	"pgdeactivate",
 	"pgfault",
 	"pgmajfault",
+
 	"pgscan",
 	"pgrefill",
 	"pgsteal",
+	"pginodesteal",
 	"kswapd_steal",
+
+	"kswapd_inodesteal",
 	"pageoutrun",
 	"allocstall",
 	"pgrotated",
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	Mon Feb 10 10:39:33 2003
+++ b/mm/pdflush.c	Mon Feb 10 10:39:33 2003
@@ -90,10 +90,10 @@
 	strcpy(current->comm, "pdflush");
 
 	/* interruptible sleep, so block all signals */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked, 0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	current->flags |= PF_FLUSHER;
 	my_work->fn = NULL;
diff -Nru a/mm/readahead.c b/mm/readahead.c
--- a/mm/readahead.c	Mon Feb 10 10:39:23 2003
+++ b/mm/readahead.c	Mon Feb 10 10:39:23 2003
@@ -42,6 +42,8 @@
 	return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 }
 
+#define list_to_page(head) (list_entry((head)->prev, struct page, list))
+
 /**
  * read_cache_pages - populate an address space with some pages, and
  * 			start reads against them.
@@ -63,7 +65,7 @@
 	pagevec_init(&lru_pvec, 0);
 
 	while (!list_empty(pages)) {
-		page = list_entry(pages->prev, struct page, list);
+		page = list_to_page(pages);
 		list_del(&page->list);
 		if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
 			page_cache_release(page);
@@ -72,8 +74,16 @@
 		ret = filler(data, page);
 		if (!pagevec_add(&lru_pvec, page))
 			__pagevec_lru_add(&lru_pvec);
-		if (ret)
+		if (ret) {
+			while (!list_empty(pages)) {
+				struct page *victim;
+
+				victim = list_to_page(pages);
+				list_del(&victim->list);
+				page_cache_release(victim);
+			}
 			break;
+		}
 	}
 	pagevec_lru_add(&lru_pvec);
 	return ret;
@@ -85,13 +95,12 @@
 	unsigned page_idx;
 	struct pagevec lru_pvec;
 
-	pagevec_init(&lru_pvec, 0);
-
 	if (mapping->a_ops->readpages)
 		return mapping->a_ops->readpages(filp, mapping, pages, nr_pages);
 
+	pagevec_init(&lru_pvec, 0);
 	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
-		struct page *page = list_entry(pages->prev, struct page, list);
+		struct page *page = list_to_page(pages);
 		list_del(&page->list);
 		if (!add_to_page_cache(page, mapping,
 					page->index, GFP_KERNEL)) {
@@ -227,10 +236,8 @@
 	 * uptodate then the caller will launch readpage again, and
 	 * will then handle the error.
 	 */
-	if (ret) {
+	if (ret)
 		read_pages(mapping, filp, &page_pool, ret);
-		blk_run_queues();
-	}
 	BUG_ON(!list_empty(&page_pool));
 out:
 	return ret;
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Mon Feb 10 10:39:30 2003
+++ b/mm/slab.c	Mon Feb 10 10:39:30 2003
@@ -439,7 +439,6 @@
 static kmem_cache_t cache_cache = {
 	.lists		= LIST3_INIT(cache_cache.lists),
 	/* Allow for boot cpu != 0 */
-	.array		= { [0 ... NR_CPUS-1] = &initarray_cache.cache },
 	.batchcount	= 1,
 	.limit		= BOOT_CPUCACHE_ENTRIES,
 	.objsize	= sizeof(kmem_cache_t),
@@ -611,6 +610,7 @@
 	init_MUTEX(&cache_chain_sem);
 	INIT_LIST_HEAD(&cache_chain);
 	list_add(&cache_cache.next, &cache_chain);
+	cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
 
 	cache_estimate(0, cache_cache.objsize, 0,
 			&left_over, &cache_cache.num);
@@ -769,7 +769,7 @@
 	*(unsigned char *)(addr+size-1) = POISON_END;
 }
 
-static int check_poison_obj (kmem_cache_t *cachep, void *addr)
+static void check_poison_obj(kmem_cache_t *cachep, void *addr)
 {
 	int size = cachep->objsize;
 	void *end;
@@ -779,8 +779,7 @@
 	}
 	end = memchr(addr, POISON_END, size);
 	if (end != (addr+size-1))
-		return 1;
-	return 0;
+		slab_error(cachep, "object was modified after freeing");
 }
 #endif
 
@@ -1420,6 +1419,8 @@
 opps1:
 	kmem_freepages(cachep, objp);
 failed:
+	if (local_flags & __GFP_WAIT)
+		local_irq_disable();
 	return 0;
 }
 
@@ -1628,8 +1629,7 @@
 	if (!objp)	
 		return objp;
 	if (cachep->flags & SLAB_POISON)
-		if (check_poison_obj(cachep, objp))
-			BUG();
+		check_poison_obj(cachep, objp);
 	if (cachep->flags & SLAB_RED_ZONE) {
 		/* Set alloc red-zone, and check old one. */
 		if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE)
@@ -2048,6 +2048,14 @@
 	int err;
 	int limit;
 
+	/* The head array serves three purposes:
+	 * - create a LIFO ordering, i.e. return objects that are cache-warm
+	 * - reduce the number of spinlock operations.
+	 * - reduce the number of linked list operations on the slab and 
+	 *   bufctl chains: array operations are cheaper.
+	 * The numbers are guessed, we should auto-tune as described by
+	 * Bonwick.
+	 */
 	if (cachep->objsize > PAGE_SIZE)
 		limit = 8;
 	else if (cachep->objsize > 1024)
@@ -2057,6 +2065,14 @@
 	else
 		limit = 248;
 
+#ifndef DEBUG
+	/* With debugging enabled, large batchcount lead to excessively
+	 * long periods with disabled local interrupts. Limit the 
+	 * batchcount
+	 */
+	if (limit > 32)
+		limit = 32;
+#endif
 	err = do_tune_cpucache(cachep, limit, limit/2);
 	if (err)
 		printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
diff -Nru a/mm/truncate.c b/mm/truncate.c
--- a/mm/truncate.c	Mon Feb 10 10:39:33 2003
+++ b/mm/truncate.c	Mon Feb 10 10:39:33 2003
@@ -64,24 +64,25 @@
  * ->page_lock.  That provides exclusion against the __set_page_dirty
  * functions.
  */
-static void
+static int
 invalidate_complete_page(struct address_space *mapping, struct page *page)
 {
 	if (page->mapping != mapping)
-		return;
+		return 0;
 
 	if (PagePrivate(page) && !try_to_release_page(page, 0))
-		return;
+		return 0;
 
 	write_lock(&mapping->page_lock);
 	if (PageDirty(page)) {
 		write_unlock(&mapping->page_lock);
-	} else {
-		__remove_from_page_cache(page);
-		write_unlock(&mapping->page_lock);
-		ClearPageUptodate(page);
-		page_cache_release(page);	/* pagecache ref */
+		return 0;
 	}
+	__remove_from_page_cache(page);
+	write_unlock(&mapping->page_lock);
+	ClearPageUptodate(page);
+	page_cache_release(page);	/* pagecache ref */
+	return 1;
 }
 
 /**
@@ -177,24 +178,29 @@
 }
 
 /**
- * invalidate_inode_pages - Invalidate all the unlocked pages of one inode
- * @inode: the inode which pages we want to invalidate
+ * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode
+ * @inode: the address_space which holds the pages to invalidate
+ * @end: the index of the last page to invalidate (inclusive)
+ * @nr_pages: defines the pagecache span.  Invalidate up to @start + @nr_pages
  *
  * This function only removes the unlocked pages, if you want to
  * remove all the pages of one inode, you must call truncate_inode_pages.
  *
- * invalidate_inode_pages() will not block on IO activity. It will not
+ * invalidate_mapping_pages() will not block on IO activity. It will not
  * invalidate pages which are dirty, locked, under writeback or mapped into
  * pagetables.
  */
-void invalidate_inode_pages(struct address_space *mapping)
+unsigned long invalidate_mapping_pages(struct address_space *mapping,
+				pgoff_t start, pgoff_t end)
 {
 	struct pagevec pvec;
-	pgoff_t next = 0;
+	pgoff_t next = start;
+	unsigned long ret = 0;
 	int i;
 
 	pagevec_init(&pvec, 0);
-	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];
 
@@ -209,13 +215,19 @@
 				goto unlock;
 			if (page_mapped(page))
 				goto unlock;
-			invalidate_complete_page(mapping, page);
+			ret += invalidate_complete_page(mapping, page);
 unlock:
 			unlock_page(page);
 		}
 		pagevec_release(&pvec);
 		cond_resched();
 	}
+	return ret;
+}
+
+unsigned long invalidate_inode_pages(struct address_space *mapping)
+{
+	return invalidate_mapping_pages(mapping, 0, ~0UL);
 }
 
 /**
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Mon Feb 10 10:39:23 2003
+++ b/mm/vmscan.c	Mon Feb 10 10:39:23 2003
@@ -894,9 +894,9 @@
 				max_scan = to_reclaim * 2;
 			if (max_scan < SWAP_CLUSTER_MAX)
 				max_scan = SWAP_CLUSTER_MAX;
-			to_free -= shrink_zone(zone, max_scan, GFP_KSWAPD,
+			to_free -= shrink_zone(zone, max_scan, GFP_KERNEL,
 					to_reclaim, &nr_mapped, ps, priority);
-			shrink_slab(max_scan + nr_mapped, GFP_KSWAPD);
+			shrink_slab(max_scan + nr_mapped, GFP_KERNEL);
 			if (zone->all_unreclaimable)
 				continue;
 			if (zone->pages_scanned > zone->present_pages * 2)
@@ -929,7 +929,7 @@
 	DEFINE_WAIT(wait);
 
 	daemonize();
-	set_cpus_allowed(tsk, __node_to_cpu_mask(pgdat->node_id));
+	set_cpus_allowed(tsk, node_to_cpumask(pgdat->node_id));
 	sprintf(tsk->comm, "kswapd%d", pgdat->node_id);
 	sigfillset(&tsk->blocked);
 	
@@ -957,7 +957,6 @@
 		finish_wait(&pgdat->kswapd_wait, &wait);
 		get_page_state(&ps);
 		balance_pgdat(pgdat, 0, &ps);
-		blk_run_queues();
 	}
 }
 
diff -Nru a/net/802/Makefile b/net/802/Makefile
--- a/net/802/Makefile	Mon Feb 10 10:39:26 2003
+++ b/net/802/Makefile	Mon Feb 10 10:39:26 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux 802.x protocol layers.
 #
 
-export-objs		:= p8022.o psnap.o
-
 obj-y			:= p8023.o
 
 # Check the p8022 selections against net/core/Makefile.
diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h
--- a/net/8021q/vlan.h	Mon Feb 10 10:39:29 2003
+++ b/net/8021q/vlan.h	Mon Feb 10 10:39:29 2003
@@ -41,7 +41,7 @@
 /*  Find a VLAN device by the MAC address of it's Ethernet device, and
  *  it's VLAN ID.  The default configuration is to have VLAN's scope
  *  to be box-wide, so the MAC will be ignored.  The mac will only be
- *  looked at if we are configured to have a seperate set of VLANs per
+ *  looked at if we are configured to have a separate set of VLANs per
  *  each MAC addressable interface.  Note that this latter option does
  *  NOT follow the spec for VLANs, but may be useful for doing very
  *  large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
diff -Nru a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/net/Kconfig	Mon Feb 10 10:39:23 2003
@@ -31,7 +31,7 @@
 	  protocol implemented in the kernel, e.g. tcpdump.  If you want them
 	  to work, choose Y.
 
-	  This driver is also available as a module called af_packet.o ( =
+	  This driver is also available as a module called af_packet ( =
 	  code which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>; if you use modprobe
@@ -149,7 +149,7 @@
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>. The module will be
-	  called unix.o.  If you try building this as a module and you have
+	  called unix.  If you try building this as a module and you have
 	  said Y to "Kernel module loader support" above, be sure to add
 	  'alias net-pf-1 unix' to your /etc/modules.conf file. Note that
 	  several important services won't work correctly if you say M here
@@ -217,7 +217,7 @@
 
 	  This protocol support is also available as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
-	  want). The module will be called ipv6.o. If you want to compile it
+	  want). The module will be called ipv6. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  It is safe to say N here for now.
@@ -329,7 +329,7 @@
 	  The IPX driver would enlarge your kernel by about 16 KB. This driver
 	  is also available as a module ( = code which can be inserted in and
 	  removed from the running kernel whenever you want).  The module will
-	  be called ipx.o.  If you want to compile it as a module, say M here
+	  be called ipx.  If you want to compile it as a module, say M here
 	  and read <file:Documentation/modules.txt>.  Unless you want to
 	  integrate your Linux box with a local Novell network, say N.
 
@@ -358,7 +358,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called appletalk.o.  If you want to compile it as a
+	  The module is called appletalk.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.  You
 	  almost certainly want to compile it as a module so you can restart
 	  your AppleTalk stack without rebooting your machine.  I hear that
@@ -388,7 +388,7 @@
 
 	  The DECnet code is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module is called decnet.o.
+	  The module is called decnet.
 
 source "net/decnet/Kconfig"
 
@@ -417,7 +417,7 @@
 	  If you want to compile this code as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called bridge.o.
+	  will be called bridge.
 
 	  If unsure, say N.
 
@@ -455,7 +455,7 @@
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called x25.o. If unsure, say N.
+	  will be called x25. If unsure, say N.
 
 config LAPB
 	tristate "LAPB Data Link Driver (EXPERIMENTAL)"
@@ -476,7 +476,7 @@
 	  If you want to compile this driver as a module though ( = code which
 	  can be inserted in and removed from the running kernel whenever you
 	  want), say M here and read <file:Documentation/modules.txt>.  The
-	  module will be called lapb.o.  If unsure, say N.
+	  module will be called lapb.  If unsure, say N.
 
 config NET_DIVERT
 	bool "Frame Diverter (EXPERIMENTAL)"
@@ -521,7 +521,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called econet.o. If you want to compile it as a
+	  The module will be called econet. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ECONET_AUNUDP
@@ -561,7 +561,7 @@
 	  information.
 
 	  The WAN routing support is also available as a module called
-	  wanrouter.o ( = code which can be inserted in and removed from the
+	  wanrouter ( = code which can be inserted in and removed from the
 	  running kernel whenever you want).  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
@@ -661,7 +661,7 @@
 	  Documentation on how to use the packet generaor can be found
 	  at <file:Documentation/networking/pktgen.txt>.
 
-	  This code is also available as a module called pktgen.o ( = code
+	  This code is also available as a module called pktgen ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/net/Makefile b/net/Makefile
--- a/net/Makefile	Mon Feb 10 10:39:26 2003
+++ b/net/Makefile	Mon Feb 10 10:39:26 2003
@@ -5,8 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs :=	netsyms.o
-
 obj-y	:= socket.o core/
 
 # LLC has to be linked before the files in net/802/
diff -Nru a/net/appletalk/Makefile b/net/appletalk/Makefile
--- a/net/appletalk/Makefile	Mon Feb 10 10:39:29 2003
+++ b/net/appletalk/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux AppleTalk layer.
 #
 
-export-objs = ddp.o
-
 obj-$(CONFIG_ATALK) += appletalk.o
 
 appletalk-y			:= aarp.o ddp.o atalk_proc.o
diff -Nru a/net/atm/Makefile b/net/atm/Makefile
--- a/net/atm/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/atm/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the ATM Protocol Families.
 #
 
-export-objs 	:= common.o atm_misc.o raw.o resources.o ipcommon.o proc.o
-
 mpoa-objs	:= mpc.o mpoa_caches.o mpoa_proc.o
 
 obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o
diff -Nru a/net/ax25/Kconfig b/net/ax25/Kconfig
--- a/net/ax25/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/net/ax25/Kconfig	Mon Feb 10 10:39:31 2003
@@ -50,7 +50,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called ax25.o. If you want to compile it as a
+	  The module will be called ax25. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config AX25_DAMA_SLAVE
@@ -83,7 +83,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called netrom.o. If you want to compile it as a
+	  The module will be called netrom. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 config ROSE
@@ -104,7 +104,7 @@
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called rose.o. If you want to compile it as a
+	  The module will be called rose. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
 
diff -Nru a/net/ax25/Makefile b/net/ax25/Makefile
--- a/net/ax25/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/ax25/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux AX.25 layer.
 #
 
-export-objs := af_ax25.o
-
 obj-$(CONFIG_AX25) += ax25.o
 
 ax25-y	 := ax25_addr.o ax25_dev.o ax25_iface.o ax25_in.o ax25_ip.o ax25_out.o \
diff -Nru a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
--- a/net/bluetooth/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/net/bluetooth/Kconfig	Mon Feb 10 10:39:31 2003
@@ -30,7 +30,7 @@
 	  Bluetooth kernel modules are provided in the BlueZ packages.
 	  For more information, see <http://bluez.sourceforge.net/>.
 
-	  If you want to compile Bluetooth Core as module (bluetooth.o) say M here.
+	  If you want to compile Bluetooth Core as module (bluetooth) say M here.
 
 config BT_L2CAP
 	tristate "L2CAP protocol support"
@@ -41,7 +41,7 @@
 	  support is required for most Bluetooth applications.
 
 	  Say Y here to compile L2CAP support into the kernel or say M to
-	  compile it as module (l2cap.o).
+	  compile it as module (l2cap).
 
 config BT_SCO
 	tristate "SCO links support"
@@ -51,7 +51,7 @@
 	  required for voice applications like Headset and Audio.
 
 	  Say Y here to compile SCO support into the kernel or say M to
-	  compile it as module (sco.o).
+	  compile it as module (sco).
 
 source "net/bluetooth/rfcomm/Kconfig"
 
diff -Nru a/net/bluetooth/Makefile b/net/bluetooth/Makefile
--- a/net/bluetooth/Makefile	Mon Feb 10 10:39:24 2003
+++ b/net/bluetooth/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux Bluetooth subsystem.
 #
 
-export-objs := syms.o
-
 obj-$(CONFIG_BT)	+= bluetooth.o
 obj-$(CONFIG_BT_L2CAP)	+= l2cap.o
 obj-$(CONFIG_BT_SCO)	+= sco.o
diff -Nru a/net/bluetooth/bnep/Kconfig b/net/bluetooth/bnep/Kconfig
--- a/net/bluetooth/bnep/Kconfig	Mon Feb 10 10:39:33 2003
+++ b/net/bluetooth/bnep/Kconfig	Mon Feb 10 10:39:33 2003
@@ -11,7 +11,7 @@
 	  For more information, see <http://bluez.sourceforge.net>.
 
 	  Say Y here to compile BNEP support into the kernel or say M to
-	  compile it as module (bnep.o).
+	  compile it as module (bnep).
 
 config BT_BNEP_MC_FILTER
 	bool "Multicast filter support"
diff -Nru a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig
--- a/net/bluetooth/rfcomm/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/net/bluetooth/rfcomm/Kconfig	Mon Feb 10 10:39:27 2003
@@ -7,7 +7,7 @@
 	  applications.
 
 	  Say Y here to compile RFCOMM support into the kernel or say M to
-	  compile it as module (rfcomm.o).
+	  compile it as module (rfcomm).
 
 config BT_RFCOMM_TTY
 	bool "RFCOMM TTY support"
diff -Nru a/net/bridge/Makefile b/net/bridge/Makefile
--- a/net/bridge/Makefile	Mon Feb 10 10:39:33 2003
+++ b/net/bridge/Makefile	Mon Feb 10 10:39:33 2003
@@ -2,8 +2,6 @@
 # Makefile for the IEEE 802.1d ethernet bridging layer.
 #
 
-export-objs := br.o
-
 obj-$(CONFIG_BRIDGE) += bridge.o
 
 bridge-objs	:= br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
diff -Nru a/net/bridge/br.c b/net/bridge/br.c
--- a/net/bridge/br.c	Mon Feb 10 10:39:23 2003
+++ b/net/bridge/br.c	Mon Feb 10 10:39:23 2003
@@ -33,12 +33,12 @@
 
 void br_dec_use_count()
 {
-	MOD_DEC_USE_COUNT;
+	module_put(THIS_MODULE);
 }
 
 void br_inc_use_count()
 {
-	MOD_INC_USE_COUNT;
+	try_module_get(THIS_MODULE);
 }
 
 static int __init br_init(void)
diff -Nru a/net/bridge/br_if.c b/net/bridge/br_if.c
--- a/net/bridge/br_if.c	Mon Feb 10 10:39:33 2003
+++ b/net/bridge/br_if.c	Mon Feb 10 10:39:33 2003
@@ -155,8 +155,6 @@
 	p->path_cost = br_initial_port_cost(dev);
 	p->priority = 0x80;
 
-	dev->br_port = p;
-
 	for (i=1;i<255;i++)
 		if (br_get_port(br, i) == NULL)
 			break;
@@ -165,6 +163,8 @@
 		kfree(p);
 		return NULL;
 	}
+
+	dev->br_port = p;
 
 	p->port_no = i;
 	br_init_port(p);
diff -Nru a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
--- a/net/bridge/netfilter/Makefile	Mon Feb 10 10:39:29 2003
+++ b/net/bridge/netfilter/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for the netfilter modules for Link Layer filtering on a bridge.
 #
 
-export-objs := ebtables.o
-
 obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
 obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o
 obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c	Mon Feb 10 10:39:33 2003
+++ b/net/core/rtnetlink.c	Mon Feb 10 10:39:33 2003
@@ -34,6 +34,7 @@
 #include <linux/capability.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -363,7 +364,7 @@
 	sz_idx = type>>2;
 	kind = type&3;
 
-	if (kind != 2 && !cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+	if (kind != 2 && security_netlink_recv(skb)) {
 		*errp = -EPERM;
 		return -1;
 	}
diff -Nru a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
--- a/net/decnet/dn_nsp_in.c	Mon Feb 10 10:39:24 2003
+++ b/net/decnet/dn_nsp_in.c	Mon Feb 10 10:39:24 2003
@@ -566,26 +566,19 @@
  */
 static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue)
 {
-#ifdef CONFIG_FILTER
-	struct sk_filter *filter;
-#endif
-
+	int err;
+	
         /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
            number of warnings when compiling with -W --ANK
          */
-        if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf
-)
-                return -ENOMEM;
-
-#ifdef CONFIG_FILTER
-        if (sk->filter) {
-		int err = 0;
-                if ((filter = sk->filter) != NULL && sk_filter(skb, sk->filter))
-                        err = -EPERM;  /* Toss packet */
-		if (err)
-			return err;
+        if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) {
+        	err = -ENOMEM;
+        	goto out;
         }
-#endif /* CONFIG_FILTER */
+
+	err = sk_filter(sk, skb, 0);
+	if (err)
+		goto out;
 
         skb_set_owner_r(skb, sk);
         skb_queue_tail(queue, skb);
@@ -603,8 +596,8 @@
 				    (sig == SIGURG) ? POLL_PRI : POLL_IN);
 	}
 	read_unlock(&sk->callback_lock);
-
-        return 0;
+out:
+        return err;
 }
 
 static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb)
diff -Nru a/net/ipv4/ah.c b/net/ipv4/ah.c
--- a/net/ipv4/ah.c	Mon Feb 10 10:39:31 2003
+++ b/net/ipv4/ah.c	Mon Feb 10 10:39:31 2003
@@ -280,6 +280,8 @@
 	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 		goto out;
 
+	skb->ip_summed = CHECKSUM_NONE;
+
 	ah = (struct ip_auth_hdr*)skb->data;
 	iph = skb->nh.iph;
 
@@ -359,7 +361,7 @@
 	ahp->icv = ah_hmac_digest;
 	
 	/*
-	 * Lookup the algorithm description maintained by pfkey,
+	 * Lookup the algorithm description maintained by xfrm_algo,
 	 * verify crypto transform properties, and store information
 	 * we need for AH processing.  This lookup cannot fail here
 	 * after a successful crypto_alloc_tfm().
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c	Mon Feb 10 10:39:24 2003
+++ b/net/ipv4/devinet.c	Mon Feb 10 10:39:24 2003
@@ -823,6 +823,34 @@
 	return notifier_chain_unregister(&inetaddr_chain, nb);
 }
 
+/* Rename ifa_labels for a device name change. Make some effort to preserve existing
+ * alias numbering and to create unique labels if possible.
+*/
+static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
+{ 
+	struct in_ifaddr *ifa;
+	int named = 0;
+
+	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { 
+		char old[IFNAMSIZ], *dot; 
+
+		memcpy(old, ifa->ifa_label, IFNAMSIZ);
+		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 
+		if (named++ == 0)
+			continue;
+		dot = strchr(ifa->ifa_label, ':');
+		if (dot == NULL) { 
+			sprintf(old, ":%d", named); 
+			dot = old;
+		}
+		if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { 
+			strcat(ifa->ifa_label, dot); 
+		} else { 
+			strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); 
+		} 
+	}	
+} 
+
 /* Called only under RTNL semaphore */
 
 static int inetdev_event(struct notifier_block *this, unsigned long event,
@@ -873,14 +901,10 @@
 		inetdev_destroy(in_dev);
 		break;
 	case NETDEV_CHANGENAME:
-		if (in_dev->ifa_list) {
-			struct in_ifaddr *ifa;
-			for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next)
-				memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
-			/* Do not notify about label change, this event is
-			   not interesting to applications using netlink.
-			 */
-		}
+		/* Do not notify about label change, this event is
+		 * not interesting to applications using netlink.
+		 */
+		inetdev_changename(dev, in_dev);
 		break;
 	}
 out:
diff -Nru a/net/ipv4/esp.c b/net/ipv4/esp.c
--- a/net/ipv4/esp.c	Mon Feb 10 10:39:29 2003
+++ b/net/ipv4/esp.c	Mon Feb 10 10:39:29 2003
@@ -10,6 +10,9 @@
 
 #define MAX_SG_ONSTACK 4
 
+typedef void (icv_update_fn_t)(struct crypto_tfm *,
+                               struct scatterlist *, unsigned int);
+
 /* BUGS:
  * - we assume replay seqno is always present.
  */
@@ -30,37 +33,40 @@
 		struct crypto_tfm	*tfm;		/* crypto handle */
 	} conf;
 
-	/* Integrity. It is active when authlen != 0 */
+	/* Integrity. It is active when icv_full_len != 0 */
 	struct {
 		u8			*key;		/* Key */
 		int			key_len;	/* Length of the key */
-		u8			*work_digest;
-		/* authlen is length of trailer containing auth token.
-		 * If it is not zero it is assumed to be
-		 * >= crypto_tfm_alg_digestsize(atfm) */
-		int			authlen;
-		void			(*digest)(struct esp_data*,
-						  struct sk_buff *skb,
-						  int offset,
-						  int len,
-						  u8 *digest);
+		u8			*work_icv;
+		int			icv_full_len;
+		int			icv_trunc_len;
+		void			(*icv)(struct esp_data*,
+		                               struct sk_buff *skb,
+		                               int offset, int len, u8 *icv);
 		struct crypto_tfm	*tfm;
 	} auth;
 };
 
 /* Move to common area: it is shared with AH. */
 
-void skb_digest_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
-		     int offset, int len)
+void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
+		  int offset, int len, icv_update_fn_t icv_update)
 {
 	int start = skb->len - skb->data_len;
 	int i, copy = start - offset;
+	struct scatterlist sg;
 
 	/* Checksum header. */
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, skb->data+offset, copy);
+		
+		sg.page = virt_to_page(skb->data + offset);
+		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
+		sg.length = copy;
+		
+		icv_update(tfm, &sg, 1);
+		
 		if ((len -= copy) == 0)
 			return;
 		offset += copy;
@@ -73,14 +79,17 @@
 
 		end = start + skb_shinfo(skb)->frags[i].size;
 		if ((copy = end - offset) > 0) {
-			u8 *vaddr;
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			if (copy > len)
 				copy = len;
-			vaddr = kmap_skb_frag(frag);
-			tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, vaddr+frag->page_offset+offset-start, copy);
-			kunmap_skb_frag(vaddr);
+			
+			sg.page = frag->page;
+			sg.offset = frag->page_offset + offset-start;
+			sg.length = copy;
+			
+			icv_update(tfm, &sg, 1);
+
 			if (!(len -= copy))
 				return;
 			offset += copy;
@@ -100,7 +109,7 @@
 			if ((copy = end - offset) > 0) {
 				if (copy > len)
 					copy = len;
-				skb_digest_walk(list, tfm, offset-start, copy);
+				skb_icv_walk(list, tfm, offset-start, copy, icv_update);
 				if ((len -= copy) == 0)
 					return;
 				offset += copy;
@@ -188,12 +197,13 @@
 		int len, u8 *auth_data)
 {
 	struct crypto_tfm *tfm = esp->auth.tfm;
-	char *digest = esp->auth.work_digest;
+	char *icv = esp->auth.work_icv;
 
+	memset(auth_data, 0, esp->auth.icv_trunc_len);
  	crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len);
-	skb_digest_walk(skb, tfm, offset, len);
-	crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, digest);
-	memcpy(auth_data, digest, esp->auth.authlen);
+	skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update);
+	crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv);
+	memcpy(auth_data, icv, esp->auth.icv_trunc_len);
 }
 
 /* Check that skb data bits are writable. If they are not, copy data
@@ -317,6 +327,7 @@
 	struct sk_buff *trailer;
 	int blksize;
 	int clen;
+	int alen;
 	int nfrags;
 	union {
 		struct iphdr	iph;
@@ -347,13 +358,14 @@
 	clen = skb->len;
 
 	esp = x->data;
+	alen = esp->auth.icv_trunc_len;
 	tfm = esp->conf.tfm;
 	blksize = crypto_tfm_alg_blocksize(tfm);
 	clen = (clen + 2 + blksize-1)&~(blksize-1);
 	if (esp->conf.padlen)
 		clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
 
-	if ((nfrags = skb_cow_data(skb, clen-skb->len+esp->auth.authlen, &trailer)) < 0)
+	if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
 		goto error;
 
 	/* Fill padding... */
@@ -373,7 +385,7 @@
 		top_iph->ihl = 5;
 		top_iph->version = 4;
 		top_iph->tos = iph->tos;	/* DS disclosed */
-		top_iph->tot_len = htons(skb->len + esp->auth.authlen);
+		top_iph->tot_len = htons(skb->len + alen);
 		top_iph->frag_off = iph->frag_off&htons(IP_DF);
 		if (!(top_iph->frag_off))
 			ip_select_ident(top_iph, dst, 0);
@@ -388,7 +400,7 @@
 		top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
 		memcpy(top_iph, &tmp_iph, iph->ihl*4);
 		iph = &tmp_iph.iph;
-		top_iph->tot_len = htons(skb->len + esp->auth.authlen);
+		top_iph->tot_len = htons(skb->len + alen);
 		top_iph->protocol = IPPROTO_ESP;
 		top_iph->check = 0;
 		top_iph->frag_off = iph->frag_off;
@@ -411,7 +423,7 @@
 				goto error;
 		}
 		skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
-		crypto_cipher_encrypt(tfm, sg, nfrags);
+		crypto_cipher_encrypt(tfm, sg, sg, clen);
 		if (unlikely(sg != sgbuf))
 			kfree(sg);
 	} while (0);
@@ -421,10 +433,10 @@
 		crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
 	}
 
-	if (esp->auth.authlen) {
-		esp->auth.digest(esp, skb, (u8*)esph-skb->data,
-				 8+esp->conf.ivlen+clen, trailer->tail);
-		pskb_put(skb, trailer, esp->auth.authlen);
+	if (esp->auth.icv_full_len) {
+		esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+		              8+esp->conf.ivlen+clen, trailer->tail);
+		pskb_put(skb, trailer, alen);
 	}
 
 	ip_send_check(top_iph);
@@ -445,6 +457,11 @@
 	return err;
 }
 
+/*
+ * Note: detecting truncated vs. non-truncated authentication data is very
+ * expensive, so we only support truncated data, which is the recommended
+ * and common case.
+ */
 int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -452,7 +469,8 @@
 	struct esp_data *esp = x->data;
 	struct sk_buff *trailer;
 	int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm);
-	int elen = skb->len - 8 - esp->conf.ivlen - esp->auth.authlen;
+	int alen = esp->auth.icv_trunc_len;
+	int elen = skb->len - 8 - esp->conf.ivlen - alen;
 	int nfrags;
 
 	if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
@@ -462,17 +480,16 @@
 		goto out;
 
 	/* If integrity check is required, do this. */
-	if (esp->auth.authlen) {
-		u8 sum[esp->auth.authlen];
-		u8 sum1[esp->auth.authlen];
+	if (esp->auth.icv_full_len) {
+		u8 sum[esp->auth.icv_full_len];
+		u8 sum1[alen];
+		
+		esp->auth.icv(esp, skb, 0, skb->len-alen, sum);
 
-		esp->auth.digest(esp, skb, 0, skb->len-esp->auth.authlen, sum);
-
-		if (skb_copy_bits(skb, skb->len-esp->auth.authlen, sum1, 
-				esp->auth.authlen))
+		if (skb_copy_bits(skb, skb->len-alen, sum1, alen))
 			BUG();
 
-		if (unlikely(memcmp(sum, sum1, esp->auth.authlen))) {
+		if (unlikely(memcmp(sum, sum1, alen))) {
 			x->stats.integrity_failed++;
 			goto out;
 		}
@@ -481,6 +498,8 @@
 	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)
 		goto out;
 
+	skb->ip_summed = CHECKSUM_NONE;
+
 	esph = (struct ip_esp_hdr*)skb->data;
 	iph = skb->nh.iph;
 
@@ -501,12 +520,11 @@
 				goto out;
 		}
 		skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen);
-		crypto_cipher_decrypt(esp->conf.tfm, sg, nfrags);
+		crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
 		if (unlikely(sg != sgbuf))
 			kfree(sg);
 
-		if (skb_copy_bits(skb, skb->len-esp->auth.authlen-2,
-				  nexthdr, 2))
+		if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
 			BUG();
 
 		padlen = nexthdr[0];
@@ -516,7 +534,7 @@
 		/* ... check padding bits here. Silly. :-) */ 
 
 		iph->protocol = nexthdr[1];
-		pskb_trim(skb, skb->len - esp->auth.authlen - padlen - 2);
+		pskb_trim(skb, skb->len - alen - padlen - 2);
 		memcpy(workbuf, skb->nh.raw, iph->ihl*4);
 		skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen);
 		skb->nh.raw += 8 + esp->conf.ivlen;
@@ -544,7 +562,7 @@
 	if (esp->conf.padlen)
 		mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
 
-	return mtu + x->props.header_len + esp->auth.authlen;
+	return mtu + x->props.header_len + esp->auth.icv_full_len;
 }
 
 void esp4_err(struct sk_buff *skb, u32 info)
@@ -581,9 +599,9 @@
 		crypto_free_tfm(esp->auth.tfm);
 		esp->auth.tfm = NULL;
 	}
-	if (esp->auth.work_digest) {
-		kfree(esp->auth.work_digest);
-		esp->auth.work_digest = NULL;
+	if (esp->auth.work_icv) {
+		kfree(esp->auth.work_icv);
+		esp->auth.work_icv = NULL;
 	}
 }
 
@@ -591,11 +609,12 @@
 {
 	struct esp_data *esp = NULL;
 
+	/* null auth and encryption can have zero length keys */
 	if (x->aalg) {
-		if (x->aalg->alg_key_len == 0 || x->aalg->alg_key_len > 512)
+		if (x->aalg->alg_key_len > 512)
 			goto error;
 	}
-	if (x->ealg == NULL || x->ealg->alg_key_len == 0)
+	if (x->ealg == NULL)
 		goto error;
 
 	esp = kmalloc(sizeof(*esp), GFP_KERNEL);
@@ -605,21 +624,32 @@
 	memset(esp, 0, sizeof(*esp));
 
 	if (x->aalg) {
-		int digestsize;
+		struct xfrm_algo_desc *aalg_desc;
 
 		esp->auth.key = x->aalg->alg_key;
 		esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
 		esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);
 		if (esp->auth.tfm == NULL)
 			goto error;
-		esp->auth.digest = esp_hmac_digest;
-		digestsize = crypto_tfm_alg_digestsize(esp->auth.tfm);
-		/* XXX RFC2403 and RFC 2404 truncate auth to 96 bit */
-		esp->auth.authlen = 12;
-		if (esp->auth.authlen > digestsize) /* XXX */
-			BUG();
-		esp->auth.work_digest = kmalloc(digestsize, GFP_KERNEL);
-		if (!esp->auth.work_digest)
+		esp->auth.icv = esp_hmac_digest;
+
+		aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name);
+		BUG_ON(!aalg_desc);
+
+		if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
+		    crypto_tfm_alg_digestsize(esp->auth.tfm)) {
+			printk(KERN_INFO "ESP: %s digestsize %u != %hu\n",
+			       x->aalg->alg_name,
+			       crypto_tfm_alg_digestsize(esp->auth.tfm),
+			       aalg_desc->uinfo.auth.icv_fullbits/8);
+			goto error;
+		}
+
+		esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
+		esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;
+
+		esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL);
+		if (!esp->auth.work_icv)
 			goto error;
 	}
 	esp->conf.key = x->ealg->alg_key;
@@ -637,7 +667,6 @@
 	x->props.header_len = 8 + esp->conf.ivlen;
 	if (x->props.mode)
 		x->props.header_len += 20;
-	x->props.trailer_len = esp->auth.authlen + crypto_tfm_alg_blocksize(esp->conf.tfm);
 	x->data = esp;
 	return 0;
 
@@ -645,8 +674,8 @@
 	if (esp) {
 		if (esp->auth.tfm)
 			crypto_free_tfm(esp->auth.tfm);
-		if (esp->auth.work_digest)
-			kfree(esp->auth.work_digest);
+		if (esp->auth.work_icv)
+			kfree(esp->auth.work_icv);
 		if (esp->conf.tfm)
 			crypto_free_tfm(esp->conf.tfm);
 		kfree(esp);
diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
--- a/net/ipv4/fib_hash.c	Mon Feb 10 10:39:27 2003
+++ b/net/ipv4/fib_hash.c	Mon Feb 10 10:39:27 2003
@@ -941,7 +941,7 @@
 
 			if (!iter->zone)
 				goto out;
-			if (iter->zone->fz_next);
+			if (iter->zone->fz_next)
 				break;
 		}
 		
diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c	Mon Feb 10 10:39:33 2003
+++ b/net/ipv4/ip_output.c	Mon Feb 10 10:39:33 2003
@@ -280,7 +280,7 @@
 		return ip_finish_output(skb);
 }
 
-int ip_queue_xmit(struct sk_buff *skb)
+int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
 {
 	struct sock *sk = skb->sk;
 	struct inet_opt *inet = inet_sk(sk);
@@ -337,7 +337,7 @@
 	iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
 	*((__u16 *)iph)	= htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
 	iph->tot_len = htons(skb->len);
-	if (ip_dont_fragment(sk, &rt->u.dst))
+	if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
 		iph->frag_off = htons(IP_DF);
 	else
 		iph->frag_off = 0;
diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
--- a/net/ipv4/netfilter/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/net/ipv4/netfilter/Kconfig	Mon Feb 10 10:39:31 2003
@@ -148,6 +148,14 @@
 config IP_NF_MATCH_DSCP
 	tristate "DSCP match support"
 	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `DSCP' match, which allows you to match against
+	  the IPv4 header DSCP field (DSCP codepoint).
+
+	  The DSCP codepoint can have any value between 0x0 and 0x4f.
+
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt.  If unsure, say `N'.
 
 config IP_NF_MATCH_AH_ESP
 	tristate "AH/ESP match support"
diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
--- a/net/ipv4/netfilter/Makefile	Mon Feb 10 10:39:24 2003
+++ b/net/ipv4/netfilter/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,9 +2,6 @@
 # Makefile for the netfilter modules on top of IPv4.
 #
 
-export-objs  := ip_conntrack_standalone.o ip_nat_standalone.o \
-		ip_tables.o arp_tables.o
-
 # objects for the conntrack and NAT core (used by standalone and backw. compat)
 ip_nf_conntrack-objs	:= ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
 ip_nf_nat-objs		:= ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
@@ -25,11 +22,9 @@
 # connection tracking helpers
 obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
 ifdef CONFIG_IP_NF_NAT_FTP
-	export-objs += ip_conntrack_ftp.o
 endif
 obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
 ifdef CONFIG_IP_NF_NAT_IRC
-	export-objs += ip_conntrack_irc.o
 endif
 
 # NAT helpers 
diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
--- a/net/ipv4/netfilter/ip_nat_helper.c	Mon Feb 10 10:39:23 2003
+++ b/net/ipv4/netfilter/ip_nat_helper.c	Mon Feb 10 10:39:23 2003
@@ -84,7 +84,6 @@
 	iph = (*skb)->nh.iph;
 	if (iph->protocol == IPPROTO_TCP) {
 		struct tcphdr *tcph = (void *)iph + iph->ihl*4;
-		void *data = (void *)tcph + tcph->doff*4;
 
 		DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
 		DUMP_OFFSET(this_way);
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	Mon Feb 10 10:39:33 2003
+++ b/net/ipv4/netfilter/ip_queue.c	Mon Feb 10 10:39:33 2003
@@ -26,6 +26,7 @@
 #include <linux/brlock.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
+#include <linux/security.h>
 #include <net/sock.h>
 #include <net/route.h>
 
@@ -496,7 +497,7 @@
 	if (type <= IPQM_BASE)
 		return;
 		
-	if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+	if (security_netlink_recv(skb))
 		RCV_SKB_FAIL(-EPERM);
 	
 	write_lock_bh(&queue_lock);
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	Mon Feb 10 10:39:33 2003
+++ b/net/ipv4/route.c	Mon Feb 10 10:39:33 2003
@@ -2288,7 +2288,7 @@
 		struct net_device *dev = __dev_get_by_index(iif);
 		err = -ENODEV;
 		if (!dev)
-			goto out;
+			goto out_free;
 		skb->protocol	= htons(ETH_P_IP);
 		skb->dev	= dev;
 		local_bh_disable();
@@ -2307,10 +2307,8 @@
 		fl.oif = oif;
 		err = ip_route_output_key(&rt, &fl);
 	}
-	if (err) {
-		kfree_skb(skb);
-		goto out;
-	}
+	if (err)
+		goto out_free;
 
 	skb->dst = &rt->u.dst;
 	if (rtm->rtm_flags & RTM_F_NOTIFY)
@@ -2321,16 +2319,20 @@
 	err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
 				RTM_NEWROUTE, 0);
 	if (!err)
-		goto out;
+		goto out_free;
 	if (err < 0) {
 		err = -EMSGSIZE;
-		goto out;
+		goto out_free;
 	}
 
 	err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
 	if (err > 0)
 		err = 0;
 out:	return err;
+
+out_free:
+	kfree_skb(skb);
+	goto out;
 }
 
 int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
--- a/net/ipv4/sysctl_net_ipv4.c	Mon Feb 10 10:39:30 2003
+++ b/net/ipv4/sysctl_net_ipv4.c	Mon Feb 10 10:39:30 2003
@@ -223,6 +223,8 @@
 	 &sysctl_tcp_tw_reuse, sizeof(int), 0644, NULL, &proc_dointvec},
 	{NET_TCP_FRTO, "tcp_frto",
 	 &sysctl_tcp_frto, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_TCP_LOW_LATENCY, "tcp_low_latency",
+	 &sysctl_tcp_low_latency, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Mon Feb 10 10:39:24 2003
+++ b/net/ipv4/tcp_ipv4.c	Mon Feb 10 10:39:24 2003
@@ -75,6 +75,7 @@
 extern int sysctl_ip_dynaddr;
 extern int sysctl_ip_default_ttl;
 int sysctl_tcp_tw_reuse;
+int sysctl_tcp_low_latency;
 
 /* Check TCP sequence numbers in ICMP packets. */
 #define ICMP_MIN_LENGTH 8
@@ -86,11 +87,11 @@
 		       struct sk_buff *skb);
 
 struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
-	.__tcp_lhash_lock =   RW_LOCK_UNLOCKED,
-	.__tcp_lhash_users =  ATOMIC_INIT(0),
+	.__tcp_lhash_lock	=	RW_LOCK_UNLOCKED,
+	.__tcp_lhash_users	=	ATOMIC_INIT(0),
 	.__tcp_lhash_wait
 	  = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
-	.__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED
+	.__tcp_portalloc_lock	=	SPIN_LOCK_UNLOCKED
 };
 
 /*
@@ -1410,11 +1411,11 @@
 int sysctl_max_syn_backlog = 256;
 
 struct or_calltable or_ipv4 = {
-	.family =	PF_INET,
-	.rtx_syn_ack =	tcp_v4_send_synack,
-	.send_ack =	tcp_v4_or_send_ack,
-	.destructor =	tcp_v4_or_free,
-	.send_reset =	tcp_v4_send_reset,
+	.family		=	PF_INET,
+	.rtx_syn_ack	=	tcp_v4_send_synack,
+	.send_ack	=	tcp_v4_or_send_ack,
+	.destructor	=	tcp_v4_or_free,
+	.send_reset	=	tcp_v4_send_reset,
 };
 
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
@@ -1696,12 +1697,6 @@
  */
 int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
-#ifdef CONFIG_FILTER
-	struct sk_filter *filter = sk->filter;
-	if (filter && sk_filter(skb, filter))
-		goto discard;
-#endif /* CONFIG_FILTER */
-
 	if (sk->state == TCP_ESTABLISHED) { /* Fast path */
 		TCP_CHECK_TIMER(sk);
 		if (tcp_rcv_established(sk, skb, skb->h.th, skb->len))
@@ -1804,6 +1799,9 @@
 	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
 
+	if (sk_filter(sk, skb, 0))
+		goto discard_and_relse;
+
 	skb->dev = NULL;
 
 	bh_lock_sock(sk);
@@ -2047,17 +2045,17 @@
 }
 
 struct tcp_func ipv4_specific = {
-	.queue_xmit =	ip_queue_xmit,
-	.send_check =	tcp_v4_send_check,
-	.rebuild_header =tcp_v4_rebuild_header,
-	.conn_request =	tcp_v4_conn_request,
-	.syn_recv_sock =tcp_v4_syn_recv_sock,
-	.remember_stamp =tcp_v4_remember_stamp,
-	.net_header_len =sizeof(struct iphdr),
-	.setsockopt =	ip_setsockopt,
-	.getsockopt =	ip_getsockopt,
-	.addr2sockaddr =v4_addr2sockaddr,
-	.sockaddr_len =	sizeof(struct sockaddr_in),
+	.queue_xmit	=	ip_queue_xmit,
+	.send_check	=	tcp_v4_send_check,
+	.rebuild_header	=	tcp_v4_rebuild_header,
+	.conn_request	=	tcp_v4_conn_request,
+	.syn_recv_sock	=	tcp_v4_syn_recv_sock,
+	.remember_stamp	=	tcp_v4_remember_stamp,
+	.net_header_len	=	sizeof(struct iphdr),
+	.setsockopt	=	ip_setsockopt,
+	.getsockopt	=	ip_getsockopt,
+	.addr2sockaddr	=	v4_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in),
 };
 
 /* NOTE: A lot of things set to zero explicitly by call to
@@ -2543,10 +2541,10 @@
 }
 
 static struct seq_operations tcp_seq_ops = {
-	.start  = tcp_seq_start,
-	.next   = tcp_seq_next,
-	.stop   = tcp_seq_stop,
-	.show   = tcp_seq_show,
+	.start	=	tcp_seq_start,
+	.next	=	tcp_seq_next,
+	.stop	=	tcp_seq_stop,
+	.show	=	tcp_seq_show,
 };
 
 static int tcp_seq_open(struct inode *inode, struct file *file)
@@ -2571,10 +2569,10 @@
 }
 
 static struct file_operations tcp_seq_fops = {
-	.open           = tcp_seq_open,
-	.read           = seq_read,
-	.llseek         = seq_lseek,
-	.release	= ip_seq_release,
+	.open		=	tcp_seq_open,
+	.read		=	seq_read,
+	.llseek		=	seq_lseek,
+	.release	=	ip_seq_release,
 };
 
 int __init tcp_proc_init(void)
@@ -2596,23 +2594,23 @@
 #endif /* CONFIG_PROC_FS */
 
 struct proto tcp_prot = {
-	.name =		"TCP",
-	.close =	tcp_close,
-	.connect =	tcp_v4_connect,
-	.disconnect =	tcp_disconnect,
-	.accept =	tcp_accept,
-	.ioctl =	tcp_ioctl,
-	.init =		tcp_v4_init_sock,
-	.destroy =	tcp_v4_destroy_sock,
-	.shutdown =	tcp_shutdown,
-	.setsockopt =	tcp_setsockopt,
-	.getsockopt =	tcp_getsockopt,
-	.sendmsg =	tcp_sendmsg,
-	.recvmsg =	tcp_recvmsg,
-	.backlog_rcv =	tcp_v4_do_rcv,
-	.hash =		tcp_v4_hash,
-	.unhash =	tcp_unhash,
-	.get_port =	tcp_v4_get_port,
+	.name		=	"TCP",
+	.close		=	tcp_close,
+	.connect	=	tcp_v4_connect,
+	.disconnect	=	tcp_disconnect,
+	.accept		=	tcp_accept,
+	.ioctl		=	tcp_ioctl,
+	.init		=	tcp_v4_init_sock,
+	.destroy	=	tcp_v4_destroy_sock,
+	.shutdown	=	tcp_shutdown,
+	.setsockopt	=	tcp_setsockopt,
+	.getsockopt	=	tcp_getsockopt,
+	.sendmsg	=	tcp_sendmsg,
+	.recvmsg	=	tcp_recvmsg,
+	.backlog_rcv	=	tcp_v4_do_rcv,
+	.hash		=	tcp_v4_hash,
+	.unhash		=	tcp_unhash,
+	.get_port	=	tcp_v4_get_port,
 };
 
 
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	Mon Feb 10 10:39:30 2003
+++ b/net/ipv4/tcp_minisocks.c	Mon Feb 10 10:39:30 2003
@@ -952,6 +952,12 @@
 	if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN))
 		goto embryonic_reset;
 
+	/* ACK sequence verified above, just make sure ACK is
+	 * set.  If ACK not set, just silently drop the packet.
+	 */
+	if (!(flg & TCP_FLAG_ACK))
+		return NULL;
+
 	/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
 	if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) {
 		req->acked = 1;
diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c	Mon Feb 10 10:39:29 2003
+++ b/net/ipv4/tcp_output.c	Mon Feb 10 10:39:29 2003
@@ -276,7 +276,7 @@
 
 		TCP_INC_STATS(TcpOutSegs);
 
-		err = tp->af_specific->queue_xmit(skb);
+		err = tp->af_specific->queue_xmit(skb, 0);
 		if (err <= 0)
 			return err;
 
@@ -786,13 +786,13 @@
 		/* Ok.  We will be able to collapse the packet. */
 		__skb_unlink(next_skb, next_skb->list);
 
+		memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size);
+
 		if (next_skb->ip_summed == CHECKSUM_HW)
 			skb->ip_summed = CHECKSUM_HW;
 
-		if (skb->ip_summed != CHECKSUM_HW) {
-			memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size);
+		if (skb->ip_summed != CHECKSUM_HW)
 			skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size);
-		}
 
 		/* Update sequence range on original skb. */
 		TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
diff -Nru a/net/ipv4/xfrm_user.c b/net/ipv4/xfrm_user.c
--- a/net/ipv4/xfrm_user.c	Mon Feb 10 10:39:28 2003
+++ b/net/ipv4/xfrm_user.c	Mon Feb 10 10:39:28 2003
@@ -16,6 +16,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 #include <linux/init.h>
+#include <linux/security.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 
@@ -276,9 +277,11 @@
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
-		RTA_PUT(skb, XFRMA_ALG_AUTH, sizeof(*(x->aalg)), x->aalg);
+		RTA_PUT(skb, XFRMA_ALG_AUTH,
+			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
 	if (x->ealg)
-		RTA_PUT(skb, XFRMA_ALG_CRYPT, sizeof(*(x->ealg)), x->ealg);
+		RTA_PUT(skb, XFRMA_ALG_CRYPT,
+			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
 	if (x->calg)
 		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
 
@@ -655,6 +658,7 @@
 	info.in_skb = cb->skb;
 	info.out_skb = skb;
 	info.nlmsg_seq = cb->nlh->nlmsg_seq;
+	info.this_idx = 0;
 	info.start_idx = cb->args[0];
 	(void) xfrm_policy_walk(dump_one_policy, &info);
 	cb->args[0] = info.this_idx;
@@ -752,7 +756,7 @@
 {
 	struct rtattr *xfrma[XFRMA_MAX];
 	struct xfrm_link *link;
-	int type, min_len, kind;
+	int type, min_len;
 
 	if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
 		return 0;
@@ -768,16 +772,15 @@
 		goto err_einval;
 
 	type -= XFRM_MSG_BASE;
-	kind = (type & 3);
 	link = &xfrm_dispatch[type];
 
 	/* All operations require privileges, even GET */
-	if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+	if (security_netlink_recv(skb)) {
 		*errp = -EPERM;
 		return -1;
 	}
 
-	if (kind == 2 && (nlh->nlmsg_flags & NLM_F_DUMP)) {
+	if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) {
 		u32 rlen;
 
 		if (link->dump == NULL)
diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile
--- a/net/ipv6/Makefile	Mon Feb 10 10:39:30 2003
+++ b/net/ipv6/Makefile	Mon Feb 10 10:39:30 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux TCP/IP (INET6) layer.
 #
 
-export-objs :=  ipv6_syms.o
-
 obj-$(CONFIG_IPV6) += ipv6.o
 
 ipv6-objs :=	af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \
diff -Nru a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
--- a/net/ipv6/netfilter/Makefile	Mon Feb 10 10:39:29 2003
+++ b/net/ipv6/netfilter/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for the netfilter modules on top of IPv6.
 #
 
-export-objs := ip6_tables.o
-
 # Link order matters here.
 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
 obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	Mon Feb 10 10:39:24 2003
+++ b/net/ipv6/netfilter/ip6_queue.c	Mon Feb 10 10:39:24 2003
@@ -538,10 +538,10 @@
 		
 	if (type <= IPQM_BASE)
 		return;
-		
-	if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
-		RCV_SKB_FAIL(-EPERM);
 	
+	if (security_netlink_recv(skb))
+		RCV_SKB_FAIL(-EPERM);	
+
 	write_lock_bh(&queue_lock);
 	
 	if (peer_pid) {
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	Mon Feb 10 10:39:30 2003
+++ b/net/ipv6/route.c	Mon Feb 10 10:39:30 2003
@@ -1548,14 +1548,14 @@
 {
 	struct rtattr **rta = arg;
 	int iif = 0;
-	int err;
+	int err = -ENOBUFS;
 	struct sk_buff *skb;
 	struct flowi fl;
 	struct rt6_info *rt;
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (skb == NULL)
-		return -ENOBUFS;
+		goto out;
 
 	/* Reserve room for dummy headers, this skb can pass
 	   through good chunk of routing engine.
@@ -1579,8 +1579,10 @@
 	if (iif) {
 		struct net_device *dev;
 		dev = __dev_get_by_index(iif);
-		if (!dev)
-			return -ENODEV;
+		if (!dev) {
+			err = -ENODEV;
+			goto out_free;
+		}
 	}
 
 	fl.oif = 0;
@@ -1597,13 +1599,19 @@
 			    fl.nl_u.ip6_u.saddr,
 			    iif,
 			    RTM_NEWROUTE, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq);
-	if (err < 0)
-		return -EMSGSIZE;
+	if (err < 0) {
+		err = -EMSGSIZE;
+		goto out_free;
+	}
 
 	err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
-	if (err < 0)
-		return err;
-	return 0;
+	if (err > 0)
+		err = 0;
+out:
+	return err;
+out_free:
+	kfree_skb(skb);
+	goto out;	
 }
 
 void inet6_rt_notify(int event, struct rt6_info *rt)
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Mon Feb 10 10:39:28 2003
+++ b/net/ipv6/tcp_ipv6.c	Mon Feb 10 10:39:28 2003
@@ -60,7 +60,7 @@
 				  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);
+static int	tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
 
 static struct tcp_func ipv6_mapped;
 static struct tcp_func ipv6_specific;
@@ -934,11 +934,11 @@
 }
 
 static struct or_calltable or_ipv6 = {
-	AF_INET6,
-	tcp_v6_send_synack,
-	tcp_v6_or_send_ack,
-	tcp_v6_or_free,
-	tcp_v6_send_reset
+	.family		=	AF_INET6,
+	.rtx_syn_ack	=	tcp_v6_send_synack,
+	.send_ack	=	tcp_v6_or_send_ack,
+	.destructor	=	tcp_v6_or_free,
+	.send_reset	=	tcp_v6_send_reset
 };
 
 static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
@@ -1470,9 +1470,6 @@
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_opt *tp;
-#ifdef CONFIG_FILTER
-	struct sk_filter *filter;
-#endif
 	struct sk_buff *opt_skb = NULL;
 
 	/* Imagine: socket is IPv6. IPv4 packet arrives,
@@ -1486,11 +1483,8 @@
 	if (skb->protocol == htons(ETH_P_IP))
 		return tcp_v4_do_rcv(sk, skb);
 
-#ifdef CONFIG_FILTER
-	filter = sk->filter;
-	if (filter && sk_filter(skb, filter))
+	if (sk_filter(sk, skb, 0))
 		goto discard;
-#endif /* CONFIG_FILTER */
 
 	/*
 	 *	socket locking is here for SMP purposes as backlog rcv
@@ -1641,6 +1635,9 @@
 	if(sk->state == TCP_TIME_WAIT)
 		goto do_time_wait;
 
+	if (sk_filter(sk, skb, 0))
+		goto discard_and_relse;
+
 	skb->dev = NULL;
 
 	bh_lock_sock(sk);
@@ -1672,6 +1669,10 @@
 	kfree_skb(skb);
 	return 0;
 
+discard_and_relse:
+	sock_put(sk);
+	goto discard_it;
+                
 do_time_wait:
 	if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
 		TCP_INC_STATS_BH(TcpInErrs);
@@ -1746,7 +1747,7 @@
 	return 0;
 }
 
-static int tcp_v6_xmit(struct sk_buff *skb)
+static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
 {
 	struct sock *sk = skb->sk;
 	struct inet_opt *inet = inet_sk(sk);
@@ -1812,18 +1813,18 @@
 }
 
 static struct tcp_func ipv6_specific = {
-	tcp_v6_xmit,
-	tcp_v6_send_check,
-	tcp_v6_rebuild_header,
-	tcp_v6_conn_request,
-	tcp_v6_syn_recv_sock,
-	tcp_v6_remember_stamp,
-	sizeof(struct ipv6hdr),
-
-	ipv6_setsockopt,
-	ipv6_getsockopt,
-	v6_addr2sockaddr,
-	sizeof(struct sockaddr_in6)
+	.queue_xmit	=	tcp_v6_xmit,
+	.send_check	=	tcp_v6_send_check,
+	.rebuild_header	=	tcp_v6_rebuild_header,
+	.conn_request	=	tcp_v6_conn_request,
+	.syn_recv_sock	=	tcp_v6_syn_recv_sock,
+	.remember_stamp	=	tcp_v6_remember_stamp,
+	.net_header_len	=	sizeof(struct ipv6hdr),
+
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	v6_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
 /*
@@ -1831,18 +1832,18 @@
  */
 
 static struct tcp_func ipv6_mapped = {
-	ip_queue_xmit,
-	tcp_v4_send_check,
-	tcp_v4_rebuild_header,
-	tcp_v6_conn_request,
-	tcp_v6_syn_recv_sock,
-	tcp_v4_remember_stamp,
-	sizeof(struct iphdr),
-
-	ipv6_setsockopt,
-	ipv6_getsockopt,
-	v6_addr2sockaddr,
-	sizeof(struct sockaddr_in6)
+	.queue_xmit	=	ip_queue_xmit,
+	.send_check	=	tcp_v4_send_check,
+	.rebuild_header	=	tcp_v4_rebuild_header,
+	.conn_request	=	tcp_v6_conn_request,
+	.syn_recv_sock	=	tcp_v6_syn_recv_sock,
+	.remember_stamp	=	tcp_v4_remember_stamp,
+	.net_header_len	=	sizeof(struct iphdr),
+
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	v6_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
 
@@ -2157,23 +2158,23 @@
 }
 
 struct proto tcpv6_prot = {
-	.name =		"TCPv6",
-	.close =	tcp_close,
-	.connect =	tcp_v6_connect,
-	.disconnect =	tcp_disconnect,
-	.accept =	tcp_accept,
-	.ioctl =	tcp_ioctl,
-	.init =		tcp_v6_init_sock,
-	.destroy =	tcp_v6_destroy_sock,
-	.shutdown =	tcp_shutdown,
-	.setsockopt =	tcp_setsockopt,
-	.getsockopt =	tcp_getsockopt,
-	.sendmsg =	tcp_sendmsg,
-	.recvmsg =	tcp_recvmsg,
-	.backlog_rcv =	tcp_v6_do_rcv,
-	.hash =		tcp_v6_hash,
-	.unhash =	tcp_unhash,
-	.get_port =	tcp_v6_get_port,
+	.name		=	"TCPv6",
+	.close		=	tcp_close,
+	.connect	=	tcp_v6_connect,
+	.disconnect	=	tcp_disconnect,
+	.accept		=	tcp_accept,
+	.ioctl		=	tcp_ioctl,
+	.init		=	tcp_v6_init_sock,
+	.destroy	=	tcp_v6_destroy_sock,
+	.shutdown	=	tcp_shutdown,
+	.setsockopt	=	tcp_setsockopt,
+	.getsockopt	=	tcp_getsockopt,
+	.sendmsg	=	tcp_sendmsg,
+	.recvmsg	=	tcp_recvmsg,
+	.backlog_rcv	=	tcp_v6_do_rcv,
+	.hash		=	tcp_v6_hash,
+	.unhash		=	tcp_unhash,
+	.get_port	=	tcp_v6_get_port,
 };
 
 static struct inet6_protocol tcpv6_protocol = {
@@ -2184,13 +2185,13 @@
 extern struct proto_ops inet6_stream_ops;
 
 static struct inet_protosw tcpv6_protosw = {
-	.type =      SOCK_STREAM,
-	.protocol =  IPPROTO_TCP,
-	.prot =      &tcpv6_prot,
-	.ops =       &inet6_stream_ops,
-	.capability =-1,
-	.no_check =  0,
-	.flags =     INET_PROTOSW_PERMANENT,
+	.type		=	SOCK_STREAM,
+	.protocol	=	IPPROTO_TCP,
+	.prot		=	&tcpv6_prot,
+	.ops		=	&inet6_stream_ops,
+	.capability	=	-1,
+	.no_check	=	0,
+	.flags		=	INET_PROTOSW_PERMANENT,
 };
 
 void __init tcpv6_init(void)
diff -Nru a/net/irda/Kconfig b/net/irda/Kconfig
--- a/net/irda/Kconfig	Mon Feb 10 10:39:27 2003
+++ b/net/irda/Kconfig	Mon Feb 10 10:39:27 2003
@@ -22,7 +22,7 @@
 	  will need to install some OBEX application, such as OpenObex :
 	  <http://sourceforge.net/projects/openobex/>
 
-	  This support is also available as a module called irda.o.  If you
+	  This support is also available as a module called irda.  If you
 	  want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.
 
diff -Nru a/net/irda/Makefile b/net/irda/Makefile
--- a/net/irda/Makefile	Mon Feb 10 10:39:31 2003
+++ b/net/irda/Makefile	Mon Feb 10 10:39:31 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux IrDA protocol layer.
 #
 
-export-objs := irsyms.o
-
 obj-$(CONFIG_IRDA) += irda.o
 obj-$(CONFIG_IRLAN) += irlan/
 obj-$(CONFIG_IRNET) += irnet/
diff -Nru a/net/irda/ircomm/Kconfig b/net/irda/ircomm/Kconfig
--- a/net/irda/ircomm/Kconfig	Mon Feb 10 10:39:23 2003
+++ b/net/irda/ircomm/Kconfig	Mon Feb 10 10:39:23 2003
@@ -3,8 +3,8 @@
 	depends on IRDA
 	help
 	  Say Y here if you want to build support for the IrCOMM protocol.  If
-	  you want to compile it as a module (you will get ircomm.o and
-	  ircomm-tty.o), say M here and read <file:Documentation/modules.txt>.
+	  you want to compile it as a module (you will get ircomm and
+	  ircomm-tty), say M here and read <file:Documentation/modules.txt>.
 	  IrCOMM implements serial port emulation, and makes it possible to
 	  use all existing applications that understands TTY's with an
 	  infrared link.  Thus you should be able to use application like PPP,
diff -Nru a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile
--- a/net/irda/ircomm/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/irda/ircomm/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux IrDA IrCOMM protocol layer.
 #
 
-export-objs := ircomm_core.o
-
 obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o
 
 ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	Mon Feb 10 10:39:24 2003
+++ b/net/irda/iriap.c	Mon Feb 10 10:39:24 2003
@@ -990,7 +990,7 @@
 		len += sprintf(buf+len, "\n");
 
 		/* Careful for priority inversions here !
-		 * All other uses of attrib spinlock are independant of
+		 * All other uses of attrib spinlock are independent of
 		 * the object spinlock, so we are safe. Jean II */
 		spin_lock(&obj->attribs->hb_spinlock);
 
diff -Nru a/net/irda/irlan/Kconfig b/net/irda/irlan/Kconfig
--- a/net/irda/irlan/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/net/irda/irlan/Kconfig	Mon Feb 10 10:39:24 2003
@@ -3,7 +3,7 @@
 	depends on IRDA
 	help
 	  Say Y here if you want to build support for the IrLAN protocol.  If
-	  you want to compile it as a module (irlan.o), say M here and read
+	  you want to compile it as a module (irlan), say M here and read
 	  <file:Documentation/modules.txt>.  IrLAN emulates an Ethernet and
 	  makes it possible to put up a wireless LAN using infrared beams.
 
diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	Mon Feb 10 10:39:32 2003
+++ b/net/irda/irlmp.c	Mon Feb 10 10:39:32 2003
@@ -1623,7 +1623,7 @@
 		ASSERT(lap->magic == LMP_LAP_MAGIC, return TRUE;);
 
 		/* Careful for priority inversions here !
-		 * All other uses of attrib spinlock are independant of
+		 * All other uses of attrib spinlock are independent of
 		 * the object spinlock, so we are safe. Jean II */
 		spin_lock(&lap->lsaps->hb_spinlock);
 
@@ -1786,7 +1786,7 @@
 		len += sprintf(buf+len, "\n");
 
 		/* Careful for priority inversions here !
-		 * All other uses of attrib spinlock are independant of
+		 * All other uses of attrib spinlock are independent of
 		 * the object spinlock, so we are safe. Jean II */
 		spin_lock(&lap->lsaps->hb_spinlock);
 
diff -Nru a/net/irda/irnet/Kconfig b/net/irda/irnet/Kconfig
--- a/net/irda/irnet/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/net/irda/irnet/Kconfig	Mon Feb 10 10:39:29 2003
@@ -3,7 +3,7 @@
 	depends on IRDA && PPP
 	help
 	  Say Y here if you want to build support for the IrNET protocol.  If
-	  you want to compile it as a module (irnet.o), say M here and read
+	  you want to compile it as a module (irnet), say M here and read
 	  <file:Documentation/modules.txt>.  IrNET is a PPP driver, so you
 	  will also need a working PPP subsystem (driver, daemon and
 	  config)...
diff -Nru a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
--- a/net/irda/irnet/irnet.h	Mon Feb 10 10:39:29 2003
+++ b/net/irda/irnet/irnet.h	Mon Feb 10 10:39:29 2003
@@ -284,7 +284,7 @@
 /*
  * This set of flags enable and disable all the various warning,
  * error and debug message of this driver.
- * Each section can be enabled and disabled independantly
+ * Each section can be enabled and disabled independently
  */
 /* In the PPP part */
 #define DEBUG_CTRL_TRACE	0	/* Control channel */
diff -Nru a/net/lapb/Makefile b/net/lapb/Makefile
--- a/net/lapb/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/lapb/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux LAPB layer.
 #
 
-export-objs := lapb_iface.o
-
 obj-$(CONFIG_LAPB) += lapb.o
 
 lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o
diff -Nru a/net/llc/Makefile b/net/llc/Makefile
--- a/net/llc/Makefile	Mon Feb 10 10:39:31 2003
+++ b/net/llc/Makefile	Mon Feb 10 10:39:31 2003
@@ -18,6 +18,3 @@
 	 llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
 	 llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o
 llc-$(CONFIG_LLC_UI)	+= af_llc.o
-
-# Objects that export symbols.
-export-objs := llc_if.o
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	Mon Feb 10 10:39:27 2003
+++ b/net/netlink/af_netlink.c	Mon Feb 10 10:39:27 2003
@@ -42,6 +42,7 @@
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/notifier.h>
+#include <linux/security.h>
 #include <net/sock.h>
 #include <net/scm.h>
 
@@ -636,7 +637,12 @@
 	   check them, when this message will be delivered
 	   to corresponding kernel module.   --ANK (980802)
 	 */
-	NETLINK_CB(skb).eff_cap = current->cap_effective;
+
+	err = security_netlink_send(skb);
+	if (err) {
+		kfree_skb(skb);
+		goto out;
+	}
 
 	err = -EFAULT;
 	if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Mon Feb 10 10:39:26 2003
+++ b/net/netsyms.c	Mon Feb 10 10:39:26 2003
@@ -248,6 +248,8 @@
 EXPORT_SYMBOL(ip_route_output_key);
 EXPORT_SYMBOL(ip_route_input);
 EXPORT_SYMBOL(icmp_send);
+EXPORT_SYMBOL(icmp_statistics);
+EXPORT_SYMBOL(icmp_err_convert);
 EXPORT_SYMBOL(ip_options_compile);
 EXPORT_SYMBOL(ip_options_undo);
 EXPORT_SYMBOL(arp_send);
@@ -427,6 +429,7 @@
 EXPORT_SYMBOL(sysctl_tcp_ecn);
 EXPORT_SYMBOL(tcp_cwnd_application_limited);
 EXPORT_SYMBOL(tcp_sendpage);
+EXPORT_SYMBOL(sysctl_tcp_low_latency);
 
 EXPORT_SYMBOL(tcp_write_xmit);
 
diff -Nru a/net/rxrpc/Makefile b/net/rxrpc/Makefile
--- a/net/rxrpc/Makefile	Mon Feb 10 10:39:29 2003
+++ b/net/rxrpc/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for Linux kernel Rx RPC
 #
 
-export-objs := rxrpc_syms.o
-
 rxrpc-objs := \
 	call.o \
 	connection.o \
diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h
--- a/net/rxrpc/internal.h	Mon Feb 10 10:39:24 2003
+++ b/net/rxrpc/internal.h	Mon Feb 10 10:39:24 2003
@@ -54,9 +54,9 @@
 	while (signal_pending(current)) {
 		siginfo_t sinfo;
 
-		spin_lock_irq(&current->sig->siglock);
+		spin_lock_irq(&current->sighand->siglock);
 		dequeue_signal(&current->blocked,&sinfo);
-		spin_unlock_irq(&current->sig->siglock);
+		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
 
diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c	Mon Feb 10 10:39:23 2003
+++ b/net/rxrpc/krxiod.c	Mon Feb 10 10:39:23 2003
@@ -47,10 +47,10 @@
 	daemonize();
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around waiting for work to do */
 	do {
diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c	Mon Feb 10 10:39:24 2003
+++ b/net/rxrpc/krxsecd.c	Mon Feb 10 10:39:24 2003
@@ -59,10 +59,10 @@
 	daemonize();
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around waiting for work to do */
 	do {
diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c	Mon Feb 10 10:39:23 2003
+++ b/net/rxrpc/krxtimod.c	Mon Feb 10 10:39:23 2003
@@ -77,10 +77,10 @@
 	complete(&krxtimod_alive);
 
 	/* only certain signals are of interest */
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked,0);
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
  loop:
diff -Nru a/net/sched/Kconfig b/net/sched/Kconfig
--- a/net/sched/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/net/sched/Kconfig	Mon Feb 10 10:39:31 2003
@@ -21,7 +21,7 @@
 	  is a routine that allows you to sort your outgoing traffic into
 	  classes based on a certain criterion.
 
-	  This code is also available as a module called sch_cbq.o ( = code
+	  This code is also available as a module called sch_cbq ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -38,7 +38,7 @@
 	  HTB is very similar to the CBQ regarding its goals however is has 
 	  different properties and different algorithm.
 
-	  This code is also available as a module called sch_htb.o ( = code
+	  This code is also available as a module called sch_htb ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -55,7 +55,7 @@
 
 	  Note: this scheduler is currently broken.
 
-	  This code is also available as a module called sch_csz.o ( = code
+	  This code is also available as a module called sch_csz ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -72,7 +72,7 @@
 	  the flow(s) it is handling to a given virtual circuit (see the top of
 	  <file:net/sched/sch_atm.c>).
 
-	  This code is also available as a module called sch_atm.o ( = code
+	  This code is also available as a module called sch_atm ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -85,7 +85,7 @@
 	  "scheduler" for some of your network devices or as a leaf discipline
 	  for the CBQ scheduling algorithm. If unsure, say Y.
 
-	  This code is also available as a module called sch_prio.o ( = code
+	  This code is also available as a module called sch_prio ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -99,7 +99,7 @@
 	  the top of <file:net/sched/sch_red.c> for details and references
 	  about the algorithm).
 
-	  This code is also available as a module called sch_red.o ( = code
+	  This code is also available as a module called sch_red ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -114,7 +114,7 @@
 	  <file:net/sched/sch_sfq.c> for details and references about the SFQ
 	  algorithm).
 
-	  This code is also available as a module called sch_sfq.o ( = code
+	  This code is also available as a module called sch_sfq ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -130,7 +130,7 @@
 	  one virtual device. (see the top of <file:net/sched/sch_teql.c> for
 	  details).
 
-	  This code is also available as a module called sch_teql.o ( = code
+	  This code is also available as a module called sch_teql ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -144,7 +144,7 @@
 	  leaf discipline for the CBQ scheduling algorithm (see the top of
 	  <file:net/sched/sch_tbf.c> for a description of the TBF algorithm).
 
-	  This code is also available as a module called sch_tbf.o ( = code
+	  This code is also available as a module called sch_tbf ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -158,7 +158,7 @@
 	  (see the top of <file:net/sched/sch_red.c> for details and
 	  references about the algorithm).
 
-	  This code is also available as a module called sch_gred.o ( = code
+	  This code is also available as a module called sch_gred ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -172,7 +172,7 @@
 	  Technical information on this method, with pointers to associated
 	  RFCs, is available at <http://www.gta.ufrj.br/diffserv/>.
 
-	  This code is also available as a module called sch_dsmark.o ( = code
+	  This code is also available as a module called sch_dsmark ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -185,7 +185,7 @@
 	  and drop packets when this bandwidth exceeds your desired rate.
 	  If unsure, say Y.
 
-	  This code is also available as a module called cls_ingress.o
+	  This code is also available as a module called cls_ingress
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want).  If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
@@ -240,7 +240,7 @@
 	  feature if you want to implement Differentiated Services using
 	  sch_dsmark. If unsure, say Y.
 
-	  This code is also available as a module called cls_tcindex.o
+	  This code is also available as a module called cls_tcindex
 	  ( = code which can be inserted in and removed from the running
 	  kernel whenever you want). If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>.
@@ -252,7 +252,7 @@
 	  If you say Y here, you will be able to classify outgoing packets
 	  according to the route table entry they matched. If unsure, say Y.
 
-	  This code is also available as a module called cls_route.o ( = code
+	  This code is also available as a module called cls_route ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -269,7 +269,7 @@
 	  If you say Y here, you will be able to classify outgoing packets
 	  according to firewall criteria you specified.
 
-	  This code is also available as a module called cls_fw.o ( = code
+	  This code is also available as a module called cls_fw ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -281,7 +281,7 @@
 	  If you say Y here, you will be able to classify outgoing packets
 	  according to their destination address. If unsure, say Y.
 
-	  This code is also available as a module called cls_u32.o ( = code
+	  This code is also available as a module called cls_u32 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -297,7 +297,7 @@
 	  Say Y here if you want to be able to classify outgoing packets based
 	  on their RSVP requests.
 
-	  This code is also available as a module called cls_rsvp.o ( = code
+	  This code is also available as a module called cls_rsvp ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -314,7 +314,7 @@
 	  on their RSVP requests and you are using the new Internet Protocol
 	  IPv6 as opposed to the older and more common IPv4.
 
-	  This code is also available as a module called cls_rsvp6.o ( = code
+	  This code is also available as a module called cls_rsvp6 ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want).  If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	Mon Feb 10 10:39:29 2003
+++ b/net/sched/sch_htb.c	Mon Feb 10 10:39:29 2003
@@ -19,7 +19,7 @@
  *			created test case so that I was able to fix nasty bug
  *		and many others. thanks.
  *
- * $Id: sch_htb.c,v 1.14 2002/09/28 12:55:22 devik Exp devik $
+ * $Id: sch_htb.c,v 1.17 2003/01/29 09:22:18 devik Exp devik $
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -71,16 +71,12 @@
 #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
 #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
 #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x30007	/* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x3000a	/* major must be matched with number suplied by TC as version */
 
 #if HTB_VER >> 16 != TC_HTB_PROTOVER
 #error "Mismatched sch_htb.c and pkt_sch.h"
 #endif
 
-/* temporary debug defines to be removed after beta stage */
-#define DEVIK_MEND(N)
-#define DEVIK_MSTART(N)
-
 /* debugging support; S is subsystem, these are defined:
   0 - netlink messages
   1 - enqueue
@@ -421,7 +417,6 @@
 	if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit())
 		printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint);
 #endif
-	DEVIK_MSTART(9);
 	cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay);
 	if (cl->pq_key == jiffies)
 		cl->pq_key++;
@@ -440,7 +435,6 @@
 	}
 	rb_link_node(&cl->pq_node, parent, p);
 	rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]);
-	DEVIK_MEND(9);
 }
 
 /**
@@ -678,7 +672,6 @@
     struct htb_sched *q = (struct htb_sched *)sch->data;
     struct htb_class *cl = htb_classify(skb,sch);
 
-    DEVIK_MSTART(0);
     if (cl == HTB_DIRECT || !cl) {
 	/* enqueue to helper queue */
 	if (q->direct_queue.qlen < q->direct_qlen && cl) {
@@ -687,25 +680,20 @@
 	} else {
 	    kfree_skb (skb);
 	    sch->stats.drops++;
-	    DEVIK_MEND(0);
 	    return NET_XMIT_DROP;
 	}
     } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
 	sch->stats.drops++;
 	cl->stats.drops++;
-	DEVIK_MEND(0);
 	return NET_XMIT_DROP;
     } else {
 	cl->stats.packets++; cl->stats.bytes += skb->len;
-	DEVIK_MSTART(1);
 	htb_activate (q,cl);
-	DEVIK_MEND(1);
     }
 
     sch->q.qlen++;
     sch->stats.packets++; sch->stats.bytes += skb->len;
     HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
-    DEVIK_MEND(0);
     return NET_XMIT_SUCCESS;
 }
 
@@ -941,7 +929,6 @@
 	//struct htb_sched *q = (struct htb_sched *)sch->data;
 	struct htb_class *cl,*start;
 	/* look initial class up in the row */
-	DEVIK_MSTART(6);
 	start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
 	
 	do {
@@ -960,8 +947,6 @@
 		cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
 	} while (cl != start);
 
-	DEVIK_MEND(6);
-	DEVIK_MSTART(7);
 	if (likely(skb != NULL)) {
 		if ((cl->un.leaf.deficit[level] -= skb->len) < 0) {
 			HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n",
@@ -973,11 +958,8 @@
 		   gives us slightly better performance */
 		if (!cl->un.leaf.q->q.qlen)
 			htb_deactivate (q,cl);
-	DEVIK_MSTART(8);
 		htb_charge_class (q,cl,level,skb->len);
-	DEVIK_MEND(8);
 	}
-	DEVIK_MEND(7);
 	return skb;
 }
 
@@ -1005,6 +987,9 @@
 	struct htb_sched *q = (struct htb_sched *)sch->data;
 	int level;
 	long min_delay;
+#ifdef HTB_DEBUG
+	int evs_used = 0;
+#endif
 
 	HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue),
 			sch->q.qlen);
@@ -1016,27 +1001,26 @@
 		return skb;
 	}
 
-	DEVIK_MSTART(2);
 	if (!sch->q.qlen) goto fin;
 	PSCHED_GET_TIME(q->now);
 
-	min_delay = HZ*5;
+	min_delay = LONG_MAX;
 	q->nwc_hit = 0;
 	for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
 		/* common case optimization - skip event handler quickly */
 		int m;
 		long delay;
-	DEVIK_MSTART(3);
 		if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
 			delay = htb_do_events(q,level);
 			q->near_ev_cache[level] += delay ? delay : HZ;
+#ifdef HTB_DEBUG
+			evs_used++;
+#endif
 		} else
 			delay = q->near_ev_cache[level] - jiffies;	
 		
 		if (delay && min_delay > delay) 
 			min_delay = delay;
-	DEVIK_MEND(3);
-	DEVIK_MSTART(5);
 		m = ~q->row_mask[level];
 		while (m != (int)(-1)) {
 			int prio = ffz (m);
@@ -1045,24 +1029,24 @@
 			if (likely(skb != NULL)) {
 				sch->q.qlen--;
 				sch->flags &= ~TCQ_F_THROTTLED;
-	DEVIK_MEND(5);
 				goto fin;
 			}
 		}
-	DEVIK_MEND(5);
 	}
-	DEVIK_MSTART(4);
 #ifdef HTB_DEBUG
-	if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { 
-		printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay);
-		htb_debug_dump(q);
+	if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) {
+		if (min_delay == LONG_MAX) {
+			printk(KERN_ERR "HTB: dequeue bug (%d), report it please !\n",
+					evs_used);
+			htb_debug_dump(q);
+		} else 
+			printk(KERN_WARNING "HTB: mindelay=%ld, some class has "
+					"too small rate\n",min_delay);
 	}
 #endif
-	htb_delay_by (sch,min_delay);
-	DEVIK_MEND(4);
+	htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay);
 fin:
 	HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb);
-	DEVIK_MEND(2);
 	return skb;
 }
 
@@ -1433,6 +1417,7 @@
 	if (!rtab || !ctab) goto failure;
 
 	if (!cl) { /* new class */
+		struct Qdisc *new_q;
 		/* check for valid classid */
 		if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch))
 			goto failure;
@@ -1456,6 +1441,10 @@
 		cl->magic = HTB_CMAGIC;
 #endif
 
+		/* create leaf qdisc early because it uses kmalloc(GPF_KERNEL)
+		   so that can't be used inside of sch_tree_lock
+		   -- thanks to Karlis Peisenieks */
+		new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
 		sch_tree_lock(sch);
 		if (parent && !parent->level) {
 			/* turn parent into inner node */
@@ -1474,8 +1463,7 @@
 			memset (&parent->un.inner,0,sizeof(parent->un.inner));
 		}
 		/* leaf (we) needs elementary qdisc */
-		if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
-			cl->un.leaf.q = &noop_qdisc;
+		cl->un.leaf.q = new_q ? new_q : &noop_qdisc;
 
 		cl->classid = classid; cl->parent = parent;
 
@@ -1503,11 +1491,11 @@
 	if (!cl->level) {
 		cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
 		if (!hopt->quantum && cl->un.leaf.quantum < 1000) {
-			printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid);
+			printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.\n", cl->classid);
 			cl->un.leaf.quantum = 1000;
 		}
 		if (!hopt->quantum && cl->un.leaf.quantum > 200000) {
-			printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid);
+			printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.\n", cl->classid);
 			cl->un.leaf.quantum = 200000;
 		}
 		if (hopt->quantum)
diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig
--- a/net/sctp/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/net/sctp/Kconfig	Mon Feb 10 10:39:24 2003
@@ -34,7 +34,7 @@
 
 	  This protocol support is also available as a module ( = code which
 	  can be inserted in and removed from the running kernel whenever you
-	  want). The module will be called sctp.o. If you want to compile it
+	  want). The module will be called sctp. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 	  If in doubt, say N.
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	Mon Feb 10 10:39:23 2003
+++ b/net/sctp/input.c	Mon Feb 10 10:39:23 2003
@@ -159,6 +159,10 @@
 	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_release;
 
+	ret = sk_filter(sk, skb, 1);
+	if (ret)
+                goto discard_release;
+
 	/* Create an SCTP packet structure. */
 	chunk = sctp_chunkify(skb, asoc, sk);
 	if (!chunk) {
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Mon Feb 10 10:39:24 2003
+++ b/net/socket.c	Mon Feb 10 10:39:24 2003
@@ -77,6 +77,7 @@
 #include <linux/highmem.h>
 #include <linux/divert.h>
 #include <linux/mount.h>
+#include <linux/security.h>
 
 #if defined(CONFIG_KMOD) && defined(CONFIG_NET)
 #include <linux/kmod.h>
@@ -527,6 +528,10 @@
 	si->msg = msg;
 	si->size = size;
 
+	err = security_socket_sendmsg(sock, msg, size);
+	if (err)
+		return err;
+
 	err = scm_send(sock, msg, si->scm);
 	if (err >= 0) {
 		err = sock->ops->sendmsg(iocb, sock, msg, size, si->scm);
@@ -551,6 +556,7 @@
 
 int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int size, int flags)
 {
+	int err;
 	struct sock_iocb *si = kiocb_to_siocb(iocb);
 
 	si->sock = sock;
@@ -560,6 +566,10 @@
 	si->size = size;
 	si->flags = flags;
 
+	err = security_socket_recvmsg(sock, msg, size, flags);
+	if (err)
+		return err;
+
 	memset(si->scm, 0, sizeof(*si->scm));
 
 	size = sock->ops->recvmsg(iocb, sock, msg, size, flags, si->scm);
@@ -963,6 +973,7 @@
 int sock_create(int family, int type, int protocol, struct socket **res)
 {
 	int i;
+	int err;
 	struct socket *sock;
 
 	/*
@@ -986,6 +997,10 @@
 		}
 		family = PF_PACKET;
 	}
+
+	err = security_socket_create(family, type, protocol);
+	if (err)
+		return err;
 		
 #if defined(CONFIG_KMOD) && defined(CONFIG_NET)
 	/* Attempt to load a protocol module if the find failed. 
@@ -1031,6 +1046,7 @@
 	}
 
 	*res = sock;
+	security_socket_post_create(sock, family, type, protocol);
 
 out:
 	net_family_read_unlock();
@@ -1141,8 +1157,14 @@
 
 	if((sock = sockfd_lookup(fd,&err))!=NULL)
 	{
-		if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
+		if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
+			err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
+			if (err) {
+				sockfd_put(sock);
+				return err;
+			}
 			err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
+		}
 		sockfd_put(sock);
 	}			
 	return err;
@@ -1163,6 +1185,13 @@
 	if ((sock = sockfd_lookup(fd, &err)) != NULL) {
 		if ((unsigned) backlog > SOMAXCONN)
 			backlog = SOMAXCONN;
+
+		err = security_socket_listen(sock, backlog);
+		if (err) {
+			sockfd_put(sock);
+			return err;
+		}
+
 		err=sock->ops->listen(sock, backlog);
 		sockfd_put(sock);
 	}
@@ -1199,6 +1228,10 @@
 	newsock->type = sock->type;
 	newsock->ops = sock->ops;
 
+	err = security_socket_accept(sock, newsock);
+	if (err)
+		goto out_release;
+
 	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
 	if (err < 0)
 		goto out_release;
@@ -1218,6 +1251,8 @@
 	if ((err = sock_map_fd(newsock)) < 0)
 		goto out_release;
 
+	security_socket_post_accept(sock, newsock);
+
 out_put:
 	sockfd_put(sock);
 out:
@@ -1253,6 +1288,11 @@
 	err = move_addr_to_kernel(uservaddr, addrlen, address);
 	if (err < 0)
 		goto out_put;
+
+	err = security_socket_connect(sock, (struct sockaddr *)address, addrlen);
+	if (err)
+		goto out_put;
+
 	err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
 				 sock->file->f_flags);
 out_put:
@@ -1275,6 +1315,11 @@
 	sock = sockfd_lookup(fd, &err);
 	if (!sock)
 		goto out;
+
+	err = security_socket_getsockname(sock);
+	if (err)
+		goto out_put;
+
 	err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
 	if (err)
 		goto out_put;
@@ -1299,6 +1344,12 @@
 
 	if ((sock = sockfd_lookup(fd, &err))!=NULL)
 	{
+		err = security_socket_getpeername(sock);
+		if (err) {
+			sockfd_put(sock);
+			return err;
+		}
+
 		err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
 		if (!err)
 			err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
@@ -1427,6 +1478,12 @@
 			
 	if ((sock = sockfd_lookup(fd, &err))!=NULL)
 	{
+		err = security_socket_setsockopt(sock,level,optname);
+		if (err) {
+			sockfd_put(sock);
+			return err;
+		}
+
 		if (level == SOL_SOCKET)
 			err=sock_setsockopt(sock,level,optname,optval,optlen);
 		else
@@ -1448,6 +1505,13 @@
 
 	if ((sock = sockfd_lookup(fd, &err))!=NULL)
 	{
+		err = security_socket_getsockopt(sock, level, 
+							   optname);
+		if (err) {
+			sockfd_put(sock);
+			return err;
+		}
+
 		if (level == SOL_SOCKET)
 			err=sock_getsockopt(sock,level,optname,optval,optlen);
 		else
@@ -1469,6 +1533,12 @@
 
 	if ((sock = sockfd_lookup(fd, &err))!=NULL)
 	{
+		err = security_socket_shutdown(sock, how);
+		if (err) {
+			sockfd_put(sock);
+			return err;
+		}
+				
 		err=sock->ops->shutdown(sock, how);
 		sockfd_put(sock);
 	}
diff -Nru a/net/sunrpc/Makefile b/net/sunrpc/Makefile
--- a/net/sunrpc/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/sunrpc/Makefile	Mon Feb 10 10:39:23 2003
@@ -6,8 +6,6 @@
 
 obj-$(CONFIG_SUNRPC) += sunrpc.o
 
-export-objs := sunrpc_syms.o
-
 sunrpc-y := clnt.o xprt.o sched.o \
 	    auth.o auth_null.o auth_unix.o \
 	    svc.o svcsock.o svcauth.o svcauth_unix.o \
diff -Nru a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
--- a/net/sunrpc/auth_gss/Makefile	Mon Feb 10 10:39:26 2003
+++ b/net/sunrpc/auth_gss/Makefile	Mon Feb 10 10:39:26 2003
@@ -4,8 +4,6 @@
 
 obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o
 
-export-objs := sunrpcgss_syms.o
-
 auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \
 	sunrpcgss_syms.o gss_mech_switch.o
 
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c	Mon Feb 10 10:39:23 2003
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c	Mon Feb 10 10:39:23 2003
@@ -78,7 +78,7 @@
 	sg[0].offset = ((long)out & ~PAGE_MASK);
 	sg[0].length = length;
 
-	ret = crypto_cipher_encrypt(tfm, sg, 1);
+	ret = crypto_cipher_encrypt(tfm, sg, sg, length);
 
 out:
 	dprintk("gss_k5encrypt returns %d\n",ret);
@@ -117,7 +117,7 @@
 	sg[0].offset = ((long)out  & ~PAGE_MASK);
 	sg[0].length = length;
 
-	ret = crypto_cipher_decrypt(tfm, sg, 1);
+	ret = crypto_cipher_decrypt(tfm, sg, sg, length);
 
 out:
 	dprintk("gss_k5decrypt returns %d\n",ret);
diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c	Mon Feb 10 10:39:25 2003
+++ b/net/sunrpc/clnt.c	Mon Feb 10 10:39:25 2003
@@ -233,27 +233,27 @@
 	
 	/* Turn off various signals */
 	if (clnt->cl_intr) {
-		struct k_sigaction *action = current->sig->action;
+		struct k_sigaction *action = current->sighand->action;
 		if (action[SIGINT-1].sa.sa_handler == SIG_DFL)
 			sigallow |= sigmask(SIGINT);
 		if (action[SIGQUIT-1].sa.sa_handler == SIG_DFL)
 			sigallow |= sigmask(SIGQUIT);
 	}
-	spin_lock_irqsave(&current->sig->siglock, irqflags);
+	spin_lock_irqsave(&current->sighand->siglock, irqflags);
 	*oldset = current->blocked;
 	siginitsetinv(&current->blocked, sigallow & ~oldset->sig[0]);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+	spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
 }
 
 void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
 {
 	unsigned long	irqflags;
 	
-	spin_lock_irqsave(&current->sig->siglock, irqflags);
+	spin_lock_irqsave(&current->sighand->siglock, irqflags);
 	current->blocked = *oldset;
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, irqflags);
+	spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
 }
 
 /*
diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c
--- a/net/sunrpc/sched.c	Mon Feb 10 10:39:27 2003
+++ b/net/sunrpc/sched.c	Mon Feb 10 10:39:27 2003
@@ -964,10 +964,10 @@
 
 	daemonize();
 
-	spin_lock_irq(&current->sig->siglock);
+	spin_lock_irq(&current->sighand->siglock);
 	siginitsetinv(&current->blocked, sigmask(SIGKILL));
 	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
+	spin_unlock_irq(&current->sighand->siglock);
 
 	strcpy(current->comm, "rpciod");
 
@@ -1022,9 +1022,9 @@
 		}
 	}
 
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
 /*
@@ -1100,9 +1100,9 @@
 		}
 		interruptible_sleep_on(&rpciod_killer);
 	}
-	spin_lock_irqsave(&current->sig->siglock, flags);
+	spin_lock_irqsave(&current->sighand->siglock, flags);
 	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sig->siglock, flags);
+	spin_unlock_irqrestore(&current->sighand->siglock, flags);
 out:
 	up(&rpciod_sema);
 	MOD_DEC_USE_COUNT;
diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c
--- a/net/sunrpc/svc.c	Mon Feb 10 10:39:32 2003
+++ b/net/sunrpc/svc.c	Mon Feb 10 10:39:32 2003
@@ -235,9 +235,9 @@
 	}
 
 	if (!port) {
-		spin_lock_irqsave(&current->sig->siglock, flags);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
 		recalc_sigpending();
-		spin_unlock_irqrestore(&current->sig->siglock, flags);
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
 	}
 
 	return error;
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	Mon Feb 10 10:39:29 2003
+++ b/net/unix/af_unix.c	Mon Feb 10 10:39:29 2003
@@ -115,6 +115,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/mount.h>
 #include <net/checksum.h>
+#include <linux/security.h>
 
 int sysctl_unix_max_dgram_qlen = 10;
 
@@ -816,6 +817,11 @@
 		err = -EPERM;
 		if (!unix_may_send(sk, other))
 			goto out_unlock;
+
+		err = security_unix_may_send(sk->socket, other->socket);
+		if (err)
+			goto out_unlock;
+
 	} else {
 		/*
 		 *	1003.1g breaking connected state with AF_UNSPEC
@@ -981,6 +987,12 @@
 		goto restart;
 	}
 
+	err = security_unix_stream_connect(sock, other->socket, newsk);
+	if (err) {
+		unix_state_wunlock(sk);
+		goto out_unlock;
+	}
+
 	/* The way is open! Fastly set all the necessary fields... */
 
 	sock_hold(sk);
@@ -1278,6 +1290,10 @@
 
 	err = -EPIPE;
 	if (other->shutdown&RCV_SHUTDOWN)
+		goto out_unlock;
+
+	err = security_unix_may_send(sk->socket, other->socket);
+	if (err)
 		goto out_unlock;
 
 	if (unix_peer(other) != sk &&
diff -Nru a/net/wanrouter/Makefile b/net/wanrouter/Makefile
--- a/net/wanrouter/Makefile	Mon Feb 10 10:39:23 2003
+++ b/net/wanrouter/Makefile	Mon Feb 10 10:39:23 2003
@@ -2,8 +2,6 @@
 # Makefile for the Linux WAN router layer.
 #
 
-export-objs := wanmain.o
-
 obj-$(CONFIG_WAN_ROUTER) += wanrouter.o
 
 wanrouter-objs :=  wanproc.o wanmain.o
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Mon Feb 10 10:39:31 2003
+++ b/scripts/Makefile.build	Mon Feb 10 10:39:31 2003
@@ -15,8 +15,12 @@
 
 include scripts/Makefile.lib
 
+ifdef export-objs
+$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.5. Please fix!)
+endif
+
 ifdef O_TARGET
-$(error kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.5. Please fix!)
+$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.5. Please fix!)
 endif
 
 ifdef L_TARGET
@@ -45,11 +49,66 @@
 endif
 endif
 
+ifdef CONFIG_MODVERSIONS
+modules := $(obj-m)
+touch-module = @echo $(@:.o=.ko) > .tmp_versions/$(@F:.o=.mod)
+else
+modules := $(obj-m:.o=.ko)
+endif
+
 __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
-	 $(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \
+	 $(if $(KBUILD_MODULES),$(modules)) \
 	 $(subdir-ym) $(build-targets)
 	@:
 
+# Module versioning
+# ---------------------------------------------------------------------------
+
+ifdef CONFIG_MODVERSIONS
+
+# $(call if_changed_rule,vcc_o_c) does essentially the same as the
+# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file
+# from a C file, keeping track of the command line and dependencies.
+#
+# However, actually it does:
+# o compile a .tmp_<file>.o from <file>.c
+# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
+#   not export symbols, we just rename .tmp_<file>.o to <file>.o and
+#   are done.
+# o otherwise, we calculate symbol versions using the good old
+#   genksyms on the preprocessed source and postprocess them in a way
+#   that they are usable as a linker script
+# o generate <file>.o from .tmp_<file>.o using the linker to
+#   replace the unresolved symbols __crc_exported_symbol with
+#   the actual value of the checksum generated by genksyms
+
+quiet_cmd_vcc_o_c = CC $(quiet_modtag)  $@
+cmd_vcc_o_c       = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
+
+define rule_vcc_o_c
+	$(if $($(quiet)cmd_vcc_o_c),echo '  $($(quiet)cmd_vcc_o_c)';)	      \
+	$(cmd_vcc_o_c);							      \
+									      \
+	if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	      \
+		mv $(@D)/.tmp_$(@F) $@;					      \
+	else								      \
+		$(CPP) -D__GENKSYMS__ $(c_flags) $<			      \
+		| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)	      \
+		| sed -n 's/\#define __ver_\(\w*\)\W*\(\w*\)/__crc_\1 = 0x\2 ;/gp' \
+		> $(@D)/.tmp_$(@F:.o=.ver);				      \
+									      \
+		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		      \
+			-T $(@D)/.tmp_$(@F:.o=.ver);			      \
+		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);	      \
+	fi;			
+					      \
+	scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp;     \
+	rm -f $(depfile);						      \
+	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
+endef
+
+endif
+
 # Compile C sources (.c)
 # ---------------------------------------------------------------------------
 
@@ -69,11 +128,6 @@
 
 $(obj-m)              : quiet_modtag := [M]
 
-$(export-objs)        : export_flags   := $(EXPORT_FLAGS)
-$(export-objs:.o=.i)  : export_flags   := $(EXPORT_FLAGS)
-$(export-objs:.o=.s)  : export_flags   := $(EXPORT_FLAGS)
-$(export-objs:.o=.lst): export_flags   := $(EXPORT_FLAGS)
-
 # Default for not multi-part modules
 modname = $(*F)
 
@@ -102,7 +156,20 @@
 cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
 
 %.o: %.c FORCE
+ifdef CONFIG_MODVERSIONS
+	$(call if_changed_rule,vcc_o_c)
+else
 	$(call if_changed_dep,cc_o_c)
+endif
+
+# For modversioning, we need to special case single-part modules
+# to mark them in $(MODVERDIR)
+
+ifdef CONFIG_MODVERSIONS
+$(single-used-m): %.o: %.c FORCE
+	$(touch-module)
+	$(call if_changed_rule,vcc_o_c)
+endif
 
 quiet_cmd_cc_lst_c = MKLST   $@
       cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
@@ -147,7 +214,7 @@
 quiet_cmd_link_o_target = LD      $@
 # If the list of objects to link is empty, just create an empty O_TARGET
 cmd_link_o_target = $(if $(strip $(obj-y)),\
-		      $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^),\
+		      $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
 		      rm -f $@; $(AR) rcs $@)
 
 $(O_TARGET): $(obj-y) FORCE
@@ -172,19 +239,20 @@
 #
 # Rule to link composite objects
 #
+#  Composite objects are specified in kbuild makefile as follows:
+#    <composite-object>-objs := <list of .o files>
+#  or
+#    <composite-object>-y    := <list of .o files>
+link_multi_deps =                     \
+$(filter $(addprefix $(obj)/,         \
+$($(subst $(obj)/,,$(@:.o=-objs)))    \
+$($(subst $(obj)/,,$(@:.o=-y)))), $^)
+ 
 quiet_cmd_link_multi-y = LD      $@
-cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
+cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
 
 quiet_cmd_link_multi-m = LD [M]  $@
-cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o
-
-quiet_cmd_link_single-m = LD [M]  $@
-cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o
-
-# Don't rebuilt vermagic.o unless we actually are in the init/ dir
-ifneq ($(obj),init)
-init/vermagic.o: ;
-endif
+cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
 
 # We would rather have a list of rules like
 # 	foo.o: $(foo-objs)
@@ -193,13 +261,34 @@
 $(multi-used-y) : %.o: $(multi-objs-y) FORCE
 	$(call if_changed,link_multi-y)
 
-$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE
+$(multi-used-m) : %.o: $(multi-objs-m) FORCE
+	$(touch-module)
 	$(call if_changed,link_multi-m)
 
-$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE
-	$(call if_changed,link_single-m)
+targets += $(multi-used-y) $(multi-used-m)
+
+#
+# Rule to link modules ( .o -> .ko )
+#
+
+# With CONFIG_MODVERSIONS, generation of the final .ko is handled
+# by scripts/Makefile.modver
+ifndef CONFIG_MODVERSIONS
 
-targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko)
+quiet_cmd_link_module = LD [M]  $@
+cmd_link_module = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o
+
+# Don't rebuilt vermagic.o unless we actually are in the init/ dir
+ifneq ($(obj),init)
+init/vermagic.o: ;
+endif
+
+$(single-used-m:.o=.ko) $(multi-used-m:.o=.ko): %.ko: %.o init/vermagic.o FORCE
+	$(call if_changed,link_module)
+
+targets += $(single-used-m:.o=.ko) $(multi-used-m:.o=.ko)
+
+endif
 
 # Compile programs on the host
 # ===========================================================================
diff -Nru a/scripts/Makefile.lib b/scripts/Makefile.lib
--- a/scripts/Makefile.lib	Mon Feb 10 10:39:27 2003
+++ b/scripts/Makefile.lib	Mon Feb 10 10:39:27 2003
@@ -34,14 +34,9 @@
 
 subdir-ym	:= $(sort $(subdir-y) $(subdir-m))
 
-# export.o is never a composite object, since $(export-objs) has a
-# fixed meaning (== objects which EXPORT_SYMBOL())
-__obj-y = $(filter-out export.o,$(obj-y))
-__obj-m = $(filter-out export.o,$(obj-m))
-
 # if $(foo-objs) exists, foo.o is a composite object 
-multi-used-y := $(sort $(foreach m,$(__obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
-multi-used-m := $(sort $(foreach m,$(__obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
+multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
+multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
 multi-used   := $(multi-used-y) $(multi-used-m)
 single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
 
@@ -59,9 +54,6 @@
 real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(EXTRA_TARGETS)
 real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
 
-# Only build module versions for files which are selected to be built
-export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m))
-
 # C code
 # Executables compiled from a single .c file
 host-csingle	:= $(foreach m,$(host-progs),$(if $($(m)-objs),,$(m)))
@@ -96,7 +88,6 @@
 build-targets	:= $(addprefix $(obj)/,$(build-targets))
 obj-y		:= $(addprefix $(obj)/,$(obj-y))
 obj-m		:= $(addprefix $(obj)/,$(obj-m))
-export-objs	:= $(addprefix $(obj)/,$(export-objs))
 subdir-obj-y	:= $(addprefix $(obj)/,$(subdir-obj-y))
 real-objs-y	:= $(addprefix $(obj)/,$(real-objs-y))
 real-objs-m	:= $(addprefix $(obj)/,$(real-objs-m))
@@ -130,13 +121,14 @@
 modname_flags  = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
 c_flags        = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
 	         $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
-	         $(basename_flags) $(modname_flags) $(export_flags) 
+	         $(basename_flags) $(modname_flags)
 a_flags        = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\
 		 $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
 hostc_flags    = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\
 		 $(HOSTCFLAGS_$(*F).o)
 hostcxx_flags  = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\
 		 $(HOSTCXXFLAGS_$(*F).o)
+ld_flags       = $(LDFLAGS) $(EXTRA_LDFLAGS)
 
 # Finds the multi-part object the current object will be linked into
 modname-multi = $(sort $(foreach m,$(multi-used),\
@@ -217,7 +209,6 @@
 		               $(filter-out $(cmd_$(1)),$(cmd_$@))\
 			       $(filter-out $(cmd_$@),$(cmd_$(1)))),\
 			@set -e; \
-			mkdir -p $(dir $@); \
 			$(rule_$(1)))
 
 # If quiet is set, only print short version of command
diff -Nru a/scripts/Makefile.modver b/scripts/Makefile.modver
--- a/scripts/Makefile.modver	Mon Feb 10 10:39:25 2003
+++ b/scripts/Makefile.modver	Mon Feb 10 10:39:25 2003
@@ -2,105 +2,87 @@
 # Module versions
 # ===========================================================================
 
-src := $(obj)
+.PHONY: __modversions
+__modversions:
 
-MODVERDIR := include/linux/modules
+include scripts/Makefile.lib
 
-.PHONY: modver
-modver:
+#
 
-include .config
+__modules := $(shell cd $(MODVERDIR); cat *.mod)
+modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
 
-include $(obj)/Makefile
+ifneq ($(filter-out $(modules),$(__modules)),)
+  $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS, don't complain if something goes wrong.)
+endif
 
-include scripts/Makefile.lib
+__modversions: $(modules)
+	@:
 
-# ===========================================================================
+# The final module link
 
-ifeq ($(strip $(export-objs)),)
+quiet_cmd_ld_ko_o = LD [M]  $@
+      cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ 		\
+			  $(filter-out FORCE,$^)
 
-# If we don't export any symbols in this dir, just descend
-# ---------------------------------------------------------------------------
+init/vermagic.o: ;
 
-modver: $(subdir-ym)
-	@:
+$(modules): %.ko :%.o %.ver.o init/vermagic.o FORCE
+	$(call if_changed,ld_ko_o)
 
-else
+targets += $(modules)
 
-# This sets version suffixes on exported symbols
-# ---------------------------------------------------------------------------
+# Compile version info for unresolved symbols
 
-#
-# Added the SMP separator to stop module accidents between uniprocessor
-# and SMP Intel boxes - AC - from bits by Michael Chastain
-#
+quiet_cmd_cc_o_c = CC      $@
+      cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $<
 
-ifdef CONFIG_SMP
-	genksyms_smp_prefix := -p smp_
-else
-	genksyms_smp_prefix := 
-endif
+$(modules:.ko=.ver.o): %.ver.o: %.ver.c FORCE
+	$(call if_changed,cc_o_c)
 
-#	Don't include modversions.h, we're just about to generate it here.
+targets += $(modules:.ko=.ver.o)
 
-CFLAGS_MODULE := $(filter-out -include include/linux/modversions.h,$(CFLAGS_MODULE))
+# Generate C source with version info for unresolved symbols
 
-$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL)
-$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE)
-$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags   := -D__GENKSYMS__
-# Default for not multi-part modules
-modname = $(*F)
-
-$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi)
-
-# Our objects only depend on modversions.h, not on the individual .ver
-# files (fix-dep filters them), so touch modversions.h if any of the .ver
-# files changes
-
-quiet_cmd_cc_ver_c = MKVER   include/linux/modules/$*.ver
-cmd_cc_ver_c = $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \
-		 -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp
-
-# Okay, let's explain what's happening in rule_make_cc_ver_c:
-# o echo the command
-# o execute the command
-# o If the $(CPP) fails, we won't notice because it's output is piped
-#   to $(GENKSYMS) which does not fail. We recognize this case by
-#   looking if the generated $(depfile) exists, though.
-# o If the .ver file changed, touch modversions.h, which is our marker
-#   of any changed .ver files.
-# o Move command line and deps into their normal .*.cmd place.  
-
-define rule_cc_ver_c
-	$(if $($(quiet)cmd_cc_ver_c),echo '  $($(quiet)cmd_cc_ver_c)';) \
-	$(cmd_cc_ver_c); \
-	if [ ! -r $(depfile) ]; then exit 1; fi; \
-	scripts/fixdep $(depfile) $@ '$(cmd_cc_ver_c)' > $(@D)/.$(@F).tmp; \
-	rm -f $(depfile); \
-	if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \
-	  touch include/linux/modversions.h; \
-	fi; \
-	mv -f $@.tmp $@
-	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
+define rule_mkver_o_c
+	echo '  MKVER   $@';						\
+	( echo "#include <linux/module.h>";				\
+	  echo "";							\
+	  echo "static const struct modversion_info ____versions[]";	\
+	  echo "__attribute__((section(\"__versions\"))) = {"; 	\
+	  for sym in `nm -u $<`; do					\
+		grep "\"$$sym\"" .tmp_all-versions			\
+		|| echo "*** Warning: $(<:.o=.ko): \"$$sym\" unresolved!" >&2;\
+	  done;								\
+	  echo "};";							\
+	) > $@
 endef
 
-targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver))
+$(modules:.ko=.ver.c): %.ver.c: %.o .tmp_all-versions FORCE
+	$(call if_changed_rule,mkver_o_c)
 
-$(MODVERDIR)/%.ver: %.c FORCE
-	@$(call if_changed_rule,cc_ver_c)
+targets += $(modules:.ko=.ver.c))
 
-modver: $(targets) $(subdir-ym)
-	@mkdir -p $(dir $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver)))
-	@touch $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver))
+# Extract all checksums for all exported symbols
 
-endif # export-objs 
+export-objs := $(shell for m in vmlinux $(modules:.ko=.o); do objdump -h $$m | grep -q __ksymtab && echo $$m; done)
+
+cmd_gen-all-versions = mksyms $(export-objs)
+define rule_gen-all-versions
+	echo '  MKSYMS  $@';						\
+	for mod in $(export-objs); do					\
+		modname=`basename $$mod`;				\
+		nm $$mod 						\
+		| grep ' __crc_'					\
+		| sed "s/\([^ ]*\) A __crc_\(.*\)/{ 0x\1, \"\2\" }, \/* $$modname *\//g;s/.* w __crc_\(.*\)/{ 0x0       , \"\1\" }, \/* $$modname *\//g"; \
+	done > $@;							\
+	echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd
+endef
 
-# Descending
-# ---------------------------------------------------------------------------
+.tmp_all-versions: $(export-objs) FORCE
+	$(call if_changed_rule,gen-all-versions)
 
-.PHONY: $(subdir-ym)
-$(subdir-ym):
-	$(Q)$(MAKE) -f scripts/Makefile.modver obj=$@
+targets += .tmp_all-versions
 
 # Add FORCE to the prequisites of a target to force it to be always rebuilt.
 # ---------------------------------------------------------------------------
diff -Nru a/scripts/per-cpu-check.awk b/scripts/per-cpu-check.awk
--- a/scripts/per-cpu-check.awk	Mon Feb 10 10:39:31 2003
+++ b/scripts/per-cpu-check.awk	Mon Feb 10 10:39:31 2003
@@ -6,7 +6,7 @@
 	IN_PER_CPU=0
 }
 
-/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ ) {
+/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ || / __kcrctab_/ ) {
 	if (!IN_PER_CPU) {
 		print $$3 " not in per-cpu section" > "/dev/stderr";
 		FOUND=1;
diff -Nru a/scripts/ver_linux b/scripts/ver_linux
--- a/scripts/ver_linux	Mon Feb 10 10:39:29 2003
+++ b/scripts/ver_linux	Mon Feb 10 10:39:29 2003
@@ -28,7 +28,7 @@
 
 mount --version | awk -F\- '{print "mount                 ", $NF}'
 
-rmmod -V  2>&1 | awk 'NR==1 {print "module-init-tools     ",$NF}'
+depmod -V  2>&1 | awk 'NR==1 {print "module-init-tools     ",$NF}'
 
 tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' |  awk \
 'NR==1 {print "e2fsprogs             ", $2}'
diff -Nru a/security/Kconfig b/security/Kconfig
--- a/security/Kconfig	Mon Feb 10 10:39:29 2003
+++ b/security/Kconfig	Mon Feb 10 10:39:29 2003
@@ -15,6 +15,15 @@
 
 	  If you are unsure how to answer this question, answer N.
 
+config SECURITY_NETWORK
+	bool "Socket and Networking Security Hooks"
+	depends on SECURITY
+	help
+	  This enables the socket and networking security hooks.
+	  If enabled, a security module can use these hooks to
+	  implement socket and networking access controls.
+	  If you are unsure how to answer this question, answer N.
+
 config SECURITY_CAPABILITIES
 	tristate "Default Linux Capabilities"
 	depends on SECURITY!=n
diff -Nru a/security/Makefile b/security/Makefile
--- a/security/Makefile	Mon Feb 10 10:39:30 2003
+++ b/security/Makefile	Mon Feb 10 10:39:30 2003
@@ -2,9 +2,6 @@
 # Makefile for the kernel security code
 #
 
-# Objects that export symbols
-export-objs	:= security.o capability.o
-
 # if we don't select a security model, use the default capabilities
 ifneq ($(CONFIG_SECURITY),y)
 obj-y		+= capability.o
diff -Nru a/security/capability.c b/security/capability.c
--- a/security/capability.c	Mon Feb 10 10:39:25 2003
+++ b/security/capability.c	Mon Feb 10 10:39:25 2003
@@ -120,28 +120,26 @@
 {
 	/* Derived from fs/exec.c:compute_creds. */
 	kernel_cap_t new_permitted, working;
-	int do_unlock = 0;
 
 	new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
 	working = cap_intersect (bprm->cap_inheritable,
 				 current->cap_inheritable);
 	new_permitted = cap_combine (new_permitted, working);
 
+	task_lock(current);
 	if (!cap_issubset (new_permitted, current->cap_permitted)) {
 		current->mm->dumpable = 0;
 
-		lock_kernel ();
 		if (must_not_trace_exec (current)
 		    || atomic_read (&current->fs->count) > 1
 		    || atomic_read (&current->files->count) > 1
-		    || atomic_read (&current->sig->count) > 1) {
+		    || atomic_read (&current->sighand->count) > 1) {
 			if (!capable (CAP_SETPCAP)) {
 				new_permitted = cap_intersect (new_permitted,
 							       current->
 							       cap_permitted);
 			}
 		}
-		do_unlock = 1;
 	}
 
 	/* For init, we want to retain the capabilities set
@@ -154,9 +152,7 @@
 	}
 
 	/* AUD: Audit candidate if current->cap_effective is set */
-
-	if (do_unlock)
-		unlock_kernel ();
+	task_unlock(current);
 
 	current->keep_capabilities = 0;
 }
@@ -286,6 +282,8 @@
 	.capset_check =			cap_capset_check,
 	.capset_set =			cap_capset_set,
 	.capable =			cap_capable,
+	.netlink_send =			cap_netlink_send,
+	.netlink_recv =			cap_netlink_recv,
 
 	.bprm_compute_creds =		cap_bprm_compute_creds,
 	.bprm_set_security =		cap_bprm_set_security,
diff -Nru a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c	Mon Feb 10 10:39:24 2003
+++ b/security/dummy.c	Mon Feb 10 10:39:24 2003
@@ -20,7 +20,7 @@
 #include <linux/security.h>
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
-
+#include <net/sock.h>
 
 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
 {
@@ -597,6 +597,118 @@
 	return 0;
 }
 
+static int dummy_netlink_send (struct sk_buff *skb)
+{
+	if (current->euid == 0)
+		cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
+	else
+		NETLINK_CB (skb).eff_cap = 0;
+	return 0;
+}
+
+static int dummy_netlink_recv (struct sk_buff *skb)
+{
+	if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN))
+		return -EPERM;
+	return 0;
+}
+
+#ifdef CONFIG_SECURITY_NETWORK
+static int dummy_unix_stream_connect (struct socket *sock,
+				      struct socket *other,
+				      struct sock *newsk)
+{
+	return 0;
+}
+
+static int dummy_unix_may_send (struct socket *sock,
+				struct socket *other)
+{
+	return 0;
+}
+
+static int dummy_socket_create (int family, int type, int protocol)
+{
+	return 0;
+}
+
+static void dummy_socket_post_create (struct socket *sock, int family, int type,
+				      int protocol)
+{
+	return;
+}
+
+static int dummy_socket_bind (struct socket *sock, struct sockaddr *address,
+			      int addrlen)
+{
+	return 0;
+}
+
+static int dummy_socket_connect (struct socket *sock, struct sockaddr *address,
+				 int addrlen)
+{
+	return 0;
+}
+
+static int dummy_socket_listen (struct socket *sock, int backlog)
+{
+	return 0;
+}
+
+static int dummy_socket_accept (struct socket *sock, struct socket *newsock)
+{
+	return 0;
+}
+
+static void dummy_socket_post_accept (struct socket *sock, 
+				      struct socket *newsock)
+{
+	return;
+}
+
+static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg,
+				 int size)
+{
+	return 0;
+}
+
+static int dummy_socket_recvmsg (struct socket *sock, struct msghdr *msg,
+				 int size, int flags)
+{
+	return 0;
+}
+
+static int dummy_socket_getsockname (struct socket *sock)
+{
+	return 0;
+}
+
+static int dummy_socket_getpeername (struct socket *sock)
+{
+	return 0;
+}
+
+static int dummy_socket_setsockopt (struct socket *sock, int level, int optname)
+{
+	return 0;
+}
+
+static int dummy_socket_getsockopt (struct socket *sock, int level, int optname)
+{
+	return 0;
+}
+
+static int dummy_socket_shutdown (struct socket *sock, int how)
+{
+	return 0;
+}
+
+static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb)
+{
+	return 0;
+}
+#endif	/* CONFIG_SECURITY_NETWORK */
+
 static int dummy_register_security (const char *name, struct security_operations *ops)
 {
 	return -EINVAL;
@@ -723,7 +835,28 @@
 	set_to_dummy_if_null(ops, sem_associate);
 	set_to_dummy_if_null(ops, sem_semctl);
 	set_to_dummy_if_null(ops, sem_semop);
+	set_to_dummy_if_null(ops, netlink_send);
+	set_to_dummy_if_null(ops, netlink_recv);
 	set_to_dummy_if_null(ops, register_security);
 	set_to_dummy_if_null(ops, unregister_security);
+#ifdef CONFIG_SECURITY_NETWORK
+	set_to_dummy_if_null(ops, unix_stream_connect);
+	set_to_dummy_if_null(ops, unix_may_send);
+	set_to_dummy_if_null(ops, socket_create);
+	set_to_dummy_if_null(ops, socket_post_create);
+	set_to_dummy_if_null(ops, socket_bind);
+	set_to_dummy_if_null(ops, socket_connect);
+	set_to_dummy_if_null(ops, socket_listen);
+	set_to_dummy_if_null(ops, socket_accept);
+	set_to_dummy_if_null(ops, socket_post_accept);
+	set_to_dummy_if_null(ops, socket_sendmsg);
+	set_to_dummy_if_null(ops, socket_recvmsg);
+	set_to_dummy_if_null(ops, socket_getsockname);
+	set_to_dummy_if_null(ops, socket_getpeername);
+	set_to_dummy_if_null(ops, socket_setsockopt);
+	set_to_dummy_if_null(ops, socket_getsockopt);
+	set_to_dummy_if_null(ops, socket_shutdown);
+	set_to_dummy_if_null(ops, socket_sock_rcv_skb);
+#endif	/* CONFIG_SECURITY_NETWORK */
 }
 
diff -Nru a/sound/Makefile b/sound/Makefile
--- a/sound/Makefile	Mon Feb 10 10:39:24 2003
+++ b/sound/Makefile	Mon Feb 10 10:39:24 2003
@@ -1,8 +1,6 @@
 # Makefile for the Linux sound card driver
 #
 
-export-objs     := sound_core.o
-
 obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_SOUND_PRIME) += oss/
 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/
diff -Nru a/sound/core/Makefile b/sound/core/Makefile
--- a/sound/core/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/core/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := sound.o pcm.o pcm_lib.o rawmidi.o timer.o hwdep.o
-
 snd-objs     := sound.o init.o memory.o info.o control.o misc.o \
                 device.o wrappers.o
 ifeq ($(CONFIG_ISA),y)
@@ -18,7 +16,6 @@
 		pcm_memory.o
 ifeq ($(CONFIG_PCI),y)
 snd-pcm-objs += pcm_sgbuf.o
-export-objs  += pcm_sgbuf.o
 endif
 
 snd-rawmidi-objs  := rawmidi.o
diff -Nru a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/control.c	Mon Feb 10 10:39:23 2003
@@ -48,9 +48,6 @@
 	snd_ctl_file_t *ctl;
 	int err;
 
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	card = snd_cards[cardnum];
 	if (!card) {
 		err = -ENODEV;
@@ -82,13 +79,10 @@
 	return 0;
 
       __error:
-      	module_put(card->module);
+	module_put(card->module);
       __error2:
 	snd_card_file_remove(card, file);
       __error1:
-#ifdef LINUX_2_2
-      	MOD_DEC_USE_COUNT;
-#endif
       	return err;
 }
 
@@ -131,9 +125,6 @@
 	snd_magic_kfree(ctl);
 	module_put(card->module);
 	snd_card_file_remove(card, file);
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -178,6 +169,15 @@
 	read_unlock(&card->ctl_files_rwlock);
 }
 
+/**
+ * snd_ctl_new - create a control instance from the template
+ * @control: the control template
+ *
+ * Allocates a new snd_kcontrol_t instance and copies the given template 
+ * to the new instance.
+ *
+ * Returns the pointer of the new instance, or NULL on failure.
+ */
 snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control)
 {
 	snd_kcontrol_t *kctl;
@@ -190,6 +190,17 @@
 	return kctl;
 }
 
+/**
+ * snd_ctl_new1 - create a control instance from the template
+ * @ncontrol: the initialization record
+ * @private_data: the private data to set
+ *
+ * Allocates a new snd_kcontrol_t instance and initialize from the given 
+ * template.  When the access field of ncontrol is 0, it's assumed as
+ * READWRITE access.
+ *
+ * Returns the pointer of the newly generated instance, or NULL on failure.
+ */
 snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
 {
 	snd_kcontrol_t kctl;
@@ -200,7 +211,8 @@
 	kctl.id.iface = ncontrol->iface;
 	kctl.id.device = ncontrol->device;
 	kctl.id.subdevice = ncontrol->subdevice;
-	strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1);
+	if (ncontrol->name)
+		strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1);
 	kctl.id.index = ncontrol->index;
 	kctl.access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
 		      (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE|SNDRV_CTL_ELEM_ACCESS_INDIRECT));
@@ -212,6 +224,14 @@
 	return snd_ctl_new(&kctl);
 }
 
+/**
+ * snd_ctl_free_one - release the control instance
+ * @kcontrol: the control instance
+ *
+ * Releases the control instance created via snd_ctl_new()
+ * 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)
 {
 	if (kcontrol) {
@@ -221,6 +241,16 @@
 	}
 }
 
+/**
+ * snd_ctl_add - add the control instance to the card
+ * @card: the card instance
+ * @kcontrol: the control instance to add
+ *
+ * Adds the control instance created via snd_ctl_new() or
+ * snd_ctl_new1() to the given card.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
 {
 	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
@@ -236,6 +266,16 @@
 	return 0;
 }
 
+/**
+ * snd_ctl_remove - remove the control from the card and release it
+ * @card: the card instance
+ * @kcontrol: the control instance to remove
+ *
+ * Removes the control from the card and then releases the instance.
+ * You don't need to call snd_ctl_free_one().
+ * 
+ * Returns 0 if successful, or a negative error code on failure.
+ */
 int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
 {
 	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
@@ -248,6 +288,16 @@
 	return 0;
 }
 
+/**
+ * snd_ctl_remove_id - remove the control of the given id and release it
+ * @card: the card instance
+ * @id: the control id to remove
+ *
+ * Finds the control instance with the given id, removes it from the
+ * card list and releases it.
+ * 
+ * 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)
 {
 	snd_kcontrol_t *kctl;
@@ -260,6 +310,17 @@
 
 static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */
 
+/**
+ * snd_ctl_rename_id - replace the id of a control on the card
+ * @card: the card instance
+ * @src_id: the old id
+ * @dst_id: the new id
+ *
+ * Finds the control with the old id from the card, and replaces the
+ * id with the new one.
+ *
+ * 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)
 {
 	snd_kcontrol_t *kctl;
@@ -315,7 +376,15 @@
 	return NULL;
 }
 
-/* exported: with read lock */
+/**
+ * snd_ctl_find_id - find the control instance with the given id
+ * @card: the card instance
+ * @id: the id to search
+ *
+ * Finds the control instance with the given id from the card.
+ *
+ * Returns the pointer of the instance if found, or NULL if not.
+ */
 snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
 {
 	snd_kcontrol_t *kctl;
@@ -325,7 +394,15 @@
 	return kctl;
 }
 
-/* exported: with read lock */
+/**
+ * snd_ctl_find_numid - find the control instance with the given number-id
+ * @card: the card instance
+ * @numid: the number-id to search
+ *
+ * Finds the control instance with the given number-id from the card.
+ *
+ * Returns the pointer of the instance if found, or NULL if not.
+ */
 snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
 {
 	snd_kcontrol_t *kctl;
@@ -637,13 +714,15 @@
 			return -EFAULT;
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
+		err = -ENOPROTOOPT;
 #ifdef CONFIG_PM
-		if (card->set_power_state == NULL)
-			return -ENOPROTOOPT;
-		return card->set_power_state(card, err);
-#else
-		return -ENOPROTOOPT;
+		if (card->set_power_state) {
+		    snd_power_lock(card);
+		    err = card->set_power_state(card, err);
+		    snd_power_unlock(card);
+		}
 #endif
+		return err;
 	case SNDRV_CTL_IOCTL_POWER_STATE:
 #ifdef CONFIG_PM
 		return put_user(card->power_state, (int *)arg) ? -EFAULT : 0;
@@ -736,6 +815,10 @@
 	return mask;
 }
 
+/*
+ * register the device-specific control-ioctls.
+ * called from each device manager like pcm.c, hwdep.c, etc.
+ */
 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
 {
 	snd_kctl_ioctl_t *pn;
@@ -751,6 +834,9 @@
 	return 0;
 }
 
+/*
+ * de-register the device-specific control-ioctls.
+ */
 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
 {
 	struct list_head *list;
@@ -806,6 +892,10 @@
 	.f_ops =	&snd_ctl_f_ops,
 };
 
+/*
+ * registration of the control device:
+ * called from init.c
+ */
 int snd_ctl_register(snd_card_t *card)
 {
 	int err, cardnum;
@@ -821,6 +911,10 @@
 	return 0;
 }
 
+/*
+ * disconnection of the control device:
+ * called from init.c
+ */
 int snd_ctl_disconnect(snd_card_t *card)
 {
 	struct list_head *flist;
@@ -836,6 +930,10 @@
 	return 0;
 }
 
+/*
+ * de-registration of the control device:
+ * called from init.c
+ */
 int snd_ctl_unregister(snd_card_t *card)
 {
 	int err, cardnum;
diff -Nru a/sound/core/device.c b/sound/core/device.c
--- a/sound/core/device.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/device.c	Mon Feb 10 10:39:29 2003
@@ -25,6 +25,22 @@
 #include <linux/errno.h>
 #include <sound/core.h>
 
+/**
+ * snd_device_new - create an ALSA device component
+ * @card: the card instance
+ * @type: the device type, SNDRV_DEV_TYPE_XXX
+ * @device_data: the data pointer of this device
+ * @ops: the operator table
+ *
+ * Creates a new device component for the given data pointer.
+ * The device will be assigned to the card and managed together
+ * by the card.
+ *
+ * The data pointer plays a role as the identifier, too, so the
+ * pointer address must be unique and unchanged.
+ *
+ * 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)
 {
@@ -43,6 +59,18 @@
 	return 0;
 }
 
+/**
+ * snd_device_free - release the device from the card
+ * @card: the card instance
+ * @device_data: the data pointer to release
+ *
+ * Removes the device from the list on the card and invokes the
+ * callback, dev_unregister or dev_free, corresponding to the state.
+ * Then release the device.
+ *
+ * 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)
 {
 	struct list_head *list;
@@ -73,6 +101,19 @@
 	return -ENXIO;
 }
 
+/**
+ * snd_device_free - disconnect the device
+ * @card: the card instance
+ * @device_data: the data pointer to disconnect
+ *
+ * Turns the device into the disconnection state, invoking
+ * dev_disconnect callback, if the device was already registered.
+ *
+ * Usually called from snd_card_disconnect().
+ *
+ * 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)
 {
 	struct list_head *list;
@@ -95,6 +136,19 @@
 	return -ENXIO;
 }
 
+/**
+ * snd_device_register - register the device
+ * @card: the card instance
+ * @device_data: the data pointer to register
+ *
+ * Registers the device which was already created via
+ * snd_device_new().  Usually this is called from snd_card_register(),
+ * but it can be called later if any new devices are created after
+ * invokation of snd_card_register().
+ *
+ * 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)
 {
 	struct list_head *list;
@@ -118,6 +172,10 @@
 	return -ENXIO;
 }
 
+/*
+ * register all the devices on the card.
+ * called from init.c
+ */
 int snd_device_register_all(snd_card_t *card)
 {
 	struct list_head *list;
@@ -136,6 +194,10 @@
 	return 0;
 }
 
+/*
+ * disconnect all the devices on the card.
+ * called from init.c
+ */
 int snd_device_disconnect_all(snd_card_t *card)
 {
 	snd_device_t *dev;
@@ -151,11 +213,16 @@
 	return err;
 }
 
+/*
+ * 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)
 {
 	snd_device_t *dev;
 	struct list_head *list;
-	int err, range_low, range_high;
+	int err;
+	unsigned int range_low, range_high;
 
 	snd_assert(card != NULL, return -ENXIO);
 	range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c
--- a/sound/core/hwdep.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/hwdep.c	Mon Feb 10 10:39:23 2003
@@ -256,6 +256,19 @@
 	.f_ops =	&snd_hwdep_f_ops,
 };
 
+/**
+ * snd_hwdep_new - create a new hwdep instance
+ * @card: the card instance
+ * @id: the id string
+ * @device: the device index (zero-based)
+ * @rhwdep: the pointer to store the new hwdep instance
+ *
+ * Creates a new hwdep instance with the given index on the card.
+ * The callbacks (hwdep->ops) must be set on the returned instance
+ * after this call manually by the caller.
+ *
+ * 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)
 {
 	snd_hwdep_t *hwdep;
diff -Nru a/sound/core/info.c b/sound/core/info.c
--- a/sound/core/info.c	Mon Feb 10 10:39:33 2003
+++ b/sound/core/info.c	Mon Feb 10 10:39:33 2003
@@ -83,10 +83,16 @@
 static int snd_info_version_init(void);
 static int snd_info_version_done(void);
 
-/*
 
+/**
+ * snd_iprintf - printf on the procfs buffer
+ * @buffer: the procfs buffer
+ * @fmt: the printf format
+ *
+ * Outputs the string on the procfs buffer just like printf().
+ *
+ * Returns the size of output string.
  */
-
 int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
 {
 	va_list args;
@@ -293,9 +299,6 @@
 		up(&info_mutex);
 		return -ENODEV;
 	}
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	if (!try_module_get(entry->module)) {
 		err = -EFAULT;
 		goto __error1;
@@ -403,9 +406,6 @@
       __error:
 	module_put(entry->module);
       __error1:
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	up(&info_mutex);
 	return err;
 }
@@ -445,9 +445,6 @@
 		break;
 	}
 	module_put(entry->module);
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	snd_magic_kfree(data);
 	return 0;
 }
@@ -600,6 +597,17 @@
 	.follow_link =		snd_info_card_followlink,
 };
 
+/**
+ * snd_create_proc_entry - create a procfs entry
+ * @name: the name of the proc file
+ * @mode: the file permission bits, S_Ixxx
+ * @parent: the parent proc-directory entry
+ *
+ * Creates a new proc file entry with the given name and permission
+ * on the given directory.
+ *
+ * Returns the pointer of new instance or NULL on failure.
+ */
 struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
 					     struct proc_dir_entry *parent)
 {
@@ -691,6 +699,10 @@
  */
 
 
+/*
+ * create a card proc file
+ * called from init.c
+ */
 int snd_info_card_create(snd_card_t * card)
 {
 	char str[8];
@@ -710,6 +722,10 @@
 	return 0;
 }
 
+/*
+ * register the card proc file
+ * called from init.c
+ */
 int snd_info_card_register(snd_card_t * card)
 {
 	char *s;
@@ -737,6 +753,10 @@
 	return 0;
 }
 
+/*
+ * de-register the card proc file
+ * called from init.c
+ */
 int snd_info_card_free(snd_card_t * card)
 {
 	void *data;
@@ -756,10 +776,17 @@
 	return 0;
 }
 
-/*
 
+/**
+ * snd_info_get_line - read one line from the procfs buffer
+ * @buffer: the procfs buffer
+ * @line: the buffer to store
+ * @len: the max. buffer size - 1
+ *
+ * Reads one line from the buffer and stores the string.
+ *
+ * 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 c = -1;
@@ -769,20 +796,20 @@
 	while (--len > 0) {
 		c = *buffer->curr++;
 		if (c == '\n') {
-			if ((buffer->curr - buffer->buffer) >= buffer->size) {
+			if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
 				buffer->stop = 1;
 			}
 			break;
 		}
 		*line++ = c;
-		if ((buffer->curr - buffer->buffer) >= buffer->size) {
+		if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
 			buffer->stop = 1;
 			break;
 		}
 	}
 	while (c != '\n' && !buffer->stop) {
 		c = *buffer->curr++;
-		if ((buffer->curr - buffer->buffer) >= buffer->size) {
+		if ((buffer->curr - buffer->buffer) >= (long)buffer->size) {
 			buffer->stop = 1;
 		}
 	}
@@ -790,6 +817,18 @@
 	return 0;
 }
 
+/**
+ * snd_info_get_line - parse a string token
+ * @dest: the buffer to store the string token
+ * @src: the original string
+ * @len: the max. length of token - 1
+ *
+ * Parses the original string and copy a token to the given
+ * string buffer.
+ *
+ * Returns the updated pointer of the original string so that
+ * it can be used for the next call.
+ */
 char *snd_info_get_str(char *dest, char *src, int len)
 {
 	int c;
@@ -814,15 +853,27 @@
 	return src;
 }
 
+/**
+ * snd_info_create_entry - create an info entry
+ * @name: the proc file name
+ *
+ * Creates an info entry with the given file name and initializes as
+ * the default state.
+ *
+ * Usually called from other functions such as
+ * snd_info_create_card_entry().
+ *
+ * Returns the pointer of the new instance, or NULL on failure.
+ */
 static snd_info_entry_t *snd_info_create_entry(const char *name)
 {
 	snd_info_entry_t *entry;
-	entry = (snd_info_entry_t *) snd_kcalloc(sizeof(snd_info_entry_t), GFP_KERNEL);
+	entry = snd_magic_kcalloc(snd_info_entry_t, 0, GFP_KERNEL);
 	if (entry == NULL)
 		return NULL;
 	entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
 	if (entry->name == NULL) {
-		kfree(entry);
+		snd_magic_kfree(entry);
 		return NULL;
 	}
 	entry->mode = S_IFREG | S_IRUGO;
@@ -831,6 +882,16 @@
 	return entry;
 }
 
+/**
+ * snd_info_create_module_entry - create an info entry for the given module
+ * @module: the module pointer
+ * @name: the file name
+ * @parent: the parent directory
+ *
+ * Creates a new info entry and assigns it to the given module.
+ *
+ * Returns the pointer of the new instance, or NULL on failure.
+ */
 snd_info_entry_t *snd_info_create_module_entry(struct module * module,
 					       const char *name,
 					       snd_info_entry_t *parent)
@@ -843,6 +904,16 @@
 	return entry;
 }
 
+/**
+ * snd_info_create_card_entry - create an info entry for the given card
+ * @card: the card instance
+ * @name: the file name
+ * @parent: the parent directory
+ *
+ * Creates a new info entry and assigns it to the given card.
+ *
+ * Returns the pointer of the new instance, or NULL on failure.
+ */
 snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
 					     const char *name,
 					     snd_info_entry_t * parent)
@@ -856,6 +927,75 @@
 	return entry;
 }
 
+static int snd_info_dev_free_entry(snd_device_t *device)
+{
+	snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+	snd_info_free_entry(entry);
+	return 0;
+}
+
+static int snd_info_dev_register_entry(snd_device_t *device)
+{
+	snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+	return snd_info_register(entry);
+}
+
+static int snd_info_dev_unregister_entry(snd_device_t *device)
+{
+	snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
+	return snd_info_unregister(entry);
+}
+
+/**
+ * snd_card_proc_new - create an info entry for the given card
+ * @card: the card instance
+ * @name: the file name
+ * @entryp: the pointer to store the new info entry
+ *
+ * Creates a new info entry and assigns it to the given card.
+ * Unlike snd_info_create_card_entry(), this function registers the
+ * info entry as an ALSA device component, so that it can be
+ * unregistered/released without explicit call.
+ * Also, you don't have to register this entry via snd_info_register(),
+ * since this will be registered by snd_card_register() automatically.
+ *
+ * The parent is assumed as card->proc_root.
+ *
+ * For releasing this entry, use snd_device_free() instead of
+ * snd_info_free_entry(). 
+ *
+ * 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)
+{
+	static snd_device_ops_t 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;
+	int err;
+
+	entry = snd_info_create_card_entry(card, name, card->proc_root);
+	if (! entry)
+		return -ENOMEM;
+	if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) {
+		snd_info_free_entry(entry);
+		return err;
+	}
+	if (entryp)
+		*entryp = entry;
+	return 0;
+}
+
+/**
+ * snd_info_free_entry - release the info entry
+ * @entry: the info entry
+ *
+ * Releases the info entry.  Don't call this after registered.
+ */
 void snd_info_free_entry(snd_info_entry_t * entry)
 {
 	if (entry == NULL)
@@ -864,7 +1004,7 @@
 		kfree((char *)entry->name);
 	if (entry->private_free)
 		entry->private_free(entry);
-	kfree(entry);
+	snd_magic_kfree(entry);
 }
 
 #ifdef LINUX_2_2
@@ -901,11 +1041,11 @@
 }
 #endif /* LINUX_2_2 */
 
+/*
+ * create a procfs device file
+ */
 snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number, unsigned int mode)
 {
-#ifdef CONFIG_DEVFS_FS
-	char dname[32];
-#endif
 	unsigned short _major = number >> 16;
 	unsigned short minor = (unsigned short) number;
 	snd_info_entry_t *entry;
@@ -921,7 +1061,7 @@
 		return NULL;
 	entry->content = SNDRV_INFO_CONTENT_DEVICE;
 	entry->mode = mode;
-	entry->c.device.major = major;
+	entry->c.device.major = _major;
 	entry->c.device.minor = minor;
 	down(&info_mutex);
 	p = create_proc_entry(entry->name, entry->mode, snd_proc_dev);
@@ -942,15 +1082,19 @@
 	up(&info_mutex);
 #ifdef CONFIG_DEVFS_FS
 	if (strncmp(name, "controlC", 8)) {	/* created in sound.c */
+		char dname[32];
 		sprintf(dname, "snd/%s", name);
 		devfs_register(NULL, dname, DEVFS_FL_DEFAULT,
-				major, minor, mode,
+				_major, minor, mode,
 				&snd_fops, NULL);
 	}
 #endif
 	return entry;
 }
 
+/*
+ * release a procfs device file
+ */
 void snd_info_free_device(snd_info_entry_t * entry)
 {
 	snd_runtime_check(entry, return);
@@ -962,6 +1106,14 @@
 	snd_info_free_entry(entry);
 }
 
+/**
+ * snd_info_register - register the info entry
+ * @entry: the info entry
+ *
+ * Registers the proc info entry.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_info_register(snd_info_entry_t * entry)
 {
 	struct proc_dir_entry *root, *p = NULL;
@@ -991,6 +1143,14 @@
 	return 0;
 }
 
+/**
+ * snd_info_unregister - de-register the info entry
+ * @entry: the info entry
+ *
+ * De-registers the info entry and releases the instance.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_info_unregister(snd_info_entry_t * entry)
 {
 	struct proc_dir_entry *root;
diff -Nru a/sound/core/init.c b/sound/core/init.c
--- a/sound/core/init.c	Mon Feb 10 10:39:24 2003
+++ b/sound/core/init.c	Mon Feb 10 10:39:24 2003
@@ -51,14 +51,16 @@
 }
 
 /**
- *  snd_card_new: create and initialize a soundcard structure
+ *  snd_card_new - create and initialize a soundcard structure
  *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
  *  @xid: card identification (ASCII string)
  *  @module: top level module for locking
  *  @extra_size: allocate this extra size after the main soundcard structure
  *
+ *  Creates and initializes a soundcard structure.
+ *
  *  Returns kmallocated snd_card_t structure. Creates the ALSA control interface
- *  (which is blocked until #snd_card_register function is called).
+ *  (which is blocked until snd_card_register function is called).
  */
 snd_card_t *snd_card_new(int idx, const char *xid,
 			 struct module *module, int extra_size)
@@ -84,11 +86,19 @@
 				idx = idx2;
 				break;
 			}
+		if (idx < 0 && snd_ecards_limit < SNDRV_CARDS)
+			/* for dynamically additional devices like hotplug:
+			 * increment the limit if still free slot exists.
+			 */
+			idx = snd_ecards_limit++;
 	} else if (idx < snd_ecards_limit) {
 		if (snd_cards_lock & (1 << idx))
 			idx = -1;	/* invalid */
-	}
-	if (idx < 0 || idx >= snd_ecards_limit) {
+	} else if (idx < SNDRV_CARDS)
+		snd_ecards_limit = idx + 1; /* increase the limit */
+	else
+		idx = -1;
+	if (idx < 0) {
 		write_unlock(&snd_card_rwlock);
 		if (idx >= snd_ecards_limit)
 			snd_printk(KERN_ERR "card %i is out of range (0-%i)\n", idx, snd_ecards_limit-1);
@@ -136,10 +146,12 @@
 }
 
 /**
- *  snd_card_disconnect: disconnect all APIs from the file-operations (user space)
+ *  snd_card_disconnect - disconnect all APIs from the file-operations (user space)
  *  @card: soundcard structure
  *
- *  Returns - zero, otherwise a negative error code.
+ *  Disconnects all APIs from the file-operations (user space).
+ *
+ *  Returns zero, otherwise a negative error code.
  *
  *  Note: The current implementation replaces all active file->f_op with special
  *        dummy file operations (they do nothing except release).
@@ -219,19 +231,18 @@
 }
 
 /**
- *  snd_card_free: frees given soundcard structure
+ *  snd_card_free - frees given soundcard structure
  *  @card: soundcard structure
  *
  *  This function releases the soundcard structure and the all assigned
  *  devices automatically.  That is, you don't have to release the devices
  *  by yourself.
  *
- *  Returns - zero. Frees all associated devices and frees the control
+ *  Returns zero. Frees all associated devices and frees the control
  *  interface associated to given soundcard.
  */
 int snd_card_free(snd_card_t * card)
 {
-	wait_queue_t wait;
 	struct snd_shutdown_f_ops *s_f_ops;
 
 	if (card == NULL)
@@ -242,13 +253,7 @@
 	write_unlock(&snd_card_rwlock);
 
 	/* wait, until all devices are ready for the free operation */
-	init_waitqueue_entry(&wait, current);
-	add_wait_queue(&card->shutdown_sleep, &wait);
-	while (card->files) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(30 * HZ);
-	}
-	remove_wait_queue(&card->shutdown_sleep, &wait);
+	wait_event(card->shutdown_sleep, card->files == NULL);
 
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	if (snd_mixer_oss_notify_callback)
@@ -292,29 +297,29 @@
 static void snd_card_free_thread(void * __card)
 {
 	snd_card_t *card = __card;
-	struct module * module;
+	struct module * module = card->module;
 
-	if (!try_module_get(module = card->module)) {
+	if (!try_module_get(module)) {
 		snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number);
 		module = NULL;
 	}
 
-	wait_event(card->shutdown_sleep, card->files == NULL);
 	snd_card_free(card);
+
 	module_put(module);
 }
 
 /**
- *  snd_card_free_in_thread: call snd_card_free() in thread
+ *  snd_card_free_in_thread - call snd_card_free() in thread
  *  @card: soundcard structure
  *
- *  This function schedules the call of #snd_card_free function in a
+ *  This function schedules the call of snd_card_free() function in a
  *  work queue.  When all devices are released (non-busy), the work
- *  is woken up and calls #snd_card_free.
+ *  is woken up and calls snd_card_free().
  *
  *  When a card can be disconnected at any time by hotplug service,
  *  this function should be used in disconnect (or detach) callback
- *  instead of calling #snd_card_free directly.
+ *  instead of calling snd_card_free() directly.
  *  
  *  Returns - zero otherwise a negative error code if the start of thread failed.
  */
@@ -347,7 +352,7 @@
 		id++;
 	}
 	id = card->id;
-	while (*spos != '\0' && id - card->id < sizeof(card->id) - 1) {
+	while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) {
 		if (isalnum(*spos))
 			*id++ = *spos;
 		spos++;
@@ -374,12 +379,12 @@
 		len = strlen(id);
 		if (idx_flag)
 			id[len-1]++;
-		else if (len <= sizeof(card->id) - 3) {
+		else if ((size_t)len <= sizeof(card->id) - 3) {
 			strcat(id, "_1");
 			idx_flag++;
 		} else {
 			spos = id + len - 2;
-			if (len <= sizeof(card->id) - 2)
+			if ((size_t)len <= sizeof(card->id) - 2)
 				spos++;
 			*spos++ = '_';
 			*spos++ = '1';
@@ -390,7 +395,7 @@
 }
 
 /**
- *  snd_card_register: register the soundcard
+ *  snd_card_register - register the soundcard
  *  @card: soundcard structure
  *
  *  This function registers all the devices assigned to the soundcard.
@@ -398,7 +403,7 @@
  *  external accesses.  Thus, you should call this function at the end
  *  of the initialization of the card.
  *
- *  Returns - zero otherwise a negative error code if the registrain failed.
+ *  Returns zero otherwise a negative error code if the registrain failed.
  */
 int snd_card_register(snd_card_t * card)
 {
@@ -515,14 +520,14 @@
 }
 
 /**
- *  snd_component_add: add a component string
+ *  snd_component_add - add a component string
  *  @card: soundcard structure
  *  @component: the component id string
  *
  *  This function adds the component id string to the supported list.
  *  The component can be referred from the alsa-lib.
  *
- *  Returns - zero otherwise a negative error code.
+ *  Returns zero otherwise a negative error code.
  */
   
 int snd_component_add(snd_card_t *card, const char *component)
@@ -546,7 +551,7 @@
 }
 
 /**
- *  snd_card_file_add: add the file to the file list of the card
+ *  snd_card_file_add - add the file to the file list of the card
  *  @card: soundcard structure
  *  @file: file pointer
  *
@@ -578,15 +583,15 @@
 }
 
 /**
- *  snd_card_file_remove: remove the file from the file list
+ *  snd_card_file_remove - remove the file from the file list
  *  @card: soundcard structure
  *  @file: file pointer
  *
  *  This function removes the file formerly added to the card via
- *  #snd_card_file_add function.
+ *  snd_card_file_add() function.
  *  If all files are removed and the release of the card is
- *  scheduled, it will wake up the the thread to call #snd_card_free
- *  (see #snd_card_free_in_thread function).
+ *  scheduled, it will wake up the the thread to call snd_card_free()
+ *  (see snd_card_free_in_thread() function).
  *
  *  Returns zero or a negative error code.
  */
@@ -621,8 +626,10 @@
 
 #ifdef CONFIG_PM
 /**
- *  snd_power_wait: wait until the power-state is changed.
+ *  snd_power_wait - wait until the power-state is changed.
  *  @card: soundcard structure
+ *
+ *  Waits until the power-state is changed.
  *
  *  Note: the power lock must be active before call.
  */
diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
--- a/sound/core/ioctl32/ioctl32.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/ioctl32/ioctl32.c	Mon Feb 10 10:39:23 2003
@@ -71,6 +71,17 @@
 
 
 /*
+ * compatible wrapper
+ */
+int snd_ioctl32_compat(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp)
+{
+	if (! filp->f_op || ! filp->f_op->ioctl)
+		return -ENOTTY;
+	return filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+}
+
+
+/*
  * Controls
  */
 
@@ -250,9 +261,9 @@
 	ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
 
 	kctl = snd_ctl_find_id(ctl->card, id);
-	if (! kctl)
+	if (! kctl) {
 		return -ENXIO;
-
+	}
 	info.id = *id;
 	err = kctl->info(kctl, &info);
 	if (err >= 0)
@@ -381,22 +392,22 @@
 
 static struct ioctl32_mapper control_mappers[] = {
 	/* controls (without rawmidi, hwdep, timer releated ones) */
-	{ SNDRV_CTL_IOCTL_PVERSION, NULL },
-	{ SNDRV_CTL_IOCTL_CARD_INFO , NULL },
+	MAP_COMPAT(SNDRV_CTL_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_CARD_INFO),
 	{ SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) },
 	{ SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) },
 	{ SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_read) },
 	{ SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_write) },
-	{ SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
-	{ SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
-	{ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
-	{ SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
-	{ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
-	{ SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
-	{ SNDRV_CTL_IOCTL_PCM_INFO, NULL },
-	{ SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL },
-	{ SNDRV_CTL_IOCTL_POWER, NULL },
-	{ SNDRV_CTL_IOCTL_POWER_STATE, NULL },
+	MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_LOCK),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_UNLOCK),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_INFO),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_INFO),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_POWER),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_POWER_STATE),
 	{ 0 }
 };
 
diff -Nru a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h
--- a/sound/core/ioctl32/ioctl32.h	Mon Feb 10 10:39:26 2003
+++ b/sound/core/ioctl32/ioctl32.h	Mon Feb 10 10:39:26 2003
@@ -69,6 +69,7 @@
 	oldseg = get_fs();\
 	set_fs(KERNEL_DS);\
 	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\
+	set_fs(oldseg);\
 	if (err < 0) \
 		return err;\
 	if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\
@@ -101,6 +102,7 @@
 	oldseg = get_fs();\
 	set_fs(KERNEL_DS);\
 	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);\
+	set_fs(oldseg);\
 	if (err < 0) \
 		goto __end;\
 	err = 0;\
@@ -122,12 +124,15 @@
 	return _snd_ioctl32_##type(fd, cmd, arg, file, native_ctl);\
 }
 
+#define MAP_COMPAT(ctl) { ctl, snd_ioctl32_compat }
 
 struct ioctl32_mapper {
 	unsigned int cmd;
 	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
 	int registered;
 };
+
+int snd_ioctl32_compat(unsigned int, unsigned int, unsigned long, struct file *);
 
 int snd_ioctl32_register(struct ioctl32_mapper *mappers);
 void snd_ioctl32_unregister(struct ioctl32_mapper *mappers);
diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
--- a/sound/core/ioctl32/pcm32.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/ioctl32/pcm32.c	Mon Feb 10 10:39:29 2003
@@ -72,7 +72,7 @@
 
 #define CVT_sndrv_pcm_hw_params()\
 {\
-	int i;\
+	unsigned int i;\
 	COPY(flags);\
 	for (i = 0; i < numberof(dst->masks); i++)\
 		COPY(masks[i]);\
@@ -423,32 +423,32 @@
 };
 
 struct ioctl32_mapper pcm_mappers[] = {
-	{ SNDRV_PCM_IOCTL_PVERSION, NULL },
-	{ SNDRV_PCM_IOCTL_INFO, NULL },
+	MAP_COMPAT(SNDRV_PCM_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_INFO),
 	{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
 	{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
 	{ SNDRV_PCM_IOCTL_HW_REFINE_OLD32, AP(pcm_hw_refine_old) },
 	{ SNDRV_PCM_IOCTL_HW_PARAMS_OLD32, AP(pcm_hw_params_old) },
-	{ SNDRV_PCM_IOCTL_HW_FREE, NULL },
+	MAP_COMPAT(SNDRV_PCM_IOCTL_HW_FREE),
 	{ SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) },
 	{ SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) },
 	{ SNDRV_PCM_IOCTL_DELAY32, AP(pcm_delay) },
 	{ SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) },
-	{ SNDRV_PCM_IOCTL_PREPARE, NULL },
-	{ SNDRV_PCM_IOCTL_RESET, NULL },
-	{ SNDRV_PCM_IOCTL_START, NULL },
-	{ SNDRV_PCM_IOCTL_DROP, NULL },
-	{ SNDRV_PCM_IOCTL_DRAIN, NULL },
-	{ SNDRV_PCM_IOCTL_PAUSE, NULL },
+	MAP_COMPAT(SNDRV_PCM_IOCTL_PREPARE),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_RESET),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_START),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_DROP),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_DRAIN),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_PAUSE),
 	{ SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) },
-	{ SNDRV_PCM_IOCTL_RESUME, NULL },
-	{ SNDRV_PCM_IOCTL_XRUN, NULL },
+	MAP_COMPAT(SNDRV_PCM_IOCTL_RESUME),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_XRUN),
 	{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) },
 	{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) },
 	{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) },
 	{ SNDRV_PCM_IOCTL_READN_FRAMES32, AP(pcm_readn) },
-	{ SNDRV_PCM_IOCTL_LINK, NULL },
-	{ SNDRV_PCM_IOCTL_UNLINK, NULL },
+	MAP_COMPAT(SNDRV_PCM_IOCTL_LINK),
+	MAP_COMPAT(SNDRV_PCM_IOCTL_UNLINK),
 
 	{ 0 },
 };
diff -Nru a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c
--- a/sound/core/ioctl32/rawmidi32.c	Mon Feb 10 10:39:27 2003
+++ b/sound/core/ioctl32/rawmidi32.c	Mon Feb 10 10:39:27 2003
@@ -78,16 +78,16 @@
 };
 
 struct ioctl32_mapper rawmidi_mappers[] = {
-	{ SNDRV_RAWMIDI_IOCTL_PVERSION, NULL },
-	{ SNDRV_RAWMIDI_IOCTL_INFO, NULL },
+	MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_INFO),
 	{ SNDRV_RAWMIDI_IOCTL_PARAMS32, AP(rawmidi_params) },
 	{ SNDRV_RAWMIDI_IOCTL_STATUS32, AP(rawmidi_status) },
-	{ SNDRV_RAWMIDI_IOCTL_DROP, NULL },
-	{ SNDRV_RAWMIDI_IOCTL_DRAIN, NULL },
+	MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DROP),
+	MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DRAIN),
 
-	{ SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, NULL },
-	{ SNDRV_CTL_IOCTL_RAWMIDI_INFO, NULL },
-	{ SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, NULL },
+	MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_INFO),
+	MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE),
 
 	{ 0 },
 };
diff -Nru a/sound/core/ioctl32/seq32.c b/sound/core/ioctl32/seq32.c
--- a/sound/core/ioctl32/seq32.c	Mon Feb 10 10:39:33 2003
+++ b/sound/core/ioctl32/seq32.c	Mon Feb 10 10:39:33 2003
@@ -79,36 +79,36 @@
 };
 
 struct ioctl32_mapper seq_mappers[] = {
-	{ SNDRV_SEQ_IOCTL_PVERSION, NULL },
-	{ SNDRV_SEQ_IOCTL_CLIENT_ID, NULL },
-	{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL },
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_CLIENT_ID),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SYSTEM_INFO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_INFO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO),
 	{ SNDRV_SEQ_IOCTL_CREATE_PORT32, AP(create_port) },
 	{ SNDRV_SEQ_IOCTL_DELETE_PORT32, AP(delete_port) },
 	{ SNDRV_SEQ_IOCTL_GET_PORT_INFO32, AP(get_port_info) },
 	{ SNDRV_SEQ_IOCTL_SET_PORT_INFO32, AP(set_port_info) },
-	{ SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL },
-	{ SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL },
-	{ SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL },
-	{ SNDRV_SEQ_IOCTL_DELETE_QUEUE, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, NULL },
-	{ SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, NULL },
-	{ SNDRV_SEQ_IOCTL_REMOVE_EVENTS, NULL },
-	{ SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL },
-	{ SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, NULL },
-	{ SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, NULL },
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_CREATE_QUEUE),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_DELETE_QUEUE),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_INFO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_INFO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_POOL),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_POOL),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_REMOVE_EVENTS),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_SUBS),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION),
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT),
 	{ SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32, AP(query_next_port) },
-	{ SNDRV_SEQ_IOCTL_RUNNING_MODE, NULL },
+	MAP_COMPAT(SNDRV_SEQ_IOCTL_RUNNING_MODE),
 	{ 0 },
 };
diff -Nru a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c
--- a/sound/core/ioctl32/timer32.c	Mon Feb 10 10:39:27 2003
+++ b/sound/core/ioctl32/timer32.c	Mon Feb 10 10:39:27 2003
@@ -87,14 +87,14 @@
 };
 
 struct ioctl32_mapper timer_mappers[] = {
-	{ SNDRV_TIMER_IOCTL_PVERSION, NULL },
-	{ SNDRV_TIMER_IOCTL_NEXT_DEVICE, NULL },
-	{ SNDRV_TIMER_IOCTL_SELECT, NULL },
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_NEXT_DEVICE),
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_SELECT),
 	{ SNDRV_TIMER_IOCTL_INFO32, AP(timer_info) },
-	{ SNDRV_TIMER_IOCTL_PARAMS, NULL },
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_PARAMS),
 	{ SNDRV_TIMER_IOCTL_STATUS32, AP(timer_status) },
-	{ SNDRV_TIMER_IOCTL_START, NULL },
-	{ SNDRV_TIMER_IOCTL_STOP, NULL },
-	{ SNDRV_TIMER_IOCTL_CONTINUE, NULL },
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_START),
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_STOP),
+	MAP_COMPAT(SNDRV_TIMER_IOCTL_CONTINUE),
 	{ 0 },
 };
diff -Nru a/sound/core/isadma.c b/sound/core/isadma.c
--- a/sound/core/isadma.c	Mon Feb 10 10:39:33 2003
+++ b/sound/core/isadma.c	Mon Feb 10 10:39:33 2003
@@ -30,10 +30,15 @@
 #include <sound/core.h>
 #include <asm/dma.h>
 
-/*
+/**
+ * snd_dma_program - program an ISA DMA transfer
+ * @dma: the dma number
+ * @addr: the physical address of the buffer
+ * @size: the DMA transfer size
+ * @mode: the DMA transfer mode, DMA_MODE_XXX
  *
+ * Programs an ISA DMA transfer for the given buffer.
  */
- 
 void snd_dma_program(unsigned long dma,
 		     unsigned long addr, unsigned int size,
                      unsigned short mode)
@@ -51,6 +56,12 @@
 	release_dma_lock(flags);
 }
 
+/**
+ * snd_dma_disable - stop the ISA DMA transfer
+ * @dma: the dma number
+ *
+ * Stops the ISA DMA transfer.
+ */
 void snd_dma_disable(unsigned long dma)
 {
 	unsigned long flags;
@@ -61,7 +72,14 @@
 	release_dma_lock(flags);
 }
 
-unsigned int snd_dma_residue(unsigned long dma)
+/**
+ * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes
+ * @dma: the dma number
+ * @size: the dma transfer size
+ *
+ * Returns the current pointer in DMA tranfer buffer in bytes
+ */
+unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
 {
 	unsigned long flags;
 	unsigned int result;
@@ -74,5 +92,9 @@
 	if (!isa_dma_bridge_buggy)
 		enable_dma(dma);
 	release_dma_lock(flags);
-	return result;
+#ifdef CONFIG_SND_DEBUG
+	if (result > size)
+		snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
+#endif
+	return result >= size ? 0 : result;
 }
diff -Nru a/sound/core/memory.c b/sound/core/memory.c
--- a/sound/core/memory.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/memory.c	Mon Feb 10 10:39:23 2003
@@ -264,7 +264,15 @@
 #endif /* CONFIG_SND_DEBUG_MEMORY */
 
 
-
+/**
+ * snd_malloc_pages - allocate pages with the given size
+ * @size: the size to allocate in bytes
+ * @dma_flags: the allocation conditions, GFP_XXX
+ *
+ * Allocates the physically contiguous pages with the given size.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_pages(unsigned long size, unsigned int dma_flags)
 {
 	int pg;
@@ -285,6 +293,19 @@
 	return res;
 }
 
+/**
+ * snd_malloc_pages_fallback - allocate pages with the given size with fallback
+ * @size: the requested size to allocate in bytes
+ * @dma_flags: the allocation conditions, GFP_XXX
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_pages_fallback(unsigned long size, unsigned int dma_flags, unsigned long *res_size)
 {
 	void *res;
@@ -301,6 +322,13 @@
 	return NULL;
 }
 
+/**
+ * snd_free_pages - release the pages
+ * @ptr: the buffer pointer to release
+ * @size: the allocated buffer size
+ *
+ * Releases the buffer allocated via snd_malloc_pages().
+ */
 void snd_free_pages(void *ptr, unsigned long size)
 {
 	int pg;
@@ -321,6 +349,16 @@
 
 #if defined(CONFIG_ISA) && ! defined(CONFIG_PCI)
 
+/**
+ * snd_malloc_isa_pages - allocate pages for ISA bus with the given size
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * ISA bus.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_isa_pages(unsigned long size, dma_addr_t *dma_addr)
 {
 	void *dma_area;
@@ -329,6 +367,19 @@
 	return dma_area;
 }
 
+/**
+ * snd_malloc_isa_pages_fallback - allocate pages with the given size with fallback for ISA bus
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for PCI bus.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_isa_pages_fallback(unsigned long size,
 				    dma_addr_t *dma_addr,
 				    unsigned long *res_size)
@@ -343,6 +394,17 @@
 
 #ifdef CONFIG_PCI
 
+/**
+ * snd_malloc_pci_pages - allocate pages for PCI bus with the given size
+ * @pci: the pci device pointer
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * PCI bus.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_pci_pages(struct pci_dev *pci,
 			   unsigned long size,
 			   dma_addr_t *dma_addr)
@@ -366,6 +428,20 @@
 	return res;
 }
 
+/**
+ * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for PCI bus
+ * @pci: pci device pointer
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for PCI bus.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_pci_pages_fallback(struct pci_dev *pci,
 				    unsigned long size,
 				    dma_addr_t *dma_addr,
@@ -384,6 +460,15 @@
 	return NULL;
 }
 
+/**
+ * snd_free_pci_pages - release the pages
+ * @pci: pci device pointer
+ * @size: the allocated buffer size
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_pages().
+ */
 void snd_free_pci_pages(struct pci_dev *pci,
 			unsigned long size,
 			void *ptr,
@@ -409,6 +494,17 @@
 
 #ifdef CONFIG_SBUS
 
+/**
+ * snd_malloc_sbus_pages - allocate pages for SBUS with the given size
+ * @sdev: sbus device pointer
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * SBUS.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_sbus_pages(struct sbus_dev *sdev,
 			    unsigned long size,
 			    dma_addr_t *dma_addr)
@@ -432,6 +528,20 @@
 	return res;
 }
 
+/**
+ * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for SBUS
+ * @sdev: sbus device pointer
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for SBUS.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
 void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev,
 				     unsigned long size,
 				     dma_addr_t *dma_addr,
@@ -450,6 +560,15 @@
 	return NULL;
 }
 
+/**
+ * snd_free_sbus_pages - release the pages
+ * @sdev: sbus device pointer
+ * @size: the allocated buffer size
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_pages().
+ */
 void snd_free_sbus_pages(struct sbus_dev *sdev,
 			 unsigned long size,
 			 void *ptr,
@@ -473,6 +592,15 @@
 
 #endif /* CONFIG_SBUS */
 
+/**
+ * snd_kcalloc - memory allocation and zero-clear
+ * @size: the size to allocate in bytes
+ * @flags: allocation conditions, GFP_XXX
+ *
+ * Allocates a memory chunk via kmalloc() and initializes it to zero.
+ *
+ * Returns the pointer, or NULL if no enoguh memory.
+ */
 void *snd_kcalloc(size_t size, int flags)
 {
 	void *ptr;
@@ -483,6 +611,15 @@
 	return ptr;
 }
 
+/**
+ * snd_kmalloc_strdup - copy the string
+ * @string: the original string
+ * @flags: allocation conditions, GFP_XXX
+ *
+ * Allocates a memory chunk via kmalloc() and copies the string to it.
+ *
+ * Returns the pointer, or NULL if no enoguh memory.
+ */
 char *snd_kmalloc_strdup(const char *string, int flags)
 {
 	size_t len;
@@ -497,6 +634,16 @@
 	return ptr;
 }
 
+/**
+ * copy_to_user_fromio - copy data from mmio-space to user-space
+ * @dst: the destination pointer on user-space
+ * @src: the source pointer on mmio
+ * @count: the data size to copy in bytes
+ *
+ * Copies the data from mmio-space to user-space.
+ *
+ * Returns zero if successful, or non-zero on failure.
+ */
 int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
@@ -518,6 +665,16 @@
 #endif
 }
 
+/**
+ * copy_from_user_toio - copy data from user-space to mmio-space
+ * @dst: the destination pointer on mmio-space
+ * @src: the source pointer on user-space
+ * @count: the data size to copy in bytes
+ *
+ * Copies the data from user-space to mmio-space.
+ *
+ * Returns zero if successful, or non-zero on failure.
+ */
 int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
@@ -538,3 +695,81 @@
 	return 0;
 #endif
 }
+
+
+#ifdef CONFIG_PCI
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(__i386__)
+/*
+ * on ix86, we allocate a page with GFP_KERNEL to assure the
+ * allocation.  the code is almost same with kernel/i386/pci-dma.c but
+ * it allocates only a single page and checks the validity of the
+ * page address with the given pci dma mask.
+ */
+
+/**
+ * snd_malloc_pci_page - allocate a page in the valid pci dma mask
+ * @pci: pci device pointer
+ * @addrp: the pointer to store the physical address of the buffer
+ *
+ * Allocates a single page for the given PCI device and returns
+ * the virtual address and stores the physical address on addrp.
+ * 
+ * This function cannot be called from interrupt handlers or
+ * within spinlocks.
+ */
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
+{
+	void *ptr;
+	dma_addr_t addr;
+	unsigned long rmask;
+
+	rmask = ~(unsigned long)(pci ? pci->dma_mask : 0x00ffffff);
+	ptr = (void *)__get_free_page(GFP_KERNEL);
+	if (ptr) {
+		addr = virt_to_phys(ptr);
+		if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) {
+			/* try to reallocate with the GFP_DMA */
+			free_page((unsigned long)ptr);
+			ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+			if (ptr) /* ok, the address must be within lower 16MB... */
+				addr = virt_to_phys(ptr);
+			else
+				addr = 0;
+		}
+	} else
+		addr = 0;
+	if (ptr) {
+		struct page *page = virt_to_page(ptr);
+		memset(ptr, 0, PAGE_SIZE);
+		SetPageReserved(page);
+#ifdef CONFIG_SND_DEBUG_MEMORY
+		snd_alloc_pages++;
+#endif
+	}
+	*addrp = addr;
+	return ptr;
+}
+#else
+/* on other architectures, call snd_malloc_pci_pages() helper function
+ * which uses pci_alloc_consistent().
+ */
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
+{
+	return snd_malloc_pci_pages(pci, PAGE_SIZE, addrp);
+}
+#endif /* 2.4 && i386 */
+
+#if 0 /* for kernel-doc */
+/**
+ * snd_free_pci_page - release a page
+ * @pci: pci device pointer
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_page().
+ */
+void snd_free_pci_page(struct pci_dev *pci, void *ptr, dma_addr_t dma_addr);
+#endif /* for kernel-doc */
+
+#endif /* CONFIG_PCI */
diff -Nru a/sound/core/oss/Makefile b/sound/core/oss/Makefile
--- a/sound/core/oss/Makefile	Mon Feb 10 10:39:23 2003
+++ b/sound/core/oss/Makefile	Mon Feb 10 10:39:23 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := mixer_oss.o
-
 snd-mixer-oss-objs := mixer_oss.o
 
 snd-pcm-oss-objs := pcm_oss.o pcm_plugin.o \
diff -Nru a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
--- a/sound/core/oss/mixer_oss.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/oss/mixer_oss.c	Mon Feb 10 10:39:29 2003
@@ -56,14 +56,8 @@
 	fmixer->card = card;
 	fmixer->mixer = card->mixer_oss;
 	file->private_data = fmixer;
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	if (!try_module_get(card->module)) {
 		kfree(fmixer);
-#ifdef LINUX_2_2
-		MOD_DEC_USE_COUNT;
-#endif
 		snd_card_file_remove(card, file);
 		return -EFAULT;
 	}
@@ -77,9 +71,6 @@
 	if (file->private_data) {
 		fmixer = (snd_mixer_oss_file_t *) file->private_data;
 		module_put(fmixer->card->module);
-#ifdef LINUX_2_2
-		MOD_DEC_USE_COUNT;
-#endif
 		snd_card_file_remove(fmixer->card, file);
 		kfree(fmixer);
 	}
@@ -473,7 +464,7 @@
 struct slot {
 	unsigned int signature;
 	unsigned int present;
-	int channels;
+	unsigned int channels;
 	snd_kcontrol_t *kcontrol[SNDRV_MIXER_OSS_ITEM_COUNT];
 	unsigned int capture_item;
 	struct snd_mixer_oss_assign_table *assigned;
@@ -741,7 +732,7 @@
 	return 0;
 }
 
-static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_index)
+static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int *active_index)
 {
 	snd_card_t *card = fmixer->card;
 	snd_mixer_oss_t *mixer = fmixer->mixer;
@@ -787,7 +778,7 @@
       	return err;
 }
 
-static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_index)
+static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int active_index)
 {
 	snd_card_t *card = fmixer->card;
 	snd_mixer_oss_t *mixer = fmixer->mixer;
@@ -796,7 +787,8 @@
 	struct slot *slot = NULL;
 	snd_ctl_elem_info_t *uinfo;
 	snd_ctl_elem_value_t *uctl;
-	int err, idx;
+	int err;
+	unsigned int idx;
 
 	uinfo = snd_kcalloc(sizeof(*uinfo), GFP_KERNEL);
 	uctl = snd_kcalloc(sizeof(*uctl), GFP_KERNEL);
@@ -1164,7 +1156,7 @@
 	static struct snd_mixer_oss_assign_table fm_table = {
 		SOUND_MIXER_SYNTH,	"FM",			0
 	};
-	int idx;
+	unsigned int idx;
 	
 	for (idx = 0; idx < sizeof(table) / sizeof(struct snd_mixer_oss_assign_table); idx++)
 		snd_mixer_oss_build_input(mixer, &table[idx], 0);
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c	Mon Feb 10 10:39:31 2003
+++ b/sound/core/oss/pcm_oss.c	Mon Feb 10 10:39:31 2003
@@ -251,6 +251,43 @@
 	return 0;
 }
 
+static int choose_rate(snd_pcm_substream_t *substream,
+		       snd_pcm_hw_params_t *params, unsigned int best_rate)
+{
+	snd_interval_t *it;
+	snd_pcm_hw_params_t *save;
+	unsigned int rate;
+
+	save = kmalloc(sizeof(*save), GFP_KERNEL);
+	if (save == NULL)
+		return -ENOMEM;
+	*save = *params;
+	it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE);
+
+	/* try multiples of the best rate */
+	rate = best_rate;
+	for (;;) {
+		if (it->max < rate || (it->max == rate && it->openmax))
+			break;
+		if (it->min < rate || (it->min == rate && !it->openmin)) {
+			int ret;
+			ret = snd_pcm_hw_param_set(substream, params,
+						   SNDRV_PCM_HW_PARAM_RATE,
+						   rate, 0);
+			if (ret == (int)rate) {
+				kfree(save);
+				return rate;
+			}
+			*params = *save;
+		}
+		rate += best_rate;
+	}
+
+	/* not found, use the nearest rate */
+	kfree(save);
+	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, 0);
+}
+
 static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -287,7 +324,7 @@
 		snd_printd("No usable accesses\n");
 		return -EINVAL;
 	}
-	snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_RATE, runtime->oss.rate, 0);
+	choose_rate(substream, &sparams, runtime->oss.rate);
 	snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, 0);
 
 	format = snd_pcm_oss_format_from(runtime->oss.format);
@@ -679,7 +716,7 @@
 				tmp = runtime->oss.period_bytes - runtime->oss.buffer_used;
 			if (tmp > 0) {
 				if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp))
-					return xfer > 0 ? xfer : -EFAULT;
+					return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
 			}
 			runtime->oss.buffer_used += tmp;
 			buf += tmp;
@@ -688,14 +725,14 @@
 			if (runtime->oss.buffer_used == runtime->oss.period_bytes) {
 				tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
 				if (tmp <= 0)
-					return xfer > 0 ? xfer : tmp;
+					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 				runtime->oss.bytes += tmp;
 				runtime->oss.buffer_used = 0;
 			}
 		} else {
 			tmp = snd_pcm_oss_write2(substream, (char *)buf, runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
-				return xfer > 0 ? xfer : tmp;
+				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 			runtime->oss.bytes += tmp;
 			buf += tmp;
 			bytes -= tmp;
@@ -751,7 +788,7 @@
 			if (runtime->oss.buffer_used == 0) {
 				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
 				if (tmp <= 0)
-					return xfer > 0 ? xfer : tmp;
+					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 				runtime->oss.bytes += tmp;
 				runtime->oss.buffer_used = runtime->oss.period_bytes;
 			}
@@ -759,7 +796,7 @@
 			if ((size_t) tmp > runtime->oss.buffer_used)
 				tmp = runtime->oss.buffer_used;
 			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_bytes - runtime->oss.buffer_used), tmp))
-				return xfer > 0 ? xfer : -EFAULT;
+				return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT;
 			buf += tmp;
 			bytes -= tmp;
 			xfer += tmp;
@@ -767,7 +804,7 @@
 		} else {
 			tmp = snd_pcm_oss_read2(substream, (char *)buf, runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
-				return xfer > 0 ? xfer : tmp;
+				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 			runtime->oss.bytes += tmp;
 			buf += tmp;
 			bytes -= tmp;
@@ -890,7 +927,7 @@
 	return substream->runtime->oss.rate;
 }
 
-static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, int channels)
+static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, unsigned int channels)
 {
 	int idx;
 	if (channels < 1)
@@ -1540,9 +1577,6 @@
 	device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ?
 		adsp_map[cardnum] : dsp_map[cardnum];
 
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device];
 	if (pcm == NULL) {
 		err = -ENODEV;
@@ -1611,13 +1645,10 @@
 	return err;
 
       __error:
-      	module_put(pcm->card->module);
+     	module_put(pcm->card->module);
       __error2:
       	snd_card_file_remove(pcm->card, file);
       __error1:
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return err;
 }
 
@@ -1640,9 +1671,6 @@
 	wake_up(&pcm->open_wait);
 	module_put(pcm->card->module);
 	snd_card_file_remove(pcm->card, file);
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -2123,7 +2151,7 @@
 static int snd_pcm_oss_register_minor(snd_pcm_t * pcm)
 {
 	pcm->oss.reg = 0;
-	if (dsp_map[pcm->card->number] == pcm->device) {
+	if (dsp_map[pcm->card->number] == (int)pcm->device) {
 		char name[128];
 		int duplex;
 		register_oss_dsp(pcm, 0);
@@ -2139,7 +2167,7 @@
 		pcm->oss.reg++;
 		pcm->oss.reg_mask |= 1;
 	}
-	if (adsp_map[pcm->card->number] == pcm->device) {
+	if (adsp_map[pcm->card->number] == (int)pcm->device) {
 		register_oss_dsp(pcm, 1);
 		pcm->oss.reg++;
 		pcm->oss.reg_mask |= 2;
@@ -2172,7 +2200,7 @@
 {
 	snd_pcm_oss_disconnect_minor(pcm);
 	if (pcm->oss.reg) {
-		if (dsp_map[pcm->card->number] == pcm->device) {
+		if (dsp_map[pcm->card->number] == (int)pcm->device) {
 #ifdef SNDRV_OSS_INFO_DEV_AUDIO
 			snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_AUDIO, pcm->card->number);
 #endif
diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
--- a/sound/core/oss/pcm_plugin.c	Mon Feb 10 10:39:24 2003
+++ b/sound/core/oss/pcm_plugin.c	Mon Feb 10 10:39:24 2003
@@ -811,7 +811,7 @@
 			}
 			frames = err;
 			if (!plugin->prev) {
-				if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final) < 0))
+				if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0)
 					return err;
 			}
 		} else {
diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c	Mon Feb 10 10:39:33 2003
+++ b/sound/core/pcm.c	Mon Feb 10 10:39:33 2003
@@ -105,7 +105,7 @@
 			if (subdevice >= pstr->substream_count)
 				return -ENXIO;
 			for (substream = pstr->substream; substream; substream = substream->next)
-				if (substream->number == subdevice)
+				if (substream->number == (int)subdevice)
 					break;
 			if (substream == NULL)
 				return -ENXIO;
@@ -542,6 +542,19 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_new_stream - create a new PCM stream
+ * @pcm: the pcm instance
+ * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
+ * @substream_count: the number of substreams
+ *
+ * Creates a new stream for the pcm.
+ * The corresponding stream on the pcm must have been empty before
+ * calling this, i.e. zero must be given to the argument of
+ * snd_pcm_new().
+ *
+ * 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 idx, err;
@@ -582,7 +595,7 @@
 			snd_magic_kfree(substream);
 			return err;
 		}
-		substream->dma_type = SNDRV_PCM_DMA_TYPE_ISA;
+		substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN;
 		substream->dma_private = NULL;
 		spin_lock_init(&substream->timer_lock);
 		prev = substream;
@@ -590,6 +603,22 @@
 	return 0;
 }				
 
+/**
+ * snd_pcm_new - create a new PCM instance
+ * @card: the card instance
+ * @id: the id string
+ * @device: the device index (zero based)
+ * @playback_count: the number of substreams for playback
+ * @capture_count: the number of substreams for capture
+ * @rpcm: the pointer to store the new pcm instance
+ *
+ * Creates a new PCM instance.
+ *
+ * The pcm operators have to be set afterwards to the new instance
+ * via snd_pcm_set_ops().
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_new(snd_card_t * card, char *id, int device,
 		int playback_count, int capture_count,
 	        snd_pcm_t ** rpcm)
@@ -660,6 +689,7 @@
 	snd_assert(pcm != NULL, return -ENXIO);
 	if (pcm->private_free)
 		pcm->private_free(pcm);
+	snd_pcm_lib_preallocate_free_for_all(pcm);
 	snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
 	snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
 	snd_magic_kfree(pcm);
@@ -774,6 +804,7 @@
 	runtime->status->state = SNDRV_PCM_STATE_OPEN;
 
 	substream->runtime = runtime;
+	substream->private_data = pcm->private_data;
 	pstr->substream_opened++;
 	*rsubstream = substream;
 	return 0;
diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c	Mon Feb 10 10:39:26 2003
+++ b/sound/core/pcm_lib.c	Mon Feb 10 10:39:26 2003
@@ -119,7 +119,7 @@
 
 	delta = hw_ptr_interrupt - new_hw_ptr;
 	if (delta > 0) {
-		if (delta < runtime->buffer_size / 2) {
+		if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
 			snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
 			return 0;
 		}
@@ -183,7 +183,7 @@
 
 	delta = old_hw_ptr - new_hw_ptr;
 	if (delta > 0) {
-		if (delta < runtime->buffer_size / 2) {
+		if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
 			snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
 			return 0;
 		}
@@ -214,10 +214,14 @@
 	return 0;
 }
 
-/*
- *  Operations
+/**
+ * snd_pcm_set_ops - set the PCM operators
+ * @pcm: the pcm instance
+ * @direction: stream direction, SNDRV_PCM_STREAM_XXX
+ * @ops: the operator table
+ *
+ * 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)
 {
 	snd_pcm_str_t *stream = &pcm->streams[direction];
@@ -227,10 +231,13 @@
 		substream->ops = ops;
 }
 
-/*
- *  Sync
+
+/**
+ * snd_pcm_sync - set the PCM sync id
+ * @substream: the pcm substream
+ *
+ * Sets the PCM sync identifier for the card.
  */
- 
 void snd_pcm_set_sync(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -354,7 +361,17 @@
 	return changed;
 }
 
-/* r <- v */
+/**
+ * snd_interval_refine - refine the interval value of configurator
+ * @i: the interval value to refine
+ * @v: the interval value to refer to
+ *
+ * Refines the interval value with the reference value.
+ * The interval is changed to the range satisfying both intervals.
+ * The interval status (min, max, integer, etc.) are evaluated.
+ *
+ * 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 changed = 0;
@@ -445,6 +462,13 @@
 	c->integer = (a->integer && b->integer);
 }
 
+/**
+ * snd_interval_div - refine the interval value with division
+ *
+ * c = a / b
+ *
+ * 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)
 {
 	unsigned int r;
@@ -469,7 +493,13 @@
 	c->integer = 0;
 }
 
-/* a * b / k */
+/**
+ * snd_interval_muldivk - refine the interval value
+ *
+ * c = a * b / k
+ *
+ * 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)
 {
@@ -490,7 +520,13 @@
 	c->integer = 0;
 }
 
-/* a * k / b */
+/**
+ * snd_interval_mulkdiv - refine the interval value
+ *
+ * c = a * k / b
+ *
+ * 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)
 {
@@ -520,6 +556,11 @@
 /* ---- */
 
 
+/**
+ * snd_interval_ratnum - refine the interval value
+ *
+ * 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)
@@ -612,6 +653,11 @@
 	return err;
 }
 
+/**
+ * snd_interval_ratden - refine the interval value
+ *
+ * Returns non-zero if the value is changed, zero if not changed.
+ */
 int snd_interval_ratden(snd_interval_t *i,
 		    unsigned int rats_count, ratden_t *rats,
 		    unsigned int *nump, unsigned int *denp)
@@ -698,6 +744,19 @@
 	return err;
 }
 
+/**
+ * snd_interval_list - refine the interval value from the list
+ * @i: the interval value to refine
+ * @count: the number of elements in the list
+ * @list: the value list
+ * @mask: the bit-mask to evaluate
+ *
+ * Refines the interval value from the list.
+ * When mask is non-zero, only the elements corresponding to bit 1 are
+ * evaluated.
+ *
+ * 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)
 {
         unsigned int k;
@@ -762,6 +821,17 @@
 
 /* Info constraints helpers */
 
+/**
+ * snd_pcm_hw_rule_add - add the hw-constraint rule
+ * @runtime: the pcm runtime instance
+ * @cond: condition bits
+ * @var: the variable to evaluate
+ * @func: the evaluation function
+ * @private: the private data pointer passed to function
+ * @dep: the dependent variables
+ *
+ * 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 var,
 			snd_pcm_hw_rule_func_t func, void *private,
@@ -808,6 +878,9 @@
 	return 0;
 }				    
 
+/**
+ * snd_pcm_hw_constraint_mask
+ */
 int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 			       u_int32_t mask)
 {
@@ -820,6 +893,9 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_hw_constraint_mask64
+ */
 int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 				 u_int64_t mask)
 {
@@ -833,12 +909,18 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_hw_constraint_integer
+ */
 int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var)
 {
 	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
 	return snd_interval_setinteger(constrs_interval(constrs, var));
 }
 
+/**
+ * snd_pcm_hw_constraint_minmax
+ */
 int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 				 unsigned int min, unsigned int max)
 {
@@ -859,6 +941,9 @@
 }		
 
 
+/**
+ * snd_pcm_hw_constraint_list
+ */
 int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
@@ -884,6 +969,9 @@
 	return err;
 }
 
+/**
+ * snd_pcm_hw_constraint_ratnums
+ */
 int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
@@ -908,6 +996,9 @@
 	return err;
 }
 
+/**
+ * snd_pcm_hw_constraint_ratdens
+ */
 int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
@@ -922,7 +1013,7 @@
 				  snd_pcm_hw_rule_t *rule)
 {
 	unsigned int l = (unsigned long) rule->private;
-	unsigned int width = l & 0xffff;
+	int width = l & 0xffff;
 	unsigned int msbits = l >> 16;
 	snd_interval_t *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
 	if (snd_interval_single(i) && snd_interval_value(i) == width)
@@ -930,6 +1021,9 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_hw_constraint_msbits
+ */
 int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, 
 				 unsigned int cond,
 				 unsigned int width,
@@ -949,6 +1043,9 @@
 	return snd_interval_step(hw_param_interval(params, rule->var), 0, step);
 }
 
+/**
+ * snd_pcm_hw_constraint_step
+ */
 int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
@@ -971,6 +1068,9 @@
 				 sizeof(pow2_sizes)/sizeof(int), pow2_sizes, 0);
 }		
 
+/**
+ * snd_pcm_hw_constraint_pow2
+ */
 int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var)
@@ -1004,6 +1104,9 @@
 	snd_BUG();
 }
 
+/**
+ * snd_pcm_hw_param_any
+ */
 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 			 snd_pcm_hw_param_t var)
 {
@@ -1022,16 +1125,23 @@
 	params->info = ~0U;
 }
 
-/* Fill PARAMS with full configuration space boundaries */
+/**
+ * snd_pcm_hw_params_any
+ *
+ * Fill PARAMS with full configuration space boundaries
+ */
 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
 	_snd_pcm_hw_params_any(params);
 	return snd_pcm_hw_refine(pcm, params);
 }
 
-/* Return the value for field PAR if it's fixed in configuration space 
-   defined by PARAMS. Return -EINVAL otherwise
-*/
+/**
+ * snd_pcm_hw_param_value
+ *
+ * Return the value for field PAR if it's fixed in configuration space 
+ *  defined by PARAMS. Return -EINVAL otherwise
+ */
 int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
 			   snd_pcm_hw_param_t var, int *dir)
 {
@@ -1055,7 +1165,11 @@
 	return -EINVAL;
 }
 
-/* Return the minimum value for field PAR. */
+/**
+ * snd_pcm_hw_param_value_min
+ *
+ * Return the minimum value for field PAR.
+ */
 unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
 					snd_pcm_hw_param_t var, int *dir)
 {
@@ -1074,7 +1188,11 @@
 	return -EINVAL;
 }
 
-/* Return the maximum value for field PAR. */
+/**
+ * snd_pcm_hw_param_value_max
+ *
+ * Return the maximum value for field PAR.
+ */
 unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
 					snd_pcm_hw_param_t var, int *dir)
 {
@@ -1122,10 +1240,13 @@
 	return changed;
 }
 	
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   non integer values. Reduce configuration space accordingly.
-   Return -EINVAL if the configuration space is empty
-*/
+/**
+ * snd_pcm_hw_param_setinteger
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ * 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,
 				snd_pcm_hw_param_t var)
@@ -1161,10 +1282,13 @@
 }
 
 
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   values > minimum. Reduce configuration space accordingly.
-   Return the minimum.
-*/
+/**
+ * snd_pcm_hw_param_first
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ * values > minimum. Reduce configuration space accordingly.
+ * Return the minimum.
+ */
 int snd_pcm_hw_param_first(snd_pcm_t *pcm, 
 			   snd_pcm_hw_params_t *params, 
 			   snd_pcm_hw_param_t var, int *dir)
@@ -1199,10 +1323,13 @@
 }
 
 
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   values < maximum. Reduce configuration space accordingly.
-   Return the maximum.
-*/
+/**
+ * snd_pcm_hw_param_last
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ * values < maximum. Reduce configuration space accordingly.
+ * Return the maximum.
+ */
 int snd_pcm_hw_param_last(snd_pcm_t *pcm, 
 			  snd_pcm_hw_params_t *params,
 			  snd_pcm_hw_param_t var, int *dir)
@@ -1247,10 +1374,13 @@
 	return changed;
 }
 
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   values < VAL. Reduce configuration space accordingly.
-   Return new minimum or -EINVAL if the configuration space is empty
-*/
+/**
+ * snd_pcm_hw_param_min
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ * values < VAL. Reduce configuration space accordingly.
+ * Return new minimum or -EINVAL if the configuration space is empty
+ */
 int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 			 snd_pcm_hw_param_t var, unsigned int val, int *dir)
 {
@@ -1297,10 +1427,13 @@
 	return changed;
 }
 
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   values >= VAL + 1. Reduce configuration space accordingly.
-   Return new maximum or -EINVAL if the configuration space is empty
-*/
+/**
+ * snd_pcm_hw_param_max
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ *  values >= VAL + 1. Reduce configuration space accordingly.
+ *  Return new maximum or -EINVAL if the configuration space is empty
+ */
 int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
 			  snd_pcm_hw_param_t var, unsigned int val, int *dir)
 {
@@ -1364,10 +1497,13 @@
 	return changed;
 }
 
-/* Inside configuration space defined by PARAMS remove from PAR all 
-   values != VAL. Reduce configuration space accordingly.
-   Return VAL or -EINVAL if the configuration space is empty
-*/
+/**
+ * snd_pcm_hw_param_set
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all 
+ * 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,
 			 snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
@@ -1395,13 +1531,16 @@
 	return changed;
 }
 
-/* Inside configuration space defined by PARAMS remove from PAR all values
-   not contained in MASK. Reduce configuration space accordingly.
-   This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
-   SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
-   Return 0 on success or -EINVAL
-   if the configuration space is empty
-*/
+/**
+ * snd_pcm_hw_param_mask
+ *
+ * Inside configuration space defined by PARAMS remove from PAR all values
+ * not contained in MASK. Reduce configuration space accordingly.
+ * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
+ * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
+ * 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)
 {
@@ -1464,12 +1603,15 @@
 	return boundary_lt(dmin, dmindir, dmax, dmaxdir);
 }
 
-/* Inside configuration space defined by PARAMS set PAR to the available value
-   nearest to VAL. Reduce configuration space accordingly.
-   This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
-   SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
-   Return the value found.
- */
+/**
+ * snd_pcm_hw_param_near
+ *
+ * Inside configuration space defined by PARAMS set PAR to the available value
+ * nearest to VAL. Reduce configuration space accordingly.
+ * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
+ * 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,
 			  snd_pcm_hw_param_t var, unsigned int best, int *dir)
 {
@@ -1537,17 +1679,14 @@
 	return v;
 }
 
-/* Choose one configuration from configuration space defined by PARAMS
-   The configuration choosen is that obtained fixing in this order:
-   first access
-   first format
-   first subformat
-   min channels
-   min rate
-   min period time
-   max buffer size
-   min tick time
-*/
+/**
+ * snd_pcm_hw_param_choose
+ *
+ * Choose one configuration from configuration space defined by PARAMS
+ * The configuration choosen is that obtained fixing in this order:
+ * 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 err;
@@ -1630,6 +1769,17 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_lib_ioctl - a generic PCM ioctl callback
+ * @substream: the pcm substream instance
+ * @cmd: ioctl command
+ * @arg: ioctl argument
+ *
+ * Processes the generic ioctl commands for PCM.
+ * Can be passed as the ioctl callback for PCM ops.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream,
 		      unsigned int cmd, void *arg)
 {
@@ -1648,30 +1798,74 @@
  *  Conditions
  */
 
+/**
+ * snd_pcm_playback_ready - check whether the playback buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough free space is available on the playback buffer.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
 int snd_pcm_playback_ready(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
 }
 
+/**
+ * snd_pcm_capture_ready - check whether the capture buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough capture data is available on the capture buffer.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
 int snd_pcm_capture_ready(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
 }
 
+/**
+ * snd_pcm_playback_data - check whether any data exists on the playback buffer
+ * @substream: the pcm substream instance
+ *
+ * Checks whether any data exists on the playback buffer. If stop_threshold
+ * is bigger or equal to boundary, then this function returns always non-zero.
+ *
+ * Returns non-zero if exists, or zero if not.
+ */
 int snd_pcm_playback_data(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
+	
+	if (runtime->stop_threshold >= runtime->boundary)
+		return 1;
 	return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
 }
 
+/**
+ * snd_pcm_playback_empty - check whether the playback buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the playback buffer is empty.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
 int snd_pcm_playback_empty(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
 }
 
+/**
+ * snd_pcm_capture_empty - check whether the capture buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the capture buffer is empty.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
 int snd_pcm_capture_empty(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1711,7 +1905,7 @@
 		    runtime->silenced_size < runtime->buffer_size) {
 			snd_pcm_sframes_t noise_dist;
 			noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silenced_size;
-			snd_assert(noise_dist <= runtime->silence_threshold, );
+			snd_assert(noise_dist <= (snd_pcm_sframes_t)runtime->silence_threshold, );
 			frames = noise_dist - runtime->silence_threshold;
 		}
 		avail = snd_pcm_playback_avail(runtime);
@@ -1720,12 +1914,12 @@
 	}
 	if (avail < runtime->control->avail_min) {
 		snd_pcm_sframes_t n = runtime->control->avail_min - avail;
-		if (n > 0 && frames > n)
+		if (n > 0 && frames > (snd_pcm_uframes_t)n)
 			frames = n;
 	}
 	if (avail < runtime->buffer_size) {
 		snd_pcm_sframes_t n = runtime->buffer_size - avail;
-		if (n > 0 && frames > n)
+		if (n > 0 && frames > (snd_pcm_uframes_t)n)
 			frames = n;
 	}
 	if (frames == ULONG_MAX) {
@@ -1766,6 +1960,17 @@
 	spin_unlock_irq(&runtime->lock);
 }
 
+/**
+ * snd_pcm_period_elapsed - update the pcm status for the next period
+ * @substream: the pcm substream instance
+ *
+ * This function is called from the interrupt handler when the
+ * PCM has processed the period size.  It will update the current
+ * pointer, set up the tick, wake up sleepers, etc.
+ *
+ * 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)
 {
 	snd_pcm_runtime_t *runtime;
@@ -1956,7 +2161,7 @@
 		size -= frames;
 		xfer += frames;
 		if (runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
-		    snd_pcm_playback_hw_avail(runtime) >= runtime->start_threshold) {
+		    snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
 			err = snd_pcm_start(substream);
 			if (err < 0)
 				goto _end_unlock;
@@ -1968,7 +2173,7 @@
  _end_unlock:
 	spin_unlock_irq(&runtime->lock);
  _end:
-	return xfer > 0 ? xfer : err;
+	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
 snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void *buf, snd_pcm_uframes_t size)
@@ -2254,7 +2459,7 @@
  _end_unlock:
 	spin_unlock_irq(&runtime->lock);
  _end:
-	return xfer > 0 ? xfer : err;
+	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
 snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void *buf, snd_pcm_uframes_t size)
@@ -2377,6 +2582,7 @@
 EXPORT_SYMBOL(snd_pcm_hw_param_first);
 EXPORT_SYMBOL(snd_pcm_hw_param_last);
 EXPORT_SYMBOL(snd_pcm_hw_param_near);
+EXPORT_SYMBOL(snd_pcm_hw_param_set);
 EXPORT_SYMBOL(snd_pcm_hw_refine);
 EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
 EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
--- a/sound/core/pcm_memory.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/pcm_memory.c	Mon Feb 10 10:39:29 2003
@@ -26,6 +26,9 @@
 #include <sound/pcm.h>
 #include <sound/info.h>
 #include <sound/initval.h>
+#ifdef CONFIG_PCI
+#include <sound/pcm_sgbuf.h>
+#endif
 
 static int preallocate_dma = 1;
 MODULE_PARM(preallocate_dma, "i");
@@ -37,36 +40,127 @@
 MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory.");
 MODULE_PARM_SYNTAX(maximum_substreams, SNDRV_BOOLEAN_TRUE_DESC);
 
-static int snd_minimum_buffer = 16384;
+const static size_t snd_minimum_buffer = 16384;
 
 
-static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream)
+/*
+ * allocate pages on the specified bus
+ */
+static int alloc_pcm_pages(snd_pcm_substream_t *substream, size_t size,
+			   void **dma_area, dma_addr_t *dma_addr)
+{
+	switch (substream->dma_type) {
+	case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
+		*dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff));
+		*dma_addr = 0UL;		/* not valid */
+		break;
+#ifdef CONFIG_ISA
+	case SNDRV_PCM_DMA_TYPE_ISA:
+		*dma_area = snd_malloc_isa_pages(size, dma_addr); 
+		break;
+#endif
+#ifdef CONFIG_PCI
+	case SNDRV_PCM_DMA_TYPE_PCI:
+		*dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, dma_addr);
+		break;
+	case SNDRV_PCM_DMA_TYPE_PCI_SG:
+		*dma_area = snd_pcm_sgbuf_alloc_pages((struct snd_sg_buf *)substream->dma_private, size);
+		*dma_addr = 0;
+		break;
+#endif
+#ifdef CONFIG_SBUS
+	case SNDRV_PCM_DMA_TYPE_SBUS:
+		*dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, dma_addr);
+		break;
+#endif
+	default:
+		*dma_area = NULL;
+		*dma_addr = 0;
+		return -ENXIO;
+	}
+	return 0;
+}
+
+/*
+ * try to allocate as the large pages as possible.
+ * stores the resultant memory size in *res_size.
+ *
+ * the minimum size is snd_minimum_buffer.  it should be power of 2.
+ */
+static void *alloc_pcm_pages_fallback(snd_pcm_substream_t *substream,
+				      size_t size, dma_addr_t *addrp,
+				      size_t *res_size)
+{
+	void *res;
+
+	snd_assert(size > 0, return NULL);
+	snd_assert(res_size != NULL, return NULL);
+	do {
+		if (alloc_pcm_pages(substream, size, &res, addrp) < 0)
+			return NULL;
+		if (res) {
+			*res_size = size;
+			return res;
+		}
+		size >>= 1;
+	} while (size >= snd_minimum_buffer);
+	*res_size = 0; /* tell error */
+	return NULL;
+}
+
+/*
+ * release the pages on the specified bus
+ */
+static void free_pcm_pages(snd_pcm_substream_t *substream, size_t size,
+			   void *dma_area, dma_addr_t dma_addr)
 {
-	if (substream->dma_area == NULL)
-		return;
 	switch (substream->dma_type) {
 	case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-		snd_free_pages(substream->dma_area, substream->dma_bytes);
+		snd_free_pages(dma_area, size);
 		break;
 #ifdef CONFIG_ISA
 	case SNDRV_PCM_DMA_TYPE_ISA:
-		snd_free_isa_pages(substream->dma_bytes, substream->dma_area, substream->dma_addr);
+		snd_free_isa_pages(size, dma_area, dma_addr);
 		break;
 #endif
 #ifdef CONFIG_PCI
 	case SNDRV_PCM_DMA_TYPE_PCI:
-		snd_free_pci_pages((struct pci_dev *)substream->dma_private, substream->dma_bytes, substream->dma_area, substream->dma_addr);
+		snd_free_pci_pages((struct pci_dev *)substream->dma_private,
+				   size, dma_area, dma_addr);
+		break;
+	case SNDRV_PCM_DMA_TYPE_PCI_SG:
+		snd_pcm_sgbuf_free_pages((struct snd_sg_buf *)substream->dma_private, dma_area);
 		break;
 #endif
 #ifdef CONFIG_SBUS
 	case SNDRV_PCM_DMA_TYPE_SBUS:
-		snd_free_sbus_pages((struct sbus_dev *)substream->dma_private, substream->dma_bytes, substream->dma_area, substream->dma_addr);
+		snd_free_sbus_pages((struct sbus_dev *)substream->dma_private,
+				    size, dma_area, dma_addr);
 		break;
 #endif
 	}
+}
+
+/*
+ * release the preallocated buffer if not yet done.
+ */
+static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream)
+{
+	if (substream->dma_area == NULL)
+		return;
+	free_pcm_pages(substream, substream->dma_bytes,
+		       substream->dma_area, substream->dma_addr);
 	substream->dma_area = NULL;
 }
 
+/**
+ * snd_pcm_lib_preallocate_free - release the preallocated buffer of the specified substream.
+ * @substream: the pcm substream instance
+ *
+ * Releases the pre-allocated buffer of the given substream.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream)
 {
 	snd_pcm_lib_preallocate_dma_free(substream);
@@ -74,9 +168,22 @@
 		snd_info_unregister(substream->proc_prealloc_entry);
 		substream->proc_prealloc_entry = NULL;
 	}
+#ifdef CONFIG_PCI
+	if (substream->dma_type == SNDRV_PCM_DMA_TYPE_PCI_SG)
+		snd_pcm_sgbuf_delete((struct snd_sg_buf *)substream->dma_private);
+#endif
+	substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN;
 	return 0;
 }
 
+/**
+ * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm
+ * @pcm: the pcm instance
+ *
+ * Releases all the pre-allocated buffers on the given pcm.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm)
 {
 	snd_pcm_substream_t *substream;
@@ -88,6 +195,11 @@
 	return 0;
 }
 
+/*
+ * 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)
 {
@@ -95,6 +207,11 @@
 	snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_bytes / 1024);
 }
 
+/*
+ * write callback for prealloc proc file
+ *
+ * accepts the preallocation size in kB.
+ */
 static void snd_pcm_lib_preallocate_proc_write(snd_info_entry_t *entry,
 					       snd_info_buffer_t *buffer)
 {
@@ -118,27 +235,7 @@
 		if (substream->dma_bytes == size)
 			return;
 		if (size > 0) {
-			switch (substream->dma_type) {
-			case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-				dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff));
-				dma_addr = 0UL;		/* not valid */
-				break;
-#ifdef CONFIG_ISA
-			case SNDRV_PCM_DMA_TYPE_ISA:
-				dma_area = snd_malloc_isa_pages(size, &dma_addr);
-				break;
-#endif
-#ifdef CONFIG_PCI
-			case SNDRV_PCM_DMA_TYPE_PCI:
-				dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, &dma_addr);
-				break;
-#endif
-#ifdef CONFIG_SBUS
-			case SNDRV_PCM_DMA_TYPE_SBUS:
-				dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, &dma_addr);
-				break;
-#endif
-			default:
+			if (alloc_pcm_pages(substream, size, &dma_area, &dma_addr) < 0) {
 				dma_area = NULL;
 				dma_addr = 0UL;
 			}
@@ -160,45 +257,19 @@
 	}
 }
 
+/*
+ * 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)
 {
-	unsigned long rsize = 0;
+	size_t rsize = 0;
 	void *dma_area = NULL;
 	dma_addr_t dma_addr = 0UL;
 	snd_info_entry_t *entry;
 
-	if (!size || !preallocate_dma || substream->number >= maximum_substreams) {
-		size = 0;
-	} else {
-		switch (substream->dma_type) {
-		case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-			dma_area = snd_malloc_pages_fallback(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff), &rsize);
-			dma_addr = 0UL;		/* not valid */
-			break;
-#ifdef CONFIG_ISA
-		case SNDRV_PCM_DMA_TYPE_ISA:
-			dma_area = snd_malloc_isa_pages_fallback(size, &dma_addr, &rsize);
-			break;
-#endif
-#ifdef CONFIG_PCI
-		case SNDRV_PCM_DMA_TYPE_PCI:
-			dma_area = snd_malloc_pci_pages_fallback((struct pci_dev *)substream->dma_private, size, &dma_addr, &rsize);
-			break;
-#endif
-#ifdef CONFIG_SBUS
-		case SNDRV_PCM_DMA_TYPE_SBUS:
-			dma_area = snd_malloc_sbus_pages_fallback((struct sbus_dev *)substream->dma_private, size, &dma_addr, &rsize);
-			break;
-#endif
-		default:
-			size = 0;
-		}
-		if (rsize < snd_minimum_buffer) {
-			snd_pcm_lib_preallocate_dma_free(substream);
-			size = 0;
-		}
-	}
+	if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
+		dma_area = alloc_pcm_pages_fallback(substream, size, &dma_addr, &rsize);
 	substream->dma_area = dma_area;
 	substream->dma_addr = dma_addr;
 	substream->dma_bytes = rsize;
@@ -220,6 +291,17 @@
 	return 0;
 }
 
+/**
+ * snd_pcm_lib_preallocate_pages - pre-allocation for the continuous memory type
+ * @substream: the pcm substream instance
+ * @size: the requested pre-allocation size in bytes
+ * @max: the max. allowed pre-allocation size
+ * @flags: allocation condition, GFP_XXX
+ *
+ * Do pre-allocation for the continuous memory type.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream,
 				      size_t size, size_t max,
 				      unsigned int flags)
@@ -229,6 +311,18 @@
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
+/**
+ * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
+ * @pcm: pcm to assign the buffer
+ * @size: the requested pre-allocation size in bytes
+ * @max: max. buffer size acceptable for the changes via proc file
+ * @flags: allocation condition, GFP_XXX
+ *
+ * Do pre-allocation to all substreams of the given pcm for the
+ * continuous memory type.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm,
 					  size_t size, size_t max,
 					  unsigned int flags)
@@ -244,6 +338,16 @@
 }
 
 #ifdef CONFIG_ISA
+/**
+ * snd_pcm_lib_preallocate_isa_pages - pre-allocation for the ISA bus
+ * @substream: substream to assign the buffer
+ * @size: the requested pre-allocation size in bytes
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation for the ISA bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_isa_pages(snd_pcm_substream_t *substream,
 				      size_t size, size_t max)
 {
@@ -252,6 +356,18 @@
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
+/*
+ * FIXME: the function name is too long for docbook!
+ *
+ * snd_pcm_lib_preallocate_isa_pages_for_all - pre-allocation for the ISA bus (all substreams)
+ * @pcm: pcm to assign the buffer
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation to all substreams of the given pcm for the
+ * ISA bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_isa_pages_for_all(snd_pcm_t *pcm,
 					      size_t size, size_t max)
 {
@@ -266,12 +382,24 @@
 }
 #endif /* CONFIG_ISA */
 
+/**
+ * snd_pcm_lib_malloc_pages - allocate the DMA buffer
+ * @substream: the substream to allocate the DMA buffer to
+ * @size: the requested buffer size in bytes
+ *
+ * Allocates the DMA buffer on the BUS type given by
+ * snd_pcm_lib_preallocate_xxx_pages().
+ *
+ * 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)
 {
 	snd_pcm_runtime_t *runtime;
 	void *dma_area = NULL;
 	dma_addr_t dma_addr = 0UL;
 
+	snd_assert(substream->dma_type != SNDRV_PCM_DMA_TYPE_UNKNOWN, return -EINVAL);
 	snd_assert(substream != NULL, return -EINVAL);
 	runtime = substream->runtime;
 	snd_assert(runtime != NULL, return -EINVAL);	
@@ -287,29 +415,7 @@
 		dma_area = substream->dma_area;
 		dma_addr = substream->dma_addr;
 	} else {
-		switch (substream->dma_type) {
-		case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-			dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff));
-			dma_addr = 0UL;		/* not valid */
-			break;
-#ifdef CONFIG_ISA
-		case SNDRV_PCM_DMA_TYPE_ISA:
-			dma_area = snd_malloc_isa_pages(size, &dma_addr); 
-			break;
-#endif
-#ifdef CONFIG_PCI
-		case SNDRV_PCM_DMA_TYPE_PCI:
-			dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, &dma_addr);
-			break;
-#endif
-#ifdef CONFIG_SBUS
-		case SNDRV_PCM_DMA_TYPE_SBUS:
-			dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, &dma_addr);
-			break;
-#endif
-		default:
-			return -ENXIO;
-		}
+		alloc_pcm_pages(substream, size, &dma_area, &dma_addr);
 	}
 	if (! dma_area)
 		return -ENOMEM;
@@ -319,6 +425,14 @@
 	return 1;			/* area was changed */
 }
 
+/**
+ * snd_pcm_lib_free_pages - release the allocated DMA buffer.
+ * @substream: the substream to release the DMA buffer
+ *
+ * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages().
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime;
@@ -328,25 +442,9 @@
 	snd_assert(runtime != NULL, return -EINVAL);
 	if (runtime->dma_area == NULL)
 		return 0;
-	if (runtime->dma_area != substream->dma_area) {
-		switch (substream->dma_type) {
-#ifdef CONFIG_ISA
-		case SNDRV_PCM_DMA_TYPE_ISA:
-			snd_free_isa_pages(runtime->dma_bytes, runtime->dma_area, runtime->dma_addr);
-			break;
-#endif
-#ifdef CONFIG_PCI
-		case SNDRV_PCM_DMA_TYPE_PCI:
-			snd_free_pci_pages((struct pci_dev *)substream->dma_private, runtime->dma_bytes, runtime->dma_area, runtime->dma_addr);
-			break;
-#endif
-#ifdef CONFIG_SBUS
-		case SNDRV_PCM_DMA_TYPE_SBUS:
-			snd_free_sbus_pages((struct sbus_dev *)substream->dma_private, runtime->dma_bytes, runtime->dma_area, runtime->dma_addr);
-			break;
-#endif
-		}
-	}
+	if (runtime->dma_area != substream->dma_area)
+		free_pcm_pages(substream, runtime->dma_bytes,
+			       runtime->dma_area, runtime->dma_addr);
 	runtime->dma_area = NULL;
 	runtime->dma_addr = 0UL;
 	runtime->dma_bytes = 0;
@@ -354,7 +452,18 @@
 }
 
 #ifdef CONFIG_PCI
-
+/**
+ * snd_pcm_lib_preallocate_pci_pages - pre-allocation for the PCI bus
+ *
+ * @pci: pci device
+ * @substream: substream to assign the buffer
+ * @size: the requested pre-allocation size in bytes
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation for the PCI bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_pci_pages(struct pci_dev *pci,
 				      snd_pcm_substream_t *substream,
 				      size_t size, size_t max)
@@ -364,6 +473,20 @@
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
+/*
+ * FIXME: the function name is too long for docbook!
+ *
+ * snd_pcm_lib_preallocate_pci_pages_for_all - pre-allocation for the PCI bus (all substreams)
+ * @pci: pci device
+ * @pcm: pcm to assign the buffer
+ * @size: the requested pre-allocation size in bytes
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation to all substreams of the given pcm for the
+ * PCI bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_pci_pages_for_all(struct pci_dev *pci,
 					      snd_pcm_t *pcm,
 					      size_t size, size_t max)
@@ -381,7 +504,17 @@
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_SBUS
-
+/**
+ * snd_pcm_lib_preallocate_sbus_pages - pre-allocation for the SBUS bus
+ *
+ * @sbus: SBUS device
+ * @substream: substream to assign the buffer
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation for the SBUS.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_sbus_pages(struct sbus_dev *sdev,
 				       snd_pcm_substream_t *substream,
 				       size_t size, size_t max)
@@ -391,6 +524,20 @@
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
+/*
+ * FIXME: the function name is too long for docbook!
+ *
+ * snd_pcm_lib_preallocate_sbus_pages_for_all - pre-allocation for the SBUS bus (all substreams)
+ * @sbus: SBUS device
+ * @pcm: pcm to assign the buffer
+ * @size: the requested pre-allocation size in bytes
+ * @max: max. buffer size acceptable for the changes via proc file
+ *
+ * Do pre-allocation to all substreams of the given pcm for the
+ * SUBS.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_pcm_lib_preallocate_sbus_pages_for_all(struct sbus_dev *sdev,
 					       snd_pcm_t *pcm,
 					       size_t size, size_t max)
diff -Nru a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
--- a/sound/core/pcm_misc.c	Mon Feb 10 10:39:30 2003
+++ b/sound/core/pcm_misc.c	Mon Feb 10 10:39:30 2003
@@ -30,6 +30,13 @@
 #define snd_enum_to_int(v) (v)
 #define snd_int_to_enum(v) (v)
 
+/**
+ * snd_pcm_format_signed - Check the PCM format is signed linear
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is signed linear, 0 if unsigned
+ * linear, and a negative error code for non-linear formats.
+ */
 int snd_pcm_format_signed(snd_pcm_format_t format)
 {
 	switch (snd_enum_to_int(format)) {
@@ -66,6 +73,13 @@
 	}
 }
 
+/**
+ * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is unsigned linear, 0 if signed
+ * linear, and a negative error code for non-linear formats.
+ */
 int snd_pcm_format_unsigned(snd_pcm_format_t format)
 {
 	int val;
@@ -76,11 +90,24 @@
 	return !val;
 }
 
+/**
+ * snd_pcm_format_linear - Check the PCM format is linear
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is linear, 0 if not.
+ */
 int snd_pcm_format_linear(snd_pcm_format_t format)
 {
 	return snd_pcm_format_signed(format) >= 0;
 }
 
+/**
+ * snd_pcm_format_little_endian - Check the PCM format is little-endian
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is little-endian, 0 if
+ * big-endian, or a negative error code if endian not specified.
+ */
 int snd_pcm_format_little_endian(snd_pcm_format_t format)
 {
 	switch (snd_enum_to_int(format)) {
@@ -121,6 +148,13 @@
 	}
 }
 
+/**
+ * snd_pcm_format_big_endian - Check the PCM format is big-endian
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is big-endian, 0 if
+ * little-endian, or a negative error code if endian not specified.
+ */
 int snd_pcm_format_big_endian(snd_pcm_format_t format)
 {
 	int val;
@@ -131,6 +165,13 @@
 	return !val;
 }
 
+/**
+ * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is CPU-endian, 0 if
+ * opposite, or a negative error code if endian not specified.
+ */
 int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
 {
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -140,6 +181,13 @@
 #endif
 }
 
+/**
+ * snd_pcm_format_width - return the bit-width of the format
+ * @format: the format to check
+ *
+ * Returns the bit-width of the format, or a negative error code
+ * if unknown format.
+ */
 int snd_pcm_format_width(snd_pcm_format_t format)
 {
 	switch (snd_enum_to_int(format)) {
@@ -193,6 +241,13 @@
 	}
 }
 
+/**
+ * snd_pcm_format_physical_width - return the physical bit-width of the format
+ * @format: the format to check
+ *
+ * Returns the physical bit-width of the format, or a negative error code
+ * if unknown format.
+ */
 int snd_pcm_format_physical_width(snd_pcm_format_t format)
 {
 	switch (snd_enum_to_int(format)) {
@@ -243,6 +298,13 @@
 	}
 }
 
+/**
+ * snd_pcm_format_size - return the byte size of samples on the given format
+ * @format: the format to check
+ *
+ * Returns the byte size of the given samples for the format, or a
+ * negative error code if unknown format.
+ */
 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
 {
 	switch (snd_enum_to_int(format)) {
@@ -296,6 +358,12 @@
 	}
 }
 
+/**
+ * snd_pcm_format_silence_64 - return the silent data in 64bit integer
+ * @format: the format to check
+ *
+ * Returns the silent data in 64bit integer for the given format.
+ */
 u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 {
 	switch (snd_enum_to_int(format)) {
@@ -451,6 +519,16 @@
 	return (u_int8_t)snd_pcm_format_silence_64(format);
 }
 
+/**
+ * snd_pcm_format_set_silence - set the silence data on the buffer
+ * @format: the PCM format
+ * @data: the buffer pointer
+ * @samples: the number of samples to set silence
+ *
+ * Sets the silence data on the buffer for the given samples.
+ *
+ * Returns zero if sucessful, or a negative error code on failure.
+ */
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
 {
 	if (samples == 0)
@@ -497,6 +575,7 @@
 #endif
 			}
 		}
+		break;
 	}
 	case 32: {
 		u_int32_t silence = snd_pcm_format_silence_64(format);
@@ -543,6 +622,14 @@
 	SNDRV_PCM_FORMAT_U32_BE
 };
 
+/**
+ * snd_pcm_build_linear_format - return the suitable linear format for the given condition
+ * @width: the bit-width
+ * @unsignd: 1 if unsigned, 0 if signed.
+ * @big_endian: 1 if big-endian, 0 if little-endian
+ *
+ * Returns the suitable linear format for the given condition.
+ */
 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
 {
 	switch (width) {
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	Mon Feb 10 10:39:24 2003
+++ b/sound/core/pcm_native.c	Mon Feb 10 10:39:24 2003
@@ -76,6 +76,8 @@
 	set_fs(fs);
 }
 
+
+
 int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info)
 {
 	snd_pcm_runtime_t * runtime;
@@ -674,6 +676,9 @@
 		snd_pcm_tick_prepare(substream);
 }
 
+/**
+ * snd_pcm_sart
+ */
 int snd_pcm_start(snd_pcm_substream_t *substream)
 {
 	SND_PCM_ACTION(start, substream, 0);
@@ -703,6 +708,9 @@
 	wake_up(&runtime->sleep);
 }
 
+/**
+ * snd_pcm_stop
+ */
 int snd_pcm_stop(snd_pcm_substream_t *substream, int state)
 {
 	SND_PCM_ACTION(stop, substream, state);
@@ -779,11 +787,17 @@
 	wake_up(&runtime->sleep);
 }
 
+/**
+ * snd_pcm_suspend
+ */
 int snd_pcm_suspend(snd_pcm_substream_t *substream)
 {
 	SND_PCM_ACTION(suspend, substream, 0);
 }
 
+/**
+ * snd_pcm_suspend_all
+ */
 int snd_pcm_suspend_all(snd_pcm_t *pcm)
 {
 	snd_pcm_substream_t *substream;
@@ -976,6 +990,9 @@
 	runtime->status->state = SNDRV_PCM_STATE_PREPARED;
 }
 
+/**
+ * snd_pcm_prepare
+ */
 int snd_pcm_prepare(snd_pcm_substream_t *substream)
 {
 	int res;
@@ -1081,6 +1098,8 @@
 		/* Fall through */
 	case SNDRV_PCM_STATE_SETUP:
 		goto _end;
+	default: 
+		break; 
 	}
 
 	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
@@ -1183,6 +1202,8 @@
 			spin_lock_irq(&runtime->lock);
 		}
 		goto _xrun_recovery;
+	default:
+		break; 
 	}
 	runtime->control->appl_ptr = runtime->status->hw_ptr;
        _end:
@@ -1236,6 +1257,8 @@
 			spin_lock_irq(&runtime->lock);
 		}
 		goto _xrun_recovery;
+	default: 
+		break; 
 	}
        _end:
 	spin_unlock_irq(&runtime->lock);
@@ -1278,6 +1301,8 @@
 	case SNDRV_PCM_STATE_XRUN:
 		snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
 		break;
+	default: 
+		break; 
 	}
 	runtime->control->appl_ptr = runtime->status->hw_ptr;
        _end: 
@@ -1779,9 +1804,6 @@
 	snd_pcm_file_t *pcm_file;
 	wait_queue_t wait;
 
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	snd_runtime_check(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) {
@@ -1829,9 +1851,6 @@
       __error2:
       	snd_card_file_remove(pcm->card, file);
       __error1:
-#ifdef LINUX_2_2
-      	MOD_DEC_USE_COUNT;
-#endif
       	return err;
 }
 
@@ -1857,9 +1876,6 @@
 	wake_up(&pcm->open_wait);
 	module_put(pcm->card->module);
 	snd_card_file_remove(pcm->card, file);
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -1895,7 +1911,7 @@
 		ret = 0;
 		goto __end;
 	}
-	if (frames > hw_avail)
+	if (frames > (snd_pcm_uframes_t)hw_avail)
 		frames = hw_avail;
 	else
 		frames -= frames % runtime->xfer_align;
@@ -1944,7 +1960,7 @@
 		ret = 0;
 		goto __end;
 	}
-	if (frames > hw_avail)
+	if (frames > (snd_pcm_uframes_t)hw_avail)
 		frames = hw_avail;
 	else
 		frames -= frames % runtime->xfer_align;
@@ -2724,7 +2740,7 @@
 	offset = area->vm_offset;
 #endif
 	dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
-	if (size > dma_bytes)
+	if ((size_t)size > dma_bytes)
 		return -EINVAL;
 	if (offset > dma_bytes - size)
 		return -EINVAL;
diff -Nru a/sound/core/pcm_sgbuf.c b/sound/core/pcm_sgbuf.c
--- a/sound/core/pcm_sgbuf.c	Mon Feb 10 10:39:32 2003
+++ b/sound/core/pcm_sgbuf.c	Mon Feb 10 10:39:32 2003
@@ -21,6 +21,7 @@
 
 #include <sound/driver.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_sgbuf.h>
@@ -30,358 +31,200 @@
 #define SGBUF_TBL_ALIGN		32
 #define sgbuf_align_table(tbl)	((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN)
 
-/*
- * shrink to the given pages.
- * free the unused pages
- */
-static void sgbuf_shrink(struct snd_sg_buf *sgbuf, int pages)
-{
-	snd_assert(sgbuf, return);
-	if (! sgbuf->table)
-		return;
-	while (sgbuf->pages > pages) {
-		sgbuf->pages--;
-		snd_free_pci_pages(sgbuf->pci, PAGE_SIZE,
-				   sgbuf->table[sgbuf->pages].buf,
-				   sgbuf->table[sgbuf->pages].addr);
-	}
-}
 
 /*
- * initialize the sg buffer
- * assigned to substream->dma_private.
- * initialize the table with the given size.
+ * snd_pcm_sgbuf_new - constructor of the sgbuf instance
+ * @pci: pci device pointer
+ *
+ * Initializes the SG-buffer instance to be assigned to
+ * substream->dma_private.
+ * 
+ * Returns the pointer of the instance, or NULL at error.
  */
-int snd_pcm_sgbuf_init(snd_pcm_substream_t *substream, struct pci_dev *pci, int tblsize)
+struct snd_sg_buf *snd_pcm_sgbuf_new(struct pci_dev *pci)
 {
 	struct snd_sg_buf *sgbuf;
 
-	tblsize = sgbuf_align_table(tblsize);
 	sgbuf = snd_magic_kcalloc(snd_pcm_sgbuf_t, 0, GFP_KERNEL);
 	if (! sgbuf)
-		return -ENOMEM;
-	substream->dma_private = sgbuf;
+		return NULL;
 	sgbuf->pci = pci;
 	sgbuf->pages = 0;
-	sgbuf->tblsize = tblsize;
-	sgbuf->table = kmalloc(sizeof(struct snd_sg_page) * tblsize, GFP_KERNEL);
-	if (! sgbuf->table) {
-		snd_pcm_sgbuf_delete(substream);
-		return -ENOMEM;
-	}
-	memset(sgbuf->table, 0, sizeof(struct snd_sg_page) * tblsize);
-	return 0;
-}
+	sgbuf->tblsize = 0;
 
-/*
- * release all pages and free the sgbuf instance
- */
-int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream)
-{
-	struct snd_sg_buf *sgbuf;
-
-	/* return in case, when sgbuf is not initialized */
-	if (substream->dma_private == NULL)
-		return -EINVAL;
-	sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
-	sgbuf_shrink(sgbuf, 0);
-	if (sgbuf->table)
-		kfree(sgbuf->table);
-	snd_magic_kfree(sgbuf);
-	substream->dma_private = NULL;
-	return 0;
+	return sgbuf;
 }
 
 /*
- * snd_pci_alloc_page - allocate a page in the valid pci dma mask
+ * snd_pcm_sgbuf_delete - destructor of sgbuf instance
+ * @sgbuf: the SG-buffer instance
  *
- * returns the virtual address and stores the physical address on
- * addrp.  this function cannot be called from interrupt handlers or
- * within spinlocks.
+ * Destructor Releaes all pages and free the sgbuf instance.
  */
-#ifdef __i386__
-/*
- * on ix86, we allocate a page with GFP_KERNEL to assure the
- * allocation.  the code is almost same with kernel/i386/pci-dma.c but
- * it allocates only a single page and checkes the validity of the
- * page address with the given pci dma mask.
- */
-inline static void *snd_pci_alloc_page(struct pci_dev *pci, dma_addr_t *addrp)
+void snd_pcm_sgbuf_delete(struct snd_sg_buf *sgbuf)
 {
-	void *ptr;
-	dma_addr_t addr;
-	unsigned long rmask;
-
-	if (pci)
-		rmask = ~(unsigned long)pci->dma_mask;
-	else
-		rmask = 0;
-	ptr = (void *)__get_free_page(GFP_KERNEL);
-	if (ptr) {
-		addr = virt_to_phys(ptr);
-		if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) {
-			/* try to reallocate with the GFP_DMA */
-			free_page((unsigned long)ptr);
-			ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-			if (ptr) /* ok, the address must be within lower 16MB... */
-				addr = virt_to_phys(ptr);
-			else
-				addr = 0;
-		}
-	} else
-		addr = 0;
-	if (ptr)
-		memset(ptr, 0, PAGE_SIZE);
-	*addrp = addr;
-	return ptr;
+	snd_pcm_sgbuf_free_pages(sgbuf, NULL);
+	snd_magic_kfree(sgbuf);
 }
-#else
-/* on other architectures, call snd_malloc_pci_pages() helper function
- * which uses pci_alloc_consistent().
- */
-#define snd_pci_alloc_page(pci, addrp) snd_malloc_pci_pages(pci, PAGE_SIZE, addrp)
-#endif
 
-/*
- * allocate sg buffer table with the given byte size.
- * if the buffer table already exists, try to resize it.
- * call this from hw_params callback.
+/**
+ * snd_pcm_sgbuf_alloc_pages - allocate the pages for the SG buffer
+ * @sgbuf: the sgbuf instance
+ * @size: the requested buffer size in bytes
+ *
+ * Allocates the buffer pages for the given size and updates the
+ * sg buffer table.  The pages are mapped to the virtually continuous
+ * memory.
+ *
+ * This function is usually called from snd_pcm_lib_malloc_pages().
+ *
+ * Returns the mapped virtual address of the buffer if allocation was
+ * successful, or NULL at error.
  */
-int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size)
+void *snd_pcm_sgbuf_alloc_pages(struct snd_sg_buf *sgbuf, size_t size)
 {
-	struct snd_sg_buf *sgbuf;
-	unsigned int pages;
-	unsigned int tblsize;
-	int changed = 0;
+	unsigned int i, pages;
+	void *vmaddr;
 
-	sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
 	pages = snd_pcm_sgbuf_pages(size);
-	tblsize = sgbuf_align_table(pages);
-	if (pages < sgbuf->pages) {
-		/* release unsed pages */
-		sgbuf_shrink(sgbuf, pages);
-		if (substream->runtime)
-			substream->runtime->dma_bytes = size;
-		return 1; /* changed */
-	} else if (pages > sgbuf->tblsize) {
-		/* bigger than existing one.  reallocate the table. */
-		struct snd_sg_page *table;
-		table = kmalloc(sizeof(*table) * tblsize, GFP_KERNEL);
-		if (! table)
-			return -ENOMEM;
-		memcpy(table, sgbuf->table, sizeof(*table) * sgbuf->tblsize);
-		kfree(sgbuf->table);
-		sgbuf->table = table;
-		sgbuf->tblsize = tblsize;
-	}
+	sgbuf->tblsize = sgbuf_align_table(pages);
+	sgbuf->table = snd_kcalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL);
+	if (! sgbuf->table)
+		goto _failed;
+	sgbuf->page_table = snd_kcalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL);
+	if (! sgbuf->page_table)
+		goto _failed;
+
 	/* allocate each page */
-	while (sgbuf->pages < pages) {
+	for (i = 0; i < pages; i++) {
 		void *ptr;
 		dma_addr_t addr;
-		ptr = snd_pci_alloc_page(sgbuf->pci, &addr);
+		ptr = snd_malloc_pci_page(sgbuf->pci, &addr);
 		if (! ptr)
-			return -ENOMEM;
-		sgbuf->table[sgbuf->pages].buf = ptr;
-		sgbuf->table[sgbuf->pages].addr = addr;
+			goto _failed;
+		sgbuf->table[i].buf = ptr;
+		sgbuf->table[i].addr = addr;
+		sgbuf->page_table[i] = virt_to_page(ptr);
 		sgbuf->pages++;
-		changed = 1;
 	}
+
 	sgbuf->size = size;
-	if (substream->runtime)
-		substream->runtime->dma_bytes = size;
-	return changed;
+	vmaddr = vmap(sgbuf->page_table, sgbuf->pages);
+	if (! vmaddr)
+		goto _failed;
+	return vmaddr;
+
+ _failed:
+	snd_pcm_sgbuf_free_pages(sgbuf, NULL); /* free the table */
+	return NULL;
 }
 
-/*
- * free the sg buffer
- * the table is kept.
- * call this from hw_free callback.
+/**
+ * snd_pcm_sgbuf_free_pages - free the sg buffer
+ * @sgbuf: the sgbuf instance
+ * @vmaddr: the mapped virtual address
+ *
+ * Releases the pages and the mapped tables.
+ *
+ * This function is called usually from snd_pcm_lib_free_pages().
+ *
+ * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_sgbuf_free(snd_pcm_substream_t *substream)
+int snd_pcm_sgbuf_free_pages(struct snd_sg_buf *sgbuf, void *vmaddr)
 {
-	struct snd_sg_buf *sgbuf;
+	if (vmaddr)
+		vunmap(vmaddr);
 
-	sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
-	sgbuf_shrink(sgbuf, 0);
+	while (sgbuf->pages > 0) {
+		sgbuf->pages--;
+		snd_free_pci_page(sgbuf->pci, sgbuf->table[sgbuf->pages].buf,
+				   sgbuf->table[sgbuf->pages].addr);
+	}
+	if (sgbuf->table)
+		kfree(sgbuf->table);
+	sgbuf->table = NULL;
+	if (sgbuf->page_table)
+		kfree(sgbuf->page_table);
+	sgbuf->page_table = NULL;
+	sgbuf->tblsize = 0;
+	sgbuf->pages = 0;
+	sgbuf->size = 0;
+	
 	return 0;
 }
 
-/*
- * get the page pointer on the given offset
- */
-static void *sgbuf_get_addr(snd_pcm_substream_t *substream, unsigned long offset)
-{
-	struct snd_sg_buf *sgbuf;
-	unsigned int idx;
-
-	sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return NULL);
-	idx = offset >> PAGE_SHIFT;
-	if (idx >= sgbuf->pages)
-		return 0;
-	return sgbuf->table[idx].buf;
-}
-
-/*
- * get the page struct at the given offset
- * used as the page callback of pcm ops
+/**
+ * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
+ * @substream: the pcm substream instance
+ * @offset: the buffer offset
+ *
+ * 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)
 {
-	void *addr = sgbuf_get_addr(substream, offset);
-	if (addr)
-		return virt_to_page(addr);
-	else
-		return 0;
-}
+	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return NULL);
 
-/*
- * do copy_from_user to the sg buffer
- */
-static int copy_from_user_sg_buf(snd_pcm_substream_t *substream,
-				 char *buf, size_t hwoff, ssize_t bytes)
-{
-	int len;
-	char *addr;
-	size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT;
-	hwoff -= p;
-	len = PAGE_SIZE - hwoff;
-	for (;;) {
-		addr = sgbuf_get_addr(substream, p);
-		if (! addr)
-			return -EFAULT;
-		if (len > bytes)
-			len = bytes;
-		if (copy_from_user(addr + hwoff, buf, len))
-			return -EFAULT;
-		bytes -= len;
-		if (bytes <= 0)
-			break;
-		buf += len;
-		p += PAGE_SIZE;
-		len = PAGE_SIZE;
-		hwoff = 0;
-	}
-	return 0;
+	unsigned int idx = offset >> PAGE_SHIFT;
+	if (idx >= (unsigned int)sgbuf->pages)
+		return NULL;
+	return sgbuf->page_table[idx];
 }
 
-/*
- * do copy_to_user from the sg buffer
- */
-static int copy_to_user_sg_buf(snd_pcm_substream_t *substream,
-			       char *buf, size_t hwoff, ssize_t bytes)
-{
-	int len;
-	char *addr;
-	size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT;
-	hwoff -= p;
-	len = PAGE_SIZE - hwoff;
-	for (;;) {
-		addr = sgbuf_get_addr(substream, p);
-		if (! addr)
-			return -EFAULT;
-		if (len > bytes)
-			len = bytes;
-		if (copy_to_user(buf, addr + hwoff, len))
-			return -EFAULT;
-		bytes -= len;
-		if (bytes <= 0)
-			break;
-		buf += len;
-		p += PAGE_SIZE;
-		len = PAGE_SIZE;
-		hwoff = 0;
-	}
-	return 0;
-}
 
-/*
- * set silence on the sg buffer
+/**
+ * snd_pcm_lib_preallocate_sg_pages - initialize SG-buffer for the PCI bus
+ *
+ * @pci: pci device
+ * @substream: substream to assign the buffer
+ *
+ * Initializes SG-buffer for the PCI bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
  */
-static int set_silence_sg_buf(snd_pcm_substream_t *substream,
-			      size_t hwoff, ssize_t samples)
+int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci,
+				     snd_pcm_substream_t *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	int len, page_len;
-	char *addr;
-	size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT;
-	hwoff -= p;
-	len = bytes_to_samples(substream->runtime, PAGE_SIZE - hwoff);
-	page_len = bytes_to_samples(substream->runtime, PAGE_SIZE);
-	for (;;) {
-		addr = sgbuf_get_addr(substream, p);
-		if (! addr)
-			return -EFAULT;
-		if (len > samples)
-			len = samples;
-		snd_pcm_format_set_silence(runtime->format, addr + hwoff, len);
-		samples -= len;
-		if (samples <= 0)
-			break;
-		p += PAGE_SIZE;
-		len = page_len;
-		hwoff = 0;
-	}
+	if ((substream->dma_private = snd_pcm_sgbuf_new(pci)) == NULL)
+		return -ENOMEM;
+	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI_SG;
+	substream->dma_area = 0;
+	substream->dma_addr = 0;
+	substream->dma_bytes = 0;
+	substream->buffer_bytes_max = UINT_MAX;
+	substream->dma_max = 0;
 	return 0;
 }
 
 /*
- * copy callback for playback pcm ops
- */
-int snd_pcm_sgbuf_ops_copy_playback(snd_pcm_substream_t *substream, int channel,
-				    snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	if (channel < 0) {
-		return copy_from_user_sg_buf(substream, buf, frames_to_bytes(runtime, hwoff), frames_to_bytes(runtime, count));
-	} else {
-		size_t dma_csize = runtime->dma_bytes / runtime->channels;
-		size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff);
-		return copy_from_user_sg_buf(substream, buf, c_ofs, samples_to_bytes(runtime, count));
-	}
-}
-
-/*
- * copy callback for capture pcm ops
+ * FIXME: the function name is too long for docbook!
+ *
+ * snd_pcm_lib_preallocate_sg_pages_for_all - initialize SG-buffer for the PCI bus (all substreams)
+ * @pci: pci device
+ * @pcm: pcm to assign the buffer
+ *
+ * Initialize the SG-buffer to all substreams of the given pcm for the
+ * PCI bus.
+ *
+ * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_sgbuf_ops_copy_capture(snd_pcm_substream_t *substream, int channel,
-				   snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count)
+int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci,
+					     snd_pcm_t *pcm)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	if (channel < 0) {
-		return copy_to_user_sg_buf(substream, buf, frames_to_bytes(runtime, hwoff), frames_to_bytes(runtime, count));
-	} else {
-		size_t dma_csize = runtime->dma_bytes / runtime->channels;
-		size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff);
-		return copy_to_user_sg_buf(substream, buf, c_ofs, samples_to_bytes(runtime, count));
-	}
-}
+	snd_pcm_substream_t *substream;
+	int stream, err;
 
-/*
- * silence callback for pcm ops
- */
-int snd_pcm_sgbuf_ops_silence(snd_pcm_substream_t *substream, int channel,
-			      snd_pcm_uframes_t hwoff, snd_pcm_uframes_t count)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	if (channel < 0) {
-		return set_silence_sg_buf(substream, frames_to_bytes(runtime, hwoff),
-					  frames_to_bytes(runtime, count));
-	} else {
-		size_t dma_csize = runtime->dma_bytes / runtime->channels;
-		size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff);
-		return set_silence_sg_buf(substream, c_ofs, samples_to_bytes(runtime, count));
-	}
+	for (stream = 0; stream < 2; stream++)
+		for (substream = pcm->streams[stream].substream; substream; substream = substream->next)
+			if ((err = snd_pcm_lib_preallocate_sg_pages(pci, substream)) < 0)
+				return err;
+	return 0;
 }
 
 
 /*
  *  Exported symbols
  */
-EXPORT_SYMBOL(snd_pcm_sgbuf_init);
-EXPORT_SYMBOL(snd_pcm_sgbuf_delete);
-EXPORT_SYMBOL(snd_pcm_sgbuf_alloc);
-EXPORT_SYMBOL(snd_pcm_sgbuf_free);
-EXPORT_SYMBOL(snd_pcm_sgbuf_ops_copy_playback);
-EXPORT_SYMBOL(snd_pcm_sgbuf_ops_copy_capture);
-EXPORT_SYMBOL(snd_pcm_sgbuf_ops_silence);
+EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages);
+EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages_for_all);
 EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/rawmidi.c	Mon Feb 10 10:39:23 2003
@@ -181,9 +181,6 @@
 
 	if (rfile)
 		rfile->input = rfile->output = NULL;
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
 	if (rmidi == NULL) {
 		err = -ENODEV;
@@ -199,7 +196,7 @@
 			err = -ENXIO;
 			goto __error;
 		}
-		if (subdevice >= 0 && subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) {
+		if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) {
 			err = -ENODEV;
 			goto __error;
 		}
@@ -214,7 +211,7 @@
 			err = -ENXIO;
 			goto __error;
 		}
-		if (subdevice >= 0 && subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) {
+		if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) {
 			err = -ENODEV;
 			goto __error;
 		}
@@ -342,9 +339,6 @@
 	module_put(rmidi->card->module);
 	up(&rmidi->open_mutex);
       __error1:
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return err;
 }
 
@@ -499,9 +493,6 @@
 	}
 	up(&rmidi->open_mutex);
 	module_put(rmidi->card->module);
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -571,7 +562,7 @@
 		return -ENXIO;
 	list_for_each(list, &pstr->substreams) {
 		substream = list_entry(list, snd_rawmidi_substream_t, list);
-		if (substream->number == info->subdevice)
+		if ((unsigned int)substream->number == info->subdevice)
 			return snd_rawmidi_info(substream, info);
 	}
 	return -ENXIO;
@@ -824,6 +815,16 @@
 	return -ENOIOCTLCMD;
 }
 
+/**
+ * snd_rawmidi_receive - receive the input data from the device
+ * @substream: the rawmidi substream
+ * @buffer: the buffer pointer
+ * @count: the data size to read
+ *
+ * Reads the data from the internal buffer.
+ *
+ * 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)
 {
 	unsigned long flags;
@@ -850,7 +851,7 @@
 		count1 = runtime->buffer_size - runtime->hw_ptr;
 		if (count1 > count)
 			count1 = count;
-		if (count1 > runtime->buffer_size - runtime->avail)
+		if (count1 > (int)(runtime->buffer_size - runtime->avail))
 			count1 = runtime->buffer_size - runtime->avail;
 		memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1);
 		runtime->hw_ptr += count1;
@@ -861,7 +862,7 @@
 		if (count > 0) {
 			buffer += count1;
 			count1 = count;
-			if (count1 > runtime->buffer_size - runtime->avail) {
+			if (count1 > (int)(runtime->buffer_size - runtime->avail)) {
 				count1 = runtime->buffer_size - runtime->avail;
 				runtime->xruns = count - count1;
 			}
@@ -895,7 +896,7 @@
 		if (count1 > count)
 			count1 = count;
 		spin_lock_irqsave(&runtime->lock, flags);
-		if (count1 > runtime->avail)
+		if (count1 > (int)runtime->avail)
 			count1 = runtime->avail;
 		if (kernel) {
 			memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1);
@@ -968,6 +969,12 @@
 	return result;
 }
 
+/**
+ * snd_rawmidi_transmit_empty - check whether the output buffer is empty
+ * @substream: the rawmidi substream
+ * 
+ * Returns 1 if the internal output buffer is empty, 0 if not.
+ */
 int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream)
 {
 	snd_rawmidi_runtime_t *runtime = substream->runtime;
@@ -986,6 +993,20 @@
 	return result;		
 }
 
+/**
+ * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * @substream: the rawmidi substream
+ * @buffer: the buffer pointer
+ * @count: data size to transfer
+ *
+ * Copies data from the internal output buffer to the given buffer.
+ *
+ * Call this in the interrupt handler when the midi output is ready,
+ * and call snd_rawmidi_transmit_ack() after the transmission is
+ * finished.
+ *
+ * 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)
 {
 	unsigned long flags;
@@ -1010,7 +1031,7 @@
 		count1 = runtime->buffer_size - runtime->hw_ptr;
 		if (count1 > count)
 			count1 = count;
-		if (count1 > runtime->buffer_size - runtime->avail)
+		if (count1 > (int)(runtime->buffer_size - runtime->avail))
 			count1 = runtime->buffer_size - runtime->avail;
 		memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1);
 		count -= count1;
@@ -1023,6 +1044,17 @@
 	return result;
 }
 
+/**
+ * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * @substream: the rawmidi substream
+ * @count: the tranferred count
+ *
+ * Advances the hardware pointer for the internal output buffer with
+ * the given size and updates the condition.
+ * Call after the transmission is finished.
+ *
+ * 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)
 {
 	unsigned long flags;
@@ -1050,6 +1082,16 @@
 	return count;
 }
 
+/**
+ * snd_rawmidi_transmit - copy from the buffer to the device
+ * @substream: the rawmidi substream
+ * @buf: the buffer pointer
+ * @count: the data size to transfer
+ * 
+ * Copies data from the buffer to the device and advances the pointer.
+ *
+ * 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)
 {
 	count = snd_rawmidi_transmit_peek(substream, buffer, count);
@@ -1070,7 +1112,7 @@
 	result = 0;
 	spin_lock_irqsave(&runtime->lock, flags);
 	if (substream->append) {
-		if (runtime->avail < count) {
+		if ((long)runtime->avail < count) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			return -EAGAIN;
 		}
@@ -1079,7 +1121,7 @@
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
 			count1 = count;
-		if (count1 > runtime->avail)
+		if (count1 > (long)runtime->avail)
 			count1 = runtime->avail;
 		if (kernel) {
 			memcpy(runtime->buffer + runtime->appl_ptr, buf, count1);
@@ -1153,7 +1195,7 @@
 			continue;
 		result += count1;
 		buf += count1;
-		if (count1 < count && (file->f_flags & O_NONBLOCK))
+		if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK))
 			break;
 		count -= count1;
 	}
@@ -1313,6 +1355,20 @@
 	return 0;
 }
 
+/**
+ * snd_rawmidi_new - create a rawmidi instance
+ * @card: the card instance
+ * @id: the id string
+ * @device: the device index
+ * @output_count: the number of output streams
+ * @input_count: the number of input streams
+ * @rrawmidi: the pointer to store the new rawmidi instance
+ *
+ * Creates a new rawmidi instance.
+ * Use snd_rawmidi_set_ops() to set the operators to the new instance.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_rawmidi_new(snd_card_t * card, char *id, int device,
 		    int output_count, int input_count,
 		    snd_rawmidi_t ** rrawmidi)
@@ -1424,7 +1480,7 @@
 	}
 #ifdef CONFIG_SND_OSSEMUL
 	rmidi->ossreg = 0;
-	if (rmidi->device == midi_map[rmidi->card->number]) {
+	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) {
 			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
@@ -1435,7 +1491,7 @@
 #endif
 		}
 	}
-	if (rmidi->device == amidi_map[rmidi->card->number]) {
+	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) {
 			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
@@ -1498,13 +1554,13 @@
 	}
 #ifdef CONFIG_SND_OSSEMUL
 	if (rmidi->ossreg) {
-		if (rmidi->device == midi_map[rmidi->card->number]) {
+		if ((int)rmidi->device == midi_map[rmidi->card->number]) {
 			snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0);
 #ifdef SNDRV_OSS_INFO_DEV_MIDI
 			snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number);
 #endif
 		}
-		if (rmidi->device == amidi_map[rmidi->card->number])
+		if ((int)rmidi->device == amidi_map[rmidi->card->number])
 			snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1);
 		rmidi->ossreg = 0;
 	}
@@ -1522,6 +1578,14 @@
 	return snd_rawmidi_free(rmidi);
 }
 
+/**
+ * snd_rawmidi_set_ops - set the rawmidi operators
+ * @rmidi: the rawmidi instance
+ * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX
+ * @ops: the operator table
+ *
+ * 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)
 {
 	struct list_head *list;
diff -Nru a/sound/core/rtctimer.c b/sound/core/rtctimer.c
--- a/sound/core/rtctimer.c	Mon Feb 10 10:39:31 2003
+++ b/sound/core/rtctimer.c	Mon Feb 10 10:39:31 2003
@@ -37,9 +37,6 @@
 #include <linux/mc146818rtc.h>
 #endif
 
-/* use tasklet for interrupt handling */
-#define USE_TASKLET
-
 #define RTC_FREQ	1024		/* default frequency */
 #define NANO_SEC	1000000000L	/* 10^9 in sec */
 
@@ -69,10 +66,6 @@
 static atomic_t rtc_inc = ATOMIC_INIT(0);
 static rtc_task_t rtc_task;
 
-/* tasklet */
-#ifdef USE_TASKLET
-static struct tasklet_struct rtc_tq;
-#endif
 
 static int
 rtctimer_open(snd_timer_t *t)
@@ -83,7 +76,6 @@
 	if (err < 0)
 		return err;
 	t->private_data = &rtc_task;
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -95,7 +87,6 @@
 		rtc_unregister(rtc);
 		t->private_data = NULL;
 	}
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -124,31 +115,13 @@
  */
 static void rtctimer_interrupt(void *private_data)
 {
-	atomic_inc(&rtc_inc);
-#ifdef USE_TASKLET
-	tasklet_hi_schedule(&rtc_tq);
-#else
-	{
-		int ticks = atomic_read(&rtc_inc);
-		snd_timer_interrupt((snd_timer_t*)private_data, ticks);
-		atomic_sub(ticks, &rtc_inc);
-	}
-#endif /* USE_TASKLET */
-}
-
-#ifdef USE_TASKLET
-static void rtctimer_interrupt2(unsigned long private_data)
-{
-	snd_timer_t *timer = (snd_timer_t *)private_data;
 	int ticks;
 
-	snd_assert(timer != NULL, return);
-	do {
-		ticks = atomic_read(&rtc_inc);
-		snd_timer_interrupt(timer, ticks);
-	} while (!atomic_sub_and_test(ticks, &rtc_inc));
+	atomic_inc(&rtc_inc);
+	ticks = atomic_read(&rtc_inc);
+	snd_timer_interrupt((snd_timer_t*)private_data, ticks);
+	atomic_sub(ticks, &rtc_inc);
 }
-#endif /* USE_TASKLET */
 
 
 /*
@@ -174,10 +147,6 @@
 	err = snd_timer_global_new("rtc", SNDRV_TIMER_GLOBAL_RTC, &timer);
 	if (err < 0)
 		return err;
-
-#ifdef USE_TASKLET
-	tasklet_init(&rtc_tq, rtctimer_interrupt2, (unsigned long)timer);
-#endif /* USE_TASKLET */
 
 	strcpy(timer->name, "RTC timer");
 	timer->hw = rtc_hw;
diff -Nru a/sound/core/seq/Makefile b/sound/core/seq/Makefile
--- a/sound/core/seq/Makefile	Mon Feb 10 10:39:32 2003
+++ b/sound/core/seq/Makefile	Mon Feb 10 10:39:32 2003
@@ -8,9 +8,6 @@
   obj-$(CONFIG_SND_SEQUENCER) += oss/
 endif
 
-export-objs  := seq_device.o seq.o seq_instr.o seq_midi_emul.o \
-		seq_midi_event.o seq_virmidi.o
-
 snd-seq-device-objs := seq_device.o
 snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \
                 seq_fifo.o seq_prioq.o seq_timer.o \
@@ -22,6 +19,17 @@
 snd-seq-dummy-objs := seq_dummy.o
 snd-seq-virmidi-objs := seq_virmidi.o
 
+RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o
+OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
+
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o
 ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
 obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o
@@ -29,53 +37,52 @@
 obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
 
 # Toplevel Module Dependency
-RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o
-OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
 obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
-obj-$(CONFIG_SND_SERIAL_U16550) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_MTPAV) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_MPU401) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_ALS100) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_AZT2320) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_DT019X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ES18XX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_OPL3SA2) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_CS4236) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_PC98_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ES1688) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_GUSEXTREME) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_INTERWAVE) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_INTERWAVE_STB) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_OPTI92X_AD1848) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_OPTI92X_CS4231) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_OPTI93X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_SB8) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_SB16) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_SBAWE) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
-obj-$(CONFIG_SND_ES968) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_WAVEFRONT) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ALS4000) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_CMIPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_CS4281) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ENS1370) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_ENS1371) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_ES1938) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ES1968) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_FM801) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_ICE1712) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_INTEL8X0) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_SONICVIBES) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_VIA82XX) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_ALI5451) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_CS46XX) += $(RAWMIDI_OBJS)
-obj-$(CONFIG_SND_EMU10K1) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o
-obj-$(CONFIG_SND_TRIDENT) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o
-obj-$(CONFIG_SND_YMFPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(CONFIG_SND_USB_AUDIO) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_SERIAL_U16550)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_MTPAV)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_MPU401)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ALS100)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_DT019X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CS4231)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CS4236)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ES1688)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_SB8)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_SB16)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
+obj-$(call sequencer,$(CONFIG_SND_ES968)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CS4281)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ENS1370)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ENS1371)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ES1938)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ES1968)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_FM801)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ICE1712)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_INTEL8X0)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_VIA82XX)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_ALI5451)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_CS46XX)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o
+obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o
+obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_USB_AUDIO)) += $(RAWMIDI_OBJS)
+obj-$(call sequencer,$(CONFIG_SND_HDSP)) += $(RAWMIDI_OBJS)
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile
--- a/sound/core/seq/instr/Makefile	Mon Feb 10 10:39:31 2003
+++ b/sound/core/seq/instr/Makefile	Mon Feb 10 10:39:31 2003
@@ -3,43 +3,49 @@
 # Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := ainstr_fm.o ainstr_simple.o ainstr_gf1.o ainstr_iw.o
-
 snd-ainstr-fm-objs := ainstr_fm.o
 snd-ainstr-simple-objs := ainstr_simple.o
 snd-ainstr-gf1-objs := ainstr_gf1.o
 snd-ainstr-iw-objs := ainstr_iw.o
 
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_ALS100) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_AZT2320) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_DT019X) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_ES18XX) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_CS4232) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_CS4236) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_PC98_CS4232) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_ES1688) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_GUSCLASSIC) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
-obj-$(CONFIG_SND_GUSMAX) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
-obj-$(CONFIG_SND_GUSEXTREME) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o
-obj-$(CONFIG_SND_INTERWAVE) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
-obj-$(CONFIG_SND_INTERWAVE_STB) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
-obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_OPTI93X) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_SB8) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_SB16) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_SBAWE) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_WAVEFRONT) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_ALS4000) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_CMIPCI) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_CS4281) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_ES1938) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_FM801) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_SONICVIBES) += snd-ainstr-fm.o
-obj-$(CONFIG_SND_TRIDENT) += snd-ainstr-simple.o
-obj-$(CONFIG_SND_YMFPCI) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_ALS100)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_DT019X)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_CS4232)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_CS4236)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_ES1688)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
+obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
+obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
+obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_SB8)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_SB16)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_CS4281)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_ES1938)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_FM801)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += snd-ainstr-fm.o
+obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-ainstr-simple.o
+obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += snd-ainstr-fm.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c
--- a/sound/core/seq/instr/ainstr_fm.c	Mon Feb 10 10:39:26 2003
+++ b/sound/core/seq/instr/ainstr_fm.c	Mon Feb 10 10:39:26 2003
@@ -44,7 +44,7 @@
 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
 		return -EINVAL;
 	/* copy instrument data */
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -EINVAL;
 	if (copy_from_user(&ix, instr_data, sizeof(ix)))
 		return -EFAULT;
@@ -85,7 +85,7 @@
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
 		return -EINVAL;
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
 	ip = (fm_instrument_t *)KINSTR_DATA(instr);
diff -Nru a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
--- a/sound/core/seq/instr/ainstr_gf1.c	Mon Feb 10 10:39:30 2003
+++ b/sound/core/seq/instr/ainstr_gf1.c	Mon Feb 10 10:39:30 2003
@@ -58,7 +58,7 @@
 	unsigned int real_size;
 	
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
-	if (*len < sizeof(xp))
+	if (*len < (long)sizeof(xp))
 		return -EINVAL;
 	if (copy_from_user(&xp, *data, sizeof(xp)))
 		return -EFAULT;
@@ -95,7 +95,7 @@
 	wp->scale_frequency = le16_to_cpu(xp.scale_frequency);
 	wp->scale_factor = le16_to_cpu(xp.scale_factor);
 	real_size = snd_seq_gf1_size(wp->size, wp->format);
-	if (real_size > *len) {
+	if ((long)real_size > *len) {
 		kfree(wp);
 		return -ENOMEM;
 	}
@@ -152,7 +152,7 @@
 		return -EINVAL;
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	/* copy instrument data */
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -EINVAL;
 	if (copy_from_user(&ix, instr_data, sizeof(ix)))
 		return -EFAULT;
@@ -168,7 +168,7 @@
 	ip->effect2 = ix.effect2;
 	ip->effect2_depth = ix.effect2_depth;
 	/* copy layers */
-	while (len > sizeof(__u32)) {
+	while (len > (long)sizeof(__u32)) {
 		__u32 stype;
 
 		if (copy_from_user(&stype, instr_data, sizeof(stype)))
@@ -202,7 +202,7 @@
 	unsigned int real_size;
 	
 	for (wp = ip->wave; wp; wp = wp->next) {
-		if (*len < sizeof(xp))
+		if (*len < (long)sizeof(xp))
 			return -ENOMEM;
 		memset(&xp, 0, sizeof(xp));
 		xp.stype = GF1_STRU_WAVE;
@@ -238,7 +238,7 @@
 		*data += sizeof(xp);
 		*len -= sizeof(xp);
 		real_size = snd_seq_gf1_size(wp->size, wp->format);
-		if (*len < real_size)
+		if (*len < (long)real_size)
 			return -ENOMEM;
 		if (ops->get_sample) {
 			err = ops->get_sample(ops->private_data, wp,
@@ -261,7 +261,7 @@
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
 		return -EINVAL;
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
 	ip = (gf1_instrument_t *)KINSTR_DATA(instr);
diff -Nru a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
--- a/sound/core/seq/instr/ainstr_iw.c	Mon Feb 10 10:39:27 2003
+++ b/sound/core/seq/instr/ainstr_iw.c	Mon Feb 10 10:39:27 2003
@@ -76,7 +76,7 @@
 	ep->index = ex->index;
 	rp_last = NULL;
 	while (1) {
-		if (*len < sizeof(__u32))
+		if (*len < (long)sizeof(__u32))
 			return -EINVAL;
 		if (copy_from_user(&stype, data, sizeof(stype)))
 			return -EFAULT;
@@ -87,7 +87,7 @@
 			    stype == IWFFFF_STRU_ENV_RECV)
 				return 0;
 		}
-		if (*len < sizeof(rx))
+		if (*len < (long)sizeof(rx))
 			return -EINVAL;
 		if (copy_from_user(&rx, *data, sizeof(rx)))
 			return -EFAULT;
@@ -136,7 +136,7 @@
 	unsigned int real_size;
 	
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
-	if (*len < sizeof(xp))
+	if (*len < (long)sizeof(xp))
 		return -EINVAL;
 	if (copy_from_user(&xp, *data, sizeof(xp)))
 		return -EFAULT;
@@ -162,7 +162,7 @@
 	wp->high_note = xp.high_note;
 	real_size = snd_seq_iwffff_size(wp->size, wp->format);
 	if (!(wp->format & IWFFFF_WAVE_ROM)) {
-		if (real_size > *len) {
+		if ((long)real_size > *len) {
 			kfree(wp);
 			return -ENOMEM;
 		}
@@ -243,7 +243,7 @@
 		return -EINVAL;
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	/* copy instrument data */
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -EINVAL;
 	if (copy_from_user(&ix, instr_data, sizeof(ix)))
 		return -EFAULT;
@@ -262,7 +262,7 @@
 	/* copy layers */
 	prev_lp = NULL;
 	while (len > 0) {
-		if (len < sizeof(iwffff_xlayer_t)) {
+		if (len < (long)sizeof(iwffff_xlayer_t)) {
 			snd_seq_iwffff_instr_free(ops, ip, atomic);
 			return -EINVAL;
 		}
@@ -315,7 +315,7 @@
 			snd_seq_iwffff_instr_free(ops, ip, atomic);
 			return err;
 		}
-		while (len > sizeof(__u32)) {
+		while (len > (long)sizeof(__u32)) {
 			__u32 stype;
 
 			if (copy_from_user(&stype, instr_data, sizeof(stype)))
@@ -363,7 +363,7 @@
 	ex->mode = ep->mode;
 	ex->index = ep->index;
 	for (rp = ep->record; rp; rp = rp->next) {
-		if (*len < sizeof(rx))
+		if (*len < (long)sizeof(rx))
 			return -ENOMEM;
 		memset(&rx, 0, sizeof(rx));
 		rx.stype = req_stype;
@@ -405,7 +405,7 @@
 	unsigned int real_size;
 	
 	for (wp = lp->wave; wp; wp = wp->next) {
-		if (*len < sizeof(xp))
+		if (*len < (long)sizeof(xp))
 			return -ENOMEM;
 		memset(&xp, 0, sizeof(xp));
 		xp.stype = IWFFFF_STRU_WAVE;
@@ -431,7 +431,7 @@
 		*len -= sizeof(xp);
 		real_size = snd_seq_iwffff_size(wp->size, wp->format);
 		if (!(wp->format & IWFFFF_WAVE_ROM)) {
-			if (*len < real_size)
+			if (*len < (long)real_size)
 				return -ENOMEM;
 		}
 		if (ops->get_sample) {
@@ -461,7 +461,7 @@
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
 		return -EINVAL;
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
 	ip = (iwffff_instrument_t *)KINSTR_DATA(instr);
@@ -478,7 +478,7 @@
 	instr_data += sizeof(ix);
 	len -= sizeof(ix);
 	for (lp = ip->layer; lp; lp = lp->next) {
-		if (len < sizeof(lx))
+		if (len < (long)sizeof(lx))
 			return -ENOMEM;
 		memset(&lx, 0, sizeof(lx));
 		lx.stype = IWFFFF_STRU_LAYER;
diff -Nru a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
--- a/sound/core/seq/instr/ainstr_simple.c	Mon Feb 10 10:39:30 2003
+++ b/sound/core/seq/instr/ainstr_simple.c	Mon Feb 10 10:39:30 2003
@@ -67,7 +67,7 @@
 		return -EINVAL;
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	/* copy instrument data */
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -EINVAL;
 	if (copy_from_user(&ix, instr_data, sizeof(ix)))
 		return -EFAULT;
@@ -91,7 +91,7 @@
 	ip->effect2 = ix.effect2;
 	ip->effect2_depth = ix.effect2_depth;
 	real_size = snd_seq_simple_size(ip->size, ip->format);
-	if (len < real_size)
+	if (len < (long)real_size)
 		return -EINVAL;
 	if (ops->put_sample) {
 		err = ops->put_sample(ops->private_data, ip,
@@ -113,7 +113,7 @@
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
 		return -EINVAL;
-	if (len < sizeof(ix))
+	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
 	ip = (simple_instrument_t *)KINSTR_DATA(instr);
@@ -137,7 +137,7 @@
 	instr_data += sizeof(ix);
 	len -= sizeof(ix);
 	real_size = snd_seq_simple_size(ip->size, ip->format);
-	if (len < real_size)
+	if (len < (long)real_size)
 		return -ENOMEM;
 	if (ops->get_sample) {
 		err = ops->get_sample(ops->private_data, ip,
diff -Nru a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile
--- a/sound/core/seq/oss/Makefile	Mon Feb 10 10:39:26 2003
+++ b/sound/core/seq/oss/Makefile	Mon Feb 10 10:39:26 2003
@@ -7,6 +7,4 @@
 		     seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \
 		     seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o
 
-ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
-  obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
-endif
+obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
diff -Nru a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
--- a/sound/core/seq/oss/seq_oss_init.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/seq/oss/seq_oss_init.c	Mon Feb 10 10:39:23 2003
@@ -275,9 +275,6 @@
 
 	client_table[dp->index] = dp;
 	num_clients++;
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 
 	debug_printk(("open done\n"));
 
@@ -434,9 +431,6 @@
 	if (dp->queue >= 0)
 		delete_seq_queue(dp);
 
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	debug_printk(("release done\n"));
 }
 
diff -Nru a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
--- a/sound/core/seq/oss/seq_oss_midi.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/seq/oss/seq_oss_midi.c	Mon Feb 10 10:39:23 2003
@@ -217,7 +217,6 @@
 	midi_devs[mdev->seq_device] = mdev;
 	spin_unlock_irqrestore(&register_lock, flags);
 
-	/*MOD_INC_USE_COUNT;*/
 	return 0;
 }
 
diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/seq/seq_clientmgr.c	Mon Feb 10 10:39:23 2003
@@ -339,10 +339,6 @@
 	/* make others aware this new client */
 	snd_seq_system_client_ev_client_start(c);
 
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
-
 	return 0;
 }
 
@@ -358,9 +354,6 @@
 		kfree(client);
 	}
 
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -1013,7 +1006,7 @@
 
 		if (snd_seq_ev_is_variable(&event)) {
 			int extlen = event.data.ext.len & ~SNDRV_SEQ_EXT_MASK;
-			if (extlen + len > count) {
+			if ((size_t)(extlen + len) > count) {
 				/* back out, will get an error this time or next */
 				err = -EINVAL;
 				break;
diff -Nru a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
--- a/sound/core/seq/seq_instr.c	Mon Feb 10 10:39:25 2003
+++ b/sound/core/seq/seq_instr.c	Mon Feb 10 10:39:25 2003
@@ -145,7 +145,7 @@
 
 static int instr_free_compare(snd_seq_kinstr_t *instr,
 			      snd_seq_instr_header_t *ifree,
-			      int client)
+			      unsigned int client)
 {
 	switch (ifree->cmd) {
 	case SNDRV_SEQ_INSTR_FREE_CMD_ALL:
@@ -193,7 +193,7 @@
 		instr = list->hash[idx];
 		prev = flist = NULL;
 		while (instr) {
-			while (instr && instr_free_compare(instr, ifree, client)) {
+			while (instr && instr_free_compare(instr, ifree, (unsigned int)client)) {
 				prev = instr;
 				instr = instr->next;
 			}
diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c	Mon Feb 10 10:39:31 2003
+++ b/sound/core/seq/seq_midi.c	Mon Feb 10 10:39:31 2003
@@ -280,7 +280,8 @@
 	seq_midisynth_t *msynth, *ms;
 	snd_seq_port_info_t port;
 	snd_rawmidi_info_t info;
-	int newclient = 0, p, ports;
+	int newclient = 0;
+	unsigned int p, ports;
 	snd_seq_client_callback_t callbacks;
 	snd_seq_port_callback_t pcallbacks;
 	snd_seq_client_info_t inf;
diff -Nru a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
--- a/sound/core/seq/seq_midi_emul.c	Mon Feb 10 10:39:32 2003
+++ b/sound/core/seq/seq_midi_emul.c	Mon Feb 10 10:39:32 2003
@@ -506,7 +506,7 @@
 	len--;
 
 	/* GM on */
-	if (len >= sizeof(gm_on_macro) &&
+	if (len >= (int)sizeof(gm_on_macro) &&
 	    memcmp(buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
 		if (chset->midi_mode != SNDRV_MIDI_MODE_GS &&
 		    chset->midi_mode != SNDRV_MIDI_MODE_XG) {
@@ -568,7 +568,7 @@
 	}
 
 	/* XG on */
-	else if (len >= sizeof(xg_on_macro) &&
+	else if (len >= (int)sizeof(xg_on_macro) &&
 		 memcmp(buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
 		int i;
 		chset->midi_mode = SNDRV_MIDI_MODE_XG;
diff -Nru a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
--- a/sound/core/seq/seq_midi_event.c	Mon Feb 10 10:39:23 2003
+++ b/sound/core/seq/seq_midi_event.c	Mon Feb 10 10:39:23 2003
@@ -108,8 +108,6 @@
 	/*{SNDRV_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/
 };
 
-#define numberof(ary)	(sizeof(ary)/sizeof(ary[0]))
-
 /*
  *  new/delete record
  */
@@ -349,16 +347,16 @@
  */
 long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev)
 {
-	int cmd, type;
+	unsigned int cmd, type;
 
 	if (ev->type == SNDRV_SEQ_EVENT_NONE)
 		return -ENOENT;
 
-	for (type = 0; type < numberof(status_event); type++) {
+	for (type = 0; type < ARRAY_SIZE(status_event); type++) {
 		if (ev->type == status_event[type].event)
 			goto __found;
 	}
-	for (type = 0; type < numberof(extra_event); type++) {
+	for (type = 0; type < ARRAY_SIZE(extra_event); type++) {
 		if (ev->type == extra_event[type].event)
 			return extra_event[type].decode(dev, buf, count, ev);
 	}
diff -Nru a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
--- a/sound/core/seq/seq_ports.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/seq/seq_ports.c	Mon Feb 10 10:39:29 2003
@@ -610,8 +610,7 @@
 /* exported */
 int snd_seq_event_port_attach(int client,
 			      snd_seq_port_callback_t *pcbp,
-			      int cap,
-			      int type,
+			      int cap, int type, int midi_channels,
 			      char *portname)
 {
 	snd_seq_port_info_t portinfo;
@@ -628,6 +627,7 @@
 	portinfo.capability = cap;
 	portinfo.type = type;
 	portinfo.kernel = pcbp;
+	portinfo.midi_channels = midi_channels;
 
 	/* Create it */
 	ret = snd_seq_kernel_client_ctl(client,
diff -Nru a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
--- a/sound/core/seq/seq_queue.c	Mon Feb 10 10:39:30 2003
+++ b/sound/core/seq/seq_queue.c	Mon Feb 10 10:39:30 2003
@@ -47,8 +47,6 @@
 #include "seq_timer.h"
 #include "seq_info.h"
 
-static void snd_seq_check_queue_in_tasklet(unsigned long private_data);
-
 /* list of allocated queues */
 static queue_t *queue_list[SNDRV_SEQ_MAX_QUEUES];
 static spinlock_t queue_list_lock = SPIN_LOCK_UNLOCKED;
@@ -123,7 +121,6 @@
 	spin_lock_init(&q->check_lock);
 	init_MUTEX(&q->timer_mutex);
 	snd_use_lock_init(&q->use_lock);
-	tasklet_init(&q->taskq, snd_seq_check_queue_in_tasklet, (unsigned long)q);
 	q->queue = -1;
 
 	q->tickq = snd_seq_prioq_new();
@@ -148,7 +145,7 @@
 static void queue_delete(queue_t *q)
 {
 	/* stop and release the timer */
-	snd_seq_timer_stop(q->timer, 0);
+	snd_seq_timer_stop(q->timer);
 	snd_seq_timer_close(q);
 	/* wait until access free */
 	snd_use_lock_sync(&q->use_lock);
@@ -258,8 +255,6 @@
 void snd_seq_check_queue(queue_t *q, int atomic, int hop)
 {
 	unsigned long flags;
-	int dequeue;
-	int rc;
 	snd_seq_event_cell_t *cell;
 
 	if (q == NULL)
@@ -275,27 +270,13 @@
 	q->check_blocked = 1;
 	spin_unlock_irqrestore(&q->check_lock, flags);
 
-	if (atomic)
-		dequeue = SNDRV_SEQ_MAX_DEQUEUE;
-	else
-		dequeue = 0x7fffffff; /* XXX */
-
       __again:
 	/* Process tick queue... */
-
-	/* limit the number of elements dequeued per pass to save the machine from lockups */
-	while (dequeue > 0) {
-
-		cell = snd_seq_prioq_cell_peek(q->tickq);
-		if (cell == NULL)
-			break;
+	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)) {
 			cell = snd_seq_prioq_cell_out(q->tickq);
-			if (cell != NULL) {
-				rc = snd_seq_dispatch_event(cell, atomic, hop);
-				if (rc > 0)
-					dequeue -= rc;
-			}
+			if (cell)
+				snd_seq_dispatch_event(cell, atomic, hop);
 		} else {
 			/* event remains in the queue */
 			break;
@@ -304,20 +285,11 @@
 
 
 	/* Process time queue... */
-
-	/* limit the number of elements dequeued per pass to save the machine from lockups */
-	while (dequeue > 0) {
-		cell = snd_seq_prioq_cell_peek(q->timeq);
-		if (cell == NULL)
-			break;
+	while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) {
 		if (snd_seq_compare_real_time(&q->timer->cur_time, &cell->event.time.time)) {
 			cell = snd_seq_prioq_cell_out(q->timeq);
-			if (cell != NULL) {
-				rc = snd_seq_dispatch_event(cell, atomic, hop);
-				if (rc > 0)
-					dequeue -= rc;
-			}
-
+			if (cell)
+				snd_seq_dispatch_event(cell, atomic, hop);
 		} else {
 			/* event remains in the queue */
 			break;
@@ -326,23 +298,15 @@
 
 	/* free lock */
 	spin_lock_irqsave(&q->check_lock, flags);
-	if (q->check_again && dequeue > 0) {
+	if (q->check_again) {
 		q->check_again = 0;
 		spin_unlock_irqrestore(&q->check_lock, flags);
 		goto __again;
 	}
 	q->check_blocked = 0;
-	if (dequeue <= 0 && atomic)
-		tasklet_hi_schedule(&q->taskq);
 	spin_unlock_irqrestore(&q->check_lock, flags);
 }
 
-/* tasklet */
-static void snd_seq_check_queue_in_tasklet(unsigned long private_data)
-{
-	queue_t *q = (queue_t *)private_data;
-	snd_seq_check_queue(q, 0, 0);
-}
 
 /* enqueue a event to singe queue */
 int snd_seq_enqueue_event(snd_seq_event_cell_t *cell, int atomic, int hop)
@@ -606,7 +570,7 @@
 		spin_unlock_irqrestore(&q->owner_lock, flags);
 		if (q->owner == client) {
 			if (q->timer->running)
-				snd_seq_timer_stop(q->timer, 0);
+				snd_seq_timer_stop(q->timer);
 			snd_seq_timer_reset(q->timer);
 		}
 		queuefree(q);
@@ -716,17 +680,17 @@
 	case SNDRV_SEQ_EVENT_START:
 		snd_seq_prioq_leave(q->tickq, ev->source.client, 1);
 		snd_seq_prioq_leave(q->timeq, ev->source.client, 1);
-		if (! snd_seq_timer_start(q->timer, atomic))
+		if (! snd_seq_timer_start(q->timer))
 			queue_broadcast_event(q, ev, from_timer_port, atomic, hop);
 		break;
 
 	case SNDRV_SEQ_EVENT_CONTINUE:
-		if (! snd_seq_timer_continue(q->timer, atomic))
+		if (! snd_seq_timer_continue(q->timer))
 			queue_broadcast_event(q, ev, from_timer_port, atomic, hop);
 		break;
 
 	case SNDRV_SEQ_EVENT_STOP:
-		snd_seq_timer_stop(q->timer, atomic);
+		snd_seq_timer_stop(q->timer);
 		queue_broadcast_event(q, ev, from_timer_port, atomic, hop);
 		break;
 
diff -Nru a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
--- a/sound/core/seq/seq_queue.h	Mon Feb 10 10:39:24 2003
+++ b/sound/core/seq/seq_queue.h	Mon Feb 10 10:39:24 2003
@@ -57,8 +57,6 @@
 	struct semaphore timer_mutex;
 
 	snd_use_lock_t use_lock;
-
-	struct tasklet_struct taskq;
 };
 
 
diff -Nru a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
--- a/sound/core/seq/seq_timer.c	Mon Feb 10 10:39:30 2003
+++ b/sound/core/seq/seq_timer.c	Mon Feb 10 10:39:30 2003
@@ -88,7 +88,7 @@
 	t->running = 0;
 
 	/* reset time */
-	snd_seq_timer_stop(t, 0);
+	snd_seq_timer_stop(t);
 	snd_seq_timer_reset(t);
 
 	kfree(t);
@@ -133,10 +133,10 @@
 /* called by timer interrupt routine. the period time since previous invocation is passed */
 static void snd_seq_timer_interrupt(snd_timer_instance_t *timeri,
 				    unsigned long resolution,
-				    unsigned long ticks, void *data)
+				    unsigned long ticks)
 {
 	unsigned long flags;
-	queue_t *q = (queue_t *)data;
+	queue_t *q = (queue_t *)timeri->callback_data;
 	seq_timer_t *tmr;
 
 	if (q == NULL)
@@ -180,7 +180,7 @@
 	if (tempo <= 0)
 		return -EINVAL;
 	spin_lock_irqsave(&tmr->lock, flags);
-	if (tempo != tmr->tempo) {
+	if ((unsigned int)tempo != tmr->tempo) {
 		tmr->tempo = tempo;
 		snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
 	}
@@ -312,17 +312,14 @@
 	return 0;
 }
 
-int snd_seq_timer_stop(seq_timer_t * tmr, int in_callback)
+int snd_seq_timer_stop(seq_timer_t * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
 	if (!tmr->running)
 		return 0;
 	tmr->running = 0;
-	if (in_callback)
-		snd_timer_del(tmr->timeri);
-	else
-		snd_timer_stop(tmr->timeri);
+	snd_timer_stop(tmr->timeri);
 	return 0;
 }
 
@@ -348,12 +345,12 @@
 	return 0;
 }
 
-int snd_seq_timer_start(seq_timer_t * tmr, int in_callback)
+int snd_seq_timer_start(seq_timer_t * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
 	if (tmr->running)
-		snd_seq_timer_stop(tmr, in_callback);
+		snd_seq_timer_stop(tmr);
 	snd_seq_timer_reset(tmr);
 	if (initialize_timer(tmr) < 0)
 		return -EINVAL;
@@ -363,7 +360,7 @@
 	return 0;
 }
 
-int snd_seq_timer_continue(seq_timer_t * tmr, int in_callback)
+int snd_seq_timer_continue(seq_timer_t * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
diff -Nru a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
--- a/sound/core/seq/seq_timer.h	Mon Feb 10 10:39:29 2003
+++ b/sound/core/seq/seq_timer.h	Mon Feb 10 10:39:29 2003
@@ -127,9 +127,9 @@
 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 in_callback);
-int snd_seq_timer_start(seq_timer_t *tmr, int in_callback);
-int snd_seq_timer_continue(seq_timer_t *tmr, int in_callback);
+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);
diff -Nru a/sound/core/sound.c b/sound/core/sound.c
--- a/sound/core/sound.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/sound.c	Mon Feb 10 10:39:29 2003
@@ -73,6 +73,13 @@
 
 #ifdef CONFIG_KMOD
 
+/**
+ * snd_request_card - try to load the card module
+ * @card: the card number
+ *
+ * Tries to load the module "snd-card-X" for the given card number
+ * via KMOD.  Returns immediately if already loaded.
+ */
 void snd_request_card(int card)
 {
 	char str[32];
@@ -83,7 +90,7 @@
 	read_unlock(&snd_card_rwlock);
 	if (locked)
 		return;
-	if (card < 0 || card >= snd_ecards_limit)
+	if (card < 0 || card >= cards_limit)
 		return;
 	sprintf(str, "snd-card-%i", card);
 	request_module(str);
@@ -188,6 +195,19 @@
 	return minor;
 }
 
+/**
+ * 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
+ * @name: the device file name
+ *
+ * Registers an ALSA device file for the given card.
+ * The operators have to be set in reg parameter.
+ *
+ * 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 minor = snd_kernel_minor(type, card, dev);
@@ -215,6 +235,17 @@
 	return 0;
 }
 
+/**
+ * snd_unregister_device - unregister the device on the given card
+ * @type: the device type, SNDRV_DEVICE_TYPE_XXX
+ * @card: the card instance
+ * @dev: the device index
+ *
+ * Unregisters the device file already registered via
+ * snd_register_device().
+ *
+ * Returns zero if sucecessful, or a negative error code on failure
+ */
 int snd_unregister_device(int type, snd_card_t * card, int dev)
 {
 	int minor = snd_kernel_minor(type, card, dev);
@@ -411,6 +442,7 @@
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(snd_malloc_pci_pages);
 EXPORT_SYMBOL(snd_malloc_pci_pages_fallback);
+EXPORT_SYMBOL(snd_malloc_pci_page);
 EXPORT_SYMBOL(snd_free_pci_pages);
 #endif
 #ifdef CONFIG_SBUS
@@ -446,7 +478,7 @@
 #ifdef CONFIG_ISA
 EXPORT_SYMBOL(snd_dma_program);
 EXPORT_SYMBOL(snd_dma_disable);
-EXPORT_SYMBOL(snd_dma_residue);
+EXPORT_SYMBOL(snd_dma_pointer);
 #endif
   /* info.c */
 #ifdef CONFIG_PROC_FS
@@ -463,6 +495,7 @@
 EXPORT_SYMBOL(snd_info_free_device);
 EXPORT_SYMBOL(snd_info_register);
 EXPORT_SYMBOL(snd_info_unregister);
+EXPORT_SYMBOL(snd_card_proc_new);
 #endif
   /* info_oss.c */
 #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
diff -Nru a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c	Mon Feb 10 10:39:29 2003
+++ b/sound/core/timer.c	Mon Feb 10 10:39:29 2003
@@ -60,6 +60,7 @@
 	snd_timer_read_t *queue;
 	spinlock_t qlock;
 	wait_queue_head_t qchange_sleep;
+	struct fasync_struct *fasync;
 } snd_timer_user_t;
 
 /* list of timers */
@@ -97,9 +98,9 @@
 	}
 	INIT_LIST_HEAD(&timeri->open_list);
 	INIT_LIST_HEAD(&timeri->active_list);
+	INIT_LIST_HEAD(&timeri->ack_list);
 	INIT_LIST_HEAD(&timeri->slave_list_head);
 	INIT_LIST_HEAD(&timeri->slave_active_head);
-	timeri->in_use = (atomic_t)ATOMIC_INIT(0);
 
 	timeri->timer = timer;
 	if (timer && timer->card && !try_module_get(timer->card->module)) {
@@ -185,7 +186,10 @@
 			    slave->slave_id == master->slave_id) {
 				list_del(&slave->open_list);
 				list_add_tail(&slave->open_list, &master->slave_list_head);
+				spin_lock_irq(&slave_active_lock);
 				slave->master = master;
+				slave->timer = master->timer;
+				spin_unlock_irq(&slave_active_lock);
 				return;
 			}
 		}
@@ -202,7 +206,6 @@
 {
 	snd_timer_instance_t *slave;
 	struct list_head *p, *n;
-	unsigned long flags;
 
 	/* check all pending slaves */
 	list_for_each_safe(p, n, &snd_timer_slave_list) {
@@ -211,12 +214,12 @@
 		    slave->slave_id == master->slave_id) {
 			list_del(p);
 			list_add_tail(p, &master->slave_list_head);
-			spin_lock_irqsave(&slave_active_lock, flags);
-			/* protected here so that timer_start() doesn't start
-			 * this slave yet.
-			 */
+			spin_lock_irq(&slave_active_lock);
 			slave->master = master;
-			spin_unlock_irqrestore(&slave_active_lock, flags);
+			slave->timer = master->timer;
+			if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
+				list_add_tail(&slave->active_list, &master->slave_active_head);
+			spin_unlock_irq(&slave_active_lock);
 		}
 	}
 }
@@ -275,6 +278,7 @@
 	return timeri;
 }
 
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag);
 
 /*
  * close a timer instance
@@ -282,7 +286,6 @@
 int snd_timer_close(snd_timer_instance_t * timeri)
 {
 	snd_timer_t *timer = NULL;
-	unsigned long flags;
 	struct list_head *p, *n;
 	snd_timer_instance_t *slave;
 
@@ -303,13 +306,13 @@
 		/* remove slave links */
 		list_for_each_safe(p, n, &timeri->slave_list_head) {
 			slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+			spin_lock_irq(&slave_active_lock);
+			_snd_timer_stop(slave, 1);
 			list_del(p);
 			list_add_tail(p, &snd_timer_slave_list);
-			spin_lock_irqsave(&slave_active_lock, flags);
-			slave->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-			list_del_init(&slave->active_list);
 			slave->master = NULL;
-			spin_unlock_irqrestore(&slave_active_lock, flags);
+			slave->timer = NULL;
+			spin_unlock_irq(&slave_active_lock);
 		}
 		up(&register_mutex);
 	}
@@ -366,6 +369,9 @@
 	return 1; /* delayed start */
 }
 
+/*
+ *  start the timer instance
+ */ 
 int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
 {
 	snd_timer_t *timer;
@@ -381,96 +387,59 @@
 		return -EINVAL;
 	spin_lock_irqsave(&timer->lock, flags);
 	timeri->ticks = timeri->cticks = ticks;
+	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, ticks);
 	spin_unlock_irqrestore(&timer->lock, flags);
 	return result;
 }
 
-/*
- * stop the timer instance.
- *
- * do not call this from the timer callback!
- */
-int snd_timer_stop(snd_timer_instance_t * timeri)
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
 
 	snd_assert(timeri != NULL, return -ENXIO);
 
-	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
-		spin_lock_irqsave(&slave_active_lock, flags);
-		if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
-			timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-			list_del_init(&timeri->active_list);
-		}
-		spin_unlock_irqrestore(&slave_active_lock, flags);
-		return 0;
-	}
 
 	timer = timeri->timer;
 	if (! timer)
 		return -EINVAL;
 	spin_lock_irqsave(&timer->lock, flags);
-	while (atomic_read(&timeri->in_use)) {
+	list_del_init(&timeri->ack_list);
+	/* wait until the callback is finished */
+	while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
 		spin_unlock_irqrestore(&timer->lock, flags);
 		udelay(10);
 		spin_lock_irqsave(&timer->lock, flags);
 	}
-	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
-		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-		list_del_init(&timeri->active_list);
-		if (!(--timer->running)) {
-			timer->hw.stop(timer);
-			if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
-				timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
-				snd_timer_reschedule(timer, 0);
-				if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
-					timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
-					timer->hw.start(timer);
-				}
+	list_del_init(&timeri->active_list);
+	if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
+	    !(timeri->flags & SNDRV_TIMER_IFLG_SLAVE) &&
+	    !(--timer->running)) {
+		timer->hw.stop(timer);
+		if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
+			timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
+			snd_timer_reschedule(timer, 0);
+			if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
+				timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
+				timer->hw.start(timer);
 			}
 		}
-	} else if (timeri->flags & SNDRV_TIMER_IFLG_START) {
-		timeri->flags &= ~SNDRV_TIMER_IFLG_START;
-		list_del_init(&timeri->active_list);
 	}
+	if (!keep_flag)
+		timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
 	spin_unlock_irqrestore(&timer->lock, flags);
 	return 0;
 }
 
 /*
- * delete the timer instance from active list.
+ * stop the timer instance.
  *
- * call this from the timer callback only!
+ * do not call this from the timer callback!
  */
-int snd_timer_del(snd_timer_instance_t * timeri)
+int snd_timer_stop(snd_timer_instance_t * timeri)
 {
-	snd_timer_t *timer;
-
-	snd_assert(timeri != NULL, return -ENXIO);
-
-	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
-		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-		list_del_init(&timeri->active_list);
-		return 0;
-	}
-
-	timer = timeri->timer;
-	if (! timer)
-		return -EINVAL;
-	spin_lock(&timer->lock);
-	if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
-		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-		list_del_init(&timeri->active_list);
-		if (!(--timer->running))
-			timer->hw.stop(timer);
-	} else if (timeri->flags & SNDRV_TIMER_IFLG_START) {
-		timeri->flags &= ~SNDRV_TIMER_IFLG_START;
-		list_del_init(&timeri->active_list);
-	}
-	spin_unlock(&timer->lock);
-	return 0;
+	return _snd_timer_stop(timeri, 0);
 }
 
 /*
@@ -492,6 +461,7 @@
 	spin_lock_irqsave(&timer->lock, flags);
 	if (!timeri->cticks)
 		timeri->cticks = 1;
+	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, timer->sticks);
 	spin_unlock_irqrestore(&timer->lock, flags);
 	return result;
@@ -532,6 +502,39 @@
 	timer->sticks = ticks;
 }
 
+/*
+ * timer tasklet
+ *
+ */
+static void snd_timer_tasklet(unsigned long arg)
+{
+	snd_timer_t *timer = (snd_timer_t *) arg;
+	snd_timer_instance_t *ti;
+	struct list_head *p;
+	unsigned long resolution, ticks;
+
+	spin_lock(&timer->lock);
+	/* now process all callbacks */
+	while (!list_empty(&timer->sack_list_head)) {
+		p = timer->sack_list_head.next;		/* get first item */
+		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
+
+		/* remove from ack_list and make empty */
+		list_del_init(p);
+		
+		ticks = ti->pticks;
+		ti->pticks = 0;
+		resolution = ti->resolution;
+
+		ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
+		spin_unlock(&timer->lock);
+		if (ti->callback)
+			ti->callback(ti, resolution, ticks);
+		spin_lock(&timer->lock);
+		ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
+	}
+	spin_unlock(&timer->lock);
+}
 
 /*
  * timer interrupt
@@ -542,35 +545,63 @@
 void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
 {
 	snd_timer_instance_t *ti, *ts;
-	unsigned long resolution;
-	LIST_HEAD(done_list_head);
+	unsigned long resolution, ticks;
 	struct list_head *p, *q, *n;
+	int use_tasklet = 0;
 
 	if (timer == NULL)
 		return;
+
 	spin_lock(&timer->lock);
+
+	/* remember the current resolution */
+	if (timer->hw.c_resolution)
+		resolution = timer->hw.c_resolution(timer);
+	else
+		resolution = timer->hw.resolution;
+
 	/* loop for all active instances
 	 * here we cannot use list_for_each because the active_list of a processed
 	 * instance is relinked to done_list_head before callback is called.
 	 */
 	list_for_each_safe(p, n, &timer->active_list_head) {
 		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
-		if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) {
-			if (ti->cticks < ticks_left)
-				ti->cticks = 0;
-			else
-				ti->cticks -= ticks_left;
-			if (!ti->cticks) { /* expired */
-				if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
-					ti->cticks = ti->ticks;
+		if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
+			continue;
+		ti->pticks += ticks_left;
+		ti->resolution = resolution;
+		if (ti->cticks < ticks_left)
+			ti->cticks = 0;
+		else
+			ti->cticks -= ticks_left;
+		if (ti->cticks) /* not expired */
+			continue;
+		if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
+			ti->cticks = ti->ticks;
+		} else {
+			ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+			if (--timer->running)
+				list_del(p);
+		}
+		if (list_empty(&ti->ack_list)) {
+			if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+			    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
+				list_add_tail(&ti->ack_list, &timer->ack_list_head);
+			} else {
+				list_add_tail(&ti->ack_list, &timer->sack_list_head);
+			}
+		}
+		list_for_each(q, &ti->slave_active_head) {
+			ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
+			ts->pticks = ti->pticks;
+			ts->resolution = resolution;
+			if (list_empty(&ts->ack_list)) {
+				if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+				    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
+					list_add_tail(&ts->ack_list, &timer->ack_list_head);
 				} else {
-					ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
-					timer->running--;
+					list_add_tail(&ts->ack_list, &timer->sack_list_head);
 				}
-				/* relink to done_list */
-				list_del(p);
-				list_add_tail(p, &done_list_head);
-				atomic_inc(&ti->in_use);
 			}
 		}
 	}
@@ -591,36 +622,32 @@
 		timer->hw.stop(timer);
 	}
 
-	/* remember the current resolution */
-	if (timer->hw.c_resolution)
-		resolution = timer->hw.c_resolution(timer);
-	else
-		resolution = timer->hw.resolution;
+	/* now process all fast callbacks */
+	while (!list_empty(&timer->ack_list_head)) {
+		p = timer->ack_list_head.next;		/* get first item */
+		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
+		
+		/* remove from ack_list and make empty */
+		list_del_init(p);
+		
+		ticks = ti->pticks;
+		ti->pticks = 0;
 
-	/* now process all callbacks */
-	list_for_each_safe(p, n, &done_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
-		/* append to active_list */
-		list_del(p);
-		if (ti->flags & SNDRV_TIMER_IFLG_RUNNING)
-			list_add_tail(p, &timer->active_list_head);
+		ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
 		spin_unlock(&timer->lock);
 		if (ti->callback)
-			ti->callback(ti, resolution, ti->ticks, ti->callback_data);
-		spin_lock(&slave_active_lock);
-		/* call callbacks of slaves */
-		list_for_each(q, &ti->slave_active_head) {
-			ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
-			if (ts->callback)
-				ts->callback(ts, resolution, ti->ticks, ts->callback_data);
-		}
-		spin_unlock(&slave_active_lock);
+			ti->callback(ti, resolution, ticks);
 		spin_lock(&timer->lock);
-		atomic_dec(&ti->in_use);
+		ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
 	}
+
+	/* do we have any slow callbacks? */
+	use_tasklet = !list_empty(&timer->sack_list_head);
 	spin_unlock(&timer->lock);
-}
 
+	if (use_tasklet)
+		tasklet_hi_schedule(&timer->task_queue);
+}
 
 /*
 
@@ -651,7 +678,10 @@
 	INIT_LIST_HEAD(&timer->device_list);
 	INIT_LIST_HEAD(&timer->open_list_head);
 	INIT_LIST_HEAD(&timer->active_list_head);
+	INIT_LIST_HEAD(&timer->ack_list_head);
+	INIT_LIST_HEAD(&timer->sack_list_head);
 	spin_lock_init(&timer->lock);
+	tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer);
 	if (card != NULL) {
 		if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) {
 			snd_timer_free(timer);
@@ -815,7 +845,7 @@
 
 static struct _snd_timer_hardware snd_timer_system =
 {
-	.flags =	SNDRV_TIMER_HW_FIRST,
+	.flags =	SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
 	.resolution =	1000000000L / HZ,
 	.ticks =	10000000L,
 	.start =	snd_timer_s_start,
@@ -904,23 +934,26 @@
 
 static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
 				     unsigned long resolution,
-				     unsigned long ticks,
-				     void *data)
+				     unsigned long ticks)
 {
-	unsigned long flags;
-	snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, data, return);
+	snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, return);
 	snd_timer_read_t *r;
+	int _wake = 0;
 	
+	spin_lock(&tu->qlock);
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
 	} else {
-		spin_lock_irqsave(&tu->qlock, flags);
 		r = &tu->queue[tu->qtail++];
 		tu->qtail %= tu->queue_size;
 		r->resolution = resolution;
 		r->ticks = ticks;
 		tu->qused++;
-		spin_unlock_irqrestore(&tu->qlock, flags);
+		_wake++;
+	}
+	spin_unlock(&tu->qlock);
+	if (_wake) {
+		kill_fasync(&tu->fasync, SIGIO, POLL_IN);
 		wake_up(&tu->qchange_sleep);
 	}
 }
@@ -942,9 +975,6 @@
 		return -ENOMEM;
 	}
 	file->private_data = tu;
-#ifdef LINUX_2_2
-	MOD_INC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -955,15 +985,13 @@
 	if (file->private_data) {
 		tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
 		file->private_data = NULL;
+		fasync_helper(-1, file, 0, &tu->fasync);
 		if (tu->timeri)
 			snd_timer_close(tu->timeri);
 		if (tu->queue)
 			kfree(tu->queue);
 		snd_magic_kfree(tu);
 	}
-#ifdef LINUX_2_2
-	MOD_DEC_USE_COUNT;
-#endif
 	return 0;
 }
 
@@ -1092,6 +1120,7 @@
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
 	if ((tu->timeri = snd_timer_open(str, &tselect.id, current->pid)) == NULL)
 		return -ENODEV;
+	tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
 	tu->timeri->callback = snd_timer_user_interrupt;
 	tu->timeri->callback_data = (void *)tu;
 	return 0;
@@ -1151,7 +1180,7 @@
 		tu->timeri->flags &= ~SNDRV_TIMER_IFLG_AUTO;
 	}
 	spin_unlock_irqrestore(&t->lock, flags);
-	if (params.queue_size > 0 && tu->queue_size != params.queue_size) {
+	if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
 		tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
 		if (tr) {
 			kfree(tu->queue);
@@ -1253,6 +1282,18 @@
 	return -ENOTTY;
 }
 
+static int snd_timer_user_fasync(int fd, struct file * file, int on)
+{
+	snd_timer_user_t *tu;
+	int err;
+	
+	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
+	err = fasync_helper(fd, file, on, &tu->fasync);
+        if (err < 0)
+		return err;
+	return 0;
+}
+
 static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count, loff_t *offset)
 {
 	snd_timer_user_t *tu;
@@ -1260,8 +1301,8 @@
 	int  err = 0;
 	
 	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
+	spin_lock_irq(&tu->qlock);
 	while (count - result >= sizeof(snd_timer_read_t)) {
-		spin_lock_irq(&tu->qlock);
 		while (!tu->qused) {
 			wait_queue_t wait;
 
@@ -1275,7 +1316,7 @@
 			init_waitqueue_entry(&wait, current);
 			add_wait_queue(&tu->qchange_sleep, &wait);
 
-			spin_unlock(&tu->qlock);
+			spin_unlock_irq(&tu->qlock);
 			schedule();
 			spin_lock_irq(&tu->qlock);
 
@@ -1297,11 +1338,12 @@
 		}
 
 		tu->qhead %= tu->queue_size;
-		spin_lock_irq(&tu->qlock);
-		tu->qused--;
-		spin_unlock_irq(&tu->qlock);
+
 		result += sizeof(snd_timer_read_t);
 		buffer += sizeof(snd_timer_read_t);
+
+		spin_lock_irq(&tu->qlock);
+		tu->qused--;
 	}
 	return result > 0 ? result : err;
 }
@@ -1332,6 +1374,7 @@
 	.release =	snd_timer_user_release,
 	.poll =		snd_timer_user_poll,
 	.ioctl =	snd_timer_user_ioctl,
+	.fasync = 	snd_timer_user_fasync,
 };
 
 static snd_minor_t snd_timer_reg =
@@ -1399,7 +1442,6 @@
 EXPORT_SYMBOL(snd_timer_resolution);
 EXPORT_SYMBOL(snd_timer_start);
 EXPORT_SYMBOL(snd_timer_stop);
-EXPORT_SYMBOL(snd_timer_del);
 EXPORT_SYMBOL(snd_timer_continue);
 EXPORT_SYMBOL(snd_timer_new);
 EXPORT_SYMBOL(snd_timer_global_new);
diff -Nru a/sound/drivers/dummy.c b/sound/drivers/dummy.c
--- a/sound/drivers/dummy.c	Mon Feb 10 10:39:32 2003
+++ b/sound/drivers/dummy.c	Mon Feb 10 10:39:32 2003
@@ -520,7 +520,8 @@
 int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy)
 {
 	snd_card_t *card = dummy->card;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	snd_assert(dummy != NULL, return -EINVAL);
 	spin_lock_init(&dummy->mixer_lock);
diff -Nru a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile
--- a/sound/drivers/mpu401/Makefile	Mon Feb 10 10:39:33 2003
+++ b/sound/drivers/mpu401/Makefile	Mon Feb 10 10:39:33 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := mpu401_uart.o
-
 snd-mpu401-objs := mpu401.o
 snd-mpu401-uart-objs := mpu401_uart.o
 
diff -Nru a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
--- a/sound/drivers/mpu401/mpu401.c	Mon Feb 10 10:39:30 2003
+++ b/sound/drivers/mpu401/mpu401.c	Mon Feb 10 10:39:30 2003
@@ -40,7 +40,7 @@
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* MPU-401 port number */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* MPU-401 IRQ */
-#ifdef CONFIG_PC9800
+#ifdef CONFIG_X86_PC9800
 static int pc98ii[SNDRV_CARDS];				/* PC98-II dauther board */
 #endif
 
@@ -59,7 +59,7 @@
 MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
 MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
-#ifdef CONFIG_PC9800
+#ifdef CONFIG_X86_PC9800
 MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
 MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
@@ -85,7 +85,7 @@
 	if (card == NULL)
 		return -ENOMEM;
 	if (snd_mpu401_uart_new(card, 0,
-#ifdef CONFIG_PC9800
+#ifdef CONFIG_X86_PC9800
 				pc98ii[dev] ? MPU401_HW_PC98II :
 #endif
 				MPU401_HW_MPU401,
@@ -154,6 +154,9 @@
 	(void)(get_option(&str,&enable[nr_dev]) == 2 &&
 	       get_option(&str,&index[nr_dev]) == 2 &&
 	       get_id(&str,&id[nr_dev]) == 2 &&
+#ifdef CONFIG_X86_PC9800
+	       get_option(&str,&pc98ii[nr_dev]) == 2 &&
+#endif
 	       get_option(&str,(int *)&port[nr_dev]) == 2 &&
 	       get_option(&str,&irq[nr_dev]) == 2);
 	nr_dev++;
diff -Nru a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
--- a/sound/drivers/mpu401/mpu401_uart.c	Mon Feb 10 10:39:25 2003
+++ b/sound/drivers/mpu401/mpu401_uart.c	Mon Feb 10 10:39:25 2003
@@ -65,15 +65,32 @@
 
 static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
 {
-	if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
-		snd_mpu401_uart_input_read(mpu);
-	else
+	if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
+		if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) {
+			spin_lock(&mpu->input_lock);
+			snd_mpu401_uart_input_read(mpu);
+			spin_unlock(&mpu->input_lock);
+			clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
+		}
+	} else
 		snd_mpu401_uart_clear_rx(mpu);
-	/* ok. for better Tx performance try do some output when input is done */
-	if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode))
+ 	/* ok. for better Tx performance try do some output when input is done */
+	if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
+	    test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
+		spin_lock(&mpu->output_lock);
 		snd_mpu401_uart_output_write(mpu);
+		spin_unlock(&mpu->output_lock);
+	}
 }
 
+/**
+ * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
+ * @irq: the irq number
+ * @dev_id: mpu401 instance
+ * @regs: the reigster
+ *
+ * Processes the interrupt for MPU401-UART i/o.
+ */
 void snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	mpu401_t *mpu = snd_magic_cast(mpu401_t, dev_id, return);
@@ -83,20 +100,26 @@
 	_snd_mpu401_uart_interrupt(mpu);
 }
 
+/*
+ * timer callback
+ * reprogram the timer and call the interrupt job
+ */
 static void snd_mpu401_uart_timer(unsigned long data)
 {
-	unsigned long flags;
 	mpu401_t *mpu = snd_magic_cast(mpu401_t, (void *)data, return);
 
-	spin_lock_irqsave(&mpu->timer_lock, flags);
+	spin_lock(&mpu->timer_lock);
 	/*mpu->mode |= MPU401_MODE_TIMER;*/
 	mpu->timer.expires = 1 + jiffies;
 	add_timer(&mpu->timer);
-	spin_unlock_irqrestore(&mpu->timer_lock, flags);
+	spin_unlock(&mpu->timer_lock);
 	if (mpu->rmidi)
 		_snd_mpu401_uart_interrupt(mpu);
 }
 
+/*
+ * initialize the timer callback if not programmed yet
+ */
 static void snd_mpu401_uart_add_timer (mpu401_t *mpu, int input)
 {
 	unsigned long flags;
@@ -113,6 +136,9 @@
 	spin_unlock_irqrestore (&mpu->timer_lock, flags);
 }
 
+/*
+ * remove the timer callback if still active
+ */
 static void snd_mpu401_uart_remove_timer (mpu401_t *mpu, int input)
 {
 	unsigned long flags;
@@ -236,7 +262,7 @@
 }
 
 /*
- * trigger input
+ * trigger input callback
  */
 static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up)
 {
@@ -245,48 +271,48 @@
 	int max = 64;
 
 	mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return);
-	spin_lock_irqsave(&mpu->input_lock, flags);
 	if (up) {
 		if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) {
-			/* flush FIFO */
+			/* first time - flush FIFO */
 			while (max-- > 0)
 				inb(MPU401D(mpu));
+			if (mpu->irq < 0)
+				snd_mpu401_uart_add_timer(mpu, 1);
+		}
+		
+		/* read data in advance */
+		/* prevent double enter via rawmidi->event callback */
+		if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) {
+			spin_lock_irqsave(&mpu->input_lock, flags);
+			snd_mpu401_uart_input_read(mpu);
+			spin_unlock_irqrestore(&mpu->input_lock, flags);
+			clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
 		}
-		if (mpu->irq < 0)
-			snd_mpu401_uart_add_timer(mpu, 1);
 	} else {
 		if (mpu->irq < 0)
 			snd_mpu401_uart_remove_timer(mpu, 1);
 		clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
 	}
-	spin_unlock_irqrestore(&mpu->input_lock, flags);
-	if (up)
-		snd_mpu401_uart_input_read(mpu);
 }
 
+/*
+ * transfer input pending data
+ * call with input_lock spinlock held
+ */
 static void snd_mpu401_uart_input_read(mpu401_t * mpu)
 {
 	int max = 128;
 	unsigned char byte;
 
-	/* prevent double enter via event callback */
-	if (test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode))
-		return;
-	spin_lock(&mpu->input_lock);
 	while (max-- > 0) {
 		if (snd_mpu401_input_avail(mpu)) {
 			byte = inb(MPU401D(mpu));
-			if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) {
-				spin_unlock(&mpu->input_lock);
+			if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
 				snd_rawmidi_receive(mpu->substream_input, &byte, 1);
-				spin_lock(&mpu->input_lock);
-			}
 		} else {
 			break; /* input not available */
 		}
 	}
-	spin_unlock(&mpu->input_lock);
-	clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
 }
 
 /*
@@ -297,18 +323,16 @@
  *    SoundBlaster AWE 64       -  2 bytes (ugly hardware)
  */
 
+/*
+ * write output pending bytes
+ * call with output_lock spinlock held
+ */
 static void snd_mpu401_uart_output_write(mpu401_t * mpu)
 {
 	unsigned char byte;
 	int max = 256, timeout;
 
-	if (!test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode))
-		return;
-	/* prevent double enter */
-	if (test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode))
-		return;
 	do {
-		spin_lock(&mpu->output_lock);
 		if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) {
 			for (timeout = 100; timeout > 0; timeout--) {
 				if (snd_mpu401_output_ready(mpu)) {
@@ -321,28 +345,38 @@
 			snd_mpu401_uart_remove_timer (mpu, 0);
 			max = 1; /* no other data - leave the tx loop */
 		}
-		spin_unlock(&mpu->output_lock);
 	} while (--max > 0);
-	clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode);
 }
 
+/*
+ * output trigger callback
+ */
 static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up)
 {
 	unsigned long flags;
 	mpu401_t *mpu;
 
 	mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return);
-	spin_lock_irqsave(&mpu->output_lock, flags);
 	if (up) {
 		set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
+		/* try to add the timer at each output trigger,
+		 * since the output timer might have been removed in
+		 * snd_mpu401_uart_output_write().
+		 */
 		snd_mpu401_uart_add_timer(mpu, 0);
+
+		/* output pending data */
+		/* prevent double enter via rawmidi->event callback */
+		if (! test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode)) {
+			spin_lock_irqsave(&mpu->output_lock, flags);
+			snd_mpu401_uart_output_write(mpu);
+			spin_unlock_irqrestore(&mpu->output_lock, flags);
+			clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode);
+		}
 	} else {
 		snd_mpu401_uart_remove_timer(mpu, 0);
 		clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
 	}
-	spin_unlock_irqrestore(&mpu->output_lock, flags);
-	if (up)
-		snd_mpu401_uart_output_write(mpu);
 }
 
 /*
@@ -375,6 +409,25 @@
 	snd_magic_kfree(mpu);
 }
 
+/**
+ * snd_mpu401_uart_new - create an MPU401-UART instance
+ * @card: the card instance
+ * @device: the device index, zero-based
+ * @hardware: the hardware type, MPU401_HW_XXXX
+ * @port: the base address of MPU401 port
+ * @integrated: non-zero if the port was already reserved by the chip
+ * @irq: the irq number, -1 if no interrupt for mpu
+ * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
+ * @rrawmidi: the pointer to store the new rawmidi instance
+ *
+ * Creates a new MPU-401 instance.
+ *
+ * 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).
+ *
+ * Returns zero if successful, or a negative error code.
+ */
 int snd_mpu401_uart_new(snd_card_t * card, int device,
 			unsigned short hardware,
 			unsigned long port, int integrated,
@@ -418,9 +471,9 @@
 			snd_device_free(card, rmidi);
 			return -EBUSY;
 		}
-		mpu->irq = irq;
-		mpu->irq_flags = irq_flags;
 	}
+	mpu->irq = irq;
+	mpu->irq_flags = irq_flags;
 	strcpy(rmidi->name, "MPU-401 (UART)");
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input);
diff -Nru a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
--- a/sound/drivers/mtpav.c	Mon Feb 10 10:39:30 2003
+++ b/sound/drivers/mtpav.c	Mon Feb 10 10:39:30 2003
@@ -503,7 +503,7 @@
 {
 	mtpav_port_t *portp;
 
-	if (mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
+	if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
 		return;
 
 	portp = &mcrd->ports[mcrd->inmidiport];
diff -Nru a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile
--- a/sound/drivers/opl3/Makefile	Mon Feb 10 10:39:23 2003
+++ b/sound/drivers/opl3/Makefile	Mon Feb 10 10:39:23 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := opl3_lib.o
-
 snd-opl3-lib-objs := opl3_lib.o opl3_synth.o
 ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
 snd-opl3-synth-objs := opl3_seq.o opl3_midi.o opl3_drums.o
diff -Nru a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
--- a/sound/drivers/opl3/opl3_oss.c	Mon Feb 10 10:39:23 2003
+++ b/sound/drivers/opl3/opl3_oss.c	Mon Feb 10 10:39:23 2003
@@ -101,6 +101,7 @@
 							  SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
 							  SNDRV_SEQ_PORT_TYPE_MIDI_GM |
 							  SNDRV_SEQ_PORT_TYPE_SYNTH,
+							  voices,
 							  name);
 	if (opl3->oss_chset->port < 0) {
 		snd_midi_channel_free_set(opl3->oss_chset);
@@ -228,7 +229,7 @@
 
 		mm_segment_t fs;
 
-		if (count < sizeof(sbi)) {
+		if (count < (int)sizeof(sbi)) {
 			snd_printk("FM Error: Patch record too short\n");
 			return -EINVAL;
 		}
diff -Nru a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
--- a/sound/drivers/opl3/opl3_seq.c	Mon Feb 10 10:39:29 2003
+++ b/sound/drivers/opl3/opl3_seq.c	Mon Feb 10 10:39:29 2003
@@ -204,6 +204,7 @@
 						      SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
 						      SNDRV_SEQ_PORT_TYPE_MIDI_GM |
 						      SNDRV_SEQ_PORT_TYPE_SYNTH,
+						      16,
 						      name);
 	if (opl3->chset->port < 0) {
 		snd_midi_channel_free_set(opl3->chset);
diff -Nru a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
--- a/sound/drivers/serial-u16550.c	Mon Feb 10 10:39:23 2003
+++ b/sound/drivers/serial-u16550.c	Mon Feb 10 10:39:23 2003
@@ -322,17 +322,20 @@
  *  return 0 if found
  *  return negative error if not found
  */
-static int __init snd_uart16550_detect(unsigned int io_base)
+static int __init snd_uart16550_detect(snd_uart16550_t *uart)
 {
+	unsigned long io_base = uart->base;
 	int ok;
 	unsigned char c;
 
-	if (check_region(io_base, 8))
-		return -EBUSY;
-
 	/* Do some vague tests for the presence of the uart */
-	if (io_base == 0)
+	if (io_base == 0) {
 		return -ENODEV;	/* Not configured */
+	}
+
+	uart->res_base = request_region(io_base, 8, "Serial MIDI");
+	if (uart->res_base == NULL)
+		return -EBUSY;
 
 	ok = 1;			/* uart detected unless one of the following tests should fail */
 	/* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
@@ -766,11 +769,13 @@
 	uart->card = card;
 	spin_lock_init(&uart->open_lock);
 	uart->irq = -1;
-	if ((uart->res_base = request_region(iobase, 8, "Serial MIDI")) == NULL) {
-		snd_printk("unable to grab ports 0x%lx-0x%lx\n", iobase, iobase + 8 - 1);
-		return -EBUSY;
-	}
 	uart->base = iobase;
+
+	if ((err = snd_uart16550_detect(uart)) <= 0) {
+		printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
+		return err;
+	}
+
 	if (irq >= 0) {
 		if (request_irq(irq, snd_uart16550_interrupt,
 				SA_INTERRUPT, "Serial MIDI", (void *) uart)) {
@@ -887,12 +892,6 @@
 
 	strcpy(card->driver, "Serial");
 	strcpy(card->shortname, "Serial midi (uart16550A)");
-
-	if ((err = snd_uart16550_detect(port[dev])) <= 0) {
-		snd_card_free(card);
-		printk(KERN_ERR "no UART detected at 0x%lx\n", (long)port[dev]);
-		return err;
-	}
 
 	if ((err = snd_uart16550_create(card,
 					port[dev],
diff -Nru a/sound/i2c/Makefile b/sound/i2c/Makefile
--- a/sound/i2c/Makefile	Mon Feb 10 10:39:28 2003
+++ b/sound/i2c/Makefile	Mon Feb 10 10:39:28 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := i2c.o cs8427.o tea6330t.o
-
 snd-i2c-objs := i2c.o
 snd-cs8427-objs := cs8427.o
 snd-tea6330t-objs := tea6330t.o
diff -Nru a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
--- a/sound/i2c/cs8427.c	Mon Feb 10 10:39:23 2003
+++ b/sound/i2c/cs8427.c	Mon Feb 10 10:39:23 2003
@@ -396,7 +396,8 @@
 {
 	cs8427_t *chip = snd_magic_cast(cs8427_t, cs8427->private_data, return -ENXIO);
 	snd_kcontrol_t *kctl;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	snd_assert(play_substream && cap_substream, return -EINVAL);
 	for (idx = 0; idx < CONTROLS; idx++) {
diff -Nru a/sound/i2c/l3/Makefile b/sound/i2c/l3/Makefile
--- a/sound/i2c/l3/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/i2c/l3/Makefile	Mon Feb 10 10:39:29 2003
@@ -2,8 +2,6 @@
 # Makefile for ALSA
 #
 
-export-objs += uda1341.o
-
 snd-uda1341-objs := uda1341.o
 
 # Module Dependency
diff -Nru a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
--- a/sound/i2c/l3/uda1341.c	Mon Feb 10 10:39:27 2003
+++ b/sound/i2c/l3/uda1341.c	Mon Feb 10 10:39:27 2003
@@ -16,7 +16,7 @@
  * 2002-04-12	Tomas Kasparek	Proc interface update, code cleanup
  */
 
-/* $Id: uda1341.c,v 1.5 2002/11/09 13:12:19 perex Exp $ */
+/* $Id: uda1341.c,v 1.6 2003/01/07 10:36:28 tiwai Exp $ */
 
 #include <sound/driver.h>
 #include <linux/module.h>
@@ -128,9 +128,6 @@
 
 	snd_card_t *card;
 
-	snd_info_entry_t *proc_entry;
-	snd_info_entry_t *proc_regs_entry;
-
 	uda1341_cfg cfg;
 };
 
@@ -410,46 +407,10 @@
 
 	DEBUG_NAME(KERN_DEBUG "proc_init\n");
         
-	if ((entry = snd_info_create_card_entry(card, "uda1341", card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = clnt;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 512;
-		entry->c.text.read = snd_uda1341_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	uda->proc_entry = entry;
-	if ((entry = snd_info_create_card_entry(card, "uda1341-regs", card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = clnt;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 1024;
-		entry->c.text.read = snd_uda1341_proc_regs_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	uda->proc_regs_entry = entry;   
-}
-
-static void snd_uda1341_proc_done(struct l3_client *clnt)
-{
-	struct uda1341 *uda = clnt->driver_data;
-
-	DEBUG_NAME(KERN_DEBUG "proc_done\n");
-        
-	if (uda->proc_regs_entry) {
-		snd_info_unregister(uda->proc_regs_entry);
-		uda->proc_regs_entry = NULL;
-	}
-	if (uda->proc_entry) {
-		snd_info_unregister(uda->proc_entry);
-		uda->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(card, "uda1341", &entry))
+		snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read);
+	if (! snd_card_proc_new(card, "uda1341-regs", &entry)) {
+		snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read);
 }
 
 /* }}} */
@@ -731,7 +692,6 @@
 {
 	DEBUG_NAME(KERN_DEBUG "uda1341 mixer_del\n");
         
-	snd_uda1341_proc_done(uda1341);
 	l3_detach_client(uda1341);
 
 	snd_magic_kfree(uda1341);
diff -Nru a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
--- a/sound/i2c/tea6330t.c	Mon Feb 10 10:39:27 2003
+++ b/sound/i2c/tea6330t.c	Mon Feb 10 10:39:27 2003
@@ -281,7 +281,8 @@
 	snd_i2c_device_t *device;
 	tea6330t_t *tea;
 	snd_kcontrol_new_t *knew;
-	int idx, err = -ENOMEM;
+	unsigned int idx;
+	int err = -ENOMEM;
 	u8 default_treble, default_bass;
 	unsigned char bytes[7];
 
diff -Nru a/sound/isa/ad1816a/Makefile b/sound/isa/ad1816a/Makefile
--- a/sound/isa/ad1816a/Makefile	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/ad1816a/Makefile	Mon Feb 10 10:39:26 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := ad1816a_lib.o
-
 snd-ad1816a-lib-objs := ad1816a_lib.o
 snd-ad1816a-objs := ad1816a.o
 
diff -Nru a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
--- a/sound/isa/ad1816a/ad1816a_lib.c	Mon Feb 10 10:39:29 2003
+++ b/sound/isa/ad1816a/ad1816a_lib.c	Mon Feb 10 10:39:29 2003
@@ -296,7 +296,7 @@
 	size_t ptr;
 	if (!(chip->mode & AD1816A_MODE_PLAYBACK))
 		return 0;
-	ptr = chip->p_dma_size - snd_dma_residue(chip->dma1);
+	ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -306,7 +306,7 @@
 	size_t ptr;
 	if (!(chip->mode & AD1816A_MODE_CAPTURE))
 		return 0;
-	ptr = chip->c_dma_size - snd_dma_residue(chip->dma2);
+	ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -934,7 +934,8 @@
 int snd_ad1816a_mixer(ad1816a_t *chip)
 {
 	snd_card_t *card;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
 
diff -Nru a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile
--- a/sound/isa/ad1848/Makefile	Mon Feb 10 10:39:24 2003
+++ b/sound/isa/ad1848/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := ad1848_lib.o
-
 snd-ad1848-lib-objs := ad1848_lib.o
 snd-ad1848-objs := ad1848.o
 
diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
--- a/sound/isa/ad1848/ad1848_lib.c	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/ad1848/ad1848_lib.c	Mon Feb 10 10:39:33 2003
@@ -28,6 +28,7 @@
 #include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/ad1848.h>
+#include <sound/control.h>
 #include <sound/pcm_params.h>
 
 #include <asm/io.h>
@@ -604,7 +605,7 @@
 	
 	if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
 		return 0;
-	ptr = chip->dma_size - snd_dma_residue(chip->dma);
+	ptr = snd_dma_pointer(chip->dma, chip->dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -615,7 +616,7 @@
 
 	if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
 		return 0;
-	ptr = chip->dma_size - snd_dma_residue(chip->dma);
+	ptr = snd_dma_pointer(chip->dma, chip->dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -936,6 +937,12 @@
 	return 0;
 }
 
+const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction)
+{
+	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
+		&snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
+}
+
 /*
  *  MIXER part
  */
@@ -990,7 +997,7 @@
 	return change;
 }
 
-int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1001,7 +1008,7 @@
 	return 0;
 }
 
-int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1018,7 +1025,7 @@
 	return 0;
 }
 
-int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1041,7 +1048,7 @@
 	return change;
 }
 
-int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1052,7 +1059,7 @@
 	return 0;
 }
 
-int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1074,7 +1081,7 @@
 	return 0;
 }
 
-int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1111,9 +1118,47 @@
 	return change;
 }
 
-#define AD1848_CONTROLS (sizeof(snd_ad1848_controls)/sizeof(snd_kcontrol_new_t))
+/*
+ */
+int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value)
+{
+	static snd_kcontrol_new_t newctls[] = {
+		[AD1848_MIX_SINGLE] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_ad1848_info_single,
+			.get = snd_ad1848_get_single,
+			.put = snd_ad1848_put_single,
+		},
+		[AD1848_MIX_DOUBLE] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_ad1848_info_double,
+			.get = snd_ad1848_get_double,
+			.put = snd_ad1848_put_double,
+		},
+		[AD1848_MIX_CAPTURE] = {
+			.info = snd_ad1848_info_mux,
+			.get = snd_ad1848_get_mux,
+			.put = snd_ad1848_put_mux,
+		},
+	};
+	snd_kcontrol_t *ctl;
+	int err;
+
+	ctl = snd_ctl_new1(&newctls[type], chip);
+	if (! ctl)
+		return -ENOMEM;
+	strncpy(ctl->id.name, name, sizeof(ctl->id.name)-1);
+	ctl->id.index = index;
+	ctl->private_value = value;
+	if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
+		snd_ctl_free_one(ctl);
+		return err;
+	}
+	return 0;
+}
+
 
-static snd_kcontrol_new_t snd_ad1848_controls[] = {
+static struct ad1848_mix_elem snd_ad1848_controls[] = {
 AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
 AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1),
 AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
@@ -1122,11 +1167,8 @@
 AD1848_DOUBLE("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
 AD1848_DOUBLE("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0),
 {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Capture Source",
-	.info = snd_ad1848_info_mux,
-	.get = snd_ad1848_get_mux,
-	.put = snd_ad1848_put_mux,
+	.type = AD1848_MIX_CAPTURE,
 },
 AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0),
 AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0)
@@ -1136,7 +1178,8 @@
 {
 	snd_card_t *card;
 	snd_pcm_t *pcm;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
 
@@ -1145,10 +1188,10 @@
 
 	strcpy(card->mixername, pcm->name);
 
-	for (idx = 0; idx < AD1848_CONTROLS; idx++) {
-		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1848_controls[idx], chip))) < 0)
+	for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++)
+		if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0)
 			return err;
-	}
+
 	return 0;
 }
 
@@ -1160,13 +1203,9 @@
 EXPORT_SYMBOL(snd_ad1848_interrupt);
 EXPORT_SYMBOL(snd_ad1848_create);
 EXPORT_SYMBOL(snd_ad1848_pcm);
+EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
 EXPORT_SYMBOL(snd_ad1848_mixer);
-EXPORT_SYMBOL(snd_ad1848_info_single);
-EXPORT_SYMBOL(snd_ad1848_get_single);
-EXPORT_SYMBOL(snd_ad1848_put_single);
-EXPORT_SYMBOL(snd_ad1848_info_double);
-EXPORT_SYMBOL(snd_ad1848_get_double);
-EXPORT_SYMBOL(snd_ad1848_put_double);
+EXPORT_SYMBOL(snd_ad1848_add_ctl);
 
 /*
  *  INIT part
diff -Nru a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
--- a/sound/isa/cmi8330.c	Mon Feb 10 10:39:23 2003
+++ b/sound/isa/cmi8330.c	Mon Feb 10 10:39:23 2003
@@ -57,6 +57,13 @@
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
+/*
+ */
+/* #define ENABLE_SB_MIXER */
+#define PLAYBACK_ON_SB
+
+/*
+ */
 MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
 MODULE_DESCRIPTION("C-Media CMI8330");
 MODULE_LICENSE("GPL");
@@ -129,8 +136,12 @@
 
 static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
 {
-	0x0,			/* 16 - recording mux */
-	0x40,			/* 17 - mute mux */
+	0x40,			/* 16 - recording mux (SB-mixer-enabled) */
+#ifdef ENABLE_SB_MIXER
+	0x40,			/* 17 - mute mux (Mode2) */
+#else
+	0x0,			/* 17 - mute mux */
+#endif
 	0x0,			/* 18 - vol */
 	0x0,			/* 19 - master volume */
 	0x0,			/* 20 - line-in volume */
@@ -142,11 +153,23 @@
 	0x0			/* 26 - cd-in rec gain */
 };
 
+typedef int (*snd_pcm_open_callback_t)(snd_pcm_substream_t *);
+
 struct snd_cmi8330 {
 #ifdef __ISAPNP__
 	struct isapnp_dev *cap;
 	struct isapnp_dev *play;
 #endif
+	snd_card_t *card;
+	ad1848_t *wss;
+	sb_t *sb;
+
+	snd_pcm_t *pcm;
+	struct snd_cmi8330_stream {
+		snd_pcm_ops_t ops;
+		snd_pcm_open_callback_t open;
+		void *private_data; /* sb or wss */
+	} streams[2];
 };
 
 static snd_card_t *snd_cmi8330_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
@@ -173,9 +196,8 @@
 
 #endif
 
-#define CMI8330_CONTROLS (sizeof(snd_cmi8330_controls)/sizeof(snd_kcontrol_new_t))
 
-static snd_kcontrol_new_t snd_cmi8330_controls[] __devinitdata = {
+static struct ad1848_mix_elem snd_cmi8330_controls[] __initdata = {
 AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
 AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1),
 AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
@@ -187,7 +209,7 @@
 AD1848_DOUBLE("CD Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0),
 AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0),
 AD1848_DOUBLE("CD Playback Volume", 0, CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0),
-AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
+AD1848_DOUBLE("CD Capture Volume", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
 AD1848_SINGLE("Mic Playback Switch", 0, CMI8330_MUTEMUX, 0, 1, 0),
 AD1848_SINGLE("Mic Playback Volume", 0, CMI8330_OUTPUTVOL, 0, 7, 0),
 AD1848_SINGLE("Mic Capture Switch", 0, CMI8330_RMUX3D, 0, 1, 0),
@@ -203,16 +225,80 @@
 AD1848_SINGLE("IEC958 Input Playback Switch", 0, CMI8330_MUTEMUX, 7, 1, 1),
 };
 
-static int __init snd_cmi8330_mixer(snd_card_t *card, ad1848_t *chip)
+#ifdef ENABLE_SB_MIXER
+static struct sbmix_elem cmi8330_sb_mixers[] __initdata = {
+SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
+SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
+SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
+SB_DOUBLE("SB PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
+SB_DOUBLE("SB CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
+SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
+SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
+SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
+SB_SINGLE("SB PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
+SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
+SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
+SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
+};
+
+static unsigned char cmi8330_sb_init_values[][2] __initdata = {
+	{ SB_DSP4_MASTER_DEV + 0, 0 },
+	{ SB_DSP4_MASTER_DEV + 1, 0 },
+	{ SB_DSP4_PCM_DEV + 0, 0 },
+	{ SB_DSP4_PCM_DEV + 1, 0 },
+	{ SB_DSP4_SYNTH_DEV + 0, 0 },
+	{ SB_DSP4_SYNTH_DEV + 1, 0 },
+	{ SB_DSP4_INPUT_LEFT, 0 },
+	{ SB_DSP4_INPUT_RIGHT, 0 },
+	{ SB_DSP4_OUTPUT_SW, 0 },
+	{ SB_DSP4_SPEAKER_DEV, 0 },
+};
+
+
+static int __init cmi8330_add_sb_mixers(sb_t *chip)
 {
 	int idx, err;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->mixer_lock, flags);
+	snd_sbmixer_write(chip, 0x00, 0x00);		/* mixer reset */
+	spin_unlock_irqrestore(&chip->mixer_lock, flags);
+
+	/* mute and zero volume channels */
+	for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_init_values); idx++) {
+		spin_lock_irqsave(&chip->mixer_lock, flags);
+		snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0],
+				  cmi8330_sb_init_values[idx][1]);
+		spin_unlock_irqrestore(&chip->mixer_lock, flags);
+	}
+
+	for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) {
+		if ((err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx])) < 0)
+			return err;
+	}
+	return 0;
+}
+#endif
+
+static int __init snd_cmi8330_mixer(snd_card_t *card, struct snd_cmi8330 *acard)
+{
+	unsigned int idx;
+	int err;
 
 	strcpy(card->mixername, "CMI8330/C3D");
 
-	for (idx = 0; idx < CMI8330_CONTROLS; idx++)
-		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmi8330_controls[idx], chip))) < 0)
+	for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
+		if ((err = snd_ad1848_add_ctl_elem(acard->wss, &snd_cmi8330_controls[idx])) < 0)
 			return err;
+	}
 
+#ifdef ENABLE_SB_MIXER
+	if ((err = cmi8330_add_sb_mixers(acard->sb)) < 0)
+		return err;
+#endif
 	return 0;
 }
 
@@ -294,6 +380,93 @@
 }
 #endif
 
+/*
+ * PCM interface
+ *
+ * since we call the different chip interfaces for playback and capture
+ * directions, we need a trick.
+ *
+ * - copy the ops for each direction into a local record.
+ * - replace the open callback with the new one, which replaces the
+ *   substream->private_data with the corresponding chip instance
+ *   and calls again the original open callback of the chip.
+ *
+ */
+
+#ifdef PLAYBACK_ON_SB
+#define CMI_SB_STREAM	SNDRV_PCM_STREAM_PLAYBACK
+#define CMI_AD_STREAM	SNDRV_PCM_STREAM_CAPTURE
+#else
+#define CMI_SB_STREAM	SNDRV_PCM_STREAM_CAPTURE
+#define CMI_AD_STREAM	SNDRV_PCM_STREAM_PLAYBACK
+#endif
+
+static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream)
+{
+	struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream);
+
+	/* replace the private_data and call the original open callback */
+	substream->private_data = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].private_data;
+	return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
+}
+
+static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
+{
+	struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream);
+
+	/* replace the private_data and call the original open callback */
+	substream->private_data = chip->streams[SNDRV_PCM_STREAM_CAPTURE].private_data;
+	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
+}
+
+static void snd_cmi8330_pcm_free(snd_pcm_t *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __init snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
+{
+	snd_pcm_t *pcm;
+	const snd_pcm_ops_t *ops;
+	int err;
+	static snd_pcm_open_callback_t cmi_open_callbacks[2] = {
+		snd_cmi8330_playback_open,
+		snd_cmi8330_capture_open
+	};
+
+	if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0)
+		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);
+	chip->streams[CMI_SB_STREAM].ops = *ops;
+	chip->streams[CMI_SB_STREAM].open = ops->open;
+	chip->streams[CMI_SB_STREAM].ops.open = cmi_open_callbacks[CMI_SB_STREAM];
+	chip->streams[CMI_SB_STREAM].private_data = chip->sb;
+
+	/* AD1848 */
+	ops = snd_ad1848_get_pcm_ops(CMI_AD_STREAM);
+	chip->streams[CMI_AD_STREAM].ops = *ops;
+	chip->streams[CMI_AD_STREAM].open = ops->open;
+	chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM];
+	chip->streams[CMI_AD_STREAM].private_data = chip->wss;
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK].ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->streams[SNDRV_PCM_STREAM_CAPTURE].ops);
+
+	snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 128*1024);
+	chip->pcm = pcm;
+
+	return 0;
+}
+
+
+/*
+ */
+
 static void snd_cmi8330_free(snd_card_t *card)
 {
 	struct snd_cmi8330 *acard = (struct snd_cmi8330 *)card->private_data;
@@ -309,12 +482,8 @@
 {
 	snd_card_t *card;
 	struct snd_cmi8330 *acard;
-	ad1848_t *chip_wss;
-	sb_t *chip_sb;
 	unsigned long flags;
 	int i, err;
-	snd_pcm_t *pcm, *wss_pcm, *sb_pcm;
-	snd_pcm_str_t *pstr;
 
 #ifdef __ISAPNP__
 	if (!isapnp[dev]) {
@@ -337,6 +506,7 @@
 		return -ENOMEM;
 	}
 	acard = (struct snd_cmi8330 *)card->private_data;
+	acard->card = card;
 	card->private_free = snd_cmi8330_free;
 
 #ifdef __ISAPNP__
@@ -352,83 +522,56 @@
 				     wssirq[dev],
 				     wssdma[dev],
 				     AD1848_HW_DETECT,
-				     &chip_wss)) < 0) {
+				     &acard->wss)) < 0) {
 		snd_printk("(AD1848) device busy??\n");
 		snd_card_free(card);
 		return err;
 	}
-	if (chip_wss->hardware != AD1848_HW_CMI8330) {
+	if (acard->wss->hardware != AD1848_HW_CMI8330) {
 		snd_printk("(AD1848) not found during probe\n");
 		snd_card_free(card);
 		return -ENODEV;
 	}
-	if ((err = snd_ad1848_pcm(chip_wss, 0, &wss_pcm)) < 0) {
-		snd_printk("(AD1848) no enough memory??\n");
-		snd_card_free(card);
-		return err;
-	}
 
 	if ((err = snd_sbdsp_create(card, sbport[dev],
 				    sbirq[dev],
 				    snd_sb16dsp_interrupt,
 				    sbdma8[dev],
 				    sbdma16[dev],
-				    SB_HW_AUTO, &chip_sb)) < 0) {
+				    SB_HW_AUTO, &acard->sb)) < 0) {
 		snd_printk("(SB16) device busy??\n");
 		snd_card_free(card);
 		return err;
 	}
-	if ((err = snd_sb16dsp_pcm(chip_sb, 1, &sb_pcm)) < 0) {
-		snd_printk("(SB16) no enough memory??\n");
-		snd_card_free(card);
-		return err;
-	}
-
-	if (chip_sb->hardware != SB_HW_16) {
+	if (acard->sb->hardware != SB_HW_16) {
 		snd_printk("(SB16) not found during probe\n");
 		snd_card_free(card);
 		return -ENODEV;
 	}
 
-	memcpy(&chip_wss->image[16], &snd_cmi8330_image, sizeof(snd_cmi8330_image));
-
-	spin_lock_irqsave(&chip_wss->reg_lock, flags);
-	snd_ad1848_out(chip_wss, AD1848_MISC_INFO,	/* switch on MODE2 */
-		       chip_wss->image[AD1848_MISC_INFO] |= 0x40);
-	spin_unlock_irqrestore(&chip_wss->reg_lock, flags);
+	spin_lock_irqsave(&acard->wss->reg_lock, flags);
+	snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
+	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
+		snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]);
+	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
-	if ((err = snd_cmi8330_mixer(card, chip_wss)) < 0) {
+	if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
 		snd_printk("failed to create mixers\n");
 		snd_card_free(card);
 		return err;
 	}
-	spin_lock_irqsave(&chip_wss->reg_lock, flags);
-	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
-		snd_ad1848_out(chip_wss, i, chip_wss->image[i]);
-	spin_unlock_irqrestore(&chip_wss->reg_lock, flags);
 
-	/*
-	 * KLUDGE ALERT
-	 *  disable AD1848 playback
-	 *  disable SB16 capture
-	 */
-	pcm = wss_pcm;
-	pstr = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
-	snd_magic_kfree(pstr->substream);
-	pstr->substream = 0;
-	pstr->substream_count = 0;
-
-	pcm = sb_pcm;
-	pstr = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
-	snd_magic_kfree(pstr->substream);
-	pstr->substream = 0;
-	pstr->substream_count = 0;
+	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
+		snd_printk("failed to create pcms\n");
+		snd_card_free(card);
+		return err;
+	}
 
 	strcpy(card->driver, "CMI8330/C3D");
 	strcpy(card->shortname, "C-Media CMI8330/C3D");
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-		wss_pcm->name,
-		chip_wss->port,
+		card->shortname,
+		acard->wss->port,
 		wssirq[dev],
 		wssdma[dev]);
 
diff -Nru a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile
--- a/sound/isa/cs423x/Makefile	Mon Feb 10 10:39:31 2003
+++ b/sound/isa/cs423x/Makefile	Mon Feb 10 10:39:31 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := cs4231_lib.o cs4236_lib.o
-
 snd-cs4231-lib-objs := cs4231_lib.o
 snd-cs4236-lib-objs := cs4236_lib.o
 snd-cs4231-objs := cs4231.o
diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
--- a/sound/isa/cs423x/cs4231_lib.c	Mon Feb 10 10:39:24 2003
+++ b/sound/isa/cs423x/cs4231_lib.c	Mon Feb 10 10:39:24 2003
@@ -158,7 +158,7 @@
 	} else {
 #endif
 #ifdef SBUS_SUPPORT
-		return sbus_writeb(chip->port + (offset << 2));
+		return sbus_readb(chip->port + (offset << 2));
 #endif
 #ifdef EBUS_SUPPORT
 	}
@@ -338,13 +338,13 @@
 	unsigned long flags;
 	int timeout;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	for (timeout = 250; timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--)
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
 		snd_printk("mce_up - auto calibration time out (0)\n");
 #endif
+	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit |= CS4231_MCE;
 	timeout = cs4231_inb(chip, CS4231P(REGSEL));
 	if (timeout == 0x80)
@@ -360,7 +360,6 @@
 	int timeout;
 	signed long time;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_cs4231_busy_wait(chip);
 #if 0
 	printk("(1) timeout = %i\n", timeout);
@@ -369,14 +368,15 @@
 	if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
 		snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
 #endif
+	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit &= ~CS4231_MCE;
 	timeout = cs4231_inb(chip, CS4231P(REGSEL));
 	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	if (timeout == 0x80)
 		snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if ((timeout & CS4231_MCE) == 0 ||
 	    !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) {
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		return;
 	}
 	snd_cs4231_busy_wait(chip);
@@ -387,7 +387,6 @@
 		udelay(10);
 	if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) {
 		snd_printd("cs4231_mce_down - auto calibration time out (1)\n");
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		return;
 	}
 #if 0
@@ -395,30 +394,25 @@
 #endif
 	time = HZ / 4;
 	while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
 			snd_printk("mce_down - auto calibration time out (2)\n");
 			return;
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
 		time = schedule_timeout(time);
-		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
 #if 0
 	printk("(3) jiffies = %li\n", jiffies);
 #endif
 	time = HZ / 10;
 	while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
-			snd_printk("mce_down - auto calibration time out (3)\n");
+			snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
 			return;
 		}
 		set_current_state(TASK_INTERRUPTIBLE);		
 		time = schedule_timeout(time);
-		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #if 0
 	printk("(4) jiffies = %li\n", jiffies);
 	snd_printk("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL)));
@@ -1005,7 +999,7 @@
 
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
 		return 0;
-	ptr = chip->p_dma_size - snd_dma_residue(chip->dma1);
+	ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1016,7 +1010,7 @@
 	
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
 		return 0;
-	ptr = chip->c_dma_size - snd_dma_residue(chip->dma2);
+	ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 #endif /* LEGACY_SUPPORT */
@@ -1375,20 +1369,19 @@
 	   This is the first half of copy of snd_cs4231_mce_down(), but doesn't
 	   include rescheduling.  -- iwai
 	   */
-	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_cs4231_busy_wait(chip);
+	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit &= ~CS4231_MCE;
 	timeout = cs4231_inb(chip, CS4231P(REGSEL));
 	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	if (timeout == 0x80)
 		snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if ((timeout & CS4231_MCE) == 0 ||
 	    !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) {
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		return;
 	}
 	snd_cs4231_busy_wait(chip);
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #endif
 }
 
@@ -1910,7 +1903,8 @@
 int snd_cs4231_mixer(cs4231_t *chip)
 {
 	snd_card_t *card;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
 
diff -Nru a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
--- a/sound/isa/cs423x/cs4236.c	Mon Feb 10 10:39:23 2003
+++ b/sound/isa/cs423x/cs4236.c	Mon Feb 10 10:39:23 2003
@@ -328,7 +328,7 @@
 	sb_port[dev] = pdev->resource[2].start;
 	irq[dev] = pdev->irq_resource[0].start;
 	dma1[dev] = pdev->dma_resource[0].start;
-	dma2[dev] = pdev->dma_resource[1].start == 4 ? -1 : pdev->dma_resource[1].start;
+	dma2[dev] = pdev->dma_resource[1].start == 4 ? -1 : (int)pdev->dma_resource[1].start;
 	snd_printdd("isapnp WSS: wss port=0x%lx, fm port=0x%lx, sb port=0x%lx\n",
 			port[dev], fm_port[dev], sb_port[dev]);
 	snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n",
diff -Nru a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
--- a/sound/isa/cs423x/cs4236_lib.c	Mon Feb 10 10:39:24 2003
+++ b/sound/isa/cs423x/cs4236_lib.c	Mon Feb 10 10:39:24 2003
@@ -270,7 +270,8 @@
 {
 	cs4231_t *chip;
 	unsigned char ver1, ver2;
-	int err, reg;
+	unsigned int reg;
+	int err;
 
 	*rchip = NULL;
 	if (hardware == CS4231_HW_DETECT)
@@ -908,7 +909,8 @@
 int snd_cs4236_mixer(cs4231_t *chip)
 {
 	snd_card_t *card;
-	int err, idx, count;
+	unsigned int idx, count;
+	int err;
 	snd_kcontrol_new_t *kcontrol;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
@@ -942,7 +944,7 @@
 		kcontrol = snd_cs4236_3d_controls_cs4238;
 		break;
 	default:
-		count = -1;
+		count = 0;
 		kcontrol = NULL;
 	}
 	for (idx = 0; idx < count; idx++, kcontrol++) {
diff -Nru a/sound/isa/es1688/Makefile b/sound/isa/es1688/Makefile
--- a/sound/isa/es1688/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/isa/es1688/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := es1688_lib.o
-
 snd-es1688-lib-objs := es1688_lib.o
 snd-es1688-objs := es1688.o
 
diff -Nru a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
--- a/sound/isa/es1688/es1688_lib.c	Mon Feb 10 10:39:29 2003
+++ b/sound/isa/es1688/es1688_lib.c	Mon Feb 10 10:39:29 2003
@@ -346,7 +346,7 @@
 	}
 #if 0
 	printk("trigger: val = 0x%x, value = 0x%x\n", val, value);
-	printk("trigger: residue = 0x%x\n", get_dma_residue(chip->dma8));
+	printk("trigger: pointer = 0x%x\n", snd_dma_pointer(chip->dma8, chip->dma_size));
 #endif
 	snd_es1688_write(chip, 0xb8, (val & 0xf0) | value);
 	spin_unlock(&chip->reg_lock);
@@ -501,7 +501,7 @@
 	
 	if (chip->trigger_value != 0x05)
 		return 0;
-	ptr = chip->dma_size - snd_dma_residue(chip->dma8);
+	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -512,7 +512,7 @@
 	
 	if (chip->trigger_value != 0x0f)
 		return 0;
-	ptr = chip->dma_size - snd_dma_residue(chip->dma8);
+	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1014,7 +1014,8 @@
 int snd_es1688_mixer(es1688_t *chip)
 {
 	snd_card_t *card;
-	int err, idx;
+	unsigned int idx;
+	int err;
 	unsigned char reg, val;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/es18xx.c	Mon Feb 10 10:39:26 2003
@@ -460,6 +460,11 @@
 	return 0;
 }
 
+static int snd_es18xx_pcm_hw_free(snd_pcm_substream_t * substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
 static int snd_es18xx_playback1_prepare(es18xx_t *chip,
 					snd_pcm_substream_t *substream)
 {
@@ -796,12 +801,12 @@
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
 		if (!(chip->active & DAC2))
 			return 0;
-		pos = chip->dma2_size - snd_dma_residue(chip->dma2);
+		pos = snd_dma_pointer(chip->dma2, chip->dma2_size);
 		return pos >> chip->dma2_shift;
 	} else {
 		if (!(chip->active & DAC1))
 			return 0;
-		pos = chip->dma1_size - snd_dma_residue(chip->dma1);
+		pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
 		return pos >> chip->dma1_shift;
 	}
 }
@@ -813,7 +818,7 @@
 
         if (!(chip->active & ADC1))
                 return 0;
-	pos = chip->dma1_size - snd_dma_residue(chip->dma1);
+	pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
 	return pos >> chip->dma1_shift;
 }
 
@@ -1540,6 +1545,7 @@
 	.close =	snd_es18xx_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_es18xx_playback_hw_params,
+	.hw_free =	snd_es18xx_pcm_hw_free,
 	.prepare =	snd_es18xx_playback_prepare,
 	.trigger =	snd_es18xx_playback_trigger,
 	.pointer =	snd_es18xx_playback_pointer,
@@ -1550,6 +1556,7 @@
 	.close =	snd_es18xx_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_es18xx_capture_hw_params,
+	.hw_free =	snd_es18xx_pcm_hw_free,
 	.prepare =	snd_es18xx_capture_prepare,
 	.trigger =	snd_es18xx_capture_trigger,
 	.pointer =	snd_es18xx_capture_pointer,
@@ -1606,9 +1613,8 @@
 {
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	snd_pcm_suspend_all(chip->pcm);
 
@@ -1619,24 +1625,19 @@
 	snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void snd_es18xx_resume(es18xx_t *chip)
 {
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	/* 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(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 /* callback for control API */
@@ -1785,14 +1786,14 @@
 static int __init snd_es18xx_mixer(es18xx_t *chip)
 {
 	snd_card_t *card;
-	int err, idx;
+	int err;
+	unsigned int idx;
 
 	card = chip->card;
 
 	strcpy(card->mixername, chip->pcm->name);
 
-	for (idx = 0; idx < sizeof(snd_es18xx_base_controls) / 
-		     sizeof(snd_es18xx_base_controls[0]); idx++) {
+	for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
 		snd_kcontrol_t *kctl;
 		kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip);
 		if (chip->caps & ES18XX_HWV) {
@@ -1811,14 +1812,12 @@
 			return err;
 	}
 	if (chip->caps & ES18XX_PCM2) {
-		for (idx = 0; idx < sizeof(snd_es18xx_pcm2_controls) / 
-			     sizeof(snd_es18xx_pcm2_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm2_controls); idx++) {
 			if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0)
 				return err;
 		} 
 	} else {
-		for (idx = 0; idx < sizeof(snd_es18xx_pcm1_controls) / 
-			     sizeof(snd_es18xx_pcm1_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm1_controls); idx++) {
 			if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0)
 				return err;
 		}
@@ -1829,8 +1828,7 @@
 			return err;
 	}
 	if (chip->caps & ES18XX_RECMIX) {
-		for (idx = 0; idx < sizeof(snd_es18xx_recmix_controls) / 
-			     sizeof(snd_es18xx_recmix_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
 			if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
 				return err;
 		}
@@ -1847,15 +1845,13 @@
 		break;
 	}
 	if (chip->caps & ES18XX_SPATIALIZER) {
-		for (idx = 0; idx < sizeof(snd_es18xx_spatializer_controls) / 
-			     sizeof(snd_es18xx_spatializer_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_spatializer_controls); idx++) {
 			if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0)
 				return err;
 		}
 	}
 	if (chip->caps & ES18XX_HWV) {
-		for (idx = 0; idx < sizeof(snd_es18xx_hw_volume_controls) / 
-			     sizeof(snd_es18xx_hw_volume_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_hw_volume_controls); idx++) {
 			snd_kcontrol_t *kctl;
 			kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip);
 			if (idx == 0)
diff -Nru a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile
--- a/sound/isa/gus/Makefile	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/gus/Makefile	Mon Feb 10 10:39:33 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := gus_main.o gus_volume.o
-
 snd-gus-lib-objs := gus_main.o \
 		    gus_io.o gus_irq.o gus_timer.o \
 		    gus_mem.o gus_mem_proc.o gus_dram.o gus_dma.o gus_volume.o \
@@ -19,18 +17,24 @@
 snd-interwave-objs := interwave.o
 snd-interwave-stb-objs := interwave-stb.o
 
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_GUSCLASSIC) += snd-gusclassic.o snd-gus-lib.o
+obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-gus-synth.o
 obj-$(CONFIG_SND_GUSMAX) += snd-gusmax.o snd-gus-lib.o
+obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-gus-synth.o
 obj-$(CONFIG_SND_GUSEXTREME) += snd-gusextreme.o snd-gus-lib.o
+obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += snd-gus-synth.o
 obj-$(CONFIG_SND_INTERWAVE) += snd-interwave.o snd-gus-lib.o
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += snd-gus-synth.o
 obj-$(CONFIG_SND_INTERWAVE_STB) += snd-interwave-stb.o snd-gus-lib.o
-ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
-  obj-$(CONFIG_SND_GUSCLASSIC) += snd-gus-synth.o
-  obj-$(CONFIG_SND_GUSMAX) += snd-gus-synth.o
-  obj-$(CONFIG_SND_GUSEXTREME) += snd-gus-synth.o
-  obj-$(CONFIG_SND_INTERWAVE) += snd-gus-synth.o
-  obj-$(CONFIG_SND_INTERWAVE_STB) += snd-gus-synth.o
-endif
+obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += snd-gus-synth.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
--- a/sound/isa/gus/gus_irq.c	Mon Feb 10 10:39:32 2003
+++ b/sound/isa/gus/gus_irq.c	Mon Feb 10 10:39:32 2003
@@ -132,26 +132,8 @@
 {
 	snd_info_entry_t *entry;
 
-	gus->irq_entry = NULL;
-	entry = snd_info_create_card_entry(gus->card, "gusirq", gus->card->proc_root);
-	if (entry) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->c.text.read_size = 512;
-		entry->c.text.read = snd_gus_irq_info_read;
-		entry->private_data = gus;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	gus->irq_entry = entry;	
+	if (! snd_card_proc_new(gus->card, "gusirq", &entry))
+		snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read);
 }
 
-void snd_gus_irq_profile_done(snd_gus_card_t *gus)
-{
-	if (gus->irq_entry) {
-		snd_info_unregister(gus->irq_entry);
-		gus->irq_entry = NULL;
-	}
-}
 #endif
diff -Nru a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
--- a/sound/isa/gus/gus_main.c	Mon Feb 10 10:39:23 2003
+++ b/sound/isa/gus/gus_main.c	Mon Feb 10 10:39:23 2003
@@ -41,18 +41,14 @@
 
 int snd_gus_use_inc(snd_gus_card_t * gus)
 {
-	MOD_INC_USE_COUNT;
-	if (!try_module_get(gus->card->module)) {
-		MOD_DEC_USE_COUNT;
+	if (!try_module_get(gus->card->module))
 		return 0;
-	}
 	return 1;
 }
 
 void snd_gus_use_dec(snd_gus_card_t * gus)
 {
 	module_put(gus->card->module);
-	MOD_DEC_USE_COUNT;
 }
 
 static int snd_gus_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
diff -Nru a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
--- a/sound/isa/gus/gus_mem.c	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/gus/gus_mem.c	Mon Feb 10 10:39:26 2003
@@ -169,7 +169,7 @@
 		if (ptr1 >= ptr2)
 			continue;
 		size1 = ptr2 - ptr1;
-		if (size <= size1) {
+		if ((int)size <= size1) {
 			block->ptr = ptr1;
 			block->size = size;
 			return 0;
@@ -196,7 +196,7 @@
 	if (share_id != NULL) {
 		nblock = snd_gf1_mem_share(alloc, share_id);
 		if (nblock != NULL) {
-			if (size != nblock->size) {
+			if (size != (int)nblock->size) {
 				/* TODO: remove in the future */
 				snd_printk("snd_gf1_mem_alloc - share: sizes differ\n");
 				goto __std;
@@ -264,19 +264,10 @@
 	if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
 		return -ENOMEM;
 #ifdef CONFIG_SND_DEBUG
-	alloc->info_entry = NULL;
-	entry = snd_info_create_card_entry(gus->card, "gusmem", gus->card->proc_root);
-	if (entry) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
+	if (! snd_card_proc_new(gus->card, "gusmem", &entry)) {
+		snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read);
 		entry->c.text.read_size = 256 * 1024;
-		entry->c.text.read = snd_gf1_mem_info_read;
-		entry->private_data = gus;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
 	}
-	alloc->info_entry = entry;
 #endif
 	return 0;
 }
@@ -293,10 +284,6 @@
 		snd_gf1_mem_xfree(alloc, block);
 		block = nblock;
 	}
-#ifdef CONFIG_SND_DEBUG
-	if (alloc->info_entry)
-		snd_info_unregister(alloc->info_entry);
-#endif
 	return 0;
 }
 
diff -Nru a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
--- a/sound/isa/gus/gus_mem_proc.c	Mon Feb 10 10:39:29 2003
+++ b/sound/isa/gus/gus_mem_proc.c	Mon Feb 10 10:39:29 2003
@@ -96,73 +96,40 @@
 	gus_proc_private_t *priv;
 	snd_info_entry_t *entry;
 
-	memset(&gus->gf1.rom_entries, 0, sizeof(gus->gf1.rom_entries));
-	memset(&gus->gf1.ram_entries, 0, sizeof(gus->gf1.ram_entries));
 	for (idx = 0; idx < 4; idx++) {
 		if (gus->gf1.mem_alloc.banks_8[idx].size > 0) {
 			priv = snd_magic_kcalloc(gus_proc_private_t, 0, GFP_KERNEL);
-			if (priv == NULL) {
-				snd_gf1_mem_proc_done(gus);
+			if (priv == NULL)
 				return -ENOMEM;
-			}
 			priv->gus = gus;
 			sprintf(name, "gus-ram-%i", idx);
-			entry = snd_info_create_card_entry(gus->card, name, gus->card->proc_root);
-			if (entry) {
+			if (! snd_card_proc_new(gus->card, name, &entry)) {
 				entry->content = SNDRV_INFO_CONTENT_DATA;
 				entry->private_data = priv;
 				entry->private_free = snd_gf1_mem_proc_free;
 				entry->c.ops = &snd_gf1_mem_proc_ops;
 				priv->address = gus->gf1.mem_alloc.banks_8[idx].address;
 				priv->size = entry->size = gus->gf1.mem_alloc.banks_8[idx].size;
-				if (snd_info_register(entry) < 0) {
-					snd_info_free_entry(entry);
-					entry = NULL;
-				}
 			}
-			gus->gf1.ram_entries[idx] = entry;
 		}
 	}
 	for (idx = 0; idx < 4; idx++) {
 		if (gus->gf1.rom_present & (1 << idx)) {
 			priv = snd_magic_kcalloc(gus_proc_private_t, 0, GFP_KERNEL);
-			if (priv == NULL) {
-				snd_gf1_mem_proc_done(gus);
+			if (priv == NULL)
 				return -ENOMEM;
-			}
 			priv->rom = 1;
 			priv->gus = gus;
 			sprintf(name, "gus-rom-%i", idx);
-			entry = snd_info_create_card_entry(gus->card, name, gus->card->proc_root);
-			if (entry) {
+			if (! snd_card_proc_new(gus->card, name, &entry)) {
 				entry->content = SNDRV_INFO_CONTENT_DATA;
 				entry->private_data = priv;
 				entry->private_free = snd_gf1_mem_proc_free;
 				entry->c.ops = &snd_gf1_mem_proc_ops;
 				priv->address = idx * 4096 * 1024;
 				priv->size = entry->size = gus->gf1.rom_memory;
-				if (snd_info_register(entry) < 0) {
-					snd_info_free_entry(entry);
-					entry = NULL;
-				}
 			}
-			gus->gf1.rom_entries[idx] = entry;
 		}
-	}
-	return 0;
-}
-
-int snd_gf1_mem_proc_done(snd_gus_card_t * gus)
-{
-	int idx;
-
-	for (idx = 0; idx < 4; idx++) {
-		if (gus->gf1.ram_entries[idx])
-			snd_info_unregister(gus->gf1.ram_entries[idx]);
-	}
-	for (idx = 0; idx < 4; idx++) {
-		if (gus->gf1.rom_entries[idx])
-			snd_info_unregister(gus->gf1.rom_entries[idx]);
 	}
 	return 0;
 }
diff -Nru a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
--- a/sound/isa/gus/gus_mixer.c	Mon Feb 10 10:39:23 2003
+++ b/sound/isa/gus/gus_mixer.c	Mon Feb 10 10:39:23 2003
@@ -172,7 +172,8 @@
 int snd_gf1_new_mixer(snd_gus_card_t * gus)
 {
 	snd_card_t *card;
-	int idx, err, max;
+	unsigned int idx, max;
+	int err;
 
 	snd_assert(gus != NULL, return -EINVAL);
 	card = gus->card;
diff -Nru a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
--- a/sound/isa/gus/gus_pcm.c	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/gus/gus_pcm.c	Mon Feb 10 10:39:26 2003
@@ -48,7 +48,7 @@
 	snd_gus_card_t * gus;
 	snd_pcm_substream_t * substream;
 	spinlock_t lock;
-	int voices;
+	unsigned int voices;
 	snd_gus_voice_t *pvoices[2];
 	unsigned int memory;
 	unsigned short flags;
@@ -186,7 +186,7 @@
 	gus_pcm_private_t * pcmp;
 	snd_pcm_runtime_t * runtime;
 	unsigned char voice_ctrl, ramp_ctrl;
-	int idx;
+	unsigned int idx;
 	unsigned int end, step;
 
 	if (!pvoice->private_data) {
@@ -600,7 +600,7 @@
 static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(snd_pcm_substream_t * substream)
 {
 	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	int pos = gus->c_period_size - snd_dma_residue(gus->gf1.dma2);
+	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;
 }
@@ -766,7 +766,8 @@
 {
 	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
-	int change, idx;
+	int change;
+	unsigned int idx;
 	unsigned short val1, val2, vol;
 	gus_pcm_private_t *pcmp;
 	snd_gus_voice_t *pvoice;
diff -Nru a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
--- a/sound/isa/gus/gus_reset.c	Mon Feb 10 10:39:23 2003
+++ b/sound/isa/gus/gus_reset.c	Mon Feb 10 10:39:23 2003
@@ -410,10 +410,6 @@
 	snd_gf1_stop_voices(gus, 0, 31);		/* stop all voices */
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* disable IRQ & DAC */
 	snd_gf1_timers_done(gus);
-#ifdef CONFIG_SND_DEBUG
-	snd_gus_irq_profile_done(gus);
-#endif
-	snd_gf1_mem_proc_done(gus);
 	snd_gf1_mem_done(gus);
 #if 0
 	snd_gf1_lfo_done(gus);
diff -Nru a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
--- a/sound/isa/gus/gus_synth.c	Mon Feb 10 10:39:27 2003
+++ b/sound/isa/gus/gus_synth.c	Mon Feb 10 10:39:27 2003
@@ -51,7 +51,7 @@
 	snd_gus_port_t * port = (snd_gus_port_t *)private_data;
 	snd_gus_card_t * gus = port->gus;
 	snd_gus_voice_t * voice;
-	int idx;
+	unsigned int idx;
 
 	if (info->voices > 32)
 		return -EINVAL;
@@ -133,7 +133,7 @@
 				       snd_seq_kinstr_t *instr,
 				       int what)
 {
-	int idx;
+	unsigned int idx;
 	snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return);
 	snd_gus_voice_t *pvoice;
 	unsigned long flags;
@@ -197,6 +197,7 @@
 						   SNDRV_SEQ_PORT_TYPE_MIDI_GS |
 						   SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
 						   SNDRV_SEQ_PORT_TYPE_SYNTH,
+						   16,
 						   name);
 	if (p->chset->port < 0) {
 		result = p->chset->port;
diff -Nru a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
--- a/sound/isa/gus/interwave.c	Mon Feb 10 10:39:27 2003
+++ b/sound/isa/gus/interwave.c	Mon Feb 10 10:39:27 2003
@@ -544,7 +544,8 @@
 {
 	snd_card_t *card = chip->card;
 	snd_ctl_elem_id_t id1, id2;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	memset(&id1, 0, sizeof(id1));
 	memset(&id2, 0, sizeof(id2));
diff -Nru a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
--- a/sound/isa/opti9xx/opti92x-ad1848.c	Mon Feb 10 10:39:24 2003
+++ b/sound/isa/opti9xx/opti92x-ad1848.c	Mon Feb 10 10:39:24 2003
@@ -842,7 +842,7 @@
 
 static unsigned char snd_opti93x_get_freq(unsigned int rate)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < RATES; i++) {
 		if (rate == rates[i])
@@ -1100,7 +1100,7 @@
 	if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_PLAYBACK_ENABLE))
 		return 0;
 
-	ptr = chip->p_dma_size - snd_dma_residue(chip->dma1);
+	ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1112,7 +1112,7 @@
 	if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_CAPTURE_ENABLE))
 		return 0;
 
-	ptr = chip->c_dma_size - snd_dma_residue(chip->dma2);
+	ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1635,7 +1635,8 @@
 {
 	snd_card_t *card;
 	snd_kcontrol_new_t knew;
-	int err, idx;
+	int err;
+	unsigned int idx;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
 
diff -Nru a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
--- a/sound/isa/sb/Makefile	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/sb/Makefile	Mon Feb 10 10:39:26 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := emu8000.o sb_common.o sb8_main.o sb16_main.o sb16_csp.o
-
 snd-sb-common-objs := sb_common.o sb_mixer.o
 snd-sb8-dsp-objs := sb8_main.o sb8_midi.o
 snd-sb16-dsp-objs := sb16_main.o
@@ -15,6 +13,14 @@
 snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
 snd-es968-objs := es968.o
 
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o
 obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o
@@ -28,8 +34,6 @@
   obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
   obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
 endif
-ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
-  obj-$(CONFIG_SND_SBAWE) += snd-emu8000-synth.o
-endif
+obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
--- a/sound/isa/sb/emu8000.c	Mon Feb 10 10:39:24 2003
+++ b/sound/isa/sb/emu8000.c	Mon Feb 10 10:39:24 2003
@@ -662,7 +662,7 @@
 		snd_printk(KERN_WARNING "illegal chorus mode %d for uploading\n", mode);
 		return -EINVAL;
 	}
-	if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
+	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
 		return -EFAULT;
 	chorus_parm[mode] = rec;
 	chorus_defined[mode] = 1;
@@ -790,7 +790,7 @@
 		snd_printk(KERN_WARNING "illegal reverb mode %d for uploading\n", mode);
 		return -EINVAL;
 	}
-	if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
+	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
 		return -EFAULT;
 	reverb_parm[mode] = rec;
 	reverb_defined[mode] = 1;
diff -Nru a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
--- a/sound/isa/sb/emu8000_pcm.c	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/sb/emu8000_pcm.c	Mon Feb 10 10:39:33 2003
@@ -215,7 +215,7 @@
 	add_timer(&rec->timer);
 
 	/* update period */
-	if (rec->period_pos >= rec->period_size) {
+	if (rec->period_pos >= (int)rec->period_size) {
 		rec->period_pos %= rec->period_size;
 		spin_unlock(&rec->timer_lock);
 		snd_pcm_period_elapsed(rec->substream);
diff -Nru a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
--- a/sound/isa/sb/sb16.c	Mon Feb 10 10:39:30 2003
+++ b/sound/isa/sb/sb16.c	Mon Feb 10 10:39:30 2003
@@ -204,6 +204,9 @@
 	ISAPNP_SB16('C','T','L',0x0070,0x0001),
 	/* Sound Blaster Vibra16CL - added by ctm@ardi.com */
 	ISAPNP_SB16('C','T','L',0x0080,0x0041),
+	/* Sound Blaster 16 'value' PnP. It says model ct4130 on the pcb, */
+	/* but ct4131 on a sticker on the board.. */
+	ISAPNP_SB16('C','T','L',0x0086,0x0041),
 	/* Sound Blaster Vibra16X */
 	ISAPNP_SB16('C','T','L',0x00f0,0x0043),
 #else  /* SNDRV_SBAWE defined */
diff -Nru a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
--- a/sound/isa/sb/sb16_csp.c	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/sb/sb16_csp.c	Mon Feb 10 10:39:33 2003
@@ -107,7 +107,6 @@
 static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p);
 
 static int init_proc_entry(snd_sb_csp_t * p, int device);
-static void delete_proc_entry(snd_sb_csp_t * p);
 static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer);
 
 /*
@@ -170,7 +169,6 @@
 	if (p) {
 		if (p->running & SNDRV_SB_CSP_ST_RUNNING)
 			snd_sb_csp_stop(p);
-		delete_proc_entry(p);
 		snd_magic_kfree(p);
 	}
 }
@@ -1104,26 +1102,9 @@
 	char name[16];
 	snd_info_entry_t *entry;
 	sprintf(name, "cspD%d", device);
-	entry = p->proc = snd_info_create_card_entry(p->chip->card, name, p->chip->card->proc_root);
-	if (entry) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = info_read;
-		entry->private_data = p;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			p->proc = NULL;
-		}
-	}
+	if (! snd_card_proc_new(p->chip->card, name, &entry))
+		snd_info_set_text_ops(entry, p, info_read);
 	return 0;
-}
-
-static void delete_proc_entry(snd_sb_csp_t * p)
-{
-	if (p->proc) {
-		snd_info_unregister(p->proc);
-		p->proc = NULL;
-	}
 }
 
 static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
diff -Nru a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
--- a/sound/isa/sb/sb16_main.c	Mon Feb 10 10:39:27 2003
+++ b/sound/isa/sb/sb16_main.c	Mon Feb 10 10:39:27 2003
@@ -60,7 +60,7 @@
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
 			if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) &&
-			    ((1 << runtime->format) == csp->acc_format)) {
+			    ((1U << runtime->format) == csp->acc_format)) {
 				/* Supported runtime PCM format for playback */
 				if (csp->ops.csp_use(csp) == 0) {
 					/* If CSP was successfully acquired */
@@ -108,7 +108,7 @@
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
 			if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) &&
-			    ((1 << runtime->format) == csp->acc_format)) {
+			    ((1U << runtime->format) == csp->acc_format)) {
 				/* Supported runtime PCM format for capture */
 				if (csp->ops.csp_use(csp) == 0) {
 					/* If CSP was successfully acquired */
@@ -451,7 +451,7 @@
 	size_t ptr;
 
 	dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16;
-	ptr = chip->p_dma_size - snd_dma_residue(dma);
+	ptr = snd_dma_pointer(dma, chip->p_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -462,7 +462,7 @@
 	size_t ptr;
 
 	dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16;
-	ptr = chip->c_dma_size - snd_dma_residue(dma);
+	ptr = snd_dma_pointer(dma, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -887,7 +887,14 @@
 	return 0;
 }
 
+const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction)
+{
+	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
+		&snd_sb16_playback_ops : &snd_sb16_capture_ops;
+}
+
 EXPORT_SYMBOL(snd_sb16dsp_pcm);
+EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
 EXPORT_SYMBOL(snd_sb16dsp_configure);
 EXPORT_SYMBOL(snd_sb16dsp_interrupt);
 
diff -Nru a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
--- a/sound/isa/sb/sb8_main.c	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/sb/sb8_main.c	Mon Feb 10 10:39:26 2003
@@ -365,7 +365,7 @@
 
 	if (chip->mode != SB_MODE_PLAYBACK_8)
 		return 0;
-	ptr = chip->p_dma_size - snd_dma_residue(chip->dma8);
+	ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -376,7 +376,7 @@
 
 	if (chip->mode != SB_MODE_CAPTURE_8)
 		return 0;
-	ptr = chip->c_dma_size - snd_dma_residue(chip->dma8);
+	ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
diff -Nru a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
--- a/sound/isa/sb/sb_common.c	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/sb/sb_common.c	Mon Feb 10 10:39:33 2003
@@ -297,6 +297,7 @@
 EXPORT_SYMBOL(snd_sbmixer_write);
 EXPORT_SYMBOL(snd_sbmixer_read);
 EXPORT_SYMBOL(snd_sbmixer_new);
+EXPORT_SYMBOL(snd_sbmixer_add_ctl);
 
 /*
  *  INIT part
diff -Nru a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
--- a/sound/isa/sb/sb_mixer.c	Mon Feb 10 10:39:26 2003
+++ b/sound/isa/sb/sb_mixer.c	Mon Feb 10 10:39:26 2003
@@ -60,13 +60,6 @@
  * Single channel mixer element
  */
 
-#define SB_SINGLE(xname, reg, shift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .info = snd_sbmixer_info_single, \
-  .get = snd_sbmixer_get_single, put: snd_sbmixer_put_single, \
-  .private_value = reg | (shift << 16) | (mask << 24) }
-
 static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -119,13 +112,6 @@
  * Double channel mixer element
  */
 
-#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .info = snd_sbmixer_info_double, \
-  .get = snd_sbmixer_get_double, put: snd_sbmixer_put_double, \
-  .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) }
-
 static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -362,13 +348,6 @@
  * SB16 input switch
  */
 
-#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .info = snd_sb16mixer_info_input_sw, \
-  .get = snd_sb16mixer_get_input_sw, put: snd_sb16mixer_put_input_sw, \
-  .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) }
-
 static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -428,61 +407,114 @@
 	return change;
 }
 
-#define SB20_CONTROLS (sizeof(snd_sb20_controls)/sizeof(snd_kcontrol_new_t *))
 
-static snd_kcontrol_new_t snd_sb20_ctl_master_play_vol =
+/*
+ */
+/*
+ */
+int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value)
+{
+	static snd_kcontrol_new_t newctls[] = {
+		[SB_MIX_SINGLE] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_sbmixer_info_single,
+			.get = snd_sbmixer_get_single,
+			.put = snd_sbmixer_put_single,
+		},
+		[SB_MIX_DOUBLE] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_sbmixer_info_double,
+			.get = snd_sbmixer_get_double,
+			.put = snd_sbmixer_put_double,
+		},
+		[SB_MIX_INPUT_SW] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_sb16mixer_info_input_sw,
+			.get = snd_sb16mixer_get_input_sw,
+			.put = snd_sb16mixer_put_input_sw,
+		},
+		[SB_MIX_CAPTURE_PRO] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_sb8mixer_info_mux,
+			.get = snd_sb8mixer_get_mux,
+			.put = snd_sb8mixer_put_mux,
+		},
+		[SB_MIX_CAPTURE_DT019X] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_dt019x_input_sw_info,
+			.get = snd_dt019x_input_sw_get,
+			.put = snd_dt019x_input_sw_put,
+		},
+	};
+	snd_kcontrol_t *ctl;
+	int err;
+
+	ctl = snd_ctl_new1(&newctls[type], chip);
+	if (! ctl)
+		return -ENOMEM;
+	strncpy(ctl->id.name, name, sizeof(ctl->id.name)-1);
+	ctl->id.index = index;
+	ctl->private_value = value;
+	if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
+		snd_ctl_free_one(ctl);
+		return err;
+	}
+	return 0;
+}
+
+/*
+ * SB 2.0 specific mixer elements
+ */
+
+static struct sbmix_elem snd_sb20_ctl_master_play_vol =
 	SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7);
-static snd_kcontrol_new_t snd_sb20_ctl_pcm_play_vol =
+static struct sbmix_elem snd_sb20_ctl_pcm_play_vol =
 	SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3);
-static snd_kcontrol_new_t snd_sb20_ctl_synth_play_vol =
+static struct sbmix_elem snd_sb20_ctl_synth_play_vol =
 	SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7);
-static snd_kcontrol_new_t snd_sb20_ctl_cd_play_vol =
+static struct sbmix_elem snd_sb20_ctl_cd_play_vol =
 	SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
 
-static snd_kcontrol_new_t *snd_sb20_controls[] = {
+static struct sbmix_elem *snd_sb20_controls[] = {
 	&snd_sb20_ctl_master_play_vol,
 	&snd_sb20_ctl_pcm_play_vol,
 	&snd_sb20_ctl_synth_play_vol,
 	&snd_sb20_ctl_cd_play_vol
 };
 
-#define SB20_INIT_VALUES (sizeof(snd_sb20_init_values)/sizeof(unsigned char)/2)
-
 static unsigned char snd_sb20_init_values[][2] = {
 	{ SB_DSP20_MASTER_DEV, 0 },
 	{ SB_DSP20_FM_DEV, 0 },
 };
 
-#define SBPRO_CONTROLS (sizeof(snd_sbpro_controls)/sizeof(snd_kcontrol_new_t *))
-
-static snd_kcontrol_new_t snd_sbpro_ctl_master_play_vol =
+/*
+ * SB Pro specific mixer elements
+ */
+static struct sbmix_elem snd_sbpro_ctl_master_play_vol =
 	SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7);
-static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_vol =
+static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol =
 	SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7);
-static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_filter =
+static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter =
 	SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1);
-static snd_kcontrol_new_t snd_sbpro_ctl_synth_play_vol =
+static struct sbmix_elem snd_sbpro_ctl_synth_play_vol =
 	SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7);
-static snd_kcontrol_new_t snd_sbpro_ctl_cd_play_vol =
+static struct sbmix_elem snd_sbpro_ctl_cd_play_vol =
 	SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7);
-static snd_kcontrol_new_t snd_sbpro_ctl_line_play_vol =
+static struct sbmix_elem snd_sbpro_ctl_line_play_vol =
 	SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7);
-static snd_kcontrol_new_t snd_sbpro_ctl_mic_play_vol =
+static struct sbmix_elem snd_sbpro_ctl_mic_play_vol =
 	SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
-static snd_kcontrol_new_t snd_sbpro_ctl_capture_source =
+static struct sbmix_elem snd_sbpro_ctl_capture_source =
 	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Capture Source",
-		.info = snd_sb8mixer_info_mux,
-		.get = snd_sb8mixer_get_mux,
-		.put = snd_sb8mixer_put_mux,
+		.type = SB_MIX_CAPTURE_PRO
 	};
-static snd_kcontrol_new_t snd_sbpro_ctl_capture_filter =
+static struct sbmix_elem snd_sbpro_ctl_capture_filter =
 	SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1);
-static snd_kcontrol_new_t snd_sbpro_ctl_capture_low_filter =
+static struct sbmix_elem snd_sbpro_ctl_capture_low_filter =
 	SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
 
-static snd_kcontrol_new_t *snd_sbpro_controls[] = {
+static struct sbmix_elem *snd_sbpro_controls[] = {
 	&snd_sbpro_ctl_master_play_vol,
 	&snd_sbpro_ctl_pcm_play_vol,
 	&snd_sbpro_ctl_pcm_play_filter,
@@ -495,58 +527,57 @@
 	&snd_sbpro_ctl_capture_low_filter
 };
 
-#define SBPRO_INIT_VALUES (sizeof(snd_sbpro_init_values)/sizeof(unsigned char)/2)
-
 static unsigned char snd_sbpro_init_values[][2] = {
 	{ SB_DSP_MASTER_DEV, 0 },
 	{ SB_DSP_PCM_DEV, 0 },
 	{ SB_DSP_FM_DEV, 0 },
 };
 
-#define SB16_CONTROLS (sizeof(snd_sb16_controls)/sizeof(snd_kcontrol_new_t *))
-
-static snd_kcontrol_new_t snd_sb16_ctl_master_play_vol =
+/*
+ * SB16 specific mixer elements
+ */
+static struct sbmix_elem snd_sb16_ctl_master_play_vol =
 	SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_3d_enhance_switch =
+static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch =
 	SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1);
-static snd_kcontrol_new_t snd_sb16_ctl_tone_bass =
+static struct sbmix_elem snd_sb16_ctl_tone_bass =
 	SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15);
-static snd_kcontrol_new_t snd_sb16_ctl_tone_treble =
+static struct sbmix_elem snd_sb16_ctl_tone_treble =
 	SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15);
-static snd_kcontrol_new_t snd_sb16_ctl_pcm_play_vol =
+static struct sbmix_elem snd_sb16_ctl_pcm_play_vol =
 	SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_synth_capture_route =
+static struct sbmix_elem snd_sb16_ctl_synth_capture_route =
 	SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5);
-static snd_kcontrol_new_t snd_sb16_ctl_synth_play_vol =
+static struct sbmix_elem snd_sb16_ctl_synth_play_vol =
 	SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_cd_capture_route =
+static struct sbmix_elem snd_sb16_ctl_cd_capture_route =
 	SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1);
-static snd_kcontrol_new_t snd_sb16_ctl_cd_play_switch =
+static struct sbmix_elem snd_sb16_ctl_cd_play_switch =
 	SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1);
-static snd_kcontrol_new_t snd_sb16_ctl_cd_play_vol =
+static struct sbmix_elem snd_sb16_ctl_cd_play_vol =
 	SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_line_capture_route =
+static struct sbmix_elem snd_sb16_ctl_line_capture_route =
 	SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3);
-static snd_kcontrol_new_t snd_sb16_ctl_line_play_switch =
+static struct sbmix_elem snd_sb16_ctl_line_play_switch =
 	SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1);
-static snd_kcontrol_new_t snd_sb16_ctl_line_play_vol =
+static struct sbmix_elem snd_sb16_ctl_line_play_vol =
 	SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_mic_capture_route =
+static struct sbmix_elem snd_sb16_ctl_mic_capture_route =
 	SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0);
-static snd_kcontrol_new_t snd_sb16_ctl_mic_play_switch =
+static struct sbmix_elem snd_sb16_ctl_mic_play_switch =
 	SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1);
-static snd_kcontrol_new_t snd_sb16_ctl_mic_play_vol =
+static struct sbmix_elem snd_sb16_ctl_mic_play_vol =
 	SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31);
-static snd_kcontrol_new_t snd_sb16_ctl_pc_speaker_vol =
+static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol =
 	SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3);
-static snd_kcontrol_new_t snd_sb16_ctl_capture_vol =
+static struct sbmix_elem snd_sb16_ctl_capture_vol =
 	SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3);
-static snd_kcontrol_new_t snd_sb16_ctl_play_vol =
+static struct sbmix_elem snd_sb16_ctl_play_vol =
 	SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3);
-static snd_kcontrol_new_t snd_sb16_ctl_auto_mic_gain =
+static struct sbmix_elem snd_sb16_ctl_auto_mic_gain =
 	SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
 
-static snd_kcontrol_new_t *snd_sb16_controls[] = {
+static struct sbmix_elem *snd_sb16_controls[] = {
 	&snd_sb16_ctl_master_play_vol,
 	&snd_sb16_ctl_3d_enhance_switch,
 	&snd_sb16_ctl_tone_bass,
@@ -569,8 +600,6 @@
 	&snd_sb16_ctl_auto_mic_gain
 };
 
-#define SB16_INIT_VALUES (sizeof(snd_sb16_init_values)/sizeof(unsigned char)/2)
-
 static unsigned char snd_sb16_init_values[][2] = {
 	{ SB_DSP4_MASTER_DEV + 0, 0 },
 	{ SB_DSP4_MASTER_DEV + 1, 0 },
@@ -584,37 +613,34 @@
 	{ SB_DSP4_SPEAKER_DEV, 0 },
 };
 
-#define DT019X_CONTROLS (sizeof(snd_dt019x_controls)/sizeof(snd_kcontrol_new_t *))
-
-
-static snd_kcontrol_new_t snd_dt019x_ctl_master_play_vol =
+/*
+ * DT019x specific mixer elements
+ */
+static struct sbmix_elem snd_dt019x_ctl_master_play_vol =
 	SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15);
-static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_vol =
+static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol =
 	SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15);
-static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_vol =
+static struct sbmix_elem snd_dt019x_ctl_synth_play_vol =
 	SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15);
-static snd_kcontrol_new_t snd_dt019x_ctl_cd_play_vol =
+static struct sbmix_elem snd_dt019x_ctl_cd_play_vol =
 	SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15);
-static snd_kcontrol_new_t snd_dt019x_ctl_mic_play_vol =
+static struct sbmix_elem snd_dt019x_ctl_mic_play_vol =
 	SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7);
-static snd_kcontrol_new_t snd_dt019x_ctl_pc_speaker_vol =
+static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol =
 	SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0,  7);
-static snd_kcontrol_new_t snd_dt019x_ctl_line_play_vol =
+static struct sbmix_elem snd_dt019x_ctl_line_play_vol =
 	SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15);
-static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_switch =
+static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch =
 	SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1);
-static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_switch =
+static struct sbmix_elem snd_dt019x_ctl_synth_play_switch =
 	SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1);
-static snd_kcontrol_new_t snd_dt019x_ctl_capture_source =
+static struct sbmix_elem snd_dt019x_ctl_capture_source =
 	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Capture Source",
-		.info = snd_dt019x_input_sw_info,
-		.get = snd_dt019x_input_sw_get,
-		.put = snd_dt019x_input_sw_put,
+		.type = SB_MIX_CAPTURE_DT019X
 	};
 
-static snd_kcontrol_new_t *snd_dt019x_controls[] = {
+static struct sbmix_elem *snd_dt019x_controls[] = {
 	&snd_dt019x_ctl_master_play_vol,
 	&snd_dt019x_ctl_pcm_play_vol,
 	&snd_dt019x_ctl_synth_play_vol,
@@ -630,8 +656,6 @@
 	&snd_dt019x_ctl_capture_source
 };
 
-#define DT019X_INIT_VALUES (sizeof(snd_dt019x_init_values)/sizeof(unsigned char)/2)
-
 static unsigned char snd_dt019x_init_values[][2] = {
         { SB_DT019X_MASTER_DEV, 0 },
         { SB_DT019X_PCM_DEV, 0 },
@@ -644,35 +668,36 @@
         { SB_DT019X_CAPTURE_SW, 0x06 },
 };
 
+/*
+ * ALS4000 specific mixer elements
+ */
 /* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl ! */
-static snd_kcontrol_new_t snd_als4000_ctl_mono_output_switch =
+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 snd_kcontrol_new_t snd_als4000_ctl_mono_input_switch =
+static struct sbmix_elem snd_als4000_ctl_mono_input_switch =
 	SB_SINGLE("Mono Input Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
-static snd_kcontrol_new_t snd_als4000_ctl_mic_20db_boost =
+static struct sbmix_elem snd_als4000_ctl_mic_20db_boost =
 	SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
-static snd_kcontrol_new_t snd_als4000_ctl_mixer_out_to_in =
+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 snd_kcontrol_new_t snd_als4000_ctl_3d_output_switch =
+static struct sbmix_elem snd_als4000_ctl_3d_output_switch =
 	SB_SINGLE("3D Output Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
-static snd_kcontrol_new_t snd_als4000_ctl_3d_output_ratio =
+static struct sbmix_elem snd_als4000_ctl_3d_output_ratio =
 	SB_SINGLE("3D Output Ratio", SB_ALS4000_3D_SND_FX, 0, 0x07);
-static snd_kcontrol_new_t snd_als4000_ctl_3d_poweroff_switch =
+static struct sbmix_elem snd_als4000_ctl_3d_poweroff_switch =
 	SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
-static snd_kcontrol_new_t snd_als4000_ctl_3d_delay =
+static struct sbmix_elem snd_als4000_ctl_3d_delay =
 	SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
 #if NOT_AVAILABLE
-static snd_kcontrol_new_t snd_als4000_ctl_fmdac =
+static struct sbmix_elem snd_als4000_ctl_fmdac =
 	SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
-static snd_kcontrol_new_t snd_als4000_ctl_qsound =
+static struct sbmix_elem snd_als4000_ctl_qsound =
 	SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
 #endif
 
-#define ALS4000_CONTROLS (sizeof(snd_als4000_controls)/sizeof(snd_kcontrol_new_t *))
-
-static snd_kcontrol_new_t *snd_als4000_controls[] = {
+static struct sbmix_elem *snd_als4000_controls[] = {
 	&snd_sb16_ctl_master_play_vol,
 	&snd_dt019x_ctl_pcm_play_switch,
 	&snd_sb16_ctl_pcm_play_vol,
@@ -706,8 +731,6 @@
 #endif
 };
 
-#define ALS4000_INIT_VALUES (sizeof(snd_als4000_init_values)/sizeof(unsigned char)/2)
-
 static unsigned char snd_als4000_init_values[][2] = {
 	{ SB_DSP4_MASTER_DEV + 0, 0 },
 	{ SB_DSP4_MASTER_DEV + 1, 0 },
@@ -723,8 +746,11 @@
 	{ SB_ALS4000_MIC_IN_GAIN, 0 },
 };
 
+
+/*
+ */
 static int snd_sbmixer_init(sb_t *chip,
-			    snd_kcontrol_new_t **controls,
+			    struct sbmix_elem **controls,
 			    int controls_count,
 			    unsigned char map[][2],
 			    int map_count,
@@ -747,7 +773,7 @@
 	}
 
 	for (idx = 0; idx < controls_count; idx++) {
-		if ((err = snd_ctl_add(card, snd_ctl_new1(controls[idx], chip))) < 0)
+		if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0)
 			return err;
 	}
 	snd_component_add(card, name);
@@ -770,37 +796,47 @@
 	case SB_HW_20:
 	case SB_HW_201:
 		if ((err = snd_sbmixer_init(chip,
-					    snd_sb20_controls, SB20_CONTROLS,
-					    snd_sb20_init_values, SB20_INIT_VALUES,
+					    snd_sb20_controls,
+					    ARRAY_SIZE(snd_sb20_controls),
+					    snd_sb20_init_values,
+					    ARRAY_SIZE(snd_sb20_init_values),
 					    "CTL1335")) < 0)
 			return err;
 		break;
 	case SB_HW_PRO:
 		if ((err = snd_sbmixer_init(chip,
-					    snd_sbpro_controls, SBPRO_CONTROLS,
-					    snd_sbpro_init_values, SBPRO_INIT_VALUES,
+					    snd_sbpro_controls,
+					    ARRAY_SIZE(snd_sbpro_controls),
+					    snd_sbpro_init_values,
+					    ARRAY_SIZE(snd_sbpro_init_values),
 					    "CTL1345")) < 0)
 			return err;
 		break;
 	case SB_HW_16:
 	case SB_HW_ALS100:
 		if ((err = snd_sbmixer_init(chip,
-					    snd_sb16_controls, SB16_CONTROLS,
-					    snd_sb16_init_values, SB16_INIT_VALUES,
+					    snd_sb16_controls,
+					    ARRAY_SIZE(snd_sb16_controls),
+					    snd_sb16_init_values,
+					    ARRAY_SIZE(snd_sb16_init_values),
 					    "CTL1745")) < 0)
 			return err;
 		break;
 	case SB_HW_ALS4000:
 		if ((err = snd_sbmixer_init(chip,
-					    snd_als4000_controls, ALS4000_CONTROLS,
-					    snd_als4000_init_values, ALS4000_INIT_VALUES,
+					    snd_als4000_controls,
+					    ARRAY_SIZE(snd_als4000_controls),
+					    snd_als4000_init_values,
+					    ARRAY_SIZE(snd_als4000_init_values),
 					    "ALS4000")) < 0)
 			return err;
 		break;
 	case SB_HW_DT019X:
 		if ((err = snd_sbmixer_init(chip,
-					    snd_dt019x_controls, DT019X_CONTROLS,
-					    snd_dt019x_init_values, DT019X_INIT_VALUES,
+					    snd_dt019x_controls,
+					    ARRAY_SIZE(snd_dt019x_controls),
+					    snd_dt019x_init_values,
+					    ARRAY_SIZE(snd_dt019x_init_values),
 					    "DT019X")) < 0)
 		break;
 	default:
diff -Nru a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
--- a/sound/isa/sgalaxy.c	Mon Feb 10 10:39:33 2003
+++ b/sound/isa/sgalaxy.c	Mon Feb 10 10:39:33 2003
@@ -30,6 +30,7 @@
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/ad1848.h>
+#include <sound/control.h>
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #define SNDRV_GET_ID
@@ -176,9 +177,7 @@
 	return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
 }
 
-#define SGALAXY_CONTROLS 2
-
-static snd_kcontrol_new_t snd_sgalaxy_controls[2] = {
+static struct ad1848_mix_elem snd_sgalaxy_controls[] = {
 AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
 };
@@ -187,7 +186,8 @@
 {
 	snd_card_t *card = chip->card;
 	snd_ctl_elem_id_t id1, id2;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	memset(&id1, 0, sizeof(id1));
 	memset(&id2, 0, sizeof(id2));
@@ -211,8 +211,8 @@
 	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
 		return err;
 	/* build AUX2 input */
-	for (idx = 0; idx < SGALAXY_CONTROLS; idx++) {
-		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sgalaxy_controls[idx], chip))) < 0)
+	for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
+		if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0)
 			return err;
 	}
 	return 0;
diff -Nru a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
--- a/sound/isa/wavefront/wavefront_fx.c	Mon Feb 10 10:39:29 2003
+++ b/sound/isa/wavefront/wavefront_fx.c	Mon Feb 10 10:39:29 2003
@@ -144,11 +144,8 @@
 snd_wavefront_fx_open (snd_hwdep_t *hw, struct file *file)
 
 {
-	MOD_INC_USE_COUNT;
-	if (!try_module_get(hw->card->module)) {
-		MOD_DEC_USE_COUNT;
+	if (!try_module_get(hw->card->module))
 		return -EFAULT;
-	}
 	file->private_data = hw;
 	return 0;
 }
@@ -158,7 +155,6 @@
 
 {
 	module_put(hw->card->module);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -199,7 +195,7 @@
 		} else if (r.data[2] == 1) {
 			pd = (unsigned short *) &r.data[3];
 		} else {
-			if (r.data[2] > sizeof (page_data)) {
+			if (r.data[2] > (long)sizeof (page_data)) {
 				snd_printk ("cannot write "
 					    "> 255 bytes to FX\n");
 				return -EIO;
diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
--- a/sound/isa/wavefront/wavefront_synth.c	Mon Feb 10 10:39:25 2003
+++ b/sound/isa/wavefront/wavefront_synth.c	Mon Feb 10 10:39:25 2003
@@ -877,7 +877,7 @@
 	u32 length;
 	u16 *data_end = 0;
 	unsigned int i;
-	const int max_blksize = 4096/2;
+	const unsigned int max_blksize = 4096/2;
 	unsigned int written;
 	unsigned int blocksize;
 	int dma_ack;
@@ -944,7 +944,7 @@
 	if (header->size) {
 		dev->freemem = wavefront_freemem (dev);
 
-		if (dev->freemem < header->size) {
+		if (dev->freemem < (int)header->size) {
 			snd_printk ("insufficient memory to "
 				    "load %d byte sample.\n",
 				    header->size);
@@ -1603,11 +1603,8 @@
 snd_wavefront_synth_open (snd_hwdep_t *hw, struct file *file)
 
 {
-	MOD_INC_USE_COUNT;
-	if (!try_module_get(hw->card->module)) {
-		MOD_DEC_USE_COUNT;
+	if (!try_module_get(hw->card->module))
 		return -EFAULT;
-	}
 	file->private_data = hw;
 	return 0;
 }
@@ -1617,7 +1614,6 @@
 
 {
 	module_put(hw->card->module);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig
--- a/sound/oss/Kconfig	Mon Feb 10 10:39:31 2003
+++ b/sound/oss/Kconfig	Mon Feb 10 10:39:31 2003
@@ -17,7 +17,7 @@
 	  don't need this driver as most TV cards handle sound with a short
 	  cable from the TV card to your sound card's line-in.
 
-	  This driver is available as a module called btaudio.o ( = code
+	  This driver is available as a module called btaudio ( = code
 	  which can be inserted in and removed from the running kernel
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
@@ -528,7 +528,7 @@
 	help
 	  OSS is the Open Sound System suite of sound card drivers.  They make
 	  sound programming easier since they provide a common API.  Say Y or
-	  M here (the module will be called sound.o) if you haven't found a
+	  M here (the module will be called sound) if you haven't found a
 	  driver for your sound card above, then pick your driver from the
 	  list below.
 
@@ -552,7 +552,7 @@
 	  until the shutdown. This option is only useful if you said Y to
 	  "OSS sound modules", above. If you said M to "OSS sound modules"
 	  then you can get the persistent DMA buffer functionality by passing
-	  the command-line argument "dmabuf=1" to the sound.o module.
+	  the command-line argument "dmabuf=1" to the sound module.
 
 	  Say Y unless you have 16MB or more RAM or a PCI sound card.
 
@@ -600,7 +600,7 @@
 	  miropcm20 driver (say M or Y here and go back to "Multimedia
 	  devices" -> "Radio Adapters").
 
-	  This driver is also available as a module and will be called aci.o.
+	  This driver is also available as a module and will be called aci.
 
 config SOUND_CS4232
 	tristate "Crystal CS4232 based (PnP) cards"
@@ -861,7 +861,7 @@
 	  command line.
 
 	  You can say M here to compile this driver as a module; the module is
-	  called sb.o.
+	  called sb.
 
 config SOUND_AWE32_SYNTH
 	tristate "AWE32 synth"
diff -Nru a/sound/oss/Makefile b/sound/oss/Makefile
--- a/sound/oss/Makefile	Mon Feb 10 10:39:24 2003
+++ b/sound/oss/Makefile	Mon Feb 10 10:39:24 2003
@@ -3,13 +3,6 @@
 # 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
 # Rewritten to use lists instead of if-statements.
 
-# All of the (potential) objects that export symbols.
-# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
-export-objs	:=  ad1848.o audio_syms.o midi_syms.o mpu401.o ac97_codec.o \
-		    msnd.o opl3.o sb_common.o sequencer_syms.o ac97.o aci.o \
-		    sound_syms.o uart401.o
-
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_SOUND_OSS)		+= sound.o
diff -Nru a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
--- a/sound/oss/ac97_codec.c	Mon Feb 10 10:39:23 2003
+++ b/sound/oss/ac97_codec.c	Mon Feb 10 10:39:23 2003
@@ -446,7 +446,7 @@
 }
 
 /* read or write the recmask, the ac97 can really have left and right recording
-   inputs independantly set, but OSS doesn't seem to want us to express that to
+   inputs independently set, but OSS doesn't seem to want us to express that to
    the user. the caller guarantees that we have a supported bit set, and they
    must be holding the card's spinlock */
 static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) 
diff -Nru a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile
--- a/sound/oss/dmasound/Makefile	Mon Feb 10 10:39:24 2003
+++ b/sound/oss/dmasound/Makefile	Mon Feb 10 10:39:24 2003
@@ -2,8 +2,6 @@
 # Makefile for the DMA sound driver
 #
 
-export-objs := dmasound_core.o
-
 obj-$(CONFIG_DMASOUND_ATARI)  += dmasound_core.o dmasound_atari.o
 obj-$(CONFIG_DMASOUND_AWACS)  += dmasound_core.o dmasound_awacs.o
 obj-$(CONFIG_DMASOUND_PAULA)  += dmasound_core.o dmasound_paula.o
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	Mon Feb 10 10:39:30 2003
+++ b/sound/oss/i810_audio.c	Mon Feb 10 10:39:30 2003
@@ -177,7 +177,7 @@
 struct i810_channel 
 {
 	/* these sg guys should probably be allocated
-	   seperately as nocache. Must be 8 byte aligned */
+	   separately as nocache. Must be 8 byte aligned */
 	struct sg_item sg[SG_LEN];	/* 32*8 */
 	u32 offset;			/* 4 */
 	u32 port;			/* 4 */
@@ -186,7 +186,7 @@
 };
 
 /*
- * we have 3 seperate dma engines.  pcm in, pcm out, and mic.
+ * we have 3 separate dma engines.  pcm in, pcm out, and mic.
  * each dma engine has controlling registers.  These goofy
  * names are from the datasheet, but make it easy to write
  * code while leafing through it.
@@ -900,7 +900,7 @@
 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
+/* allocate DMA buffer, playback and recording buffer should be allocated separately */
 static int alloc_dmabuf(struct i810_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c	Mon Feb 10 10:39:31 2003
+++ b/sound/oss/maestro.c	Mon Feb 10 10:39:31 2003
@@ -668,7 +668,7 @@
 		if (mixer == SOUND_MIXER_IGAIN) {
 			right = (right * 100) / mh->scale;
 			left = (left * 100) / mh->scale;
-		else {
+		} else {
 			right = 100 - ((right * 100) / mh->scale);
 			left = 100 - ((left * 100) / mh->scale);
 		}
@@ -793,7 +793,7 @@
 	
 /* read or write the recmask 
 	the ac97 can really have left and right recording
-	inputs independantly set, but OSS doesn't seem to 
+	inputs independently set, but OSS doesn't seem to 
 	want us to express that to the user. 
 	the caller guarantees that we have a supported bit set,
 	and they must be holding the card's spinlock */
diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c	Mon Feb 10 10:39:30 2003
+++ b/sound/oss/trident.c	Mon Feb 10 10:39:30 2003
@@ -1227,7 +1227,7 @@
 }
 
 /* allocate the main DMA buffer, playback and recording buffer should be */ 
-/* allocated seperately */
+/* allocated separately */
 static int alloc_main_dmabuf(struct trident_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/Kconfig	Mon Feb 10 10:39:24 2003
@@ -51,8 +51,8 @@
 	tristate "RME Digi32, 32/8, 32 PRO"
 	depends on SND
 	help
-	  Say 'Y' or 'M' to include support for RME Digi32, Digi32/8 and
-	  Digi32 PRO audio devices.
+	  Say 'Y' or 'M' to include support for RME Digi32, Digi32 PRO and
+	  Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio devices.
 
 config SND_RME96
 	tristate "RME Digi96, 96/8, 96/8 PRO"
@@ -116,10 +116,10 @@
 	  Sound Blaster PCI 64 or 128 soundcards.
 
 config SND_ES1938
-	tristate "ESS ES1938/1946 (Solo-1)"
+	tristate "ESS ES1938/1946/1969 (Solo-1)"
 	depends on SND && SOUND_GAMEPORT
 	help
-	  Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946)
+	  Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946, ES1969)
 	  soundcard.
 
 config SND_ES1968
diff -Nru a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
--- a/sound/pci/ac97/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/ac97/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := ac97_codec.o ak4531_codec.o
-
 snd-ac97-codec-objs := ac97_codec.o ac97_patch.o
 snd-ak4531-codec-objs := ak4531_codec.o
 
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	Mon Feb 10 10:39:25 2003
+++ b/sound/pci/ac97/ac97_codec.c	Mon Feb 10 10:39:25 2003
@@ -51,7 +51,6 @@
  */
 
 static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97);
-static void snd_ac97_proc_done(ac97_t * ac97);
 
 typedef struct {
 	unsigned int id;
@@ -68,6 +67,7 @@
 { 0x434d4900, 0xffffff00, "C-Media Electronics", NULL },
 { 0x43525900, 0xffffff00, "Cirrus Logic",	NULL },
 { 0x43585400, 0xffffff00, "Conexant",           NULL },
+{ 0x44543000, 0xffffff00, "Diamond Technology", NULL },
 { 0x454d4300, 0xffffff00, "eMicro",		NULL },
 { 0x45838300, 0xffffff00, "ESS Technology",	NULL },
 { 0x48525300, 0xffffff00, "Intersil",		NULL },
@@ -121,6 +121,7 @@
 { 0x43525960, 0xfffffff8, "CS4291",		NULL },
 { 0x43585421, 0xffffffff, "HSD11246",		NULL },	// SmartMC II
 { 0x43585428, 0xfffffff8, "Cx20468",		patch_conexant }, // SmartAMC fixme: the mask might be different
+{ 0x44543031, 0xfffffff0, "DT0398",		NULL },
 { 0x454d4328, 0xffffffff, "28028",		NULL },  // same as TR28028?
 { 0x45838308, 0xffffffff, "ESS1988",		NULL },
 { 0x48525300, 0xffffff00, "HMP9701",		NULL },
@@ -142,7 +143,7 @@
 { 0x57454301, 0xffffffff, "W83971D",		NULL },
 { 0x574d4c00, 0xffffffff, "WM9701A",		patch_wolfson00 },
 { 0x574d4c03, 0xffffffff, "WM9703/9707",	patch_wolfson03 },
-{ 0x574d4c04, 0xffffffff, "WM9704 (quad)",	patch_wolfson04 },
+{ 0x574d4c04, 0xffffffff, "WM9704/quad",	patch_wolfson04 },
 { 0x574d4c05, 0xffffffff, "WM9705",		NULL },	// patch?
 { 0x594d4800, 0xffffffff, "YMF743",		NULL },
 { 0x594d4802, 0xffffffff, "YMF752",		NULL },
@@ -240,6 +241,18 @@
 	return 1;
 }
 
+/**
+ * snd_ac97_write - write a value on the given register
+ * @ac97: the ac97 instance
+ * @reg: the register to change
+ * @value: the value to set
+ *
+ * Writes a value on the given register.  This will invoke the write
+ * callback directly after the register check.
+ * This function doesn't change the register cache unlike
+ * #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)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
@@ -247,6 +260,17 @@
 	ac97->write(ac97, reg, value);
 }
 
+/**
+ * snd_ac97_read - read a value from the given register
+ * 
+ * @ac97: the ac97 instance
+ * @reg: the register to read
+ *
+ * Reads a value from the given register.  This will invoke the read
+ * callback directly after the register check.
+ *
+ * Returns the read value.
+ */
 unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
@@ -254,13 +278,24 @@
 	return ac97->read(ac97, reg);
 }
 
+/**
+ * snd_ac97_write_cache - write a value on the given register and update the cache
+ * @ac97: the ac97 instance
+ * @reg: the register to change
+ * @value: the value to set
+ *
+ * Writes a value on the given register and updates the register
+ * 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)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
 	spin_lock(&ac97->reg_lock);
-	ac97->write(ac97, reg, ac97->regs[reg] = value);
+	ac97->regs[reg] = value;
 	spin_unlock(&ac97->reg_lock);
+	ac97->write(ac97, reg, value);
 	set_bit(reg, ac97->reg_accessed);
 }
 
@@ -269,16 +304,28 @@
 #if 0
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
-	spin_lock(&ac97->reg_lock);
+	//spin_lock(&ac97->reg_lock);
 	ac97->write(ac97, reg, value);
 	ac97->regs[reg] = ac97->read(ac97, reg);
 	if (value != ac97->regs[reg])
 		snd_printk("AC97 reg=%02x val=%04x real=%04x\n", reg, value, ac97->regs[reg]);
-	spin_unlock(&ac97->reg_lock);
+	//spin_unlock(&ac97->reg_lock);
 #endif
 	snd_ac97_write_cache(ac97, reg, value);
 }
 
+/**
+ * snd_ac97_update - update the value on the given register
+ * @ac97: the ac97 instance
+ * @reg: the register to change
+ * @value: the value to set
+ *
+ * Compares the value with the register cache and updates the value
+ * only when the value is changed.
+ *
+ * Retruns 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 change;
@@ -288,40 +335,48 @@
 	spin_lock(&ac97->reg_lock);
 	change = ac97->regs[reg] != value;
 	if (change) {
-		ac97->write(ac97, reg, value);
 		ac97->regs[reg] = value;
-	}
-	spin_unlock(&ac97->reg_lock);
+		spin_unlock(&ac97->reg_lock);
+		ac97->write(ac97, reg, value);
+	} else
+		spin_unlock(&ac97->reg_lock);
 	return change;
 }
 
-int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
+/**
+ * snd_ac97_update_bits - update the bits on the given register
+ * @ac97: the ac97 instance
+ * @reg: the register to change
+ * @mask: the bit-mask to change
+ * @value: the value to set
+ *
+ * Updates the masked-bits on the given register onle when the value
+ * is changed.
+ *
+ * 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 change;
 	unsigned short old, new;
 
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return -EINVAL;
+	spin_lock(&ac97->reg_lock);
 	old = ac97->regs[reg];
 	new = (old & ~mask) | value;
 	change = old != new;
 	if (change) {
-		ac97->write(ac97, reg, new);
 		ac97->regs[reg] = new;
-	}
-	return change;
-}
-
-int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
-{
-	int change;
-	spin_lock(&ac97->reg_lock);
-	change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
-	spin_unlock(&ac97->reg_lock);
+		spin_unlock(&ac97->reg_lock);
+		ac97->write(ac97, reg, new);
+	} else
+		spin_unlock(&ac97->reg_lock);
 	return change;
 }
 
-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(ac97_t *ac97, int codec, unsigned short mask, unsigned short value)
 {
 	int change;
 	unsigned short old, new;
@@ -332,15 +387,16 @@
 	new = (old & ~mask) | value;
 	change = old != new;
 	if (change) {
+		ac97->spec.ad18xx.pcmreg[codec] = new;
+		spin_unlock(&ac97->reg_lock);
 		/* select single codec */
 		ac97->write(ac97, AC97_AD_SERIAL_CFG, ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]);
 		/* update PCM bits */
 		ac97->write(ac97, AC97_PCM, new);
 		/* select all codecs */
 		ac97->write(ac97, AC97_AD_SERIAL_CFG, 0x7000);
-		ac97->spec.ad18xx.pcmreg[codec] = new;
-	}
-	spin_unlock(&ac97->reg_lock);
+	} else
+		spin_unlock(&ac97->reg_lock);
 	up(&ac97->spec.ad18xx.mutex);
 	return change;
 }
@@ -671,6 +727,11 @@
 AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
 };
 
+static const snd_kcontrol_new_t snd_ac97_sigmatel_surround[2] = {
+AC97_SINGLE("Sigmatel Surround Playback Switch", AC97_HEADPHONE, 15, 1, 1),
+AC97_DOUBLE("Sigmatel Surround Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1)
+};
+
 static const snd_kcontrol_new_t 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)
@@ -733,7 +794,7 @@
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned int new = 0;
 	unsigned short val = 0;
-	int change = 0;
+	int change;
 
 	spin_lock(&ac97->reg_lock);
 	new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO);
@@ -764,7 +825,9 @@
 		}
 	}
 
-	
+	change = ac97->spdif_status != new;
+	ac97->spdif_status = new;
+	spin_unlock(&ac97->reg_lock);
 
 	if (ac97->flags & AC97_CS_SPDIF) {
 		int x = (val >> 12) & 0x03;
@@ -773,24 +836,51 @@
 		case 2: x = 0; break;  // 48.0
 		default: x = 0; break; // illegal.
 		}
-		change = snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
+		change |= snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
 	} else if (ac97->flags & AC97_CX_SPDIF) {
 		int v;
-		v = ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
-		v |= ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
-		change = snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC, 
-						     AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
-						     v);
+		v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
+		v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
+		change |= snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC, 
+					       AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
+					       v);
 	} else {
-		change = snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
+		change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
 	}
 
-	change |= ac97->spdif_status != new;
-	ac97->spdif_status = new;
-	spin_unlock(&ac97->reg_lock);
 	return change;
 }
 
+static int snd_ac97_put_spsa(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ac97_t *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;
+	// int invert = (kcontrol->private_value >> 24) & 0xff;
+	unsigned short value, old, new;
+
+	value = (ucontrol->value.integer.value[0] & mask);
+
+	mask <<= shift;
+	value <<= shift;
+	spin_lock(&ac97->reg_lock);
+	old = ac97->regs[reg];
+	new = (old & ~mask) | value;
+	spin_unlock(&ac97->reg_lock);
+
+	if (old != new) {
+		int change;
+		unsigned short extst = ac97->regs[AC97_EXTENDED_STATUS];
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
+		change = snd_ac97_update_bits(ac97, reg, mask, value);
+		if (extst & AC97_EA_SPDIF)
+			snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
+		return change;
+	}
+	return 0;
+}
+
 static const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -815,7 +905,15 @@
 	},
 
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),AC97_EXTENDED_STATUS, 2, 1, 0),
-	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",AC97_EXTENDED_STATUS, 4, 3, 0)
+	// AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",AC97_EXTENDED_STATUS, 4, 3, 0)
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",
+		.info = snd_ac97_info_single,
+		.get = snd_ac97_get_single,
+		.put = snd_ac97_put_spsa,
+		.private_value = AC97_EXTENDED_STATUS | (4 << 8) | (3 << 16) | (0 << 24),
+	},
 };
 
 static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = {
@@ -930,17 +1028,29 @@
 	AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
 	AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
 	AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
+	/* 4: Analog Input To Surround */
+	/* 5: Analog Input To Center/LFE */
+	/* 6: Indepedent Master Volume Right */
+	/* 7: Indepedent Master Volume Left */
+	/* 8: reserved */
 	AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0),
 	AC97_SINGLE("Mic As Center/LFE", AC97_ALC650_MULTICH, 10, 1, 0),
-	AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
-	AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
-	AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0),
 #if 0 /* always set in patch_alc650 */
 	AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
 	AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
+	AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1),
+	AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1),
+	AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
+	AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
 #endif
 };
 
+static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
+	AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
+	AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
+	AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0),
+};
+
 /* 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. */
@@ -1093,7 +1203,6 @@
 static int snd_ac97_free(ac97_t *ac97)
 {
 	if (ac97) {
-		snd_ac97_proc_done(ac97);
 		if (ac97->private_free)
 			ac97->private_free(ac97);
 		snd_magic_kfree(ac97);
@@ -1236,7 +1345,9 @@
 static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97)
 {
 	snd_kcontrol_t *kctl;
-	int err, idx;
+	const snd_kcontrol_new_t *knew;
+	int err;
+	unsigned int idx;
 	unsigned char max;
 
 	/* build master controls */
@@ -1291,10 +1402,11 @@
 	}
 
 	/* build headphone controls */
-	if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_headphone[0], ac97))) < 0)
+	if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE) || ac97->id == AC97_ID_STAC9708) {
+		knew = ac97->id == AC97_ID_STAC9708 ? snd_ac97_sigmatel_surround : snd_ac97_controls_headphone;
+		if ((err = snd_ctl_add(card, snd_ac97_cnew(knew, ac97))) < 0)
 			return err;
-		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_headphone[1], ac97))) < 0)
+		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(knew + 1, ac97))) < 0)
 			return err;
 		snd_ac97_change_volume_params1(ac97, AC97_HEADPHONE, &max);
 		kctl->private_value &= ~(0xff << 16);
@@ -1590,6 +1702,11 @@
 		for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_alc650); idx++)
 			if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_alc650[idx], ac97))) < 0)
 				return err;
+		if (ac97->ext_id & AC97_EI_SPDIF) {
+			for (idx = 0; idx < ARRAY_SIZE(snd_ac97_spdif_controls_alc650); idx++)
+				if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_spdif_controls_alc650[idx], ac97))) < 0)
+					return err;
+		}
 		break;
 	case AC97_ID_VT1616:
 		if (snd_ac97_try_bit(ac97, 0x5a, 9))
@@ -1676,9 +1793,68 @@
 				pid->patch(ac97);
 			return;
 		}
-	sprintf(name + strlen(name), " (%x)", id & 0xff);
+	sprintf(name + strlen(name), " id %x", id & 0xff);
 }
 
+
+/* 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)
+{
+	signed long end_time;
+	end_time = jiffies + timeout;
+	do {
+		unsigned short ext_mid;
+		
+		/* use preliminary reads to settle the communication */
+		snd_ac97_read(ac97, AC97_RESET);
+		snd_ac97_read(ac97, AC97_VENDOR_ID1);
+		snd_ac97_read(ac97, AC97_VENDOR_ID2);
+		/* modem? */
+		if (with_modem) {
+			ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+			if (ext_mid != 0xffff && (ext_mid & 1) != 0)
+				return 0;
+		}
+		/* because the PCM or MASTER volume registers can be modified,
+		 * the REC_GAIN register is used for tests
+		 */
+		/* test if we can write to the record gain volume register */
+		snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
+		if (snd_ac97_read(ac97, AC97_REC_GAIN) == 0x8a05)
+			return 0;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ/100);
+	} while (time_after_eq(end_time, jiffies));
+	return -ENODEV;
+}
+
+/**
+ * snd_ac97_mixer - create an AC97 codec component
+ * @card: the card instance
+ * @_ac97: the template of ac97, including index, callbacks and
+ *         the private data.
+ * @rac97: the pointer to store the new ac97 instance.
+ *
+ * Creates an AC97 codec component.  An ac97_t instance is newly
+ * allocated and initialized from the template (_ac97).  The codec
+ * is then initialized by the standard procedure.
+ *
+ * The template must include the valid callbacks (at least read and
+ * write), the codec number (num) and address (addr), and the private
+ * data (private_data).  The other callbacks, wait and reset, are not
+ * mandantory.
+ * 
+ * The clock is set to 48000.  If another clock is needed, reset
+ * ac97->clock manually afterwards.
+ *
+ * The ac97 instance is registered as a low-level device, so you don't
+ * have to release it manually.
+ *
+ * Returns zero if sucessful, or a negative error code on failure.
+ */
+
 int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
 {
 	int err;
@@ -1709,32 +1885,12 @@
 		ac97->wait(ac97);
 	else {
 		udelay(50);
-
-		/* it's necessary to wait awhile until registers are accessible after RESET */
-		/* because the PCM or MASTER volume registers can be modified, */
-		/* the REC_GAIN register is used for tests */
-		end_time = jiffies + HZ;
-		do {
-			unsigned short ext_mid;
-		
-			/* use preliminary reads to settle the communication */
-			snd_ac97_read(ac97, AC97_RESET);
-			snd_ac97_read(ac97, AC97_VENDOR_ID1);
-			snd_ac97_read(ac97, AC97_VENDOR_ID2);
-			/* modem? */
-			ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
-			if (ext_mid != 0xffff && (ext_mid & 1) != 0)
-				goto __access_ok;
-			/* test if we can write to the record gain volume register */
-			snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
-			if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
-				goto __access_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/100);
-		} while (time_after_eq(end_time, jiffies));
-		snd_printk("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err);
-		snd_ac97_free(ac97);
-		return -ENXIO;
+		if (ac97_reset_wait(ac97, HZ/2, 0) < 0 &&
+		    ac97_reset_wait(ac97, HZ/2, 1) < 0) {
+			snd_printk("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err);
+			snd_ac97_free(ac97);
+			return -ENXIO;
+		}
 	}
       __access_ok:
 	ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
@@ -1859,7 +2015,7 @@
 }
 
 /*
-
+ * proc interface
  */
 
 static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
@@ -2082,46 +2238,14 @@
 		sprintf(name, "ac97#%d-%d", ac97->addr, ac97->num);
 	else
 		sprintf(name, "ac97#%d", ac97->addr);
-	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ac97;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 512;
-		entry->c.text.read = snd_ac97_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ac97->proc_entry = entry;
+	if (! snd_card_proc_new(card, name, &entry))
+		snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
 	if (ac97->num)
 		sprintf(name, "ac97#%d-%dregs", ac97->addr, ac97->num);
 	else
 		sprintf(name, "ac97#%dregs", ac97->addr);
-	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ac97;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 1024;
-		entry->c.text.read = snd_ac97_proc_regs_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ac97->proc_regs_entry = entry;
-}
-
-static void snd_ac97_proc_done(ac97_t * ac97)
-{
-	if (ac97->proc_regs_entry) {
-		snd_info_unregister(ac97->proc_regs_entry);
-		ac97->proc_regs_entry = NULL;
-	}
-	if (ac97->proc_entry) {
-		snd_info_unregister(ac97->proc_entry);
-		ac97->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(card, name, &entry))
+		snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
 }
 
 /*
@@ -2158,15 +2282,32 @@
 
 	spin_lock(&ac97->reg_lock);
 	old = ac97->regs[reg] & ~AC97_SC_SPSR_MASK;
+	spin_unlock(&ac97->reg_lock);
 	if (old != bits) {
-		snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
-		snd_ac97_update_bits_nolock(ac97, reg, AC97_SC_SPSR_MASK, bits);
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
+		snd_ac97_update_bits(ac97, reg, AC97_SC_SPSR_MASK, bits);
 	}
-	snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
-	spin_unlock(&ac97->reg_lock);
+	snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
 	return 0;
 }
 
+/**
+ * snd_ac97_set_rate - change the rate of the given input/output.
+ * @ac97: the ac97 instance
+ * @reg: the register to change
+ * @rate: the sample rate to set
+ *
+ * Changes the rate of the given input/output on the codec.
+ * If the codec doesn't support VAR, the rate must be 48000 (except
+ * for SPDIF).
+ *
+ * The valid registers are AC97_PMC_MIC_ADC_RATE,
+ * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE and AC97_SPDIF.
+ * The SPDIF register is a pseudo-register to change the rate of SPDIF
+ * (only if supported).
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
 int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate)
 {
 	unsigned short mask;
@@ -2206,8 +2347,11 @@
 
 
 #ifdef CONFIG_PM
-/*
- * general suspend procedure
+/**
+ * snd_ac97_suspend - General suspend function for AC97 codec
+ * @ac97: the ac97 instance
+ *
+ * Suspends the codec, power down the chip.
  */
 void snd_ac97_suspend(ac97_t *ac97)
 {
@@ -2224,8 +2368,12 @@
 	snd_ac97_write(ac97, AC97_POWERDOWN, power);
 }
 
-/*
- * general resume procedure
+/**
+ * snd_ac97_resume - General resume function for AC97 codec
+ * @ac97: the ac97 instance
+ *
+ * Do the standard resume procedure, power up and restoring the
+ * old register values.
  */
 void snd_ac97_resume(ac97_t *ac97)
 {
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	Mon Feb 10 10:39:32 2003
+++ b/sound/pci/ac97/ac97_patch.c	Mon Feb 10 10:39:32 2003
@@ -353,8 +353,23 @@
 
 int patch_alc650(ac97_t * ac97)
 {
-	/* enable spdif in */
-	snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK,
-			     snd_ac97_read(ac97, AC97_ALC650_CLOCK) | 0x03);
+	unsigned short val;
+
+	/* check spdif */
+	val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
+	if (val & AC97_EA_SPCV) {
+		/* enable spdif in */
+		snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK,
+				     snd_ac97_read(ac97, AC97_ALC650_CLOCK) | 0x03);
+	} else
+		ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */
+
+	val = snd_ac97_read(ac97, AC97_ALC650_MULTICH);
+	val &= ~0xc000; /* slot: 3,4,7,8,6,9 */
+	snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, val | 0x03);
+
+	/* full DAC volume */
+	snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
+	snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
 	return 0;
 }
diff -Nru a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
--- a/sound/pci/ac97/ak4531_codec.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/ac97/ak4531_codec.c	Mon Feb 10 10:39:23 2003
@@ -33,7 +33,6 @@
 #define chip_t ak4531_t
 
 static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531);
-static void snd_ak4531_proc_done(ak4531_t * ak4531);
 
 /*
  *
@@ -314,7 +313,6 @@
 static int snd_ak4531_free(ak4531_t *ak4531)
 {
 	if (ak4531) {
-		snd_ak4531_proc_done(ak4531);
 		if (ak4531->private_free)
 			ak4531->private_free(ak4531);
 		snd_magic_kfree(ak4531);
@@ -359,7 +357,8 @@
 
 int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531)
 {
-	int idx, err;
+	unsigned int idx;
+	int err;
 	ak4531_t * ak4531;
 	static snd_device_ops_t ops = {
 		.dev_free =	snd_ak4531_dev_free,
@@ -425,26 +424,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(card, "ak4531", card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ak4531;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_ak4531_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ak4531->proc_entry = entry;
-}
-
-static void snd_ak4531_proc_done(ak4531_t * ak4531)
-{
-	if (ak4531->proc_entry) {
-		snd_info_unregister(ak4531->proc_entry);
-		ak4531->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(card, "ak4531", &entry))
+		snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
 }
 
 EXPORT_SYMBOL(snd_ak4531_mixer);
diff -Nru a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
--- a/sound/pci/ali5451/ali5451.c	Mon Feb 10 10:39:32 2003
+++ b/sound/pci/ali5451/ali5451.c	Mon Feb 10 10:39:32 2003
@@ -529,7 +529,8 @@
 		udelay(5000);
 	}
 
-	snd_printk(KERN_WARNING "ali5451: reset time out\n");
+	/* non-fatal if you have a non PM capable codec */
+	/* snd_printk(KERN_WARNING "ali5451: reset time out\n"); */
 	return 0;
 }
 
@@ -1850,7 +1851,8 @@
 static int __devinit snd_ali_mixer(ali_t * codec)
 {
 	ac97_t ac97;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.write = snd_ali_codec_write;
@@ -2088,12 +2090,12 @@
 	/* enable PCI device */
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	/* check, if we can restrict PCI DMA transfers to 30 bits */
-	if (!pci_dma_supported(pci, 0x3fffffff)) {
-		snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+	/* check, if we can restrict PCI DMA transfers to 31 bits */
+	if (!pci_dma_supported(pci, 0x7fffffff)) {
+		snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
 		return -ENXIO;
 	}
-	pci_set_dma_mask(pci, 0x3fffffff);
+	pci_set_dma_mask(pci, 0x7fffffff);
 
 	if ((codec = snd_magic_kcalloc(ali_t, 0, GFP_KERNEL)) == NULL)
 		return -ENOMEM;
diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/cmipci.c	Mon Feb 10 10:39:23 2003
@@ -20,9 +20,7 @@
 /* Does not work. Warning may block system in capture mode */
 /* #define USE_VAR48KRATE */
 
-/* Define this if you want soft ac3 encoding - it's still buggy..  */
-/* #define DO_SOFT_AC3 */
-/* #define USE_AES_IEC958 */
+/* Define this if you want soft ac3 encoding */
 #define DO_SOFT_AC3
 #define USE_AES_IEC958
 
@@ -59,6 +57,9 @@
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
 static long mpu_port[SNDRV_CARDS] = {0x330, [1 ... (SNDRV_CARDS-1)]=-1};
 static long fm_port[SNDRV_CARDS] = {0x388, [1 ... (SNDRV_CARDS-1)]=-1};
+#ifdef DO_SOFT_AC3
+static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
+#endif
 
 MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard.");
@@ -75,6 +76,11 @@
 MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
 MODULE_PARM_DESC(fm_port, "FM port.");
 MODULE_PARM_SYNTAX(fm_port, SNDRV_ENABLED ",allows:{{-1},{0x388},{0x3c8},{0x3e0},{0x3e8}},dialog:list");
+#ifdef DO_SOFT_AC3
+MODULE_PARM(soft_ac3, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only).");
+MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
+#endif
 
 #ifndef PCI_DEVICE_ID_CMEDIA_CM8738
 #define PCI_DEVICE_ID_CMEDIA_CM8738	0x0111
@@ -366,8 +372,10 @@
 #define CM_OPEN_DAC	0x10
 #define CM_OPEN_ADC	0x20
 #define CM_OPEN_SPDIF	0x40
+#define CM_OPEN_MCHAN	0x80
 #define CM_OPEN_PLAYBACK	(CM_CH_PLAY | CM_OPEN_DAC)
 #define CM_OPEN_PLAYBACK2	(CM_CH_CAPT | CM_OPEN_DAC)
+#define CM_OPEN_PLAYBACK_MULTI	(CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_MCHAN)
 #define CM_OPEN_CAPTURE		(CM_CH_CAPT | CM_OPEN_ADC)
 #define CM_OPEN_SPDIF_PLAYBACK	(CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_SPDIF)
 #define CM_OPEN_SPDIF_CAPTURE	(CM_CH_CAPT | CM_OPEN_ADC | CM_OPEN_SPDIF)
@@ -419,7 +427,7 @@
 	// {"IEC958 Out To DAC", 1}, // no longer used
 	{"IEC958 Loop", 0},
 };
-#define CM_SAVED_MIXERS		(sizeof(cm_saved_mixer)/sizeof(cm_saved_mixer[0]))
+#define CM_SAVED_MIXERS		ARRAY_SIZE(cm_saved_mixer)
 
 struct snd_stru_cmipci {
 	snd_card_t *card;
@@ -442,6 +450,7 @@
 	unsigned int can_ac3_sw: 1;
 	unsigned int can_ac3_hw: 1;
 	unsigned int can_multi_ch: 1;
+	unsigned int do_soft_ac3: 1;
 
 	unsigned int spdif_playback_avail: 1;	/* spdif ready? */
 	unsigned int spdif_playback_enabled: 1;	/* spdif switch enabled? */
@@ -472,7 +481,6 @@
 	snd_rawmidi_t *rmidi;
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
 };
 
 
@@ -552,13 +560,12 @@
  * calculate frequency
  */
 
-static int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
-#define RATES (sizeof(rates) / sizeof(rates[0]))
+static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
 
 static unsigned int snd_cmipci_rate_freq(unsigned int rate)
 {
-	int i;
-	for (i = 0; i < RATES; i++) {
+	unsigned int i;
+	for (i = 0; i < ARRAY_SIZE(rates); i++) {
 		if (rates[i] == rate)
 			return i;
 	}
@@ -638,6 +645,23 @@
 	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)
+{
+	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	if (params_channels(hw_params) > 2) {
+		down(&cm->open_mutex);
+		if (cm->opened[CM_CH_PLAY]) {
+			up(&cm->open_mutex);
+			return -EBUSY;
+		}
+		/* reserve the channel A */
+		cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
+		up(&cm->open_mutex);
+	}
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
 static void snd_cmipci_ch_reset(cmipci_t *cm, int ch)
 {
 	int reset = CM_RST_CH0 << (cm->channel[ch].ch);
@@ -741,6 +765,11 @@
 	rec->period_size = runtime->period_size << rec->shift;
 	rec->dma_size <<= rec->ac3_shift;
 	rec->period_size <<= rec->ac3_shift;
+	if (runtime->channels > 2) {
+		/* multi-channels */
+		rec->dma_size = (rec->dma_size * runtime->channels) / 2;
+		rec->period_size = (rec->period_size * runtime->channels) / 2;
+	}
 
 	spin_lock_irqsave(&cm->reg_lock, flags);
 
@@ -750,7 +779,7 @@
 	/* program sample counts */
 	reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
 	snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
-	snd_cmipci_write_w(cm, reg + 2, rec->period_size); /* FIXME: or period_size-1 ?? */
+	snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1);
 
 	/* set adc/dac flag */
 	val = rec->ch ? CM_CHADC1 : CM_CHADC0;
@@ -862,6 +891,8 @@
 	ptr = bytes_to_frames(substream->runtime, ptr);
 #endif
 	ptr >>= rec->ac3_shift;
+	if (substream->runtime->channels > 2)
+		ptr = (ptr * 2) / substream->runtime->channels;
 	return ptr;
 }
 
@@ -1397,7 +1428,7 @@
 static void save_mixer_state(cmipci_t *cm)
 {
 	if (! cm->mixer_insensitive) {
-		int i;
+		unsigned int i;
 		for (i = 0; i < CM_SAVED_MIXERS; i++) {
 			snd_kcontrol_t *ctl = cm->mixer_res_ctl[i];
 			if (ctl) {
@@ -1425,7 +1456,7 @@
 static void restore_mixer_state(cmipci_t *cm)
 {
 	if (cm->mixer_insensitive) {
-		int i;
+		unsigned int i;
 		cm->mixer_insensitive = 0; /* at first clear this;
 					      otherwise the changes will be ignored */
 		for (i = 0; i < CM_SAVED_MIXERS; i++) {
@@ -1781,9 +1812,11 @@
 
 	down(&cm->open_mutex);
 	if (cm->opened[ch] == mode) {
-		snd_cmipci_ch_reset(cm, ch);
-		cm->channel[ch].running = 0;
-		cm->channel[ch].substream = NULL;
+		if (cm->channel[ch].substream) {
+			snd_cmipci_ch_reset(cm, ch);
+			cm->channel[ch].running = 0;
+			cm->channel[ch].substream = NULL;
+		}
 		cm->opened[ch] = 0;
 		if (! cm->channel[ch].is_dac) {
 			/* enable dual DAC mode again */
@@ -1808,13 +1841,6 @@
 	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
 		return err;
 	runtime->hw = snd_cmipci_playback;
-	if (cm->can_multi_ch) {
-		runtime->hw.channels_max = cm->max_channels;
-		if (cm->max_channels == 4)
-			snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
-		else
-			snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
-	}
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
 	return 0;
 }
@@ -1841,7 +1867,18 @@
 	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
 		return err;
 	runtime->hw = snd_cmipci_playback2;
-	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
+	down(&cm->open_mutex);
+	if (! cm->opened[CM_CH_PLAY]) {
+		if (cm->can_multi_ch) {
+			runtime->hw.channels_max = cm->max_channels;
+			if (cm->max_channels == 4)
+				snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4);
+			else
+				snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6);
+		}
+		snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
+	}
+	up(&cm->open_mutex);
 	return 0;
 }
 
@@ -1898,6 +1935,7 @@
 {
 	cmipci_t *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_PLAYBACK2);
+	close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);
 	return 0;
 }
 
@@ -1945,7 +1983,7 @@
 	.open =		snd_cmipci_playback2_open,
 	.close =	snd_cmipci_playback2_close,
 	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_cmipci_hw_params,
+	.hw_params =	snd_cmipci_playback2_hw_params,
 	.hw_free =	snd_cmipci_hw_free,
 	.prepare =	snd_cmipci_capture_prepare,	/* channel B */
 	.trigger =	snd_cmipci_capture_trigger,	/* channel B */
@@ -1961,11 +1999,22 @@
 	.prepare =	snd_cmipci_playback_spdif_prepare,	/* set up rate */
 	.trigger =	snd_cmipci_playback_trigger,
 	.pointer =	snd_cmipci_playback_pointer,
+};
+
 #ifdef DO_SOFT_AC3
+static snd_pcm_ops_t snd_cmipci_playback_spdif_soft_ops = {
+	.open =		snd_cmipci_playback_spdif_open,
+	.close =	snd_cmipci_playback_spdif_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_cmipci_hw_params,
+	.hw_free =	snd_cmipci_playback_hw_free,
+	.prepare =	snd_cmipci_playback_spdif_prepare,	/* set up rate */
+	.trigger =	snd_cmipci_playback_trigger,
+	.pointer =	snd_cmipci_playback_pointer,
 	.copy =		snd_cmipci_ac3_copy,
 	.silence =	snd_cmipci_ac3_silence,
-#endif
 };
+#endif
 
 static snd_pcm_ops_t snd_cmipci_capture_spdif_ops = {
 	.open =		snd_cmipci_capture_spdif_open,
@@ -2041,7 +2090,14 @@
 	if (err < 0)
 		return err;
 
+#ifdef DO_SOFT_AC3
+	if (cm->can_ac3_hw)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops);
+	else
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_soft_ops);
+#else
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops);
+#endif
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_spdif_ops);
 
 	pcm->private_data = cm;
@@ -2637,7 +2693,8 @@
 	snd_card_t *card;
 	snd_kcontrol_new_t *sw;
 	snd_kcontrol_t *kctl;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	snd_assert(cm != NULL && cm->card != NULL, return -EINVAL);
 
@@ -2746,26 +2803,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(cm->card, "cmipci", cm->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = cm;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_cmipci_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	cm->proc_entry = entry;
-}
-
-static void snd_cmipci_proc_done(cmipci_t *cm)
-{
-	if (cm->proc_entry) {
-		snd_info_unregister(cm->proc_entry);
-		cm->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(cm->card, "cmipci", &entry))
+		snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
 }
 
 
@@ -2795,7 +2834,10 @@
 		if (! detect) {
 			cm->chip_version = 33;
 			cm->max_channels = 2;
-			cm->can_ac3_sw = 1;
+			if (cm->do_soft_ac3)
+				cm->can_ac3_sw = 1;
+			else
+				cm->can_ac3_hw = 1;
 			cm->has_dual_dac = 1;
 		} else {
 			cm->chip_version = 37;
@@ -2832,8 +2874,6 @@
 
 static int snd_cmipci_free(cmipci_t *cm)
 {
-	snd_cmipci_proc_done(cm);
-
 	if (cm->irq >= 0) {
 		snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
 		snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT);
@@ -2864,11 +2904,8 @@
 	return snd_cmipci_free(cm);
 }
 
-static int __devinit snd_cmipci_create(snd_card_t *card,
-				    struct pci_dev *pci,
-				    unsigned long iomidi,
-				    unsigned long iosynth,
-				    cmipci_t **rcmipci)
+static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
+				       int dev, cmipci_t **rcmipci)
 {
 	cmipci_t *cm;
 	int err;
@@ -2876,8 +2913,10 @@
 		.dev_free =	snd_cmipci_dev_free,
 	};
 	unsigned int val = 0;
+	unsigned long iomidi = mpu_port[dev];
+	unsigned long iosynth = fm_port[dev];
 	int pcm_index, pcm_spdif_index;
-	
+
 	*rcmipci = NULL;
 
 	if ((err = pci_enable_device(pci)) < 0)
@@ -2918,6 +2957,9 @@
 
 	cm->chip_version = 0;
 	cm->max_channels = 2;
+#ifdef DO_SOFT_AC3
+	cm->do_soft_ac3 = soft_ac3[dev];
+#endif
 
 	query_chip(cm);
 
@@ -2949,20 +2991,10 @@
 
 	/* Assume TX and compatible chip set (Autodetection required for VX chip sets) */
 	switch (pci->device) {
-		struct list_head *pos;
-		int txvx;
 	case PCI_DEVICE_ID_CMEDIA_CM8738:
 	case PCI_DEVICE_ID_CMEDIA_CM8738B:
-		txvx = 1;
-		list_for_each(pos, &(pci->global_list)) {
-			struct pci_dev * cur = list_entry(pos, struct pci_dev, global_list);
-			if (cur->vendor != 0x8086) /* PCI_VENDOR_ID_INTEL */
-				continue;
-			if (cur->device != 0x7030) /* PCI_DEVICE_ID_INTEL_82437VX */
-				continue;
-			txvx = 0;
-		}
-		if (txvx)
+		/* PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX */
+		if (! pci_find_device(0x8086, 0x7030, NULL))
 			snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_TXVX);
 		break;
 	default:
@@ -3054,7 +3086,7 @@
 		return err;
 	}
 #ifdef USE_VAR48KRATE
-	for (val = 0; val < RATES; val++)
+	for (val = 0; val < ARRAY_SIZE(rates); val++)
 		snd_cmipci_set_pll(cm, rates[val], val);
 
 	/*
@@ -3109,10 +3141,7 @@
 		break;
 	}
 
-	if ((err = snd_cmipci_create(card, pci,
-				     mpu_port[dev],
-				     fm_port[dev],
-				     &cm)) < 0) {
+	if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c	Mon Feb 10 10:39:33 2003
+++ b/sound/pci/cs4281.c	Mon Feb 10 10:39:33 2003
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/gameport.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -35,9 +36,6 @@
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
-#ifndef LINUX_2_2
-#include <linux/gameport.h>
-#endif
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Cirrus Logic CS4281");
@@ -501,13 +499,9 @@
 	unsigned int spurious_dhtc_irq;
 	unsigned int spurious_dtc_irq;
 
-	void *proc_entry_BA0;
-	void *proc_entry_BA1;
-
 	spinlock_t reg_lock;
 	unsigned int midcr;
 	unsigned int uartm;
-	snd_info_entry_t *proc_entry;
 
 	struct snd_cs4281_gameport *gameport;
 
@@ -1253,55 +1247,19 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(chip->card, "cs4281", chip->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = chip;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_cs4281_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	chip->proc_entry = entry;
-	if ((entry = snd_info_create_card_entry(chip->card, "cs4281_BA0", chip->card->proc_root)) != NULL) {
+	if (! snd_card_proc_new(chip->card, "cs4281", &entry))
+		snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read);
+	if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = chip;
 		entry->c.ops = &snd_cs4281_proc_ops_BA0;
 		entry->size = CS4281_BA0_SIZE;
-		if (snd_info_register(entry) < 0) {
-			snd_info_unregister(entry);
-			entry = NULL;
-		}
 	}
-	chip->proc_entry_BA0 = entry;
-	if ((entry = snd_info_create_card_entry(chip->card, "cs4281_BA1", chip->card->proc_root)) != NULL) {
+	if (! snd_card_proc_new(chip->card, "cs4281_BA1", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = chip;
 		entry->c.ops = &snd_cs4281_proc_ops_BA1;
 		entry->size = CS4281_BA1_SIZE;
-		if (snd_info_register(entry) < 0) {
-			snd_info_unregister(entry);
-			entry = NULL;
-		}
-	}
-	chip->proc_entry_BA1 = entry;
-}
-
-static void snd_cs4281_proc_done(cs4281_t * chip)
-{
-	if (chip->proc_entry_BA1) {
-		snd_info_unregister(chip->proc_entry_BA1);
-		chip->proc_entry_BA1 = NULL;
-	}
-	if (chip->proc_entry_BA0) {
-		snd_info_unregister(chip->proc_entry_BA0);
-		chip->proc_entry_BA0 = NULL;
-	}
-	if (chip->proc_entry) {
-		snd_info_unregister(chip->proc_entry);
-		chip->proc_entry = NULL;
 	}
 }
 
@@ -1309,7 +1267,7 @@
  * joystick support
  */
 
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 
 typedef struct snd_cs4281_gameport {
 	struct gameport info;
@@ -1399,7 +1357,9 @@
 	gameport_register_port(&gp->info);
 }
 
-#endif /* !LINUX_2_2 */
+#else
+#define snd_cs4281_gameport(chip) /*NOP*/
+#endif /* CONFIG_GAMEPORT || CONFIG_GAMEPORT_MODULE */
 
 
 /*
@@ -1408,13 +1368,12 @@
 
 static int snd_cs4281_free(cs4281_t *chip)
 {
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (chip->gameport) {
 		gameport_unregister_port(&chip->gameport->info);
 		kfree(chip->gameport);
 	}
 #endif
-	snd_cs4281_proc_done(chip);
 	if (chip->irq >= 0)
 		synchronize_irq(chip->irq);
 
@@ -2041,9 +2000,7 @@
 		snd_card_free(card);
 		return err;
 	}
-#ifndef LINUX_2_2
 	snd_cs4281_gameport(chip);
-#endif
 	strcpy(card->driver, "CS4281");
 	strcpy(card->shortname, "Cirrus Logic CS4281");
 	sprintf(card->longname, "%s at 0x%lx, irq %d",
@@ -2097,11 +2054,10 @@
 {
 	snd_card_t *card = chip->card;
 	u32 ulCLK;
-	int i;
+	unsigned int i;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	snd_pcm_suspend_all(chip->pcm);
 
@@ -2134,19 +2090,16 @@
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- __skip:
-      	snd_power_unlock(card);
 }
 
 static void cs4281_resume(cs4281_t *chip)
 {
 	snd_card_t *card = chip->card;
-	int i;
+	unsigned int i;
 	u32 ulCLK;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	pci_enable_device(chip->pci);
 
@@ -2171,8 +2124,6 @@
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 #ifndef PCI_OLD_SUSPEND
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/cs46xx/cs46xx_lib.c	Mon Feb 10 10:39:23 2003
@@ -26,7 +26,7 @@
  *           at Cirrus for have helping me out with the DSP, however we
  *           still dont have sufficient documentation and technical
  *           references to be able to implement all fancy feutures
- *           supported by the cs46xx DPS's. 
+ *           supported by the cs46xx DSP's. 
  *           Benny <benny@hostmobility.com>
  *                
  *   This program is free software; you can redistribute it and/or modify
@@ -52,14 +52,14 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/gameport.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/info.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
 #include <sound/cs46xx.h>
-#ifndef LINUX_2_2
-#include <linux/gameport.h>
-#endif
 
 #include <asm/io.h>
 
@@ -273,9 +273,6 @@
 				   unsigned short val)
 {
 	cs46xx_t *chip = snd_magic_cast(cs46xx_t, ac97->private_data, return);
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
-	int val2 = 0;
-#endif
 	int codec_index = -1;
 
 	/* UGGLY: nr_ac97_codecs == 0 primery codec detection is in progress */
@@ -287,59 +284,9 @@
 	else
 		snd_assert(0,return);
 
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
-	if (reg == AC97_CD)
-		val2 = snd_cs46xx_codec_read(chip, AC97_CD, codec_index);
-#endif
-
+	chip->active_ctrl(chip, 1);
 	snd_cs46xx_codec_write(chip, reg, val, codec_index);
-
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
-    /* Benny: I've not found *one* soundcard where
-       this code below could do any sense, and
-       with the HW mixering it's anyway broken, with
-       more then 1 PCM stream the amplifier will not
-       be turned off by unmuting CD channel. So just
-       lets skip it.
-    */
-	
-	/*
-	 *	Adjust power if the mixer is selected/deselected according
-	 *	to the CD.
-	 *
-	 *	IF the CD is a valid input source (mixer or direct) AND
-	 *		the CD is not muted THEN power is needed
-	 *
-	 *	We do two things. When record select changes the input to
-	 *	add/remove the CD we adjust the power count if the CD is
-	 *	unmuted.
-	 *
-	 *	When the CD mute changes we adjust the power level if the
-	 *	CD was a valid input.
-	 *
-	 *      We also check for CD volume != 0, as the CD mute isn't
-	 *      normally tweaked from userspace.
-	 */
-	 
-	/* CD mute change ? */
-
-	/* Benny: this hack dont seems to make any sense to me, at least on the Game Theater XP,
-	   Turning of the amplifier just make the PCM sound very distorcionated.
-	   is this really needed ????????????????
-	*/
-	if (reg == AC97_CD) {
-		/* Mute bit change ? */
-		if ((val2^val)&0x8000 || ((val2 == 0x1f1f || val == 0x1f1f) && val2 != val)) {
-			/* Mute on */
-			if(val&0x8000 || val == 0x1f1f)
-				chip->amplifier_ctrl(chip, -1);
-			else /* Mute off power on */
-				chip->amplifier_ctrl(chip, 1);
-		}
-	}
-
 	chip->active_ctrl(chip, -1);
-#endif
 }
 
 
@@ -732,10 +679,12 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t diff;
 	cs46xx_pcm_t * cpcm;
-	int buffer_size = runtime->period_size * CS46XX_FRAGS * 4;
+	int buffer_size;
 
 	cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO);
 
+	buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
+
 	diff = runtime->control->appl_ptr - cpcm->appl_ptr;
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
@@ -749,7 +698,7 @@
 		size_t hw_to_end = buffer_size - cpcm->hw_data;
 		size_t sw_to_end = cpcm->sw_bufsize - cpcm->sw_data;
 		size_t bytes = buffer_size - cpcm->hw_ready;
-		if (cpcm->sw_ready < bytes)
+		if (cpcm->sw_ready < (int)bytes)
 			bytes = cpcm->sw_ready;
 		if (hw_to_end < bytes)
 			bytes = hw_to_end;
@@ -759,7 +708,7 @@
 		       runtime->dma_area + cpcm->sw_data,
 		       bytes);
 		cpcm->hw_data += bytes;
-		if (cpcm->hw_data == buffer_size)
+		if ((int)cpcm->hw_data == buffer_size)
 			cpcm->hw_data = 0;
 		cpcm->sw_data += bytes;
 		if (cpcm->sw_data == cpcm->sw_bufsize)
@@ -776,7 +725,7 @@
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_sframes_t diff = runtime->control->appl_ptr - chip->capt.appl_ptr;
-	int buffer_size = runtime->period_size * CS46XX_FRAGS * 4;
+	int buffer_size = runtime->period_size * CS46XX_FRAGS << chip->capt.shift;
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
@@ -785,11 +734,11 @@
 	chip->capt.sw_ready -= frames << chip->capt.shift;
 	chip->capt.appl_ptr = runtime->control->appl_ptr + frames;
 	while (chip->capt.hw_ready > 0 && 
-	       chip->capt.sw_ready < chip->capt.sw_bufsize) {
+	       chip->capt.sw_ready < (int)chip->capt.sw_bufsize) {
 		size_t hw_to_end = buffer_size - chip->capt.hw_data;
 		size_t sw_to_end = chip->capt.sw_bufsize - chip->capt.sw_data;
 		size_t bytes = chip->capt.sw_bufsize - chip->capt.sw_ready;
-		if (chip->capt.hw_ready < bytes)
+		if (chip->capt.hw_ready < (int)bytes)
 			bytes = chip->capt.hw_ready;
 		if (hw_to_end < bytes)
 			bytes = hw_to_end;
@@ -799,7 +748,7 @@
 		       chip->capt.hw_area + chip->capt.hw_data,
 		       bytes);
 		chip->capt.hw_data += bytes;
-		if (chip->capt.hw_data == buffer_size)
+		if ((int)chip->capt.hw_data == buffer_size)
 			chip->capt.hw_data = 0;
 		chip->capt.sw_data += bytes;
 		if (chip->capt.sw_data == chip->capt.sw_bufsize)
@@ -832,7 +781,7 @@
 	size_t ptr;
 	cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO);
 	ssize_t bytes;
-	int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4;
+	int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << cpcm->shift;
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	snd_assert (cpcm->pcm_channel,return -ENXIO);
@@ -867,7 +816,7 @@
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_addr;
 	ssize_t bytes = ptr - chip->capt.hw_io;
-	int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4;
+	int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << chip->capt.shift;
 
 	if (bytes < 0)
 		bytes += buffer_size;
@@ -1044,7 +993,7 @@
 		cpcm->pcm_channel->sample_rate = sample_rate;
 	} else
 	/* if sample rate is changed */
-	if (cpcm->pcm_channel->sample_rate != sample_rate) {
+	if ((int)cpcm->pcm_channel->sample_rate != sample_rate) {
 		int unlinked = cpcm->pcm_channel->unlinked;
 		cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel);
 
@@ -1073,7 +1022,7 @@
 	int err;
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	int sample_rate = params_rate(hw_params);
-	int period_size = params_period_size(hw_params);
+	int period_size = params_period_bytes(hw_params);
 	cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1092,12 +1041,15 @@
 		return -ENXIO;
 	}
 
-	if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size * 4)) {
+
+	if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) {
 		 up (&chip->spos_mutex);
 		 return -EINVAL;
 	 }
-	snd_printdd ("period_size (%d), periods (%d)\n",
-		     period_size, params_periods(hw_params));
+
+	snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n",
+		     period_size, params_periods(hw_params),
+		     params_buffer_bytes(hw_params));
 #endif
 
 	if (params_periods(hw_params) == CS46XX_FRAGS) {
@@ -1257,12 +1209,10 @@
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
-	int period_size = params_period_size(hw_params);
+	int period_size = params_period_bytes(hw_params);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	snd_printdd ("capture period size (%d)\n",period_size);
-
-	cs46xx_dsp_pcm_ostream_set_period (chip,period_size * 4);
+	cs46xx_dsp_pcm_ostream_set_period (chip,period_size);
 #endif
 	if (runtime->periods == CS46XX_FRAGS) {
 		if (runtime->dma_area != chip->capt.hw_area)
@@ -1447,7 +1397,7 @@
 	.fifo_size =		0,
 };
 
-static unsigned int period_sizes[] = { 8, 16, 32, 64, 128, 256, 512 };
+static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
 
 #define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0])
 
@@ -1490,8 +1440,11 @@
 	cpcm->pcm_channel = NULL; 
 	cpcm->pcm_channel_id = pcm_channel_id;
 
-	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 
+
+	snd_pcm_hw_constraint_list(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
 				   &hw_constraints_period_sizes);
+
 	up (&chip->spos_mutex);
 #else
 	chip->playback_pcm = cpcm; /* HACK */
@@ -1500,7 +1453,6 @@
 	if (chip->accept_valid)
 		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
 	chip->active_ctrl(chip, 1);
-	chip->amplifier_ctrl(chip, 1);
 
 	return 0;
 }
@@ -1564,10 +1516,10 @@
 		substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID;
 
 	chip->active_ctrl(chip, 1);
-	chip->amplifier_ctrl(chip, 1);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 
+	snd_pcm_hw_constraint_list(substream->runtime, 0,
+				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 
 				   &hw_constraints_period_sizes);
 #endif
 	return 0;
@@ -1598,7 +1550,6 @@
 	cpcm->substream = NULL;
 	snd_free_pci_pages(chip->pci, cpcm->hw_size, cpcm->hw_area, cpcm->hw_addr);
 	chip->active_ctrl(chip, -1);
-	chip->amplifier_ctrl(chip, -1);
 
 	return 0;
 }
@@ -1610,7 +1561,6 @@
 	chip->capt.substream = NULL;
 	snd_free_pci_pages(chip->pci, chip->capt.hw_size, chip->capt.hw_area, chip->capt.hw_addr);
 	chip->active_ctrl(chip, -1);
-	chip->amplifier_ctrl(chip, -1);
 
 	return 0;
 }
@@ -2098,7 +2048,7 @@
 
 	/* checking diff from the EGPIO direction register 
 	   should be enough */
-	return (val1 != snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
+	return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));
 }
 
 
@@ -2141,7 +2091,7 @@
 		(1 << 13) | (1 << 12);
 
 
-	change = ins->spdif_csuv_default != val;
+	change = (unsigned int)ins->spdif_csuv_default != val;
 	ins->spdif_csuv_default = val;
 
 	if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )
@@ -2459,7 +2409,7 @@
 	ac97_t ac97;
 	snd_ctl_elem_id_t id;
 	int err;
-	int idx;
+	unsigned int idx;
 
 	/* detect primary codec */
 	chip->nr_ac97_codecs = 0;
@@ -2537,17 +2487,10 @@
 
  _end:
 
-	/* dosoundcard specific mixer setup */
-	if (chip->mixer_init) {
-		snd_printdd ("calling chip->mixer_init(chip);\n");
-		chip->mixer_init(chip);
-	}
-    
 #endif /* CONFIG_SND_CS46XX_NEW_DSP */
 
 	/* add cs4630 mixer controls */
-	for (idx = 0; idx < sizeof(snd_cs46xx_controls) / 
-		     sizeof(snd_cs46xx_controls[0]); idx++) {
+	for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
 		snd_kcontrol_t *kctl;
 		kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
 		if ((err = snd_ctl_add(card, kctl)) < 0)
@@ -2560,6 +2503,17 @@
 	strcpy(id.name, "External Amplifier Power Down");
 	chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
     
+	/* turn on amplifier */
+	chip->amplifier_ctrl(chip, 1);
+
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+	/* do soundcard specific mixer setup */
+	if (chip->mixer_init) {
+		snd_printdd ("calling chip->mixer_init(chip);\n");
+		chip->mixer_init(chip);
+	}
+#endif
+    
 	return 0;
 }
 
@@ -2740,7 +2694,7 @@
  * gameport interface
  */
 
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 
 typedef struct snd_cs46xx_gameport {
 	struct gameport info;
@@ -2824,13 +2778,13 @@
 	gameport_register_port(&gp->info);
 }
 
-#else /* LINUX_2_2 */
+#else
 
 void __devinit snd_cs46xx_gameport(cs46xx_t *chip)
 {
 }
 
-#endif /* !LINUX_2_2 */
+#endif /* CONFIG_GAMEPORT */
 
 /*
  *  proc interface
@@ -2843,7 +2797,7 @@
 	snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
 	
 	size = count;
-	if (file->f_pos + size > region->size)
+	if (file->f_pos + (size_t)size > region->size)
 		size = region->size - file->f_pos;
 	if (size > 0) {
 		char *tmp;
@@ -2876,19 +2830,13 @@
 	
 	for (idx = 0; idx < 5; idx++) {
 		snd_cs46xx_region_t *region = &chip->region.idx[idx];
-		entry = snd_info_create_card_entry(card, region->name, card->proc_root);
-		if (entry) {
+		if (! snd_card_proc_new(card, region->name, &entry)) {
 			entry->content = SNDRV_INFO_CONTENT_DATA;
 			entry->private_data = chip;
 			entry->c.ops = &snd_cs46xx_proc_io_ops;
 			entry->size = region->size;
 			entry->mode = S_IFREG | S_IRUSR;
-			if (snd_info_register(entry) < 0) {
-				snd_info_unregister(entry);
-				entry = NULL;
-			}
 		}
-		region->proc_entry = entry;
 	}
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	cs46xx_dsp_proc_init(card, chip);
@@ -2898,15 +2846,6 @@
 
 static int snd_cs46xx_proc_done(cs46xx_t *chip)
 {
-	int idx;
-
-	for (idx = 0; idx < 5; idx++) {
-		snd_cs46xx_region_t *region = &chip->region.idx[idx];
-		if (region->proc_entry) {
-			snd_info_unregister((snd_info_entry_t *) region->proc_entry);
-			region->proc_entry = NULL;
-		}
-	}
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	cs46xx_dsp_proc_done(chip);
 #endif
@@ -2972,7 +2911,7 @@
 	if (chip->active_ctrl)
 		chip->active_ctrl(chip, 1);
 
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (chip->gameport) {
 		gameport_unregister_port(&chip->gameport->info);
 		kfree(chip->gameport);
@@ -3553,9 +3492,6 @@
 {
 	snd_printdd ("initializing Voyetra mixer\n");
 
-	/* turnon Amplifier and leave it on */
-	chip->amplifier_ctrl(chip, 1);
-  
 	/* Enable SPDIF out */
 	snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
 	snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
@@ -3564,7 +3500,8 @@
 static void hercules_mixer_init (cs46xx_t *chip)
 {
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	int idx,err;
+	unsigned int idx;
+	int err;
 	snd_card_t *card = chip->card;
 #endif
 
@@ -3574,11 +3511,7 @@
 	snd_printdd ("initializing Hercules mixer\n");
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	/* turnon Amplifier and leave it on */
-	chip->amplifier_ctrl(chip, 1);
-
-	for (idx = 0 ; idx < sizeof(snd_hercules_controls) / 
-		     sizeof(snd_hercules_controls[0]) ; idx++) {
+	for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
 		snd_kcontrol_t *kctl;
 
 		kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
@@ -3692,21 +3625,88 @@
 };
 
 static struct cs_card_type __devinitdata cards[] = {
-	{0x1489, 0x7001, "Genius Soundmaker 128 value", NULL, amp_none, NULL, NULL},
-	{0x5053, 0x3357, "Voyetra", NULL, amp_voyetra, NULL, voyetra_mixer_init},
-	{0x1071, 0x6003, "Mitac MI6020/21", NULL, amp_voyetra, NULL, NULL},
-	{0x14AF, 0x0050, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
-	{0x1681, 0x0050, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
-	{0x1681, 0x0051, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
-	{0x1681, 0x0052, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
-	{0x1681, 0x0053, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
-	{0x1681, 0x0054, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init},
+	{
+		.vendor = 0x1489,
+		.id = 0x7001,
+		.name = "Genius Soundmaker 128 value",
+		/* nothing special */
+	},
+	{
+		.vendor = 0x5053,
+		.id = 0x3357,
+		.name = "Voyetra",
+		.amp = amp_voyetra,
+		.mixer_init = voyetra_mixer_init
+	},
+	{
+		.vendor = 0x1071,
+		.id = 0x6003,
+		.name = "Mitac MI6020/21",
+		.amp = amp_voyetra
+	},
+	{
+		.vendor = 0x14AF,
+		.id = 0x0050,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
+	{
+		.vendor = 0x1681,
+		.id = 0x0050,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
+	{
+		.vendor = 0x1681,
+		.id = 0x0051,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
+	{
+		.vendor = 0x1681,
+		.id = 0x0052,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
+	{
+		.vendor = 0x1681,
+		.id = 0x0053,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
+	{
+		.vendor = 0x1681,
+		.id = 0x0054,
+		.name = "Hercules Game Theatre XP",
+		.amp = amp_hercules,
+		.mixer_init = hercules_mixer_init
+	},
 	/* Not sure if the 570 needs the clkrun hack */
-	{PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", clkrun_init, NULL, clkrun_hack, NULL},
-	{PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", clkrun_init, NULL, clkrun_hack, NULL},
-	{PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL, NULL, NULL},
-	{0, 0, "Card without SSID set", NULL, NULL, NULL, NULL },
-	{0, 0, NULL, NULL, NULL, NULL, NULL}
+	{
+		.vendor = PCI_VENDOR_ID_IBM,
+		.id = 0x0132,
+		.name = "Thinkpad 570",
+		.init = clkrun_init,
+		.active = clkrun_hack
+	},
+	{
+		.vendor = PCI_VENDOR_ID_IBM,
+		.id = 0x0153,
+		.name = "Thinkpad 600X/A20/T20",
+		.init = clkrun_init,
+		.active = clkrun_hack
+	},
+	{
+		.vendor = PCI_VENDOR_ID_IBM,
+		.id = 0x1010,
+		.name = "Thinkpad 600E (unsupported)"
+	},
+	{} /* terminator */
 };
 
 
@@ -3716,18 +3716,23 @@
 #ifdef CONFIG_PM
 void snd_cs46xx_suspend(cs46xx_t *chip)
 {
+	int amp_saved;
+
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 	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);
+	amp_saved = chip->amplifier;
+	/* turn off amp */
+	chip->amplifier_ctrl(chip, -chip->amplifier);
 	snd_cs46xx_hw_stop(chip);
+	/* disable CLKRUN */
+	chip->active_ctrl(chip, -chip->amplifier);
+	chip->amplifier = amp_saved; /* restore the status */
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 void snd_cs46xx_resume(cs46xx_t *chip)
@@ -3735,9 +3740,8 @@
 	snd_card_t *card = chip->card;
 	int amp_saved;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	pci_enable_device(chip->pci);
 	amp_saved = chip->amplifier;
@@ -3760,14 +3764,11 @@
 	snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
 
 	if (amp_saved)
-		chip->amplifier_ctrl(chip, 1); /* try to turn on */
-	if (! amp_saved) {
-		chip->amplifier = 1;
-		chip->active_ctrl(chip, -1);
-	}
+		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);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static int snd_cs46xx_set_power_state(snd_card_t *card, unsigned int power_state)
@@ -3828,8 +3829,8 @@
 	chip->irq = -1;
 	chip->ba0_addr = pci_resource_start(pci, 0);
 	chip->ba1_addr = pci_resource_start(pci, 1);
-	if (chip->ba0_addr == 0 || chip->ba0_addr == ~0 ||
-	    chip->ba1_addr == 0 || chip->ba1_addr == ~0) {
+	if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
+	    chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
 	    	snd_cs46xx_free(chip);
 	    	snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
 	    	return -ENOMEM;
@@ -3867,11 +3868,11 @@
 	for (cp = &cards[0]; cp->name; cp++) {
 		if (cp->vendor == ss_vendor && cp->id == ss_card) {
 			snd_printd ("hack for %s enabled\n", cp->name);
-			if (cp->init)
-				cp->init(chip);
 			chip->amplifier_ctrl = cp->amp;
 			chip->active_ctrl = cp->active;
 			chip->mixer_init = cp->mixer_init;
+			if (cp->init)
+				cp->init(chip);
 			break;
 		}
 	}
@@ -3892,27 +3893,27 @@
 	if (chip->active_ctrl == NULL)
 		chip->active_ctrl = amp_none;
 
-	chip->active_ctrl(chip, 1);
+	chip->active_ctrl(chip, 1); /* enable CLKRUN */
 
 	pci_set_master(pci);
 
 	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_cs46xx_free(chip);
 			snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+			snd_cs46xx_free(chip);
 			return -EBUSY;
 		}
 		region->remap_addr = (unsigned long) ioremap_nocache(region->base, region->size);
 		if (region->remap_addr == 0) {
-			snd_cs46xx_free(chip);
 			snd_printk("%s ioremap problem\n", region->name);
+			snd_cs46xx_free(chip);
 			return -ENOMEM;
 		}
 	}
 	if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
-		snd_cs46xx_free(chip);
 		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_cs46xx_free(chip);
 		return -EBUSY;
 	}
 	chip->irq = pci->irq;
@@ -3943,7 +3944,7 @@
 		return err;
 	}
 	
-	chip->active_ctrl(chip, -1);
+	chip->active_ctrl(chip, -1); /* disable CLKRUN */
 
 	*rchip = chip;
 	return 0;
diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
--- a/sound/pci/cs46xx/dsp_spos.c	Mon Feb 10 10:39:31 2003
+++ b/sound/pci/cs46xx/dsp_spos.c	Mon Feb 10 10:39:31 2003
@@ -54,7 +54,7 @@
 
 static int shadow_and_reallocate_code (cs46xx_t * chip,u32 * data,u32 size, u32 overlay_begin_address)
 {
-	int i = 0,j, nreallocated = 0;
+	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;
@@ -569,7 +569,7 @@
 {
 	cs46xx_t *chip = snd_magic_cast(cs46xx_t, entry->private_data, return);
 	/*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */
-	int i,col = 0;
+	unsigned int i,col = 0;
 	unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 	symbol_entry_t * symbol; 
 
@@ -585,7 +585,7 @@
 		}
 
 		if (col == 0) {
-			snd_iprintf(buffer, "%04X ",i / sizeof(u32));
+			snd_iprintf(buffer, "%04X ", i / (unsigned int)sizeof(u32));
 		}
 
 		snd_iprintf(buffer,"%08X ",readl(dst + i));
diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c	Mon Feb 10 10:39:32 2003
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c	Mon Feb 10 10:39:32 2003
@@ -162,7 +162,7 @@
 
 static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count) 
 {
-	u32 dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
+	unsigned long dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
 	int i;
   
 	for (i = 0; i < dword_count ; ++i ) {
diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
--- a/sound/pci/emu10k1/Makefile	Mon Feb 10 10:39:25 2003
+++ b/sound/pci/emu10k1/Makefile	Mon Feb 10 10:39:25 2003
@@ -3,15 +3,19 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := emu10k1_main.o
-
 snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
 		    irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
 		    emuproc.o emumixer.o emufx.o
 snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
 
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
-ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
-  obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1-synth.o
-endif
+obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emu10k1-synth.o
diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
--- a/sound/pci/emu10k1/emu10k1.c	Mon Feb 10 10:39:22 2003
+++ b/sound/pci/emu10k1/emu10k1.c	Mon Feb 10 10:39:22 2003
@@ -80,6 +80,7 @@
 
 static struct pci_device_id snd_emu10k1_ids[] __devinitdata = {
 	{ 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* EMU10K1 */
+	{ 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* Dell OEM version (EMU10K1) */
 	{ 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },	/* Audigy */
 	{ 0, }
 };
@@ -181,7 +182,7 @@
 		strcpy(card->driver, "EMU10K1");
 		strcpy(card->shortname, "Sound Blaster Live!");
 	}
-	sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, emu->port, emu->irq);
+	sprintf(card->longname, "%s (rev.%d) at 0x%lx, irq %i", card->shortname, emu->revision, emu->port, emu->irq);
 
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c	Mon Feb 10 10:39:33 2003
+++ b/sound/pci/emu10k1/emu10k1_main.c	Mon Feb 10 10:39:33 2003
@@ -161,6 +161,26 @@
 			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
 			SPCS_GENERATIONSTATUS | 0x00001200 |
 			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+
+	if (emu->audigy && emu->revision == 4) { /* audigy2 */
+		/* Hacks for Alice3 to work independent of haP16V driver */
+		u32 tmp;
+
+		//Setup SRCMulti_I2S SamplingRate
+		tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
+		tmp &= 0xfffff1ff;
+		tmp |= (0x2<<9);
+		snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
+
+		/* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
+		outl(0x600000, emu->port + 0x20);
+		outl(0x14, emu->port + 0x24);
+
+		/* Setup SRCMulti Input Audio Enable */
+		outl(0x6E0000, emu->port + 0x20);
+		outl(0xFF00FF00, emu->port + 0x24);
+	}
+
 	/*
 	 *  Clear page with silence & setup all pointers to this page
 	 */
@@ -185,9 +205,15 @@
 	 *   Lock Sound Memory = 0
 	 *   Auto Mute = 1
 	 */
-	if (emu->audigy)
-		outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
-	else if (emu->model == 0x20 ||
+	if (emu->audigy) {
+		if (emu->revision == 4) /* audigy2 */
+			outl(HCFG_AUDIOENABLE |
+			     HCFG_AC3ENABLE_CDSPDIF |
+			     HCFG_AC3ENABLE_GPSPDIF |
+			     HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
+		else
+			outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
+	} else if (emu->model == 0x20 ||
 	    emu->model == 0xc400 ||
 	    (emu->model == 0x21 && emu->revision < 6))
 		outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
@@ -221,9 +247,17 @@
 	outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
 
 	/* Enable analog/digital outs on audigy */
-	if (emu->audigy)
+	if (emu->audigy) {
 		outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
-
+ 
+		if (emu->revision == 4) { /* audigy2 */
+			/* Unmute Analog now.  Set GPO6 to 1 for Apollo.
+			 * This has to be done after init ALice3 I2SOut beyond 48KHz.
+			 * So, sequence is important. */
+			outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
+		}
+	}
+	
 #if 0
 	{
 	unsigned int tmp;
@@ -494,7 +528,6 @@
 
 static int snd_emu10k1_free(emu10k1_t *emu)
 {
-	snd_emu10k1_proc_done(emu);
 	if (emu->res_port != NULL) {	/* avoid access to already used hardware */
 	       	snd_emu10k1_fx8010_tram_setup(emu, 0);
 		snd_emu10k1_done(emu);
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	Mon Feb 10 10:39:27 2003
+++ b/sound/pci/emu10k1/emufx.c	Mon Feb 10 10:39:27 2003
@@ -329,7 +329,7 @@
 	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
 	snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
 	unsigned long flags;
-	int i;
+	unsigned int i;
 	
 	spin_lock_irqsave(&emu->reg_lock, flags);
 	for (i = 0; i < ctl->vcount; i++)
@@ -344,7 +344,8 @@
 	snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
 	unsigned long flags;
 	unsigned int nval, val;
-	int i, j, change = 0;
+	unsigned int i, j;
+	int change = 0;
 	
 	spin_lock_irqsave(&emu->reg_lock, flags);
 	for (i = 0; i < ctl->vcount; i++) {
@@ -572,7 +573,7 @@
 {
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < pcm->channels; i++)
 		snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
@@ -585,7 +586,7 @@
 	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];
-	int i;
+	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);
 	pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0;
@@ -914,7 +915,7 @@
 
 static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
-	int i;
+	unsigned int i;
 	snd_ctl_elem_id_t *_id, id;
 	emu10k1_fx8010_control_gpr_t *_gctl, gctl;
 	
@@ -958,7 +959,7 @@
 
 static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
-	int i, j;
+	unsigned int i, j;
 	emu10k1_fx8010_control_gpr_t *_gctl, gctl;
 	snd_emu10k1_fx8010_ctl_t *ctl, nctl;
 	snd_kcontrol_new_t knew;
@@ -1020,7 +1021,7 @@
 
 static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
-	int i;
+	unsigned int i;
 	snd_ctl_elem_id_t *_id, id;
 	snd_emu10k1_fx8010_ctl_t *ctl;
 	
@@ -1036,7 +1037,7 @@
 
 static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
 {
-	int i = 0, j;
+	unsigned int i = 0, j;
 	unsigned int total = 0;
 	emu10k1_fx8010_control_gpr_t *_gctl, gctl;
 	snd_emu10k1_fx8010_ctl_t *ctl;
@@ -1123,7 +1124,8 @@
 
 static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
 {
-	int err = 0, i;
+	unsigned int i;
+	int err = 0;
 	snd_emu10k1_fx8010_pcm_t *pcm;
 
 	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
@@ -1167,7 +1169,8 @@
 
 static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
 {
-	int err = 0, i;
+	unsigned int i;
+	int err = 0;
 	snd_emu10k1_fx8010_pcm_t *pcm;
 
 	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/emu10k1/emupcm.c	Mon Feb 10 10:39:23 2003
@@ -359,13 +359,13 @@
 
 	if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
 		return err;
-	if ((err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params))) < 0)
+	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;
 		if (epcm->memblk != NULL)
 			snd_emu10k1_free_pages(emu, epcm->memblk);
-		memblk = snd_emu10k1_alloc_pages(emu, (struct snd_sg_buf *)substream->dma_private);
+		memblk = snd_emu10k1_alloc_pages(emu, substream);
 		if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) {
 			epcm->start_addr = 0;
 			return -ENOMEM;
@@ -401,7 +401,7 @@
 		epcm->memblk = NULL;
 		epcm->start_addr = 0;
 	}
-	snd_pcm_sgbuf_free(substream);
+	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
@@ -784,10 +784,6 @@
 	runtime->private_data = epcm;
 	runtime->private_free = snd_emu10k1_pcm_free_substream;
 	runtime->hw = snd_emu10k1_playback;
-	if ((err = snd_pcm_sgbuf_init(substream, emu->pci, 32)) < 0) {
-		snd_magic_kfree(epcm);
-		return err;
-	}
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
 		snd_magic_kfree(epcm);
 		return err;
@@ -814,7 +810,6 @@
 	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number];
 
 	mix->epcm = NULL;
-	snd_pcm_sgbuf_delete(substream);
 	snd_emu10k1_pcm_mixer_notify(emu->card, mix, 0);
 	return 0;
 }
@@ -953,8 +948,6 @@
 	.prepare =		snd_emu10k1_playback_prepare,
 	.trigger =		snd_emu10k1_playback_trigger,
 	.pointer =		snd_emu10k1_playback_pointer,
-	.copy =			snd_pcm_sgbuf_ops_copy_playback,
-	.silence =		snd_pcm_sgbuf_ops_silence,
 	.page =			snd_pcm_sgbuf_ops_page,
 };
 
@@ -999,9 +992,12 @@
 	strcpy(pcm->name, "EMU10K1");
 	emu->pcm = pcm;
 
+	for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
+		if ((err = snd_pcm_lib_preallocate_sg_pages(emu->pci, substream)) < 0)
+			return err;
+
 	for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
 		snd_pcm_lib_preallocate_pci_pages(emu->pci, substream, 64*1024, 64*1024);
-			return err;
 
 	if (rpcm)
 		*rpcm = pcm;
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/emu10k1/emuproc.c	Mon Feb 10 10:39:24 2003
@@ -239,111 +239,43 @@
 {
 	snd_info_entry_t *entry;
 	
-	if ((entry = snd_info_create_card_entry(emu->card, "emu10k1", emu->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 4096;
-		entry->c.text.read = snd_emu10k1_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	emu->proc_entry = entry;
-	entry = NULL;
-	if ((entry = snd_info_create_card_entry(emu->card, "fx8010_gpr", emu->card->proc_root)) != NULL) {
+	if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
+		snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read);
+
+	if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
 		entry->size = TOTAL_SIZE_GPR;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
 	}
-	emu->proc_entry_fx8010_gpr = entry;
-	entry = NULL;
-	if (!emu->audigy && (entry = snd_info_create_card_entry(emu->card, "fx8010_tram_data", emu->card->proc_root)) != NULL) {
+	if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
 		entry->size = TOTAL_SIZE_TANKMEM_DATA;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
 	}
-	emu->proc_entry_fx8010_tram_data = entry;
-	entry = NULL;
-	if (!emu->audigy && (entry = snd_info_create_card_entry(emu->card, "fx8010_tram_addr", emu->card->proc_root)) != NULL) {
+	if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
 		entry->size = TOTAL_SIZE_TANKMEM_ADDR;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
 	}
-	emu->proc_entry_fx8010_tram_addr = entry;
-	entry = NULL;
-	if ((entry = snd_info_create_card_entry(emu->card, "fx8010_code", emu->card->proc_root)) != NULL) {
+	if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
 		entry->size = TOTAL_SIZE_CODE;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
 	}
-	emu->proc_entry_fx8010_code = entry;
-	entry = NULL;
-	if ((entry = snd_info_create_card_entry(emu->card, "fx8010_acode", emu->card->proc_root)) != NULL) {
+	if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_TEXT;
 		entry->private_data = emu;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
 		entry->c.text.read_size = 64*1024;
 		entry->c.text.read = snd_emu10k1_proc_acode_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	emu->proc_entry_fx8010_iblocks = entry;
-	return 0;
-}
-
-int snd_emu10k1_proc_done(emu10k1_t * emu)
-{
-	if (emu->proc_entry) {
-		snd_info_unregister(emu->proc_entry);
-		emu->proc_entry = NULL;
-	}
-	if (emu->proc_entry_fx8010_gpr) {
-		snd_info_unregister(emu->proc_entry_fx8010_gpr);
-		emu->proc_entry_fx8010_gpr = NULL;
-	}
-	if (emu->proc_entry_fx8010_tram_data) {
-		snd_info_unregister(emu->proc_entry_fx8010_tram_data);
-		emu->proc_entry_fx8010_tram_data = NULL;
-	}
-	if (emu->proc_entry_fx8010_tram_addr) {
-		snd_info_unregister(emu->proc_entry_fx8010_tram_addr);
-		emu->proc_entry_fx8010_tram_addr = NULL;
-	}
-	if (emu->proc_entry_fx8010_code) {
-		snd_info_unregister(emu->proc_entry_fx8010_code);
-		emu->proc_entry_fx8010_code = NULL;
-	}
-	if (emu->proc_entry_fx8010_iblocks) {
-		snd_info_unregister(emu->proc_entry_fx8010_iblocks);
-		emu->proc_entry_fx8010_iblocks = NULL;
 	}
 	return 0;
 }
diff -Nru a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
--- a/sound/pci/emu10k1/memory.c	Mon Feb 10 10:39:32 2003
+++ b/sound/pci/emu10k1/memory.c	Mon Feb 10 10:39:32 2003
@@ -25,6 +25,7 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
+#include <sound/pcm_sgbuf.h>
 
 /* page arguments of these two macros are Emu page (4096 bytes), not like
  * aligned pages in others
@@ -288,8 +289,9 @@
  * page allocation for DMA
  */
 snd_util_memblk_t *
-snd_emu10k1_alloc_pages(emu10k1_t *emu, struct snd_sg_buf *sgbuf)
+snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream)
 {
+	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL);
 	snd_util_memhdr_t *hdr;
 	emu10k1_memblk_t *blk;
 	int page, err, idx;
@@ -306,7 +308,7 @@
 		return NULL;
 	}
 	/* fill buffer addresses but pointers are not stored so that
-	 * snd_free_pci_pages() is not called in in synth_free()
+	 * snd_free_pci_page() is not called in in synth_free()
 	 */
 	idx = 0;
 	for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
@@ -430,11 +432,11 @@
 	get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
 	/* allocate kernel pages */
 	for (page = first_page; page <= last_page; page++) {
-		ptr = snd_malloc_pci_pages(emu->pci, PAGE_SIZE, &addr);
+		ptr = snd_malloc_pci_page(emu->pci, &addr);
 		if (ptr == NULL)
 			goto __fail;
 		if (! is_valid_page(addr)) {
-			snd_free_pci_pages(emu->pci, PAGE_SIZE, ptr, addr);
+			snd_free_pci_page(emu->pci, ptr, addr);
 			goto __fail;
 		}
 		emu->page_addr_table[page] = addr;
@@ -446,7 +448,7 @@
 	/* release allocated pages */
 	last_page = page - 1;
 	for (page = first_page; page <= last_page; page++) {
-		snd_free_pci_pages(emu->pci, PAGE_SIZE, emu->page_ptr_table[page], emu->page_addr_table[page]);
+		snd_free_pci_page(emu->pci, emu->page_ptr_table[page], emu->page_addr_table[page]);
 		emu->page_addr_table[page] = 0;
 		emu->page_ptr_table[page] = NULL;
 	}
@@ -464,7 +466,7 @@
 	get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
 	for (page = first_page; page <= last_page; page++) {
 		if (emu->page_ptr_table[page])
-			snd_free_pci_pages(emu->pci, PAGE_SIZE, emu->page_ptr_table[page], emu->page_addr_table[page]);
+			snd_free_pci_page(emu->pci, emu->page_ptr_table[page], emu->page_addr_table[page]);
 		emu->page_addr_table[page] = 0;
 		emu->page_ptr_table[page] = NULL;
 	}
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	Mon Feb 10 10:39:31 2003
+++ b/sound/pci/ens1370.c	Mon Feb 10 10:39:31 2003
@@ -150,6 +150,9 @@
 #define ES_REG_STATUS	0x04	/* R/O: Interrupt/Chip select status register */
 #define   ES_INTR               (1<<31)		/* Interrupt is pending */
 #define   ES_1371_ST_AC97_RST	(1<<29)		/* CT5880 AC'97 Reset bit */
+#define   ES_1373_REAR_BIT27	(1<<27)		/* rear bits: 000 - front, 010 - mirror, 101 - separate */
+#define   ES_1373_REAR_BIT26	(1<<26)
+#define   ES_1373_REAR_BIT24	(1<<24)
 #define   ES_1373_GPIO_INT_EN(o)(((o)&0x0f)<<20)/* GPIO [3:0] pins - interrupt enable */
 #define   ES_1373_SPDIF_EN	(1<<18)		/* SPDIF enable */
 #define   ES_1373_SPDIF_TEST	(1<<17)		/* SPDIF test */
@@ -398,15 +401,15 @@
 	unsigned int spdif_default;
 	unsigned int spdif_stream;
 
-	snd_info_entry_t *proc_entry;
-
 #ifdef CHIP1370
 	unsigned char *bugbuf;
 	dma_addr_t bugbuf_addr;
 #endif
 
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	struct gameport gameport;
 	struct semaphore joy_sem;	// gameport configuration semaphore
+#endif
 };
 
 static void snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -1197,7 +1200,11 @@
 	if (err < 0)
 		return err;
 
+#ifdef CHIP1370
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
+#else
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
+#endif
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops);
 
 	pcm->private_data = ensoniq;
@@ -1239,8 +1246,11 @@
 	if (err < 0)
 		return err;
 
+#ifdef CHIP1370
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops);
-
+#else
+	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;
@@ -1262,9 +1272,10 @@
  *  Mixer section
  */
 
+/*
+ * ENS1371 mixer (including SPDIF interface)
+ */
 #ifdef CHIP1371
-
-
 static int snd_ens1373_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
@@ -1421,6 +1432,53 @@
 static snd_kcontrol_new_t snd_es1371_mixer_spdif __devinitdata =
 ES1371_SPDIF("IEC958 Playback Switch");
 
+static int snd_es1373_rear_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 snd_es1373_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ensoniq_t *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)
+	    	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)
+{
+	ensoniq_t *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);
+	spin_lock_irq(&ensoniq->reg_lock);
+	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));
+	spin_unlock_irq(&ensoniq->reg_lock);
+	return change;
+}
+
+static snd_kcontrol_new_t snd_ens1373_rear __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"AC97 2ch->4ch Copy Switch",
+	.info =		snd_es1373_rear_info,
+	.get =		snd_es1373_rear_get,
+	.put =		snd_es1373_rear_put,
+};
+
 static void snd_ensoniq_mixer_free_ac97(ac97_t *ac97)
 {
 	ensoniq_t *ensoniq = snd_magic_cast(ensoniq_t, ac97->private_data, return);
@@ -1431,7 +1489,7 @@
 	unsigned short vid;		/* vendor ID */
 	unsigned short did;		/* device ID */
 	unsigned char rev;		/* revision */
-} __devinitdata es1371_spdif_present[] = {
+} es1371_spdif_present[] __devinitdata = {
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
@@ -1483,11 +1541,19 @@
 			snd_ctl_add(card, kctl);
 			break;
 		}
+	if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
+		/* mirror rear to front speakers */
+		ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
+		ensoniq->cssr |= ES_1373_REAR_BIT26;
+		snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq));
+	}
 	return 0;
 }
 
 #endif /* CHIP1371 */
 
+/* generic control callbacks for ens1370 and for joystick */
+#if defined(CHIP1370) || defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 #define ENSONIQ_CONTROL(xname, mask) \
 { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
   .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
@@ -1515,7 +1581,6 @@
 }
 
 #ifdef CHIP1370
-
 static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
@@ -1533,14 +1598,21 @@
 	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 	return change;
 }
+#endif /* CHIP1370 */
+#endif /* CHIP1370 || GAMEPORT */
 
-#define ES1370_CONTROLS 2
+/*
+ * ENS1370 mixer
+ */
 
+#ifdef CHIP1370
 static snd_kcontrol_new_t 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)
 {
 	ensoniq_t *ensoniq = snd_magic_cast(ensoniq_t, ak4531->private_data, return);
@@ -1551,7 +1623,8 @@
 {
 	snd_card_t *card = ensoniq->card;
 	ak4531_t ak4531;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	/* try reset AK4531 */
 	outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
@@ -1576,6 +1649,7 @@
  *  General Switches...
  */
 
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 /* MQ: gameport driver connectivity */
 #define ENSONIQ_JOY_CONTROL(xname, mask) \
 { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \
@@ -1584,7 +1658,7 @@
 
 static int snd_ensoniq_joy_enable(ensoniq_t *ensoniq)
 {
-	static int last_jiffies = 0;
+	static unsigned long last_jiffies = 0;
 	unsigned long flags;
 
 	if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) {
@@ -1693,6 +1767,7 @@
 ES1371_JOYSTICK_ADDR("Joystick Address");
 
 #endif /* CHIP1371 */
+#endif /* CONFIG_GAMEPORT */
 
 /*
 
@@ -1721,26 +1796,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(ensoniq->card, "audiopci", ensoniq->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ensoniq;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_ensoniq_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ensoniq->proc_entry = entry;
-}
-
-static void snd_ensoniq_proc_done(ensoniq_t * ensoniq)
-{
-	if (ensoniq->proc_entry) {
-		snd_info_unregister(ensoniq->proc_entry);
-		ensoniq->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
+		snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read);
 }
 
 /*
@@ -1749,9 +1806,10 @@
 
 static int snd_ensoniq_free(ensoniq_t *ensoniq)
 {
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (ensoniq->ctrl & ES_JYSTK_EN)
 		snd_ensoniq_joy_disable(ensoniq);
-	snd_ensoniq_proc_done(ensoniq);
+#endif
 	if (ensoniq->irq < 0)
 		goto __hw_end;
 #ifdef CHIP1370
@@ -1831,7 +1889,6 @@
 	if (ensoniq == NULL)
 		return -ENOMEM;
 	spin_lock_init(&ensoniq->reg_lock);
-	init_MUTEX(&ensoniq->joy_sem);
 	ensoniq->card = card;
 	ensoniq->pci = pci;
 	ensoniq->irq = -1;
@@ -1946,11 +2003,14 @@
 	outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL));
 	outb(0x00, ES_REG(ensoniq, UART_RES));
 	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
+	init_MUTEX(&ensoniq->joy_sem);
 #ifdef CHIP1371
 	snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq));
 #endif
 	snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq));
 	ensoniq->gameport.io = 0x200;	// FIXME: is ES1371 configured like this above ?
+#endif
 	synchronize_irq(ensoniq->irq);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
diff -Nru a/sound/pci/es1938.c b/sound/pci/es1938.c
--- a/sound/pci/es1938.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/es1938.c	Mon Feb 10 10:39:29 2003
@@ -52,6 +52,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/gameport.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -59,9 +60,6 @@
 #include <sound/mpu401.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
-#ifndef LINUX_2_2
-#include <linux/gameport.h>
-#endif
 
 #include <asm/io.h>
 
@@ -204,8 +202,6 @@
 typedef struct _snd_es1938 es1938_t;
 
 struct _snd_es1938 {
-	unsigned long dma1size;
-	unsigned long dma2size;
 	int irq;
 
 	unsigned long io_port;
@@ -248,7 +244,7 @@
 	spinlock_t mixer_lock;
         snd_info_entry_t *proc_entry;
 
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	struct gameport gameport;
 #endif
 };
@@ -842,6 +838,25 @@
 	return 0;
 }
 
+/*
+ * buffer management
+ */
+static int snd_es1938_pcm_hw_params(snd_pcm_substream_t *substream,
+				    snd_pcm_hw_params_t * hw_params)
+
+{
+	int err;
+
+	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
+		return err;
+	return 0;
+}
+
+static int snd_es1938_pcm_hw_free(snd_pcm_substream_t *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
 /* ----------------------------------------------------------------------
  * Audio1 Capture (ADC)
  * ----------------------------------------------------------------------*/
@@ -892,8 +907,6 @@
 
 	if (chip->playback2_substream)
 		return -EAGAIN;
-	if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma2size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL)
-		return -ENOMEM;
 	chip->capture_substream = substream;
 	runtime->hw = snd_es1938_capture;
 	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
@@ -909,15 +922,11 @@
 
 	switch (substream->number) {
 	case 0:
-		if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma1size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL)
-			return -ENOMEM;
 		chip->playback1_substream = substream;
 		break;
 	case 1:
 		if (chip->capture_substream)
 			return -EAGAIN;
-		if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma1size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL)
-			return -ENOMEM;
 		chip->playback2_substream = substream;
 		break;
 	default:
@@ -965,6 +974,8 @@
 	.open =		snd_es1938_playback_open,
 	.close =	snd_es1938_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_es1938_pcm_hw_params,
+	.hw_free =	snd_es1938_pcm_hw_free,
 	.prepare =	snd_es1938_playback_prepare,
 	.trigger =	snd_es1938_playback_trigger,
 	.pointer =	snd_es1938_playback_pointer,
@@ -974,6 +985,8 @@
 	.open =		snd_es1938_capture_open,
 	.close =	snd_es1938_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_es1938_pcm_hw_params,
+	.hw_free =	snd_es1938_pcm_hw_free,
 	.prepare =	snd_es1938_capture_prepare,
 	.trigger =	snd_es1938_capture_trigger,
 	.pointer =	snd_es1938_capture_pointer,
@@ -1328,7 +1341,9 @@
 
 static int snd_es1938_free(es1938_t *chip)
 {
-#ifndef LINUX_2_2
+	/*if (chip->rmidi)
+	  snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);*/
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (chip->gameport.io)
 		gameport_unregister_port(&chip->gameport);
 #endif
@@ -1366,8 +1381,6 @@
 
 static int __devinit snd_es1938_create(snd_card_t * card,
 				    struct pci_dev * pci,
-				    unsigned long dma1size,
-				    unsigned long dma2size,
 				    es1938_t ** rchip)
 {
 	es1938_t *chip;
@@ -1395,8 +1408,6 @@
 	spin_lock_init(&chip->mixer_lock);
 	chip->card = card;
 	chip->pci = pci;
-	chip->dma1size = dma1size;
-	chip->dma2size = dma2size;
 	chip->io_port = pci_resource_start(pci, 0);
 	if ((chip->res_io_port = request_region(chip->io_port, 8, "ESS Solo-1")) == NULL) {
 		snd_es1938_free(chip);
@@ -1531,9 +1542,7 @@
 
 	/* MPU401 */
 	if (status & 0x80) {
-		/* ack */
-		snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
-		printk("midi interrupt..\n");
+		// snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
 		if (chip->rmidi)
 			snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
 	}
@@ -1545,7 +1554,8 @@
 {
 	snd_card_t *card;
 	es1938_t *chip;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	snd_assert(pcm != NULL && pcm->card != NULL, return -EINVAL);
 
@@ -1554,8 +1564,7 @@
 
 	strcpy(card->mixername, pcm->name);
 
-	for (idx = 0; idx < sizeof(snd_es1938_controls) / 
-		     sizeof(snd_es1938_controls[0]); idx++) {
+	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
 		snd_kcontrol_t *kctl;
 		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
 		switch (idx) {
@@ -1610,10 +1619,7 @@
 		    	return -ENODEV;
 		}
 	}
-	if ((err = snd_es1938_create(card, pci,
-				     64 * 1024,
-				     64 * 1024,
-				     &chip)) < 0) {
+	if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1644,8 +1650,10 @@
 	if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 				chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
 		printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
-	}
-#ifndef LINUX_2_2
+	} /*else
+	    snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);*/
+
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	chip->gameport.io = chip->game_port;
 	gameport_register_port(&chip->gameport);
 #endif
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/es1968.c	Mon Feb 10 10:39:29 2003
@@ -1414,7 +1414,7 @@
    * DMA memory management *
    *************************/
 
-/* Because the Maestro can only take adresses relative to the PCM base adress
+/* Because the Maestro can only take addresses relative to the PCM base adress
    register :( */
 
 static int calc_available_memory_size(es1968_t *chip)
@@ -2420,15 +2420,12 @@
 	if (! chip->do_pm)
 		return;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	snd_pcm_suspend_all(chip->pcm);
 	snd_es1968_bob_stop(chip);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void es1968_resume(es1968_t *chip)
@@ -2438,9 +2435,8 @@
 	if (! chip->do_pm)
 		return;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	/* restore all our config */
 	pci_enable_device(chip->pci);
@@ -2459,8 +2455,6 @@
 	if (atomic_read(&chip->bobclient))
 		snd_es1968_bob_start(chip);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 #ifndef PCI_OLD_SUSPEND
@@ -2674,7 +2668,7 @@
 	val = oval & ~0x04;
 	if (ucontrol->value.integer.value[0])
 		val |= 0x04;
-	if (val != oval); {
+	if (val != oval) {
 		pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val);
 		return 1;
 	}
@@ -2701,7 +2695,8 @@
 	static int dev;
 	snd_card_t *card;
 	es1968_t *chip;
-	int i, err;
+	unsigned int i;
+	int err;
 
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
diff -Nru a/sound/pci/fm801.c b/sound/pci/fm801.c
--- a/sound/pci/fm801.c	Mon Feb 10 10:39:30 2003
+++ b/sound/pci/fm801.c	Mon Feb 10 10:39:30 2003
@@ -130,7 +130,7 @@
 	struct resource *res_port;
 	unsigned int multichannel: 1,	/* multichannel support */
 		     secondary: 1;	/* secondary codec */
-	unsigned char secondary_addr;	/* addres of the secondary codec */
+	unsigned char secondary_addr;	/* address of the secondary codec */
 
 	unsigned short ply_ctrl; /* playback control */
 	unsigned short cap_ctrl; /* capture control */
@@ -293,7 +293,7 @@
  *  Sample rate routines
  */
 
-static unsigned short snd_fm801_rate_bits(int rate)
+static unsigned short snd_fm801_rate_bits(unsigned int rate)
 {
 	unsigned int idx;
 
@@ -312,48 +312,66 @@
 				      int cmd)
 {
 	fm801_t *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:
 		chip->ply_ctrl &= ~(FM801_BUF1_LAST |
 				     FM801_BUF2_LAST |
 				     FM801_PAUSE);
 		chip->ply_ctrl |= FM801_START |
 				   FM801_IMMED_STOP;
-		outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		chip->ply_ctrl &= ~FM801_START;
-		outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
-	} else {
-		result = -EINVAL;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE);
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		chip->ply_ctrl |= FM801_PAUSE;
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		chip->ply_ctrl &= ~FM801_PAUSE;
+		break;
+	default:
+		spin_unlock(&chip->reg_lock);
+		snd_BUG();
+		return -EINVAL;
 	}
+	outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL));
 	spin_unlock(&chip->reg_lock);
-	return result;
+	return 0;
 }
 
 static int snd_fm801_capture_trigger(snd_pcm_substream_t * substream,
 				     int cmd)
 {
 	fm801_t *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:
 		chip->cap_ctrl &= ~(FM801_BUF1_LAST |
 				     FM801_BUF2_LAST |
 				     FM801_PAUSE);
 		chip->cap_ctrl |= FM801_START |
 				   FM801_IMMED_STOP;
-		outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		chip->cap_ctrl &= ~FM801_START;
-		outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
-	} else {
-		result = -EINVAL;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE);
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		chip->cap_ctrl |= FM801_PAUSE;
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		chip->cap_ctrl &= ~FM801_PAUSE;
+		break;
+	default:
+		spin_unlock(&chip->reg_lock);
+		snd_BUG();
+		return -EINVAL;
 	}
+	outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL));
 	spin_unlock(&chip->reg_lock);
-	return result;
+	return 0;
 }
 
 static int snd_fm801_hw_params(snd_pcm_substream_t * substream,
@@ -470,8 +488,11 @@
 	unsigned int tmp;
 
 	status = inw(FM801_REG(chip, IRQ_STATUS));
-	if ((status & (FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME)) == 0)
+	status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME;
+	if (! status)
 		return;
+	/* ack first */
+	outw(status, FM801_REG(chip, IRQ_STATUS));
 	if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) {
 		spin_lock(&chip->reg_lock);
 		chip->ply_buf++;
@@ -483,7 +504,6 @@
 				(chip->ply_buf & 1) ?
 					FM801_REG(chip, PLY_BUF1) :
 					FM801_REG(chip, PLY_BUF2));
-		outw(FM801_IRQ_PLAYBACK, FM801_REG(chip, IRQ_STATUS));
 		spin_unlock(&chip->reg_lock);
 		snd_pcm_period_elapsed(chip->playback_substream);
 	}
@@ -498,24 +518,20 @@
 				(chip->cap_buf & 1) ?
 					FM801_REG(chip, CAP_BUF1) :
 					FM801_REG(chip, CAP_BUF2));
-		outw(FM801_IRQ_CAPTURE, FM801_REG(chip, IRQ_STATUS));
 		spin_unlock(&chip->reg_lock);
 		snd_pcm_period_elapsed(chip->capture_substream);
 	}
-	if ((status & FM801_IRQ_MPU) && chip->rmidi != NULL) {
+	if (chip->rmidi && (status & FM801_IRQ_MPU))
 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-		outw(FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
-	}
-	if (status & FM801_IRQ_VOLUME) {
-		/* TODO */
-		outw(FM801_IRQ_VOLUME, FM801_REG(chip, IRQ_STATUS));
-	}
+	if (status & FM801_IRQ_VOLUME)
+		;/* TODO */
 }
 
 static snd_pcm_hardware_t snd_fm801_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_PAUSE |
 				 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,
@@ -535,6 +551,7 @@
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_PAUSE |
 				 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,
@@ -822,6 +839,7 @@
 FM801_SINGLE("IEC958 Capture Switch", FM801_I2S_MODE, 8, 1, 0),
 FM801_SINGLE("IEC958 Raw Data Playback Switch", FM801_I2S_MODE, 9, 1, 0),
 FM801_SINGLE("IEC958 Raw Data Capture Switch", FM801_I2S_MODE, 10, 1, 0),
+FM801_SINGLE("IEC958 Playback Switch", FM801_GEN_CTRL, 2, 1, 0),
 };
 
 static void snd_fm801_mixer_free_ac97(ac97_t *ac97)
@@ -837,7 +855,8 @@
 static int __devinit snd_fm801_mixer(fm801_t *chip)
 {
 	ac97_t ac97;
-	int err, i;
+	unsigned int i;
+	int err;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.write = snd_fm801_codec_write;
diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
--- a/sound/pci/ice1712/Makefile	Mon Feb 10 10:39:25 2003
+++ b/sound/pci/ice1712/Makefile	Mon Feb 10 10:39:25 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := ice1712.o
-
 snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o amp.o
 
 # Toplevel Module Dependency
diff -Nru a/sound/pci/ice1712/ak4524.c b/sound/pci/ice1712/ak4524.c
--- a/sound/pci/ice1712/ak4524.c	Mon Feb 10 10:39:28 2003
+++ b/sound/pci/ice1712/ak4524.c	Mon Feb 10 10:39:28 2003
@@ -112,7 +112,7 @@
 
 void snd_ice1712_ak4524_reset(ice1712_t *ice, int state)
 {
-	int chip;
+	unsigned int chip;
 	unsigned char reg;
 	ak4524_t *ak = &ice->ak4524;
 	
@@ -341,7 +341,8 @@
 
 int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice)
 {
-	int err, idx;
+	unsigned int idx;
+	int err;
 	ak4524_t *ak = &ice->ak4524;
 
 	for (idx = 0; idx < ak->num_dacs; ++idx) {
diff -Nru a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
--- a/sound/pci/ice1712/amp.c	Mon Feb 10 10:39:27 2003
+++ b/sound/pci/ice1712/amp.c	Mon Feb 10 10:39:27 2003
@@ -42,6 +42,13 @@
 	return 0;
 }
 
+static int __devinit snd_vt1724_amp_add_controls(ice1712_t *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);
+	return 0;
+}
+
 
 /* entry point */
 struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
@@ -49,6 +56,7 @@
 		VT1724_SUBDEVICE_AUDIO2000,
 		"AMP Ltd AUDIO2000",
 		snd_vt1724_amp_init,
+		snd_vt1724_amp_add_controls,
 	},
 	{ } /* terminator */
 };
diff -Nru a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
--- a/sound/pci/ice1712/ews.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/ice1712/ews.c	Mon Feb 10 10:39:24 2003
@@ -851,7 +851,8 @@
 
 static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice)
 {
-	int err, idx;
+	unsigned int idx;
+	int err;
 	snd_kcontrol_t *kctl;
 	
 	/* all terratec cards have spdif */
@@ -873,7 +874,7 @@
 	/* card specific controls */
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_EWX2496:
-		for (idx = 0; idx < sizeof(snd_ice1712_ewx2496_controls)/sizeof(snd_ice1712_ewx2496_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) {
 			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice));
 			if (err < 0)
 				return err;
@@ -892,14 +893,14 @@
 			return err;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		for (idx = 0; idx < sizeof(snd_ice1712_ews88d_controls)/sizeof(snd_ice1712_ews88d_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) {
 			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
 			if (err < 0)
 				return err;
 		}
 		break;
 	case ICE1712_SUBDEVICE_DMX6FIRE:
-		for (idx = 0; idx < sizeof(snd_ice1712_6fire_controls)/sizeof(snd_ice1712_6fire_controls[0]); idx++) {
+		for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) {
 			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
 			if (err < 0)
 				return err;
diff -Nru a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
--- a/sound/pci/ice1712/ice1712.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/ice1712/ice1712.c	Mon Feb 10 10:39:24 2003
@@ -107,9 +107,13 @@
 #define PCI_DEVICE_ID_VT1724		0x1724
 #endif
 
+enum {
+	TYPE_ICE1712, TYPE_VT1724
+};
+
 static struct pci_device_id snd_ice1712_ids[] __devinitdata = {
-	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ICE1712 */
-	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	   /* VT1724 */
+	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_ICE1712 },   /* ICE1712 */
+	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VT1724 },	   /* VT1724 */
 	{ 0, }
 };
 
@@ -1681,12 +1685,11 @@
 			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));
-
-	}
-	else {
+	} else {
 		snd_iprintf(buffer, "  PSDOUT03         : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
 		snd_iprintf(buffer, "  CAPTURE          : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
 		snd_iprintf(buffer, "  SPDOUT           : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
+		snd_iprintf(buffer, "  RATE             : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
 	}
 }
 
@@ -1694,26 +1697,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(ice->card, "ice1712", ice->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ice;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 2048;
-		entry->c.text.read = snd_ice1712_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ice->proc_entry = entry;
-}
-
-static void snd_ice1712_proc_done(ice1712_t * ice)
-{
-	if (ice->proc_entry) {
-		snd_info_unregister(ice->proc_entry);
-		ice->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(ice->card, "ice1712", &entry))
+		snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read);
 }
 
 /*
@@ -2689,7 +2674,6 @@
 	outb(0xff, ICEREG(ice, IRQMASK));
 	/* --- */
       __hw_end:
-	snd_ice1712_proc_done(ice);
 	if (ice->irq >= 0) {
 		synchronize_irq(ice->irq);
 		free_irq(ice->irq, (void *) ice);
@@ -2721,9 +2705,10 @@
 }
 
 static int __devinit snd_ice1712_create(snd_card_t * card,
-				     struct pci_dev *pci,
-				     int omni,
-				     ice1712_t ** r_ice1712)
+					struct pci_dev *pci,
+					int vt1724,
+					int omni,
+					ice1712_t ** r_ice1712)
 {
 	ice1712_t *ice;
 	int err;
@@ -2737,7 +2722,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 	/* VT1724 does not have 28bit DMA transfer limit */
-	if (pci->device==PCI_DEVICE_ID_ICE_1712) {
+	if (! vt1724) {
 		/* check, if we can restrict PCI DMA transfers to 28 bits */
 		if (!pci_dma_supported(pci, 0x0fffffff)) {
 			snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
@@ -2745,13 +2730,13 @@
 		}
 		pci_set_dma_mask(pci, 0x0fffffff);
 	}
-	else pci_set_dma_mask(pci, 0xffffffff); 
+	else
+		pci_set_dma_mask(pci, 0xffffffff); 
 
 	ice = snd_magic_kcalloc(ice1712_t, 0, GFP_KERNEL);
 	if (ice == NULL)
 		return -ENOMEM;
-	if (pci->device==PCI_DEVICE_ID_VT1724)
-		ice->vt1724=1;
+	ice->vt1724 = vt1724 ? 1 : 0;
 	ice->omni = omni ? 1 : 0;
 	spin_lock_init(&ice->reg_lock);
 	init_MUTEX(&ice->gpio_mutex);
@@ -2893,6 +2878,7 @@
 	snd_card_t *card;
 	ice1712_t *ice;
 	int pcm_dev = 0, err;
+	int chip_type;
 	struct snd_ice1712_card_info **tbl, *c;
 
 	if (dev >= SNDRV_CARDS)
@@ -2906,7 +2892,8 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	if (pci->device==PCI_DEVICE_ID_ICE_1712) {
+	chip_type = pci_id->driver_data;
+	if (chip_type == TYPE_ICE1712) {
 		strcpy(card->driver, "ICE1712");
 		strcpy(card->shortname, "ICEnsemble ICE1712");
 	} else {
@@ -2914,7 +2901,7 @@
 		strcpy(card->shortname, "ICEnsemble ICE1724");
 	}
 	
-	if ((err = snd_ice1712_create(card, pci, omni[dev], &ice)) < 0) {
+	if ((err = snd_ice1712_create(card, pci, chip_type, omni[dev], &ice)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
diff -Nru a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
--- a/sound/pci/ice1712/ice1712.h	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/ice1712/ice1712.h	Mon Feb 10 10:39:23 2003
@@ -237,8 +237,8 @@
 } ice1712_eeprom_t;
 
 struct snd_ak4524 {
-	int num_adcs;			/* AK4524 or AK4528 ADCs */
-	int num_dacs;			/* AK4524 or AK4528 DACs */
+	unsigned int num_adcs;		/* AK4524 or AK4528 ADCs */
+	unsigned int num_dacs;		/* AK4524 or AK4528 DACs */
 	unsigned char images[4][16];
 	unsigned char ipga_gain[4][2];
 	/* */
@@ -323,7 +323,7 @@
 
 	unsigned int pro_volumes[20];
 	int omni: 1;			/* Delta Omni I/O */
-	int num_total_dacs;		/* total DACs */
+	unsigned int num_total_dacs;	/* total DACs */
 	unsigned char hoontech_boxbits[4];
 	unsigned int hoontech_config;
 	unsigned short hoontech_boxconfig[4];
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/intel8x0.c	Mon Feb 10 10:39:29 2003
@@ -131,6 +131,9 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO	0x006a
 #endif
+#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
+#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO	0x00da
+#endif
 
 enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI };
 
@@ -319,7 +322,6 @@
 	unsigned char piv_saved;
 	unsigned short picb_saved;
 #endif
-	snd_info_entry_t *proc_entry;
 } ichdev_t;
 
 typedef struct _snd_intel8x0 intel8x0_t;
@@ -365,7 +367,6 @@
 
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
-	snd_info_entry_t *proc_entry;
 	
 	u32 bdbars_count;
 	u32 *bdbars;
@@ -388,6 +389,7 @@
 	{ 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS },	/* SI7012 */
 	{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* NFORCE */
 	{ 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* NFORCE2 */
+	{ 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* NFORCE3 */
 	{ 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* AMD8111 */
 	{ 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* AMD768 */
 	{ 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
@@ -709,7 +711,7 @@
 	intel8x0_t *chip = snd_magic_cast(intel8x0_t, dev_id, return);
 	ichdev_t *ichdev;
 	unsigned int status;
-	int i;
+	unsigned int i;
 
 	spin_lock(&chip->reg_lock);
 	status = igetdword(chip, chip->int_sta_reg);
@@ -1276,6 +1278,9 @@
 	sprintf(pcm->name, "%s - MIC ADC", chip->card->shortname);
 
 	chip->pcm_mic = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1310,6 +1315,9 @@
 	sprintf(pcm->name, "%s - MIC2 ADC", chip->card->shortname);
 
 	chip->pcm_mic2 = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1344,6 +1352,9 @@
 	sprintf(pcm->name, "%s - ADC2", chip->card->shortname);
 
 	chip->pcm2 = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1378,6 +1389,9 @@
 	sprintf(pcm->name, "%s - IEC958", chip->card->shortname);
 
 	chip->pcm_spdif = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1413,6 +1427,9 @@
 	sprintf(pcm->name, "%s - IEC958", chip->card->shortname);
 
 	chip->pcm_spdif = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1447,6 +1464,9 @@
 	sprintf(pcm->name, "%s - AC97 IEC958", chip->card->shortname);
 
 	chip->pcm_ac97spdif = pcm;	
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1788,6 +1808,10 @@
 	} while (time_after_eq(end_time, jiffies));
 
       __ok3:      
+	if (chip->device_type == DEVICE_SIS) {
+		/* unmute the output on SIS7012 */
+		iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
+	}
       	return 0;
 }
 
@@ -1827,7 +1851,8 @@
 
 static int snd_intel8x0_chip_init(intel8x0_t *chip)
 {
-	int i, err;
+	unsigned int i;
+	int err;
 	
 	if (chip->device_type != DEVICE_ALI)
 		err = snd_intel8x0_ich_chip_init(chip);
@@ -1850,11 +1875,9 @@
 	return 0;
 }
 
-static void snd_intel8x0_proc_done(intel8x0_t * chip);
-
 static int snd_intel8x0_free(intel8x0_t *chip)
 {
-	int i;
+	unsigned int i;
 
 	if (chip->irq < 0)
 		goto __hw_end;
@@ -1867,7 +1890,6 @@
 	/* --- */
 	synchronize_irq(chip->irq);
       __hw_end:
-	snd_intel8x0_proc_done(chip);
 	if (chip->bdbars)
 		snd_free_pci_pages(chip->pci, chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, chip->bdbars, chip->bdbars_addr);
 	if (chip->remap_addr)
@@ -1896,17 +1918,15 @@
 {
 	snd_card_t *card = chip->card;
 
-	chip->in_suspend = 1;
-	snd_power_lock(card);
-	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+	if (chip->in_suspend ||
+	    card->power_state == SNDRV_CTL_POWER_D3hot)
+		return;
 
+	chip->in_suspend = 1;
 	snd_pcm_suspend_all(chip->pcm);
 	if (chip->pcm_mic)
 		snd_pcm_suspend_all(chip->pcm_mic);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void intel8x0_resume(intel8x0_t *chip)
@@ -1914,9 +1934,9 @@
 	snd_card_t *card = chip->card;
 	int i;
 
-	snd_power_lock(card);
-	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+	if (! chip->in_suspend ||
+	    card->power_state == SNDRV_CTL_POWER_D0)
+		return;
 
 	pci_enable_device(chip->pci);
 	snd_intel8x0_chip_init(chip);
@@ -1926,8 +1946,6 @@
 
 	chip->in_suspend = 0;
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 #ifndef PCI_OLD_SUSPEND
@@ -2096,26 +2114,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(chip->card, "intel8x0", chip->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = chip;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 2048;
-		entry->c.text.read = snd_intel8x0_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	chip->proc_entry = entry;
-}
-
-static void snd_intel8x0_proc_done(intel8x0_t * chip)
-{
-	if (chip->proc_entry) {
-		snd_info_unregister(chip->proc_entry);
-		chip->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
+		snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read);
 }
 
 static int snd_intel8x0_dev_free(snd_device_t *device)
@@ -2130,7 +2130,8 @@
 					 intel8x0_t ** r_intel8x0)
 {
 	intel8x0_t *chip;
-	int err, i;
+	int err;
+	unsigned int i;
 	unsigned int int_sta_masks;
 	ichdev_t *ichdev;
 	static snd_device_ops_t ops = {
@@ -2247,7 +2248,7 @@
 	chip->bdbars_count = 3;
 	if (device_type == DEVICE_INTEL_ICH4 || device_type == DEVICE_ALI)
 		chip->bdbars_count = 6;
-	chip->bdbars = (u32 *)snd_malloc_pci_pages(pci, chip->bdbars_count * sizeof(unsigned int) * ICH_MAX_FRAGS * 2, &chip->bdbars_addr);
+	chip->bdbars = (u32 *)snd_malloc_pci_pages(pci, chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, &chip->bdbars_addr);
 	if (chip->bdbars == NULL) {
 		snd_intel8x0_free(chip);
 		return -ENOMEM;
@@ -2304,6 +2305,7 @@
 	{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia NForce2" },
+	{ PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia NForce3" },
 	{ 0x746d, "AMD AMD8111" },
 	{ 0x7445, "AMD AMD768" },
 	{ 0x5455, "ALi M5455" },
@@ -2488,6 +2490,8 @@
 	// { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* 440MX */
 	// { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* SI7012 */
 	{ 0x10de, 0x01b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE */
+	{ 0x10de, 0x006b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE2 */
+	{ 0x10de, 0x00db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE3 */
 	{ 0, }
 };
 
@@ -2496,6 +2500,8 @@
 	.id_table = snd_intel8x0_joystick_ids,
 	.probe = snd_intel8x0_joystick_probe,
 };
+
+static int have_joystick;
 #endif
 
 static int __init alsa_card_intel8x0_init(void)
@@ -2509,7 +2515,13 @@
                 return err;
         }
 #if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
-	pci_module_init(&joystick_driver);
+	if (pci_module_init(&joystick_driver) < 0) {
+		snd_printdd(KERN_INFO "no joystick found\n");
+		have_joystick = 0;
+	} else {
+		snd_printdd(KERN_INFO "joystick(s) found\n");
+		have_joystick = 1;
+	}
 #endif
         return 0;
 
@@ -2519,7 +2531,8 @@
 {
 	pci_unregister_driver(&driver);
 #if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
-	pci_unregister_driver(&joystick_driver);
+	if (have_joystick)
+		pci_unregister_driver(&joystick_driver);
 #endif
 }
 
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/korg1212/korg1212.c	Mon Feb 10 10:39:23 2003
@@ -368,7 +368,6 @@
 
         snd_pcm_substream_t *playback_substream;
         snd_pcm_substream_t *capture_substream;
-        snd_info_entry_t * proc_entry;
 
  	CardState cardState;
         int running;
@@ -1704,13 +1703,13 @@
 
 	i = kcontrol->private_value;
 
-	if (u->value.enumerated.item[0] != korg1212->sharedBufferPtr->volumeData[i]) {
+	if (u->value.enumerated.item[0] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i]) {
 		korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
 		change = 1;
 	}
 
 	if (i >= 8) {
-		if (u->value.enumerated.item[1] != korg1212->sharedBufferPtr->volumeData[i+1]) {
+		if (u->value.enumerated.item[1] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i+1]) {
 			korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
 			change = 1;
 		}
@@ -1898,33 +1897,15 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(korg1212->card, "korg1212", korg1212->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = korg1212;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_korg1212_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	korg1212->proc_entry = entry;
-}
-
-static void snd_korg1212_proc_done(korg1212_t * korg1212)
-{
-	if (korg1212->proc_entry) {
-		snd_info_unregister(korg1212->proc_entry);
-		korg1212->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
+		snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read);
 }
 
 static int __devinit snd_korg1212_create(korg1212_t *korg1212)
 {
         struct pci_dev *pci = korg1212->pci;
         int err;
-        int i;
+        unsigned int i;
 	unsigned ioport_size, iomem_size, iomem2_size;
 	dma_addr_t phys_addr;
 
@@ -2173,8 +2154,6 @@
         if (korg1212 == NULL) {
                 return;
         }
-
-        snd_korg1212_proc_done(korg1212);
 
         snd_korg1212_TurnOffIdleMonitor(korg1212);
 
diff -Nru a/sound/pci/maestro3.c b/sound/pci/maestro3.c
--- a/sound/pci/maestro3.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/maestro3.c	Mon Feb 10 10:39:29 2003
@@ -1328,7 +1328,7 @@
 static void
 snd_m3_playback_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
 {
-	int i;
+	unsigned int i;
 
 	/*
 	 * some per client initializers
@@ -1355,7 +1355,7 @@
 	/*
 	 * set an armload of static initializers
 	 */
-	for (i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) 
+	for (i = 0; i < ARRAY_SIZE(pv); i++) 
 		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
 				  s->inst.data + pv[i].addr, pv[i].val);
 }
@@ -1394,7 +1394,7 @@
 static void
 snd_m3_capture_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
 {
-	int i;
+	unsigned int i;
 
 	/*
 	 * some per client initializers
@@ -1413,7 +1413,7 @@
 	/*
 	 * set an armload of static initializers
 	 */
-	for (i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) 
+	for (i = 0; i < ARRAY_SIZE(rv); i++) 
 		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
 				  s->inst.data + rv[i].addr, rv[i].val);
 }
@@ -2121,7 +2121,7 @@
 
 static void snd_m3_assp_init(m3_t *chip)
 {
-	int i;
+	unsigned int i;
 
 	/* zero kernel data */
 	for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
@@ -2377,9 +2377,8 @@
 	snd_card_t *card = chip->card;
 	int i, index;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	snd_pcm_suspend_all(chip->pcm);
 
@@ -2400,8 +2399,6 @@
 	snd_m3_outw(chip, 0xffff, 0x54);
 	snd_m3_outw(chip, 0xffff, 0x56);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void m3_resume(m3_t *chip)
@@ -2409,9 +2406,8 @@
 	snd_card_t *card = chip->card;
 	int i, index;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	/* first lets just bring everything back. .*/
 	snd_m3_outw(chip, 0, 0x54);
@@ -2442,8 +2438,6 @@
 	snd_m3_amp_enable(chip, 1);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 #ifndef PCI_OLD_SUSPEND
diff -Nru a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
--- a/sound/pci/nm256/nm256.c	Mon Feb 10 10:39:31 2003
+++ b/sound/pci/nm256/nm256.c	Mon Feb 10 10:39:31 2003
@@ -405,7 +405,7 @@
 
 
 /* The actual rates supported by the card. */
-static int samplerates[8] = {
+static unsigned int samplerates[8] = {
 	8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
 };
 #define NUM_SAMPLERATES (sizeof(samplerates) / sizeof(samplerates[0]))
@@ -419,9 +419,9 @@
  * return the index of the target rate
  */
 static int
-snd_nm256_fixed_rate(int rate)
+snd_nm256_fixed_rate(unsigned int rate)
 {
-	int i;
+	unsigned int i;
 	for (i = 0; i < NUM_SAMPLERATES; i++) {
 		if (rate == samplerates[i])
 			return i;
@@ -1270,24 +1270,20 @@
 {
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	snd_pcm_suspend_all(chip->pcm);
 	chip->coeffs_current = 0;
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void nm256_resume(nm256_t *chip)
 {
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	/* Perform a full reset on the hardware */
 	pci_enable_device(chip->pci);
@@ -1297,8 +1293,6 @@
 	snd_ac97_resume(chip->ac97);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 #ifndef PCI_OLD_SUSPEND
@@ -1539,7 +1533,7 @@
 	if ((err = snd_nm256_pcm(chip, 0)) < 0)
 		goto __error;
 	
-	if ((err = snd_nm256_mixer(chip) < 0))
+	if ((err = snd_nm256_mixer(chip)) < 0)
 		goto __error;
 
 	// pci_set_master(pci); /* needed? */
diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c	Mon Feb 10 10:39:33 2003
+++ b/sound/pci/rme32.c	Mon Feb 10 10:39:33 2003
@@ -1,7 +1,7 @@
 /*
  *   ALSA driver for RME Digi32, Digi32/8 and Digi32 PRO audio interfaces
  *
- *	Copyright (c) 2002 Martin Langer <martin-langer@gmx.de>
+ *	Copyright (c) 2002, 2003 Martin Langer <martin-langer@gmx.de>
  *
  *      Thanks to :        Anders Torger <torger@ludd.luth.se>,
  *                         Henk Hesselink <henk@anda.nl>
@@ -220,7 +220,6 @@
 	snd_pcm_t *spdif_pcm;
 	snd_pcm_t *adat_pcm;
 	struct pci_dev *pci;
-	snd_info_entry_t *proc_entry;
 	snd_kcontrol_t *spdif_ctl;
 } rme32_t;
 
@@ -257,8 +256,6 @@
 
 static void snd_rme32_proc_init(rme32_t * rme32);
 
-static void snd_rme32_proc_done(rme32_t * rme32);
-
 static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32);
 
 static inline unsigned int snd_rme32_playback_ptr(rme32_t * rme32)
@@ -274,6 +271,19 @@
 		& RME32_RCR_AUDIO_ADDR_MASK) >> rme32->capture_frlog;
 }
 
+static int snd_rme32_ratecode(int rate)
+{
+	switch (rate) {
+	case 32000: return SNDRV_PCM_RATE_32000;
+	case 44100: return SNDRV_PCM_RATE_44100;
+	case 48000: return SNDRV_PCM_RATE_48000;
+	case 64000: return SNDRV_PCM_RATE_64000;
+	case 88200: return SNDRV_PCM_RATE_88200;
+	case 96000: return SNDRV_PCM_RATE_96000;
+	}
+	return 0;
+}
+
 static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int channel,	/* not used (interleaved data) */
 				      snd_pcm_uframes_t pos,
 				      snd_pcm_uframes_t count)
@@ -561,18 +571,22 @@
 {
 	switch (mode) {
 	case RME32_CLOCKMODE_SLAVE:
+		/* AutoSync */
 		rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) & 
 			~RME32_WCR_FREQ_1;
 		break;
 	case RME32_CLOCKMODE_MASTER_32:
+		/* Internal 32.0kHz */
 		rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) & 
 			~RME32_WCR_FREQ_1;
 		break;
 	case RME32_CLOCKMODE_MASTER_44:
+		/* Internal 44.1kHz */
 		rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) | 
 			RME32_WCR_FREQ_1;
 		break;
 	case RME32_CLOCKMODE_MASTER_48:
+		/* Internal 48.0kHz */
 		rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) | 
 			RME32_WCR_FREQ_1;
 		break;
@@ -661,14 +675,21 @@
 snd_rme32_playback_hw_params(snd_pcm_substream_t * substream,
 			     snd_pcm_hw_params_t * params)
 {
+	int err, rate, dummy;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-	int err;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream,
 				      params_buffer_bytes(params))) < 0)
 		return err;
 	spin_lock_irq(&rme32->lock);
-	if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
+	if ((rme32->rcreg & RME32_RCR_KMODE) &&
+	    (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+		/* AutoSync */
+		if ((int)params_rate(params) != rate) {
+			spin_unlock_irq(&rme32->lock);
+			return -EIO;
+		}
+	} else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
 		spin_unlock_irq(&rme32->lock);
 		return err;
 	}
@@ -708,8 +729,9 @@
 			    snd_pcm_hw_params_t * params)
 {
 	unsigned long flags;
+	int err, isadat, rate;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-	int err, isadat;
+	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream,
 				      params_buffer_bytes(params))) < 0)
@@ -727,9 +749,16 @@
 		spin_unlock_irqrestore(&rme32->lock, flags);
 		return err;
 	}
-	if (params_rate(params) != snd_rme32_capture_getrate(rme32, &isadat)) {
-		spin_unlock_irqrestore(&rme32->lock, flags);
-		return -EBUSY;
+	if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+                if ((int)params_rate(params) != rate) {
+                        spin_unlock_irqrestore(&rme32->lock, flags);
+                        return -EIO;                    
+                }
+                if ((isadat && runtime->hw.channels_min == 2) ||
+                    (!isadat && runtime->hw.channels_min == 8)) {
+                        spin_unlock_irqrestore(&rme32->lock, flags);
+                        return -EIO;
+                }
 	}
 	/* AutoSync off for recording */
 	rme32->wcreg &= ~RME32_WCR_AUTOSYNC;
@@ -789,7 +818,8 @@
 		writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
 	}
 	rme32->wcreg &= ~RME32_WCR_START;
-	rme32->wcreg |= RME32_WCR_MUTE;
+	if (rme32->wcreg & RME32_WCR_SEL)
+		rme32->wcreg |= RME32_WCR_MUTE;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 }
 
@@ -836,12 +866,17 @@
 static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
+	int rate, dummy;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
 	spin_lock_irqsave(&rme32->lock, flags);
+	if (rme32->playback_substream != NULL) {
+		spin_unlock_irqrestore(&rme32->lock, flags);
+		return -EBUSY;
+	}
 	rme32->wcreg &= ~RME32_WCR_ADAT;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	rme32->playback_substream = substream;
@@ -854,7 +889,13 @@
 		runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
 		runtime->hw.rate_max = 96000;
 	}
-
+	if ((rme32->rcreg & RME32_RCR_KMODE) &&
+	    (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+		/* AutoSync */
+		runtime->hw.rates = snd_rme32_ratecode(rate);
+		runtime->hw.rate_min = rate;
+		runtime->hw.rate_max = rate;
+	}       
 	snd_pcm_hw_constraint_minmax(runtime,
 				     SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
 				     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
@@ -872,23 +913,17 @@
 static int snd_rme32_capture_spdif_open(snd_pcm_substream_t * substream)
 {
 	unsigned long flags;
-	int isadat;
+	int isadat, rate;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
-	if (snd_rme32_capture_getrate(rme32, &isadat) < 0) {
-		/* no input */
-		return -EIO;
-	}
-	if (isadat) {
-		/* ADAT input */
-		return -EBUSY;
-	}
 	snd_pcm_set_sync(substream);
 
 	spin_lock_irqsave(&rme32->lock, flags);
-
+        if (rme32->capture_substream != NULL) {
+	        spin_unlock_irqrestore(&rme32->lock, flags);
+                return -EBUSY;
+        }
 	rme32->capture_substream = substream;
 	rme32->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
@@ -898,6 +933,14 @@
 		runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
 		runtime->hw.rate_max = 96000;
 	}
+	if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+		if (isadat) {
+			return -EIO;
+		}
+		runtime->hw.rates = snd_rme32_ratecode(rate);
+		runtime->hw.rate_min = rate;
+		runtime->hw.rate_max = rate;
+	}
 
 	snd_pcm_hw_constraint_minmax(runtime,
 				     SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
@@ -913,12 +956,17 @@
 snd_rme32_playback_adat_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
+	int rate, dummy;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	
 	snd_pcm_set_sync(substream);
 
 	spin_lock_irqsave(&rme32->lock, flags);	
+        if (rme32->playback_substream != NULL) {
+	        spin_unlock_irqrestore(&rme32->lock, flags);
+                return -EBUSY;
+        }
 	rme32->wcreg |= RME32_WCR_ADAT;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	rme32->playback_substream = substream;
@@ -927,6 +975,13 @@
 	spin_unlock_irqrestore(&rme32->lock, flags);
 	
 	runtime->hw = snd_rme32_playback_adat_info;
+	if ((rme32->rcreg & RME32_RCR_KMODE) &&
+	    (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+                /* AutoSync */
+                runtime->hw.rates = snd_rme32_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+	}        
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
 				     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -938,27 +993,31 @@
 snd_rme32_capture_adat_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
-	int isadat;
+	int isadat, rate;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
-	if (snd_rme32_capture_getrate(rme32, &isadat) < 0) {
-		/* no input */
-		return -EIO;
-	}
-	if (!isadat) {
-		/* S/PDIF input */
-		return -EBUSY;
-	}
-	snd_pcm_set_sync(substream);
+	runtime->hw = snd_rme32_capture_adat_info;
+	if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+		if (!isadat) {
+			return -EIO;
+		}
+                runtime->hw.rates = snd_rme32_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+        }
 
+	snd_pcm_set_sync(substream);
+        
 	spin_lock_irqsave(&rme32->lock, flags);	
+	if (rme32->capture_substream != NULL) {
+		spin_unlock_irqrestore(&rme32->lock, flags);
+		return -EBUSY;
+        }
 	rme32->capture_substream = substream;
 	rme32->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
 
-	runtime->hw = snd_rme32_capture_adat_info;
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
 				     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -1008,7 +1067,8 @@
 		snd_rme32_playback_stop(rme32);
 	}
 	writel(0, rme32->iobase + RME32_IO_RESET_POS);
-	rme32->wcreg &= ~RME32_WCR_MUTE;
+	if (rme32->wcreg & RME32_WCR_SEL)
+		rme32->wcreg &= ~RME32_WCR_MUTE;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	spin_unlock_irqrestore(&rme32->lock, flags);
 	return 0;
@@ -1240,7 +1300,6 @@
 	if (rme32->irq >= 0) {
 		snd_rme32_playback_stop(rme32);
 		snd_rme32_capture_stop(rme32);
-		snd_rme32_proc_done(rme32);
 		free_irq(rme32->irq, (void *) rme32);
 		rme32->irq = -1;
 	}
@@ -1463,10 +1522,10 @@
 		snd_iprintf(buffer, "  sample rate: %d Hz\n",
 			    snd_rme32_playback_getrate(rme32));
 	}
-	if (rme32->wcreg & RME32_RCR_KMODE) {
-		snd_iprintf(buffer, "  clock mode: slave\n");
+	if (rme32->rcreg & RME32_RCR_KMODE) {
+		snd_iprintf(buffer, "  sample clock source: AutoSync\n");
 	} else {
-		snd_iprintf(buffer, "  clock mode: master\n");
+		snd_iprintf(buffer, "  sample clock source: Internal\n");
 	}
 	if (rme32->wcreg & RME32_WCR_PRO) {
 		snd_iprintf(buffer, "  format: AES/EBU (professional)\n");
@@ -1484,26 +1543,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(rme32->card, "rme32", rme32->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = rme32;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_rme32_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	rme32->proc_entry = entry;
-}
-
-static void snd_rme32_proc_done(rme32_t * rme32)
-{
-	if (rme32->proc_entry) {
-		snd_info_unregister(rme32->proc_entry);
-		rme32->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(rme32->card, "rme32", &entry))
+		snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read);
 }
 
 /*
@@ -1546,6 +1587,10 @@
 	spin_lock_irqsave(&rme32->lock, flags);
 	val = (rme32->wcreg & ~RME32_WCR_SEL) | val;
 	change = val != rme32->wcreg;
+	if (ucontrol->value.integer.value[0])
+		val &= ~RME32_WCR_MUTE;
+	else
+		val |= RME32_WCR_MUTE;
 	writel(rme32->wcreg =
 	       val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	spin_unlock_irqrestore(&rme32->lock, flags);
@@ -1588,7 +1633,7 @@
 {
 	rme32_t *rme32 = _snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
-	int items = 3;
+	unsigned int items = 3;
 
 	spin_lock_irqsave(&rme32->lock, flags);
 	ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);
@@ -1636,7 +1681,7 @@
 	val = ucontrol->value.enumerated.item[0] % items;
 
 	spin_lock_irqsave(&rme32->lock, flags);
-	change = val != snd_rme32_getinputtype(rme32);
+	change = val != (unsigned int)snd_rme32_getinputtype(rme32);
 	snd_rme32_setinputtype(rme32, val);
 	spin_unlock_irqrestore(&rme32->lock, flags);
 	return change;
@@ -1646,7 +1691,10 @@
 snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol,
 				 snd_ctl_elem_info_t * uinfo)
 {
-	static char *texts[4] = { "Slave", "Master (32.0 kHz)", "Master (44.1 kHz)", "Master (48.0 kHz)" };
+	static char *texts[4] = { "AutoSync", 
+				  "Internal 32.0kHz", 
+				  "Internal 44.1kHz", 
+				  "Internal 48.0kHz" };
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1681,7 +1729,7 @@
 
 	val = ucontrol->value.enumerated.item[0] % 3;
 	spin_lock_irqsave(&rme32->lock, flags);
-	change = val != snd_rme32_getclockmode(rme32);
+	change = val != (unsigned int)snd_rme32_getclockmode(rme32);
 	snd_rme32_setclockmode(rme32, val);
 	spin_unlock_irqrestore(&rme32->lock, flags);
 	return change;
@@ -1843,7 +1891,7 @@
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
-		.name =	"Clock Mode",
+		.name =	"Sample Clock Source",
 		.info =	snd_rme32_info_clockmode_control,
 		.get =	snd_rme32_get_clockmode_control,
 		.put =	snd_rme32_put_clockmode_control
diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c
--- a/sound/pci/rme96.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/rme96.c	Mon Feb 10 10:39:24 2003
@@ -257,7 +257,6 @@
 	snd_pcm_t          *spdif_pcm;
 	snd_pcm_t          *adat_pcm; 
 	struct pci_dev     *pci;
-	snd_info_entry_t   *proc_entry;
 	snd_kcontrol_t	   *spdif_ctl;
 } rme96_t;
 
@@ -308,13 +307,13 @@
 static void __devinit 
 snd_rme96_proc_init(rme96_t *rme96);
 
-static void
-snd_rme96_proc_done(rme96_t *rme96);
-
 static int
 snd_rme96_create_switches(snd_card_t *card,
 			  rme96_t *rme96);
 
+static int
+snd_rme96_getinputtype(rme96_t *rme96);
+
 static inline unsigned int
 snd_rme96_playback_ptr(rme96_t *rme96)
 {
@@ -330,6 +329,20 @@
 }
 
 static int
+snd_rme96_ratecode(int rate)
+{
+    switch (rate) {
+    case 32000: return SNDRV_PCM_RATE_32000;
+    case 44100: return SNDRV_PCM_RATE_44100;
+    case 48000: return SNDRV_PCM_RATE_48000;
+    case 64000: return SNDRV_PCM_RATE_64000;
+    case 88200: return SNDRV_PCM_RATE_88200;
+    case 96000: return SNDRV_PCM_RATE_96000;
+    }
+    return 0;
+}
+
+static int
 snd_rme96_playback_silence(snd_pcm_substream_t *substream,
 			   int channel, /* not used (interleaved data) */
 			   snd_pcm_uframes_t pos,
@@ -669,10 +682,11 @@
 	int rate, dummy;
 
 	if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+            snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
 	    (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
 	{
-	    /* slave clock */
-	    return rate;
+	        /* slave clock */
+	        return rate;
 	}
 	rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) +
 		(((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1);
@@ -974,14 +988,23 @@
 snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
 			     snd_pcm_hw_params_t *params)
 {
-	unsigned long flags;
+	unsigned long flags;        
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-	int err;
+	int err, rate, dummy;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
 		return err;
 	spin_lock_irqsave(&rme96->lock, flags);
-	if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
+	if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+            snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
+	    (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+	{
+                /* slave clock */
+                if ((int)params_rate(params) != rate) {
+		        spin_unlock_irqrestore(&rme96->lock, flags);
+			return -EIO;                    
+                }
+	} else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
 		spin_unlock_irqrestore(&rme96->lock, flags);
 		return err;
 	}
@@ -1024,7 +1047,8 @@
 {
 	unsigned long flags;
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-	int err, isadat;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err, isadat, rate;
 	
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
 		return err;
@@ -1040,10 +1064,18 @@
 			spin_unlock_irqrestore(&rme96->lock, flags);
 			return err;
 		}
-	} else if (params_rate(params) != snd_rme96_capture_getrate(rme96, &isadat)) {
-		spin_unlock_irqrestore(&rme96->lock, flags);
-		return -EBUSY;
-	}
+	} else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+                if ((int)params_rate(params) != rate) {
+			spin_unlock_irqrestore(&rme96->lock, flags);
+			return -EIO;                    
+                }
+                if ((isadat && runtime->hw.channels_min == 2) ||
+                    (!isadat && runtime->hw.channels_min == 8))
+                {
+			spin_unlock_irqrestore(&rme96->lock, flags);
+			return -EIO;
+                }
+        }
 	snd_rme96_setframelog(rme96, params_channels(params), 0);
 	if (rme96->playback_periodsize != 0) {
 		if (params_period_size(params) << rme96->capture_frlog !=
@@ -1138,7 +1170,7 @@
 	
 	if (rme96->rcreg & RME96_RCR_IRQ) {
 		/* playback */
-		snd_pcm_period_elapsed(rme96->playback_substream);
+                snd_pcm_period_elapsed(rme96->playback_substream);
 		writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
 	}
 	if (rme96->rcreg & RME96_RCR_IRQ_2) {
@@ -1162,12 +1194,17 @@
 snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
+        int rate, dummy;
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
 	spin_lock_irqsave(&rme96->lock, flags);	
+        if (rme96->playback_substream != NULL) {
+	        spin_unlock_irqrestore(&rme96->lock, flags);
+                return -EBUSY;
+        }
 	rme96->wcreg &= ~RME96_WCR_ADAT;
 	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	rme96->playback_substream = substream;
@@ -1175,7 +1212,16 @@
 	rme96->playback_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 
-	runtime->hw = snd_rme96_playback_spdif_info;	
+	runtime->hw = snd_rme96_playback_spdif_info;
+	if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+            snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
+	    (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+	{
+                /* slave clock */
+                runtime->hw.rates = snd_rme96_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+	}        
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
 
@@ -1190,28 +1236,33 @@
 snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
-	int isadat;
+        int isadat, rate;
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
-	if (snd_rme96_capture_getrate(rme96, &isadat) < 0) {
-		/* no input */
-		return -EIO;
-	}
-	if (isadat) {
-		/* ADAT input */
-		return -EBUSY;
-	}
 	snd_pcm_set_sync(substream);
 
-	spin_lock_irqsave(&rme96->lock, flags);	
+	runtime->hw = snd_rme96_capture_spdif_info;
+        if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
+            (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
+        {
+                if (isadat) {
+                        return -EIO;
+                }
+                runtime->hw.rates = snd_rme96_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+        }
+        
+	spin_lock_irqsave(&rme96->lock, flags);
+        if (rme96->capture_substream != NULL) {
+	        spin_unlock_irqrestore(&rme96->lock, flags);
+                return -EBUSY;
+        }
 	rme96->capture_substream = substream;
 	rme96->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	
-	runtime->hw = snd_rme96_capture_spdif_info;
-	
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
 
@@ -1222,12 +1273,17 @@
 snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
+        int rate, dummy;
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_pcm_runtime_t *runtime = substream->runtime;        
 	
 	snd_pcm_set_sync(substream);
 
 	spin_lock_irqsave(&rme96->lock, flags);	
+        if (rme96->playback_substream != NULL) {
+	        spin_unlock_irqrestore(&rme96->lock, flags);
+                return -EBUSY;
+        }
 	rme96->wcreg |= RME96_WCR_ADAT;
 	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	rme96->playback_substream = substream;
@@ -1236,6 +1292,15 @@
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	
 	runtime->hw = snd_rme96_playback_adat_info;
+	if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+            snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
+	    (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+	{
+                /* slave clock */
+                runtime->hw.rates = snd_rme96_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+	}        
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
 	return 0;
@@ -1245,27 +1310,36 @@
 snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
 {
 	unsigned long flags;
-	int isadat;
+        int isadat, rate;
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
-	if (snd_rme96_capture_getrate(rme96, &isadat) < 0) {
-		/* no input */
-		return -EIO;
-	}
-	if (!isadat) {
-		/* S/PDIF input */
-		return -EBUSY;
-	}
 	snd_pcm_set_sync(substream);
 
+	runtime->hw = snd_rme96_capture_adat_info;
+        if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) {
+                /* makes no sense to use analog input. Note that analog
+                   expension cards AEB4/8-I are RME96_INPUT_INTERNAL */
+                return -EIO;
+        }
+        if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+                if (!isadat) {
+                        return -EIO;
+                }
+                runtime->hw.rates = snd_rme96_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+        }
+        
 	spin_lock_irqsave(&rme96->lock, flags);	
+        if (rme96->capture_substream != NULL) {
+	        spin_unlock_irqrestore(&rme96->lock, flags);
+                return -EBUSY;
+        }
 	rme96->capture_substream = substream;
 	rme96->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 
-	runtime->hw = snd_rme96_capture_adat_info;
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
 	return 0;
@@ -1279,6 +1353,9 @@
 	int spdif = 0;
 
 	spin_lock_irqsave(&rme96->lock, flags);	
+	if (RME96_ISPLAYING(rme96)) {
+		snd_rme96_playback_stop(rme96);
+	}
 	rme96->playback_substream = NULL;
 	rme96->playback_periodsize = 0;
 	spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
@@ -1298,6 +1375,9 @@
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
 	
 	spin_lock_irqsave(&rme96->lock, flags);	
+	if (RME96_ISRECORDING(rme96)) {
+		snd_rme96_capture_stop(rme96);
+	}
 	rme96->capture_substream = NULL;
 	rme96->capture_periodsize = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
@@ -1558,7 +1638,6 @@
 		snd_rme96_capture_stop(rme96);
 		rme96->areg &= ~RME96_AR_DAC_EN;
 		writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
-		snd_rme96_proc_done(rme96);
 		free_irq(rme96->irq, (void *)rme96);
 		rme96->irq = -1;
 	}
@@ -1785,6 +1864,10 @@
 		snd_iprintf(buffer, "  clock mode: word clock\n");
 	} else if (rme96->wcreg & RME96_WCR_MASTER) {
 		snd_iprintf(buffer, "  clock mode: master\n");
+	} else if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
+		snd_iprintf(buffer, "  clock mode: slave (master anyway due to analog input setting)\n");
+	} else if (snd_rme96_capture_getrate(rme96, &n) < 0) {
+		snd_iprintf(buffer, "  clock mode: slave (master anyway due to no valid signal)\n");
 	} else {
 		snd_iprintf(buffer, "  clock mode: slave\n");
 	}
@@ -1843,27 +1926,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(rme96->card, "rme96", rme96->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = rme96;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_rme96_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	rme96->proc_entry = entry;
-}
-
-static void
-snd_rme96_proc_done(rme96_t * rme96)
-{
-	if (rme96->proc_entry) {
-		snd_info_unregister(rme96->proc_entry);
-		rme96->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(rme96->card, "rme96", &entry))
+		snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read);
 }
 
 /*
@@ -1949,7 +2013,7 @@
 {
 	rme96_t *rme96 = _snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
-	int items = 3;
+	unsigned int items = 3;
 	
 	spin_lock_irqsave(&rme96->lock, flags);
 	ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);
@@ -2021,7 +2085,7 @@
 	}
 	
 	spin_lock_irqsave(&rme96->lock, flags);
-	change = val != snd_rme96_getinputtype(rme96);
+	change = (int)val != snd_rme96_getinputtype(rme96);
 	snd_rme96_setinputtype(rme96, val);
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	return change;
@@ -2062,7 +2126,7 @@
 	
 	val = ucontrol->value.enumerated.item[0] % 3;
 	spin_lock_irqsave(&rme96->lock, flags);
-	change = val != snd_rme96_getclockmode(rme96);
+	change = (int)val != snd_rme96_getclockmode(rme96);
 	snd_rme96_setclockmode(rme96, val);
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	return change;
@@ -2103,7 +2167,8 @@
 	
 	val = ucontrol->value.enumerated.item[0] % 4;
 	spin_lock_irqsave(&rme96->lock, flags);
-	change = val != snd_rme96_getattenuation(rme96);
+
+	change = (int)val != snd_rme96_getattenuation(rme96);
 	snd_rme96_setattenuation(rme96, val);
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	return change;
@@ -2144,7 +2209,7 @@
 	
 	val = ucontrol->value.enumerated.item[0] % 4;
 	spin_lock_irqsave(&rme96->lock, flags);
-	change = val != snd_rme96_getmontracks(rme96);
+	change = (int)val != snd_rme96_getmontracks(rme96);
 	snd_rme96_setmontracks(rme96, val);
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	return change;
diff -Nru a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
--- a/sound/pci/rme9652/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/rme9652/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := hammerfall_mem.o
-
 snd-hammerfall-mem-objs := hammerfall_mem.o
 snd-rme9652-objs := rme9652.o
 snd-hdsp-objs := hdsp.o
diff -Nru a/sound/pci/rme9652/hammerfall_mem.c b/sound/pci/rme9652/hammerfall_mem.c
--- a/sound/pci/rme9652/hammerfall_mem.c	Mon Feb 10 10:39:23 2003
+++ b/sound/pci/rme9652/hammerfall_mem.c	Mon Feb 10 10:39:23 2003
@@ -25,7 +25,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: hammerfall_mem.c,v 1.5 2002/11/04 09:11:42 perex Exp $
+    $Id: hammerfall_mem.c,v 1.7 2003/01/06 14:21:28 perex Exp $
 
 
     Tue Oct 17 2000  Jaroslav Kysela <perex@suse.cz>
@@ -150,9 +150,10 @@
 	for (i = 0; i < NBUFS; i++) {
 		rbuf = &hammerfall_buffers[i];
 		if (rbuf->flags == HAMMERFALL_BUF_ALLOCATED) {
+			if (! try_module_get(THIS_MODULE))
+				return NULL;
 			rbuf->flags |= HAMMERFALL_BUF_USED;
 			rbuf->pci = pcidev;
-			MOD_INC_USE_COUNT;
 			*dmaaddr = rbuf->addr;
 			return rbuf->buf;
 		}
@@ -169,8 +170,8 @@
 	for (i = 0; i < NBUFS; i++) {
 		rbuf = &hammerfall_buffers[i];
 		if (rbuf->buf == addr && rbuf->pci == pcidev) {
-			MOD_DEC_USE_COUNT;
 			rbuf->flags &= ~HAMMERFALL_BUF_USED;
+			module_put(THIS_MODULE);
 			return;
 		}
 	}
@@ -178,7 +179,7 @@
 	printk ("Hammerfall memory allocator: unknown buffer address or PCI device ID");
 }
 
-static void __exit hammerfall_free_buffers (void)
+static void hammerfall_free_buffers (void)
 
 {
 	int i;
diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/rme9652/hdsp.c	Mon Feb 10 10:39:24 2003
@@ -23,6 +23,7 @@
 #include <sound/driver.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 
@@ -368,7 +369,6 @@
 	snd_card_t *card;
 	snd_pcm_t *pcm;
 	struct pci_dev *pci;
-	snd_info_entry_t *proc_entry;
 	snd_kcontrol_t *spdif_ctl;
         unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
 };
@@ -461,7 +461,7 @@
 	*/
 	
 	for (i = 0; i < timeout; i++)
-		if ((hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)
+		if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)
 			return 0;
 
 	snd_printk ("wait for FIFO status <= %d failed after %d iterations\n",
@@ -818,10 +818,18 @@
 
 static inline int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
 {
+	int fifo_bytes_used;
+
 	if (id) {
-		return (hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff) < 128;
+		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
+	} else {
+		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
+	}
+
+	if (fifo_bytes_used < 128) {
+		return  128 - fifo_bytes_used;
 	} else {
-		return (hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff)< 128;
+		return 0;
 	}
 }
 
@@ -836,7 +844,6 @@
 {
 	unsigned long flags;
 	int n_pending;
-	int clear_timer = 0;
 	int to_write;
 	int i;
 	unsigned char buf[128];
@@ -848,23 +855,15 @@
 	if (hmidi->output) {
 		if (!snd_rawmidi_transmit_empty (hmidi->output)) {
 			if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) {
-				if (n_pending > sizeof (buf))
+				if (n_pending > (int)sizeof (buf))
 					n_pending = sizeof (buf);
 				
 				if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
 					for (i = 0; i < to_write; ++i) 
 						snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]);
-				} else {
-					clear_timer = 1;
 				}
 			}
-		} else {
-			clear_timer = 1;
 		}
-
-		if (clear_timer && hmidi->istimer && --hmidi->istimer <= 0) {
-			del_timer(&hmidi->timer);
-		} 
 	}
 
 	spin_unlock_irqrestore (&hmidi->lock, flags);
@@ -882,7 +881,7 @@
 
 	if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
 		if (hmidi->input) {
-			if (n_pending > sizeof (buf)) {
+			if (n_pending > (int)sizeof (buf)) {
 				n_pending = sizeof (buf);
 			}
 			for (i = 0; i < n_pending; ++i) {
@@ -972,6 +971,8 @@
 		}
 	}
 	spin_unlock_irqrestore (&hmidi->lock, flags);
+	if (up)
+		snd_hdsp_midi_output_write(hmidi);
 }
 
 static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream)
@@ -1288,7 +1289,7 @@
 		return -EBUSY;
 	val = ucontrol->value.integer.value[0] & 1;
 	spin_lock_irqsave(&hdsp->lock, flags);
-	change = val != hdsp_spdif_out(hdsp);
+	change = (int)val != hdsp_spdif_out(hdsp);
 	hdsp_set_spdif_output(hdsp, val);
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return change;
@@ -1403,7 +1404,7 @@
 	max = hdsp->ss_channels == (hdsp->type == Digiface) ? 7 : 6;
 	val = ucontrol->value.enumerated.item[0] % max;
 	spin_lock_irqsave(&hdsp->lock, flags);
-	change = val != hdsp_sync_pref(hdsp);
+	change = (int)val != hdsp_sync_pref(hdsp);
 	hdsp_set_sync_pref(hdsp, val);
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return change;
@@ -1507,7 +1508,7 @@
 		return -EBUSY;
 	val = ucontrol->value.integer.value[0] & 1;
 	spin_lock_irqsave(&hdsp->lock, flags);
-	change = val != hdsp_line_out(hdsp);
+	change = (int)val != hdsp_line_out(hdsp);
 	hdsp_set_line_output(hdsp, val);
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return change;
@@ -1576,7 +1577,8 @@
 	gain = ucontrol->value.integer.value[2];
 
 	spin_lock_irqsave(&hdsp->lock, flags);
-	if ((change = gain != hdsp_read_gain(hdsp, addr)))
+	change = gain != hdsp_read_gain(hdsp, addr);
+	if (change)
 		hdsp_write_gain(hdsp, addr, gain);
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return change;
@@ -1654,7 +1656,8 @@
 
 
 	spin_lock_irqsave(&hdsp->lock, flags);
-	if ((change = gain != hdsp_read_gain(hdsp, addr)))
+	change = gain != hdsp_read_gain(hdsp, addr);
+	if (change)
 		hdsp_write_gain(hdsp, addr, gain);
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return change;
@@ -1826,7 +1829,8 @@
 
 int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
 {
-	int idx, err, limit;
+	unsigned int idx, limit;
+	int err;
 	snd_kcontrol_t *kctl;
 
 	for (idx = 0; idx < HDSP_CONTROLS; idx++) {
@@ -2076,27 +2080,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(hdsp->card, "hdsp", hdsp->card->proc_root)) !=
-	    NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = hdsp;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_hdsp_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	hdsp->proc_entry = entry;
-}
-
-static void snd_hdsp_proc_done(hdsp_t *hdsp)
-{
-	if (hdsp->proc_entry) {
-		snd_info_unregister(hdsp->proc_entry);
-		hdsp->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
+		snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read);
 }
 
 static void snd_hdsp_free_buffers(hdsp_t *hdsp)
@@ -2413,7 +2398,7 @@
 		   that matter are the same.
 		 */
 
-		if (params_rate(params) != hdsp_system_sample_rate(hdsp)) {
+		if ((int)params_rate(params) != hdsp_system_sample_rate(hdsp)) {
 			spin_unlock_irq(&hdsp->lock);
 			_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
 			return -EBUSY;
@@ -2589,9 +2574,9 @@
 	.rate_max =		96000,
 	.channels_min =		14,
 	.channels_max =		HDSP_MAX_CHANNELS,
-	.buffer_bytes_max =	1024*1024,
-	.period_bytes_min =	1,
-	.period_bytes_max =	1024*1024,
+	.buffer_bytes_max =	HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
+	.period_bytes_min =	(64 * 4) *10,
+	.period_bytes_max =	(8192 * 4) * HDSP_MAX_CHANNELS,
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
@@ -2614,9 +2599,9 @@
 	.rate_max =		96000,
 	.channels_min =		14,
 	.channels_max =		HDSP_MAX_CHANNELS,
-	.buffer_bytes_max =	1024*1024,
-	.period_bytes_min =	1,
-	.period_bytes_max =	1024*1024,
+	.buffer_bytes_max =	HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
+	.period_bytes_min =	(64 * 4) * 10,
+	.period_bytes_max =	(8192 * 4) * HDSP_MAX_CHANNELS,
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
@@ -3078,7 +3063,6 @@
 	if (hdsp->irq >= 0)
 		free_irq(hdsp->irq, (void *)hdsp);
 
-	snd_hdsp_proc_done(hdsp);
 	snd_hdsp_free_buffers(hdsp);
 	
 	if (hdsp->iobase)
diff -Nru a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
--- a/sound/pci/rme9652/rme9652.c	Mon Feb 10 10:39:26 2003
+++ b/sound/pci/rme9652/rme9652.c	Mon Feb 10 10:39:26 2003
@@ -263,7 +263,6 @@
 	snd_card_t *card;
 	snd_pcm_t *pcm;
 	struct pci_dev *pci;
-	snd_info_entry_t *proc_entry;
 	snd_kcontrol_t *spdif_ctl;
 
 } rme9652_t;
@@ -375,7 +374,7 @@
 static snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652)
 {
 	int status;
-	int offset, frag;
+	unsigned int offset, frag;
 	snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
 	snd_pcm_sframes_t delta;
 
@@ -390,7 +389,7 @@
 
 	delta = rme9652->prev_hw_offset - offset;
 	delta &= 0xffff;
-	if (delta <= rme9652->max_jitter * 4)
+	if (delta <= (snd_pcm_sframes_t)rme9652->max_jitter * 4)
 		offset = rme9652->prev_hw_offset;
 	else
 		rme9652->prev_hw_offset = offset;
@@ -1103,7 +1102,7 @@
 		return -EBUSY;
 	val = ucontrol->value.integer.value[0] & 1;
 	spin_lock_irqsave(&rme9652->lock, flags);
-	change = val != rme9652_spdif_out(rme9652);
+	change = (int)val != rme9652_spdif_out(rme9652);
 	rme9652_set_spdif_output(rme9652, val);
 	spin_unlock_irqrestore(&rme9652->lock, flags);
 	return change;
@@ -1190,7 +1189,7 @@
 	
 	val = ucontrol->value.enumerated.item[0] % 3;
 	spin_lock_irqsave(&rme9652->lock, flags);
-	change = val != rme9652_sync_mode(rme9652);
+	change = (int)val != rme9652_sync_mode(rme9652);
 	rme9652_set_sync_mode(rme9652, val);
 	spin_unlock_irqrestore(&rme9652->lock, flags);
 	return change;
@@ -1287,7 +1286,7 @@
 	max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;
 	val = ucontrol->value.enumerated.item[0] % max;
 	spin_lock_irqsave(&rme9652->lock, flags);
-	change = val != rme9652_sync_pref(rme9652);
+	change = (int)val != rme9652_sync_pref(rme9652);
 	rme9652_set_sync_pref(rme9652, val);
 	spin_unlock_irqrestore(&rme9652->lock, flags);
 	return change;
@@ -1601,7 +1600,8 @@
 
 int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
 {
-	int idx, err;
+	unsigned int idx;
+	int err;
 	snd_kcontrol_t *kctl;
 
 	for (idx = 0; idx < RME9652_CONTROLS; idx++) {
@@ -1803,27 +1803,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(rme9652->card, "rme9652", rme9652->card->proc_root)) !=
-	    NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = rme9652;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_rme9652_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	rme9652->proc_entry = entry;
-}
-
-static void snd_rme9652_proc_done(rme9652_t *rme9652)
-{
-	if (rme9652->proc_entry) {
-		snd_info_unregister(rme9652->proc_entry);
-		rme9652->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
+		snd_info_set_text_ops(entry, rme9652, snd_rme9652_proc_read);
 }
 
 static void snd_rme9652_free_buffers(rme9652_t *rme9652)
@@ -1855,7 +1836,6 @@
 {
 	if (rme9652->irq >= 0)
 		rme9652_stop(rme9652);
-	snd_rme9652_proc_done(rme9652);
 	snd_rme9652_free_buffers(rme9652);
 
 	if (rme9652->iobase)
@@ -2116,7 +2096,7 @@
 		   that matter are the same.
 		 */
 
-		if (params_rate(params) !=
+		if ((int)params_rate(params) !=
 		    rme9652_adat_sample_rate(rme9652)) {
 			spin_unlock_irq(&rme9652->lock);
 			_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
@@ -2288,9 +2268,9 @@
 	.rate_max =		96000,
 	.channels_min =		10,
 	.channels_max =		26,
-	.buffer_bytes_max =	1024*1024,
-	.period_bytes_min =	1,
-	.period_bytes_max =	1024*1024,
+	.buffer_bytes_max =	RME9652_CHANNEL_BUFFER_BYTES * 26,
+	.period_bytes_min =	(64 * 4) * 10,
+	.period_bytes_max =	(8192 * 4) * 26,
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
@@ -2311,9 +2291,9 @@
 	.rate_max =		96000,
 	.channels_min =		10,
 	.channels_max =		26,
-	.buffer_bytes_max =	1024*1024,
-	.period_bytes_min =	1,
-	.period_bytes_max =	1024*1024,
+	.buffer_bytes_max =	RME9652_CHANNEL_BUFFER_BYTES *26,
+	.period_bytes_min =	(64 * 4) * 10,
+	.period_bytes_max =	(8192 * 4) * 26,
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
diff -Nru a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
--- a/sound/pci/sonicvibes.c	Mon Feb 10 10:39:30 2003
+++ b/sound/pci/sonicvibes.c	Mon Feb 10 10:39:30 2003
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/gameport.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -37,9 +38,6 @@
 #include <sound/opl3.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
-#ifndef LINUX_2_2
-#include <linux/gameport.h>
-#endif
 
 #include <asm/io.h>
 
@@ -249,7 +247,6 @@
 	snd_hwdep_t *fmsynth;	/* S3FM */
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
 
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
@@ -257,7 +254,7 @@
 	snd_kcontrol_t *master_mute;
 	snd_kcontrol_t *master_volume;
 
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	struct gameport gameport;
 #endif
 };
@@ -1122,7 +1119,8 @@
 {
 	snd_card_t *card;
 	snd_kcontrol_t *kctl;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL);
 	card = sonic->card;
@@ -1177,26 +1175,8 @@
 {
 	snd_info_entry_t *entry;
 
-	if ((entry = snd_info_create_card_entry(sonic->card, "sonicvibes", sonic->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = sonic;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_sonicvibes_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	sonic->proc_entry = entry;
-}
-
-static void snd_sonicvibes_proc_done(sonicvibes_t * sonic)
-{
-	if (sonic->proc_entry) {
-		snd_info_unregister(sonic->proc_entry);
-		sonic->proc_entry = NULL;
-	}
+	if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
+		snd_info_set_text_ops(entry, sonic, snd_sonicvibes_proc_read);
 }
 
 /*
@@ -1208,11 +1188,10 @@
 
 static int snd_sonicvibes_free(sonicvibes_t *sonic)
 {
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (sonic->gameport.io)
 		gameport_unregister_port(&sonic->gameport);
 #endif
-	snd_sonicvibes_proc_done(sonic);
 	pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
 	pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
 	if (sonic->res_sb_port) {
@@ -1440,7 +1419,8 @@
 	mpu401_t * mpu = snd_magic_cast(mpu401_t, rmidi->private_data, return -ENXIO);
 	snd_card_t *card = sonic->card;
 	snd_rawmidi_str_t *dir;
-	int idx, err;
+	unsigned int idx;
+	int err;
 
 	mpu->private_data = sonic;
 	mpu->open_input = snd_sonicvibes_midi_input_open;
@@ -1512,7 +1492,7 @@
 		snd_card_free(card);
 		return err;
 	}
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	sonic->gameport.io = sonic->game_port;
 	gameport_register_port(&sonic->gameport);
 #endif
diff -Nru a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile
--- a/sound/pci/trident/Makefile	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/trident/Makefile	Mon Feb 10 10:39:29 2003
@@ -3,13 +3,17 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := trident_main.o
-
 snd-trident-objs := trident.o trident_main.o trident_memory.o
 snd-trident-synth-objs := trident_synth.o
 
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
+
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_TRIDENT) += snd-trident.o
-ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
-  obj-$(CONFIG_SND_TRIDENT) += snd-trident-synth.o
-endif
+obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-trident-synth.o
diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
--- a/sound/pci/trident/trident_main.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/trident/trident_main.c	Mon Feb 10 10:39:29 2003
@@ -34,15 +34,14 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/gameport.h>
 
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/control.h>
 #include <sound/trident.h>
 #include <sound/asoundef.h>
-#ifndef LINUX_2_2
-#include <linux/gameport.h>
-#endif
+#include <sound/pcm_sgbuf.h>
 
 #include <asm/io.h>
 
@@ -760,14 +759,14 @@
 
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
 		return err;
-	if (err > 0 && trident->tlb.entries) {
-		if (voice->memblk)
-			snd_trident_free_pages(trident, voice->memblk);
-		spin_lock_irq(&trident->reg_lock);
-		voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
-		spin_unlock_irq(&trident->reg_lock);
-		if (voice->memblk == NULL)
-			return -ENOMEM;
+	if (trident->tlb.entries) {
+		if (err > 0) { /* change */
+			if (voice->memblk)
+				snd_trident_free_pages(trident, voice->memblk);
+			voice->memblk = snd_trident_alloc_pages(trident, substream);
+			if (voice->memblk == NULL)
+				return -ENOMEM;
+		}
 	}
 	return 0;
 }
@@ -794,7 +793,7 @@
 
 	/* voice management */
 
-	if (params_buffer_size(hw_params) / 2 != params_buffer_size(hw_params)) {
+	if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {
 		if (evoice == NULL) {
 			evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
 			if (evoice == NULL)
@@ -853,9 +852,11 @@
 	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
 	snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
 
-	if (trident->tlb.entries && voice && voice->memblk) {
-		snd_trident_free_pages(trident, voice->memblk);
-		voice->memblk = NULL;
+	if (trident->tlb.entries) {
+		if (voice && voice->memblk) {
+			snd_trident_free_pages(trident, voice->memblk);
+			voice->memblk = NULL;
+		}
 	}
 	snd_pcm_lib_free_pages(substream);
 	if (evoice != NULL) {
@@ -992,10 +993,12 @@
 	outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
 
 	// Set channel buffer Address
-	voice->LBA = runtime->dma_addr;
-	outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
+	/* FIXME: LEGACY_DMAR0 correctly set? */
 	if (voice->memblk)
 		voice->LBA = voice->memblk->offset;
+	else
+		voice->LBA = runtime->dma_addr;
+	outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
 
 	// set ESO
 	ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
@@ -1345,6 +1348,7 @@
 		voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
 
 		/* set Loop Back Address */
+		/* FIXME: LBAO?? */
 		LBAO = runtime->dma_addr;
 		if (voice->memblk)
 			voice->LBA = voice->memblk->offset;
@@ -1573,11 +1577,11 @@
 		cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;
 	}
 
-	if (++cso > runtime->buffer_size)
-		cso = runtime->buffer_size;
-
 	spin_unlock(&trident->reg_lock);
 
+	if (++cso >= runtime->buffer_size)
+		cso = 0;
+
 	return cso;
 }
 
@@ -1605,7 +1609,8 @@
 	result = inw(TRID_REG(trident, T4D_SBBL_SBCL));
 	if (runtime->channels > 1)
 		result >>= 1;
-	result = runtime->buffer_size - result;
+	if (result > 0)
+		result = runtime->buffer_size - result;
 
 	// printk("capture result = 0x%x, cso = 0x%x\n", result, cso);
 
@@ -1759,15 +1764,12 @@
 
 static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	unsigned long flags;
 	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
 	trident_t *trident;
 
 	if (voice) {
 		trident = voice->trident;
-		spin_lock_irqsave(&trident->reg_lock, flags);
 		snd_trident_free_voice(trident, voice);
-		spin_unlock_irqrestore(&trident->reg_lock, flags);
 	}
 }
 
@@ -1777,13 +1779,9 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_trident_voice_t *voice;
 
-	spin_lock_irq(&trident->reg_lock);
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
-	if (voice == NULL) {
-		spin_unlock_irq(&trident->reg_lock);
+	if (voice == NULL)
 		return -EAGAIN;
-	}
-	spin_unlock_irq(&trident->reg_lock);
 	snd_trident_pcm_mixer_build(trident, voice, substream);
 	voice->substream = substream;
 	runtime->private_data = voice;
@@ -1830,12 +1828,9 @@
 	snd_trident_voice_t *voice;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	
-	spin_lock_irq(&trident->reg_lock);
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
-	if (voice == NULL) {
-		spin_unlock_irq(&trident->reg_lock);
+	if (voice == NULL)
 		return -EAGAIN;
-	}
 	voice->spdif = 1;
 	voice->substream = substream;
 	trident->spdif_pcm_bits = trident->spdif_bits;
@@ -1911,14 +1906,10 @@
 	snd_trident_voice_t *voice;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	spin_lock_irq(&trident->reg_lock);
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
-	if (voice == NULL) {
-		spin_unlock_irq(&trident->reg_lock);
+	if (voice == NULL)
 		return -EAGAIN;
-	}
 	voice->capture = 1;
-	spin_unlock_irq(&trident->reg_lock);
 	voice->substream = substream;
 	runtime->private_data = voice;
 	runtime->private_free = snd_trident_pcm_free_substream;
@@ -1959,23 +1950,11 @@
 	snd_trident_voice_t *voice;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	spin_lock_irq(&trident->reg_lock);
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
-	if (voice == NULL) {
-		spin_unlock_irq(&trident->reg_lock);
+	if (voice == NULL)
 		return -EAGAIN;
-	}
-	if (trident->tlb.entries) {
-		voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
-		if (voice->memblk == NULL) {
-			snd_trident_free_voice(trident, voice);
-			spin_unlock_irq(&trident->reg_lock);
-			return -ENOMEM;
-		}
-	}
-	voice->substream = substream;
 	voice->foldback_chan = substream->number;
-	spin_unlock_irq(&trident->reg_lock);
+	voice->substream = substream;
 	runtime->private_data = voice;
 	runtime->private_free = snd_trident_pcm_free_substream;
 	runtime->hw = snd_trident_foldback;
@@ -2021,6 +2000,18 @@
 	.pointer =	snd_trident_playback_pointer,
 };
 
+static snd_pcm_ops_t snd_trident_nx_playback_ops = {
+	.open =		snd_trident_playback_open,
+	.close =	snd_trident_playback_close,
+	.ioctl =	snd_trident_ioctl,
+	.hw_params =	snd_trident_hw_params,
+	.hw_free =	snd_trident_hw_free,
+	.prepare =	snd_trident_playback_prepare,
+	.trigger =	snd_trident_trigger,
+	.pointer =	snd_trident_playback_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
 static snd_pcm_ops_t snd_trident_capture_ops = {
 	.open =		snd_trident_capture_open,
 	.close =	snd_trident_capture_close,
@@ -2032,6 +2023,18 @@
 	.pointer =	snd_trident_capture_pointer,
 };
 
+static snd_pcm_ops_t snd_trident_nx_capture_ops = {
+	.open =		snd_trident_capture_open,
+	.close =	snd_trident_capture_close,
+	.ioctl =	snd_trident_ioctl,
+	.hw_params =	snd_trident_capture_hw_params,
+	.hw_free =	snd_trident_hw_free,
+	.prepare =	snd_trident_capture_prepare,
+	.trigger =	snd_trident_trigger,
+	.pointer =	snd_trident_capture_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
 static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
 	.open =		snd_trident_capture_open,
 	.close =	snd_trident_capture_close,
@@ -2054,6 +2057,18 @@
 	.pointer =	snd_trident_playback_pointer,
 };
 
+static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
+	.open =		snd_trident_foldback_open,
+	.close =	snd_trident_foldback_close,
+	.ioctl =	snd_trident_ioctl,
+	.hw_params =	snd_trident_hw_params,
+	.hw_free =	snd_trident_hw_free,
+	.prepare =	snd_trident_foldback_prepare,
+	.trigger =	snd_trident_trigger,
+	.pointer =	snd_trident_playback_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
 static snd_pcm_ops_t snd_trident_spdif_ops = {
 	.open =		snd_trident_spdif_open,
 	.close =	snd_trident_spdif_close,
@@ -2065,6 +2080,18 @@
 	.pointer =	snd_trident_spdif_pointer,
 };
 
+static snd_pcm_ops_t snd_trident_nx_spdif_ops = {
+	.open =		snd_trident_spdif_open,
+	.close =	snd_trident_spdif_close,
+	.ioctl =	snd_trident_ioctl,
+	.hw_params =	snd_trident_spdif_hw_params,
+	.hw_free =	snd_trident_hw_free,
+	.prepare =	snd_trident_spdif_prepare,
+	.trigger =	snd_trident_trigger,
+	.pointer =	snd_trident_spdif_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
 static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
 	.open =		snd_trident_spdif_open,
 	.close =	snd_trident_spdif_close,
@@ -2131,18 +2158,26 @@
 	pcm->private_data = trident;
 	pcm->private_free = snd_trident_pcm_free;
 
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+	if (trident->tlb.entries) {
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_capture_ops);
+	} else {
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
 				trident->device != TRIDENT_DEVICE_ID_SI7018 ?
-					&snd_trident_capture_ops :
-					&snd_trident_si7018_capture_ops);
+				&snd_trident_capture_ops :
+				&snd_trident_si7018_capture_ops);
+	}
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, "Trident 4DWave");
 	trident->pcm = pcm;
 
-	snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 256*1024);
+	if (trident->tlb.entries)
+		snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, pcm);
+	else
+		snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 128*1024);
 
 	if (rpcm)
 		*rpcm = pcm;
@@ -2176,7 +2211,10 @@
 
 	foldback->private_data = trident;
 	foldback->private_free = snd_trident_foldback_pcm_free;
-	snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
+	if (trident->tlb.entries)
+		snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
+	else
+		snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops);
 	foldback->info_flags = 0;
 	strcpy(foldback->name, "Trident 4DWave");
 	substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
@@ -2191,7 +2229,10 @@
 	}
 	trident->foldback = foldback;
 
-	snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, foldback, 64*1024, 128*1024);
+	if (trident->tlb.entries)
+		snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, foldback);
+	else
+		snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, foldback, 64*1024, 128*1024);
 
 	if (rpcm)
 		*rpcm = foldback;
@@ -2221,7 +2262,9 @@
 
 	spdif->private_data = trident;
 	spdif->private_free = snd_trident_spdif_pcm_free;
-	if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
+	if (trident->tlb.entries) {
+		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_spdif_ops);
+	} else if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
 		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
 	} else {
 		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
@@ -2230,7 +2273,10 @@
 	strcpy(spdif->name, "Trident 4DWave IEC958");
 	trident->spdif = spdif;
 
-	snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024);
+	if (trident->tlb.entries)
+		snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, spdif);
+	else
+		snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024);
 
 	if (rpcm)
 		*rpcm = spdif;
@@ -2888,7 +2934,7 @@
 
 static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device)
 {
-	ac97_t _ac97, *ac97;
+	ac97_t _ac97;
 	snd_card_t * card = trident->card;
 	snd_kcontrol_t *kctl;
 	snd_ctl_elem_value_t uctl;
@@ -2902,7 +2948,7 @@
 	_ac97.private_data = trident;
 	trident->ac97_detect = 1;
       __again:
-	if ((err = snd_ac97_mixer(trident->card, &_ac97, &ac97)) < 0) {
+	if ((err = snd_ac97_mixer(trident->card, &_ac97, &trident->ac97)) < 0) {
 		if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
 			if ((err = snd_trident_sis_reset(trident)) < 0)
 				return err;
@@ -2987,7 +3033,7 @@
 /*
  * gameport interface
  */
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 
 typedef struct snd_trident_gameport {
 	struct gameport info;
@@ -3076,7 +3122,22 @@
 void __devinit snd_trident_gameport(trident_t *chip)
 {
 }
+#endif /* CONFIG_GAMEPORT */
+
+/*
+ * delay for 1 tick
+ */
+inline static void do_delay(trident_t *chip)
+{
+#ifdef CONFIG_PM
+	if (chip->in_suspend) {
+		mdelay((1000 + HZ - 1) / HZ);
+		return;
+	}
 #endif
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(1);
+}
 
 /*
  *  SiS reset routine
@@ -3088,7 +3149,7 @@
 	unsigned int i;
 	int r;
 
-	r = 2;	/* count of retries */
+	r = trident->in_suspend ? 0 : 2;	/* count of retries */
       __si7018_retry:
 	pci_write_config_byte(trident->pci, 0x46, 0x04);	/* SOFTWARE RESET */
 	udelay(100);
@@ -3109,15 +3170,13 @@
 	do {
 		if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0)
 			goto __si7018_ok;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		do_delay(trident);
 	} while (time_after_eq(end_time, jiffies));
 	snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
 	if (r-- > 0) {
 		end_time = jiffies + HZ;
 		do {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			do_delay(trident);
 		} while (time_after_eq(end_time, jiffies));
 		goto __si7018_retry;
 	}
@@ -3175,36 +3234,195 @@
 static void __devinit snd_trident_proc_init(trident_t * trident)
 {
 	snd_info_entry_t *entry;
-	char *s = "trident";
+	const char *s = "trident";
 	
 	if (trident->device == TRIDENT_DEVICE_ID_SI7018)
 		s = "sis7018";
-	if ((entry = snd_info_create_card_entry(trident->card, s, trident->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = trident;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_trident_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
+	if (! snd_card_proc_new(trident->card, s, &entry))
+		snd_info_set_text_ops(entry, trident, snd_trident_proc_read);
+}
+
+static int snd_trident_dev_free(snd_device_t *device)
+{
+	trident_t *trident = snd_magic_cast(trident_t, device->device_data, return -ENXIO);
+	return snd_trident_free(trident);
+}
+
+/*---------------------------------------------------------------------------
+   snd_trident_tlb_alloc
+  
+   Description: Allocate and set up the TLB page table on 4D NX.
+		Each entry has 4 bytes (physical PCI address).
+                
+   Paramters:   trident - pointer to target device class for 4DWave.
+
+   Returns:     0 or negative error code
+  
+  ---------------------------------------------------------------------------*/
+
+static int __devinit snd_trident_tlb_alloc(trident_t *trident)
+{
+	int i;
+
+	/* TLB array must be aligned to 16kB !!! so we allocate
+	   32kB region and correct offset when necessary */
+
+	trident->tlb.buffer = snd_malloc_pci_pages(trident->pci, 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer_dmaaddr);
+	if (trident->tlb.buffer == NULL) {
+		snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n");
+		return -ENOMEM;
 	}
-	trident->proc_entry = entry;
+	trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
+	trident->tlb.entries_dmaaddr = (trident->tlb.buffer_dmaaddr + 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));
+	if (trident->tlb.shadow_entries == NULL) {
+		snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
+		return -ENOMEM;
+	}
+	/* allocate and setup silent page and initialise TLB entries */
+	trident->tlb.silent_page = snd_malloc_pci_pages(trident->pci, SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page_dmaaddr);
+	if (trident->tlb.silent_page == 0UL) {
+		snd_printk(KERN_ERR "trident: unable to allocate silent page\n");
+		return -ENOMEM;
+	}
+	memset(trident->tlb.silent_page, 0, SNDRV_TRIDENT_PAGE_SIZE);
+	for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
+		trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page_dmaaddr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
+		trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page;
+	}
+
+	/* use emu memory block manager code to manage tlb page allocation */
+	trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
+	if (trident->tlb.memhdr == NULL)
+		return -ENOMEM;
+
+	trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
+	return 0;
+}
+
+/*
+ * initialize 4D DX chip
+ */
+
+static void snd_trident_stop_all_voices(trident_t *trident)
+{
+	outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
+	outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
+	outl(0, TRID_REG(trident, T4D_AINTEN_A));
+	outl(0, TRID_REG(trident, T4D_AINTEN_B));
+}
+
+static int snd_trident_4d_dx_init(trident_t *trident)
+{
+	struct pci_dev *pci = trident->pci;
+	signed long end_time;
+
+	/* reset the legacy configuration and whole audio/wavetable block */
+	pci_write_config_dword(pci, 0x40, 0);	/* DDMA */
+	pci_write_config_byte(pci, 0x44, 0);	/* ports */
+	pci_write_config_byte(pci, 0x45, 0);	/* Legacy DMA */
+	pci_write_config_byte(pci, 0x46, 4); /* reset */
+	udelay(100);
+	pci_write_config_byte(pci, 0x46, 0); /* release reset */
+	udelay(100);
+	
+	/* warm reset of the AC'97 codec */
+	outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
+	udelay(100);
+	outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
+	/* DAC on, disable SB IRQ and try to force ADC valid signal */
+	trident->ac97_ctrl = 0x0000004a;
+	outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
+	/* wait, until the codec is ready */
+	end_time = (jiffies + (HZ * 3) / 4) + 1;
+	do {
+		if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
+			goto __dx_ok;
+		do_delay(trident);
+	} while (time_after_eq(end_time, jiffies));
+	snd_printk(KERN_ERR "AC'97 codec ready error\n");
+	return -EIO;
+
+ __dx_ok:
+	snd_trident_stop_all_voices(trident);
+
+	return 0;
 }
 
-static void snd_trident_proc_done(trident_t * trident)
+/*
+ * initialize 4D NX chip
+ */
+static int snd_trident_4d_nx_init(trident_t *trident)
 {
-	if (trident->proc_entry) {
-		snd_info_unregister(trident->proc_entry);
-		trident->proc_entry = NULL;
+	struct pci_dev *pci = trident->pci;
+	signed long end_time;
+
+	/* reset the legacy configuration and whole audio/wavetable block */
+	pci_write_config_dword(pci, 0x40, 0);	/* DDMA */
+	pci_write_config_byte(pci, 0x44, 0);	/* ports */
+	pci_write_config_byte(pci, 0x45, 0);	/* Legacy DMA */
+
+	pci_write_config_byte(pci, 0x46, 1); /* reset */
+	udelay(100);
+	pci_write_config_byte(pci, 0x46, 0); /* release reset */
+	udelay(100);
+
+	/* warm reset of the AC'97 codec */
+	outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+	udelay(100);
+	outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+	/* wait, until the codec is ready */
+	end_time = (jiffies + (HZ * 3) / 4) + 1;
+	do {
+		if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
+			goto __nx_ok;
+		do_delay(trident);
+	} while (time_after_eq(end_time, jiffies));
+	snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
+	return -EIO;
+
+ __nx_ok:
+	/* DAC on */
+	trident->ac97_ctrl = 0x00000002;
+	outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+	/* disable SB IRQ */
+	outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
+
+	snd_trident_stop_all_voices(trident);
+
+	if (trident->tlb.entries != NULL) {
+		unsigned int i;
+		/* enable virtual addressing via TLB */
+		i = trident->tlb.entries_dmaaddr;
+		i |= 0x00000001;
+		outl(i, TRID_REG(trident, NX_TLBC));
+	} else {
+		outl(0, TRID_REG(trident, NX_TLBC));
 	}
+	/* initialize S/PDIF */
+	outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
+	outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
+
+	return 0;
 }
 
-static int snd_trident_dev_free(snd_device_t *device)
+/*
+ * initialize sis7018 chip
+ */
+static int snd_trident_sis_init(trident_t *trident)
 {
-	trident_t *trident = snd_magic_cast(trident_t, device->device_data, return -ENXIO);
-	return snd_trident_free(trident);
+	int err;
+
+	if ((err = snd_trident_sis_reset(trident)) < 0)
+		return err;
+
+	snd_trident_stop_all_voices(trident);
+
+	/* initialize S/PDIF */
+	outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
+
+	return 0;
 }
 
 /*---------------------------------------------------------------------------
@@ -3231,9 +3449,7 @@
 		       trident_t ** rtrident)
 {
 	trident_t *trident;
-	unsigned int i;
-	int err;
-	signed long end_time;
+	int i, err;
 	snd_trident_voice_t *voice;
 	snd_trident_pcm_mixer_t *tmix;
 	static snd_device_ops_t ops = {
@@ -3292,151 +3508,39 @@
 	trident->tlb.entries = NULL;
 	trident->tlb.buffer = NULL;
 	if (trident->device == TRIDENT_DEVICE_ID_NX) {
-		/* allocate and setup TLB page table */
-		/* each entry has 4 bytes (physical PCI address) */
-		/* TLB array must be aligned to 16kB !!! so we allocate
-		   32kB region and correct offset when necessary */
-		trident->tlb.buffer = snd_malloc_pci_pages(trident->pci, 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer_dmaaddr);
-		if (trident->tlb.buffer == NULL) {
+		if ((err = snd_trident_tlb_alloc(trident)) < 0) {
 			snd_trident_free(trident);
-			snd_printk("unable to allocate TLB buffer\n");
-			return -ENOMEM;
-		}
-		trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
-		trident->tlb.entries_dmaaddr = (trident->tlb.buffer_dmaaddr + 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));
-		if (trident->tlb.shadow_entries == NULL) {
-			snd_trident_free(trident);
-			snd_printk("unable to allocate shadow TLB entries\n");
-			return -ENOMEM;
-		}
-		/* allocate and setup silent page and initialise TLB entries */
-		trident->tlb.silent_page = snd_malloc_pci_pages(trident->pci, SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page_dmaaddr);
-		if (trident->tlb.silent_page == 0UL) {
-			snd_trident_free(trident);
-			snd_printk("unable to allocate silent page\n");
-			return -ENOMEM;
-		}
-		memset(trident->tlb.silent_page, 0, SNDRV_TRIDENT_PAGE_SIZE);
-		for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) {
-			trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page_dmaaddr & ~(SNDRV_TRIDENT_PAGE_SIZE-1));
-			trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page;
-		}
-
-		/* use emu memory block manager code to manage tlb page allocation */
-		trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES);
-		if (trident->tlb.memhdr == NULL) {
-			snd_trident_free(trident);
-			return -ENOMEM;
+			return err;
 		}
-		trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
 	}
 
-	/* reset the legacy configuration and whole audio/wavetable block */
-	if (trident->device == TRIDENT_DEVICE_ID_DX ||
-	    trident->device == TRIDENT_DEVICE_ID_NX) {
-		pci_write_config_dword(pci, 0x40, 0);	/* DDMA */
-		pci_write_config_byte(pci, 0x44, 0);	/* ports */
-		pci_write_config_byte(pci, 0x45, 0);	/* Legacy DMA */
-		if (trident->device == TRIDENT_DEVICE_ID_DX) {
-			pci_write_config_byte(pci, 0x46, 4); /* reset */
-			udelay(100);
-			pci_write_config_byte(pci, 0x46, 0); /* release reset */
-			udelay(100);
-		} else /* NX */ {
-			pci_write_config_byte(pci, 0x46, 1); /* reset */
-			udelay(100);
-			pci_write_config_byte(pci, 0x46, 0); /* release reset */
-			udelay(100);
-		}
-	}
-	
-	/* initialize chip */
+	trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
 
+	/* initialize chip */
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
-		/* warm reset of the AC'97 codec */
-		outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
-		udelay(100);
-		outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
-		/* DAC on, disable SB IRQ and try to force ADC valid signal */
-		trident->ac97_ctrl = 0x0000004a;
-		outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
-		/* wait, until the codec is ready */
-		end_time = (jiffies + (HZ * 3) / 4) + 1;
-		do {
-			if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0)
-				goto __dx_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		} while (end_time - (signed long)jiffies >= 0);
-		snd_printk("AC'97 codec ready error\n");
-		snd_trident_free(trident);
-		return -EIO;
-	      __dx_ok:
+		err = snd_trident_4d_dx_init(trident);
 		break;
 	case TRIDENT_DEVICE_ID_NX:
-		/* warm reset of the AC'97 codec */
-		outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
-		udelay(100);
-		outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
-		/* wait, until the codec is ready */
-		end_time = (jiffies + (HZ * 3) / 4) + 1;
-		do {
-			if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0)
-				goto __nx_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		} while (end_time - (signed long)jiffies >= 0);
-		snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)));
-		snd_trident_free(trident);
-		return -EIO;
-	      __nx_ok:
-		/* DAC on */
-		trident->ac97_ctrl = 0x00000002;
-		outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
-		/* disable SB IRQ */
-		outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT));
+		err = snd_trident_4d_nx_init(trident);
 		break;
 	case TRIDENT_DEVICE_ID_SI7018:
-		if ((err = snd_trident_sis_reset(trident)) < 0) {
-			snd_trident_free(trident);
-			return err;
-		}
+		err = snd_trident_sis_init(trident);
+		break;
+	default:
+		snd_BUG();
+		break;
+	}
+	if (err < 0) {
+		snd_trident_free(trident);
+		return err;
 	}
-
-	outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
-	outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
-	outl(0, TRID_REG(trident, T4D_AINTEN_A));
-	outl(0, TRID_REG(trident, T4D_AINTEN_B));
 
 	if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0) {
 		snd_trident_free(trident);
 		return err;
 	}
 	
-	if (trident->device == TRIDENT_DEVICE_ID_NX) {
-		if (trident->tlb.entries != NULL) {
-			/* enable virtual addressing via TLB */
-			i = trident->tlb.entries_dmaaddr;
-			i |= 0x00000001;
-			outl(i, TRID_REG(trident, NX_TLBC));
-		} else {
-			outl(0, TRID_REG(trident, NX_TLBC));
-		}
-		/* initialize S/PDIF */
-		trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
-		outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS));
-		outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));
-	}
-
-	if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
-		/* initialize S/PDIF */
-		trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
-		outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS));
-	}
-
 	/* initialise synth voices */
 	for (i = 0; i < 64; i++) {
 		voice = &trident->synth.voices[i];
@@ -3482,7 +3586,7 @@
 
 int snd_trident_free(trident_t *trident)
 {
-#ifndef LINUX_2_2
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
 	if (trident->gameport) {
 		gameport_unregister_port(&trident->gameport->info);
 		kfree(trident->gameport);
@@ -3495,7 +3599,6 @@
 	else if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
 		outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL));
 	}
-	snd_trident_proc_done(trident);
 	if (trident->tlb.buffer) {
 		outl(0, TRID_REG(trident, NX_TLBC));
 		if (trident->tlb.memhdr)
@@ -3568,10 +3671,10 @@
 			delta = (int)stimer - (int)voice->stimer;
 			if (delta < 0)
 				delta = -delta;
-			if (delta < voice->spurious_threshold) {
+			if ((unsigned int)delta < voice->spurious_threshold) {
 				/* do some statistics here */
 				trident->spurious_irq_count++;
-				if (trident->spurious_irq_max_delta < delta)
+				if (trident->spurious_irq_max_delta < (unsigned int)delta)
 					trident->spurious_irq_max_delta = delta;
 				continue;
 			}
@@ -3656,6 +3759,7 @@
 		pvoice->capture = 0;
 		pvoice->spdif = 0;
 		pvoice->memblk = NULL;
+		pvoice->substream = NULL;
 		spin_unlock_irqrestore(&trident->voice_alloc, flags);
 		return pvoice;
 	}
@@ -3734,9 +3838,9 @@
 {
 	snd_card_t *card = trident->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
+	trident->in_suspend = 1;
 	snd_pcm_suspend_all(trident->pcm);
 	if (trident->foldback)
 		snd_pcm_suspend_all(trident->foldback);
@@ -3750,27 +3854,40 @@
 		break;
 	}
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 void snd_trident_resume(trident_t *trident)
 {
 	snd_card_t *card = trident->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
+
+	pci_enable_device(trident->pci);
+	pci_set_dma_mask(trident->pci, 0x3fffffff); /* to be sure */
+	pci_set_master(trident->pci); /* to be sure */
+
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
+		snd_trident_4d_dx_init(trident);
+		break;
 	case TRIDENT_DEVICE_ID_NX:
-		break;			/* TODO */
+		snd_trident_4d_nx_init(trident);
+		break;
 	case TRIDENT_DEVICE_ID_SI7018:
+		snd_trident_sis_init(trident);
 		break;
 	}
+
+	snd_ac97_resume(trident->ac97);
+
+	/* 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);
-      __skip:
-	snd_power_unlock(card);
+	trident->in_suspend = 0;
 }
 
 static int snd_trident_set_power_state(snd_card_t *card, unsigned int power_state)
diff -Nru a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
--- a/sound/pci/trident/trident_memory.c	Mon Feb 10 10:39:29 2003
+++ b/sound/pci/trident/trident_memory.c	Mon Feb 10 10:39:29 2003
@@ -28,6 +28,7 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/trident.h>
+#include <sound/pcm_sgbuf.h>
 
 /* page arguments of these two macros are Trident page (4096 bytes), not like
  * aligned pages in others
@@ -166,9 +167,8 @@
 /*
  * check if the given pointer is valid for pages
  */
-static int is_valid_page(void *pages)
+static int is_valid_page(unsigned long ptr)
 {
-	unsigned long ptr = (unsigned long)virt_to_phys(pages);
 	if (ptr & ~0x3fffffffUL) {
 		snd_printk("max memory size is 1GB!!\n");
 		return 0;
@@ -184,33 +184,42 @@
  * page allocation for DMA
  */
 snd_util_memblk_t *
-snd_trident_alloc_pages(trident_t *trident, void *pages, dma_addr_t addr, unsigned long size)
+snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
 {
-	unsigned long ptr;
 	snd_util_memhdr_t *hdr;
 	snd_util_memblk_t *blk;
-	int page;
+	int idx, page;
+	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL);
 
 	snd_assert(trident != NULL, return NULL);
-	snd_assert(size > 0 && size < SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+	snd_assert(sgbuf->size > 0 && sgbuf->size < SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
 	hdr = trident->tlb.memhdr;
 	snd_assert(hdr != NULL, return NULL);
 
-	if (! is_valid_page(pages))
-		return NULL;
-
 	down(&hdr->block_mutex);
-	blk = search_empty(hdr, size);
+	blk = search_empty(hdr, sgbuf->size);
 	if (blk == NULL) {
 		up(&hdr->block_mutex);
 		return NULL;
 	}
+	if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) {
+		snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk));
+		__snd_util_mem_free(hdr, blk);
+		up(&hdr->block_mutex);
+		return NULL;
+	}
+			   
 	/* set TLB entries */
-	ptr = (unsigned long)pages;
-	for (page = firstpg(blk); page <= lastpg(blk); page++) {
+	idx = 0;
+	for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) {
+		dma_addr_t addr = sgbuf->table[idx].addr;
+		unsigned long ptr = (unsigned long)sgbuf->table[idx].buf;
+		if (! is_valid_page(addr)) {
+			__snd_util_mem_free(hdr, blk);
+			up(&hdr->block_mutex);
+			return NULL;
+		}
 		set_tlb_bus(trident, page, ptr, addr);
-		ptr += ALIGN_PAGE_SIZE;
-		addr += ALIGN_PAGE_SIZE;
 	}
 	up(&hdr->block_mutex);
 	return blk;
@@ -301,7 +310,8 @@
 	void *ptr = page_to_ptr(trident, page);
 	dma_addr_t addr = page_to_addr(trident, page);
 	set_silent_tlb(trident, page);
-	snd_free_pci_pages(trident->pci, ALIGN_PAGE_SIZE, ptr, addr);
+	if (ptr)
+		snd_free_pci_pages(trident->pci, ALIGN_PAGE_SIZE, ptr, addr);
 }
 
 /* check new allocation range */
@@ -346,7 +356,7 @@
 		ptr = snd_malloc_pci_pages(hw->pci, ALIGN_PAGE_SIZE, &addr);
 		if (ptr == NULL)
 			goto __fail;
-		if (! is_valid_page(ptr)) {
+		if (! is_valid_page(addr)) {
 			snd_free_pci_pages(hw->pci, ALIGN_PAGE_SIZE, ptr, addr);
 			goto __fail;
 		}
diff -Nru a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
--- a/sound/pci/trident/trident_synth.c	Mon Feb 10 10:39:26 2003
+++ b/sound/pci/trident/trident_synth.c	Mon Feb 10 10:39:26 2003
@@ -392,7 +392,7 @@
 					break;
 		} else {			/* attenuate right (pan left) */
 			for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ ) 
-				if (volume->lr >= pan_table[voice->Pan] )
+				if ((unsigned int)volume->lr >= pan_table[voice->Pan] )
 					break;
 			voice->Pan |= 0x40;
 		}
@@ -746,7 +746,7 @@
 	snd_trident_port_t *port = (snd_trident_port_t *) private_data;
 	trident_t *trident = port->trident;
 	snd_trident_voice_t *voice;
-	int idx;
+	unsigned int idx;
 	unsigned long flags;
 
 	if (info->voices > 32)
@@ -909,6 +909,7 @@
 						   SNDRV_SEQ_PORT_TYPE_MIDI_GS |
 						   SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
 						   SNDRV_SEQ_PORT_TYPE_SYNTH,
+						   16,
 						   name);
 	if (p->chset->port < 0) {
 		result = p->chset->port;
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	Mon Feb 10 10:39:24 2003
+++ b/sound/pci/via82xx.c	Mon Feb 10 10:39:24 2003
@@ -23,6 +23,26 @@
  *
  */
 
+/*
+ * Changes:
+ *
+ * Dec. 19, 2002	Takashi Iwai <tiwai@suse.de>
+ *	- use the DSX channels for the first pcm playback.
+ *	  (on VIA8233, 8233C and 8235 only)
+ *	  this will allow you play simultaneously up to 4 streams.
+ *	  multi-channel playback is assigned to the second device
+ *	  on these chips.
+ *	- support the secondary capture (on VIA8233/C,8235)
+ *	- SPDIF support
+ *	  the DSX3 channel can be used for SPDIF output.
+ *	  on VIA8233A, this channel is assigned to the second pcm
+ *	  playback.
+ *	  the card config of alsa-lib will assign the correct
+ *	  device for applications.
+ *	- clean up the code, separate low-level initialization
+ *	  routines for each chipset.
+ */
+
 #include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
@@ -40,11 +60,15 @@
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
+#if 0
+#define POINTER_DEBUG
+#endif
+
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("VIA VT82xx audio");
 MODULE_LICENSE("GPL");
 MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/B/C}}");
+MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
@@ -64,7 +88,7 @@
 MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
 MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
 MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT_DESC);
-MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000");
 
@@ -77,6 +101,14 @@
 #define PCI_DEVICE_ID_VIA_8233_5	0x3059
 #endif
 
+/* revision numbers for via686 */
+#define VIA_REV_686_A		0x10
+#define VIA_REV_686_B		0x11
+#define VIA_REV_686_C		0x12
+#define VIA_REV_686_D		0x13
+#define VIA_REV_686_E		0x14
+#define VIA_REV_686_H		0x20
+
 /* revision numbers for via8233 */
 #define VIA_REV_PRE_8233	0x10	/* not in market */
 #define VIA_REV_8233C		0x20	/* 2 rec, 4 pb, 1 multi-pb */
@@ -89,6 +121,7 @@
  */
 
 #define VIAREG(via, x) ((via)->port + VIA_REG_##x)
+#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x)
 
 /* common offsets */
 #define VIA_REG_OFFSET_STATUS		0x00	/* byte - channel status */
@@ -156,21 +189,51 @@
 #define   VIA_REG_AC97_CMD_MASK		0x7e
 #define   VIA_REG_AC97_DATA_SHIFT	0
 #define   VIA_REG_AC97_DATA_MASK	0xffff
+
 #define VIA_REG_SGD_SHADOW		0x84	/* dword */
+/* via686 */
+#define   VIA_REG_SGD_STAT_PB_FLAG	(1<<0)
+#define   VIA_REG_SGD_STAT_CP_FLAG	(1<<1)
+#define   VIA_REG_SGD_STAT_FM_FLAG	(1<<2)
+#define   VIA_REG_SGD_STAT_PB_EOL	(1<<4)
+#define   VIA_REG_SGD_STAT_CP_EOL	(1<<5)
+#define   VIA_REG_SGD_STAT_FM_EOL	(1<<6)
+#define   VIA_REG_SGD_STAT_PB_STOP	(1<<8)
+#define   VIA_REG_SGD_STAT_CP_STOP	(1<<9)
+#define   VIA_REG_SGD_STAT_FM_STOP	(1<<10)
+#define   VIA_REG_SGD_STAT_PB_ACTIVE	(1<<12)
+#define   VIA_REG_SGD_STAT_CP_ACTIVE	(1<<13)
+#define   VIA_REG_SGD_STAT_FM_ACTIVE	(1<<14)
+/* via8233 */
+#define   VIA8233_REG_SGD_STAT_FLAG	(1<<0)
+#define   VIA8233_REG_SGD_STAT_EOL	(1<<1)
+#define   VIA8233_REG_SGD_STAT_STOP	(1<<2)
+#define   VIA8233_REG_SGD_STAT_ACTIVE	(1<<3)
+#define   VIA8233_REG_SGD_SDX0_SHIFT	0
+#define   VIA8233_REG_SGD_SDX1_SHIFT	4
+#define   VIA8233_REG_SGD_SDX2_SHIFT	8
+#define   VIA8233_REG_SGD_SDX3_SHIFT	12
+#define   VIA8233_REG_SGD_MCHAN_SHIFT	16
+#define   VIA8233_REG_SGD_REC0_SHIFT	24
+#define   VIA8233_REG_SGD_REC1_SHIFT	28
+
+#define VIA_REG_GPI_STATUS		0x88
+#define VIA_REG_GPI_INTR		0x8c
 
 /* multi-channel and capture registers for via8233 */
 DEFINE_VIA_REGSET(MULTPLAY, 0x40);
 DEFINE_VIA_REGSET(CAPTURE_8233, 0x60);
 
 /* via8233-specific registers */
-#define VIA_REG_PLAYBACK_VOLUME_L	0x02	/* byte */
-#define VIA_REG_PLAYBACK_VOLUME_R	0x03	/* byte */
-#define VIA_REG_MULTPLAY_FORMAT		0x42	/* byte - format and channels */
+#define VIA_REG_OFS_PLAYBACK_VOLUME_L	0x02	/* byte */
+#define VIA_REG_OFS_PLAYBACK_VOLUME_R	0x03	/* byte */
+#define VIA_REG_OFS_MULTPLAY_FORMAT	0x02	/* byte - format and channels */
 #define   VIA_REG_MULTPLAY_FMT_8BIT	0x00
 #define   VIA_REG_MULTPLAY_FMT_16BIT	0x80
 #define   VIA_REG_MULTPLAY_FMT_CH_MASK	0x70	/* # channels << 4 (valid = 1,2,4,6) */
-#define VIA_REG_CAPTURE_FIFO		0x62	/* byte - bit 6 = fifo  enable */
+#define VIA_REG_OFS_CAPTURE_FIFO	0x62	/* byte - bit 6 = fifo  enable */
 #define   VIA_REG_CAPTURE_FIFO_ENABLE	0x40
+
 #define VIA_REG_CAPTURE_CHANNEL		0x63	/* byte - input select */
 #define   VIA_REG_CAPTURE_CHANNEL_MIC	0x4
 #define   VIA_REG_CAPTURE_CHANNEL_LINE	0
@@ -179,6 +242,53 @@
 #define VIA_TBL_BIT_FLAG	0x40000000
 #define VIA_TBL_BIT_EOL		0x80000000
 
+/* pci space */
+#define VIA_ACLINK_STAT		0x40
+#define  VIA_ACLINK_C11_READY	0x20
+#define  VIA_ACLINK_C10_READY	0x10
+#define  VIA_ACLINK_C01_READY	0x04 /* secondary codec ready */
+#define  VIA_ACLINK_LOWPOWER	0x02 /* low-power state */
+#define  VIA_ACLINK_C00_READY	0x01 /* primary codec ready */
+#define VIA_ACLINK_CTRL		0x41
+#define  VIA_ACLINK_CTRL_ENABLE	0x80 /* 0: disable, 1: enable */
+#define  VIA_ACLINK_CTRL_RESET	0x40 /* 0: assert, 1: de-assert */
+#define  VIA_ACLINK_CTRL_SYNC	0x20 /* 0: release SYNC, 1: force SYNC hi */
+#define  VIA_ACLINK_CTRL_SDO	0x10 /* 0: release SDO, 1: force SDO hi */
+#define  VIA_ACLINK_CTRL_VRA	0x08 /* 0: disable VRA, 1: enable VRA */
+#define  VIA_ACLINK_CTRL_PCM	0x04 /* 0: disable PCM, 1: enable PCM */
+#define  VIA_ACLINK_CTRL_FM	0x02 /* via686 only */
+#define  VIA_ACLINK_CTRL_SB	0x01 /* via686 only */
+#define  VIA_ACLINK_CTRL_INIT	(VIA_ACLINK_CTRL_ENABLE|\
+				 VIA_ACLINK_CTRL_RESET|\
+				 VIA_ACLINK_CTRL_PCM|\
+				 VIA_ACLINK_CTRL_VRA)
+#define VIA_FUNC_ENABLE		0x42
+#define  VIA_FUNC_MIDI_PNP	0x80 /* FIXME: it's 0x40 in the datasheet! */
+#define  VIA_FUNC_MIDI_IRQMASK	0x40 /* FIXME: not documented! */
+#define  VIA_FUNC_RX2C_WRITE	0x20
+#define  VIA_FUNC_SB_FIFO_EMPTY	0x10
+#define  VIA_FUNC_ENABLE_GAME	0x08
+#define  VIA_FUNC_ENABLE_FM	0x04
+#define  VIA_FUNC_ENABLE_MIDI	0x02
+#define  VIA_FUNC_ENABLE_SB	0x01
+#define VIA_PNP_CONTROL		0x43
+#define VIA_FM_NMI_CTRL		0x48
+#define VIA8233_VOLCHG_CTRL	0x48
+#define VIA8233_SPDIF_CTRL	0x49
+#define  VIA8233_SPDIF_DX3	0x08
+#define  VIA8233_SPDIF_SLOT_MASK	0x03
+#define  VIA8233_SPDIF_SLOT_1011	0x00
+#define  VIA8233_SPDIF_SLOT_34		0x01
+#define  VIA8233_SPDIF_SLOT_78		0x02
+#define  VIA8233_SPDIF_SLOT_69		0x03
+
+/*
+ */
+
+typedef struct _snd_via82xx via82xx_t;
+typedef struct via_dev viadev_t;
+#define chip_t via82xx_t
+
 /*
  * pcm stream
  */
@@ -190,15 +300,21 @@
 
 #define VIA_TABLE_SIZE	255
 
-typedef struct {
-	unsigned long reg_offset;
+struct via_dev {
+	unsigned int reg_offset;
+	unsigned long port;
+	int direction;	/* playback = 0, capture = 1 */
         snd_pcm_substream_t *substream;
 	int running;
 	unsigned int tbl_entries; /* # descriptors */
 	u32 *table; /* physical address + flag */
 	dma_addr_t table_addr;
 	struct snd_via_sg_table *idx_table;
-} viadev_t;
+	/* for recovery from the unexpected pointer */
+	unsigned int lastpos;
+	unsigned int bufsize;
+	unsigned int bufsize2;
+};
 
 
 /*
@@ -208,10 +324,10 @@
  */
 static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
 			   struct pci_dev *pci,
-			   int periods, int fragsize)
+			   unsigned int periods, unsigned int fragsize)
 {
-	int i, idx, ofs, rest;
-	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL);
+	unsigned int i, idx, ofs, rest;
+	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
 
 	if (! dev->table) {
 		/* the start of each lists must be aligned to 8 bytes,
@@ -237,8 +353,13 @@
 		 * over page boundary.
 		 */
 		do {
-			int r;
+			unsigned int r;
 			unsigned int flag;
+
+			if (idx >= VIA_TABLE_SIZE) {
+				snd_printk(KERN_ERR "via82xx: too much table size!\n");
+				return -EINVAL;
+			}
 			dev->table[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs));
 			r = PAGE_SIZE - (ofs % PAGE_SIZE);
 			if (rest < r)
@@ -257,13 +378,11 @@
 			dev->idx_table[idx].size = r;
 			ofs += r;
 			idx++;
-			if (idx >= VIA_TABLE_SIZE) {
-				snd_printk(KERN_ERR "via82xx: too much table size!\n");
-				return -EINVAL;
-			}
 		} while (rest > 0);
 	}
 	dev->tbl_entries = idx;
+	dev->bufsize = periods * fragsize;
+	dev->bufsize2 = dev->bufsize / 2;
 	return 0;
 }
 
@@ -285,10 +404,16 @@
 /*
  */
 
-enum { TYPE_VIA686 = 1, TYPE_VIA8233 };
+enum { TYPE_CARD_VIA686 = 1, TYPE_CARD_VIA8233 };
+enum { TYPE_VIA686, TYPE_VIA8233, TYPE_VIA8233A };
 
-typedef struct _snd_via82xx via82xx_t;
-#define chip_t via82xx_t
+#define VIA_MAX_DEVS	7	/* 4 playback, 1 multi, 2 capture */
+
+struct via_rate_lock {
+	spinlock_t lock;
+	int rate;
+	int used;
+};
 
 struct _snd_via82xx {
 	int irq;
@@ -301,12 +426,17 @@
 	unsigned char old_legacy;
 	unsigned char old_legacy_cfg;
 
+	unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
+
+	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
+
 	struct pci_dev *pci;
 	snd_card_t *card;
 
-	snd_pcm_t *pcm;
-	viadev_t playback;
-	viadev_t capture;
+	unsigned int num_devs;
+	unsigned int playback_devno, multi_devno, capture_devno;
+	viadev_t devs[VIA_MAX_DEVS];
+	struct via_rate_lock rates[2]; /* playback and capture */
 
 	snd_rawmidi_t *rmidi;
 
@@ -320,8 +450,8 @@
 };
 
 static struct pci_device_id snd_via82xx_ids[] __devinitdata = {
-	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA686, },	/* 686A */
-	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA8233, },	/* VT8233 */
+	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
+	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
 	{ 0, }
 };
 
@@ -351,7 +481,7 @@
 		if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
 			return val & 0xffff;
 	}
-	snd_printk("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;
 }
  
@@ -367,7 +497,7 @@
 		if ((val = snd_via82xx_codec_xread(chip)) & stat)
 			return val & 0xffff;
 	}
-	snd_printk("codec_valid: codec %i is not valid [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
+	snd_printk(KERN_ERR "codec_valid: codec %i is not valid [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
 	return -EIO;
 }
  
@@ -429,24 +559,70 @@
 
 static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
 {
-	unsigned long port = chip->port + viadev->reg_offset;
-
-	outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET, port + VIA_REG_OFFSET_CONTROL);
+	outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
+	     VIADEV_REG(viadev, OFFSET_CONTROL));
 	udelay(50);
 	/* disable interrupts */
-	outb(0x00, port + VIA_REG_OFFSET_CONTROL);
+	outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL));
 	/* clear interrupts */
-	outb(0x03, port + VIA_REG_OFFSET_STATUS);
-	outb(0x00, port + VIA_REG_OFFSET_TYPE); /* for via686 */
-	outl(0, port + VIA_REG_OFFSET_CURR_PTR);
+	outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS));
+	outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
+	// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
+	viadev->lastpos = 0;
+}
+
+
+/*
+ *  Interrupt handler
+ */
+
+static void snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	via82xx_t *chip = snd_magic_cast(via82xx_t, dev_id, return);
+	unsigned int status;
+	unsigned int i;
+
+	spin_lock(&chip->reg_lock);
+	status = inl(VIAREG(chip, SGD_SHADOW));
+	if (! (status & chip->intr_mask)) {
+		spin_unlock(&chip->reg_lock);
+		if (chip->rmidi)
+			/* check mpu401 interrupt */
+			snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+		return;
+	}
+
+	/* check status for each stream */
+	for (i = 0; i < chip->num_devs; i++) {
+		viadev_t *viadev = &chip->devs[i];
+		unsigned char status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+		status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
+		if (! status)
+			continue;
+		outb(status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+		if (viadev->substream && viadev->running) {
+			spin_unlock(&chip->reg_lock);
+			snd_pcm_period_elapsed(viadev->substream);
+			spin_lock(&chip->reg_lock);
+		}
+	}
+	spin_unlock(&chip->reg_lock);
 }
 
-static int snd_via82xx_trigger(via82xx_t *chip, viadev_t *viadev, int cmd)
+/*
+ *  PCM callbacks
+ */
+
+/*
+ * trigger callback
+ */
+static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
 {
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	unsigned char val;
-	unsigned long port = chip->port + viadev->reg_offset;
-	
-	if (chip->chip_type == TYPE_VIA8233)
+
+	if (chip->chip_type != TYPE_VIA686)
 		val = VIA_REG_CTRL_INT;
 	else
 		val = 0;
@@ -469,124 +645,121 @@
 	default:
 		return -EINVAL;
 	}
-	outb(val, port + VIA_REG_OFFSET_CONTROL);
+	outb(val, VIADEV_REG(viadev, OFFSET_CONTROL));
 	if (cmd == SNDRV_PCM_TRIGGER_STOP)
 		snd_via82xx_channel_reset(chip, viadev);
 	return 0;
 }
 
 
-static int snd_via82xx_set_format(via82xx_t *chip, viadev_t *viadev,
-				  snd_pcm_substream_t *substream)
+/*
+ * pointer callbacks
+ */
+
+/*
+ * calculate the linear position at the given sg-buffer index and the rest count
+ */
+static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	unsigned long port = chip->port + viadev->reg_offset;
+	unsigned int size, res;
 
-	snd_via82xx_channel_reset(chip, viadev);
+	size = viadev->idx_table[idx].size;
+	res = viadev->idx_table[idx].offset + size - count;
 
-	outl((u32)viadev->table_addr, port + VIA_REG_OFFSET_TABLE_PTR);
-	switch (chip->chip_type) {
-	case TYPE_VIA686:
-		outb(VIA_REG_TYPE_AUTOSTART |
-		     (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) |
-		     (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) |
-		     ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) |
-		     VIA_REG_TYPE_INT_EOL |
-		     VIA_REG_TYPE_INT_FLAG, port + VIA_REG_OFFSET_TYPE);
-		break;
-	case TYPE_VIA8233:
-		if (viadev->reg_offset == VIA_REG_MULTPLAY_STATUS) {
-			unsigned int slots;
-			int fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
-			fmt |= runtime->channels << 4;
-			outb(fmt, port + VIA_REG_OFFSET_TYPE);
-			/* set sample number to slot 3, 4, 7, 8, 6, 9 */
-			switch (runtime->channels) {
-			case 1: slots = (1<<0) | (1<<4); break;
-			case 2: slots = (1<<0) | (2<<4); break;
-			case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
-			case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break;
-			default: slots = 0; break;
-			}
-			/* STOP index is never reached */
-			outl(0xff000000 | slots, port + VIA_REG_OFFSET_STOP_IDX);
+	/* check the validity of the calculated position */
+	if (size < count || (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))) {
+#ifdef POINTER_DEBUG
+		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+#endif
+		/* count register returns full size when end of buffer is reached */
+		if (size != count) {
+			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
+			res = viadev->lastpos;
 		} else {
-			outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) |
-			     (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) |
-			     0xff000000,    /* STOP index is never reached */
-			     port + VIA_REG_OFFSET_STOP_IDX);
+			res = viadev->idx_table[idx].offset + size;
+			if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) {
+				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
+				res = viadev->lastpos;
+			}
 		}
-		break;
 	}
-	return 0;
+	viadev->lastpos = res; /* remember the last positiion */
+	if (res >= viadev->bufsize)
+		res -= viadev->bufsize;
+	return res;
 }
 
 /*
- *  Interrupt handler
+ * get the current pointer on via686
  */
-
-static inline void snd_via82xx_update(via82xx_t *chip, viadev_t *viadev)
+static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
 {
-	outb(VIA_REG_STAT_FLAG | VIA_REG_STAT_EOL, VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset);
-	if (viadev->substream && viadev->running) {
-		spin_unlock(&chip->reg_lock);
-		snd_pcm_period_elapsed(viadev->substream);
-		spin_lock(&chip->reg_lock);
-	}
-}
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	unsigned int idx, ptr, count, res;
 
-static void snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	via82xx_t *chip = snd_magic_cast(via82xx_t, dev_id, return);
-	unsigned int status;
+	snd_assert(viadev->tbl_entries, return 0);
+	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
+		return 0;
 
 	spin_lock(&chip->reg_lock);
-	if (chip->chip_type == TYPE_VIA686) {
-		/* check mpu401 interrupt */
-		status = inl(VIAREG(chip, SGD_SHADOW));
-		if ((status & 0x00000077) == 0) {
-			spin_unlock(&chip->reg_lock);
-			if (chip->rmidi != NULL)
-				snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-			return;
-		}
-	}
-	/* check status for each stream */
-	if (inb(chip->port + chip->playback.reg_offset) & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG))
-		snd_via82xx_update(chip, &chip->playback);
-	if (inb(chip->port + chip->capture.reg_offset) & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG))
-		snd_via82xx_update(chip, &chip->capture);
+	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff;
+	/* The via686a does not have the current index register,
+	 * so we need to calculate the index from CURR_PTR.
+	 */
+	ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR));
+	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;
+	res = calc_linear_pos(viadev, idx, count);
 	spin_unlock(&chip->reg_lock);
+
+	return bytes_to_frames(substream->runtime, res);
 }
 
 /*
- *  PCM part
+ * get the current pointer on via823x
  */
-
-static int snd_via82xx_playback_trigger(snd_pcm_substream_t * substream,
-					int cmd)
+static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	unsigned int idx, count, res;
+	
+	snd_assert(viadev->tbl_entries, return 0);
+	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
+		return 0;
+	spin_lock(&chip->reg_lock);
+	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+	idx = count >> 24;
+	if (idx >= viadev->tbl_entries) {
+#ifdef POINTER_DEBUG
+		printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+#endif
+		res = viadev->lastpos;
+	} else {
+		count &= 0xffffff;
+		res = calc_linear_pos(viadev, idx, count);
+	}
+	spin_unlock(&chip->reg_lock);
 
-	return snd_via82xx_trigger(chip, &chip->playback, cmd);
+	return bytes_to_frames(substream->runtime, res);
 }
 
-static int snd_via82xx_capture_trigger(snd_pcm_substream_t * substream,
-				       int cmd)
-{
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-
-	return snd_via82xx_trigger(chip, &chip->capture, cmd);
-}
 
+/*
+ * 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)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture;
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	int err;
 
-	err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params));
+	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 	if (err < 0)
 		return err;
 	err = build_via_table(viadev, substream, chip->pci,
@@ -594,105 +767,206 @@
 			      params_period_bytes(hw_params));
 	if (err < 0)
 		return err;
-	return err;
+
+	return 0;
 }
 
+/*
+ * hw_free callback:
+ * clean up the buffer description table and release the buffer
+ */
 static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture;
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 
 	clean_via_table(viadev, substream, chip->pci);
-	snd_pcm_sgbuf_free(substream);
+	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_via82xx_playback_prepare(snd_pcm_substream_t * substream)
+
+/*
+ * set up the table pointer
+ */
+static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
+{
+	snd_via82xx_codec_ready(chip, 0);
+	outl((u32)viadev->table_addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
+	udelay(20);
+	snd_via82xx_codec_ready(chip, 0);
+}
+
+/*
+ * prepare callback for playback and capture on via686
+ */
+static void via686_setup_format(via82xx_t *chip, viadev_t *viadev, snd_pcm_runtime_t *runtime)
+{
+	snd_via82xx_channel_reset(chip, viadev);
+	/* this must be set after channel_reset */
+	snd_via82xx_set_table_ptr(chip, viadev);
+	outb(VIA_REG_TYPE_AUTOSTART |
+	     (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) |
+	     (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) |
+	     ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) |
+	     VIA_REG_TYPE_INT_EOL |
+	     VIA_REG_TYPE_INT_FLAG, VIADEV_REG(viadev, OFFSET_TYPE));
+}
+
+static int snd_via686_playback_prepare(snd_pcm_substream_t *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;
 
 	snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
-	snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate);
-	snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate);
-	snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
-	if (chip->chip_type == TYPE_VIA8233 &&
-	    chip->playback.reg_offset != VIA_REG_MULTPLAY_STATUS) {
-		unsigned int tmp;
-		/* I don't understand this stuff but its from the documentation and this way it works */
-		outb(0 , VIAREG(chip, PLAYBACK_VOLUME_L));
-		outb(0 , VIAREG(chip, PLAYBACK_VOLUME_R));
-		tmp = inl(VIAREG(chip, PLAYBACK_STOP_IDX)) & ~0xfffff;
-		outl(tmp | (0xffff * runtime->rate)/(48000/16), VIAREG(chip, PLAYBACK_STOP_IDX));
-	}
-	return snd_via82xx_set_format(chip, &chip->playback, substream);
+	via686_setup_format(chip, viadev, runtime);
+	return 0;
 }
 
-static int snd_via82xx_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_via686_capture_prepare(snd_pcm_substream_t *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;
 
 	snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
-	if (chip->chip_type == TYPE_VIA8233)
-		outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIAREG(chip, CAPTURE_FIFO));
-	return snd_via82xx_set_format(chip, &chip->capture, substream);
+	via686_setup_format(chip, viadev, runtime);
+	return 0;
 }
 
-static inline unsigned int snd_via82xx_cur_ptr(via82xx_t *chip, viadev_t *viadev)
+/*
+ * lock the current rate
+ */
+static int via_lock_rate(struct via_rate_lock *rec, int rate)
 {
-	unsigned int val, ptr, count;
-	
-	snd_assert(viadev->tbl_entries, return 0);
-	if (!(inb(VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset) & VIA_REG_STAT_ACTIVE))
-		return 0;
+	int changed = 0;
 
-	count = inl(VIAREG(chip, OFFSET_CURR_COUNT) + viadev->reg_offset) & 0xffffff;
-	switch (chip->chip_type) {
-	case TYPE_VIA686:
-		/* The via686a does not have the current index register,
-		 * so we need to calculate the index from CURR_PTR.
-		 */
-		ptr = inl(VIAREG(chip, OFFSET_CURR_PTR) + viadev->reg_offset);
-		if (ptr <= (unsigned int)viadev->table_addr)
-			val = 0;
-		else /* CURR_PTR holds the address + 8 */
-			val = ((ptr - (unsigned int)viadev->table_addr) / 8 - 1) % viadev->tbl_entries;
-		break;
-
-	case TYPE_VIA8233:
-	default:
-		/* ah, this register makes life easier for us here. */
-		val = inb(VIAREG(chip, OFFSET_CURR_INDEX) + viadev->reg_offset) % viadev->tbl_entries;
-		break;
+	spin_lock(&rec->lock);
+	if (rec->rate) {
+		if (rec->rate != rate && rec->used > 1) {
+			spin_unlock(&rec->lock);
+			return -EINVAL;
+		}
+	} else {
+		rec->rate = rate;
+		changed = 1;
 	}
+	spin_unlock(&rec->lock);
+	return changed;
+}
+
+/*
+ * prepare callback for DSX playback on via823x
+ */
+static int snd_via8233_playback_prepare(snd_pcm_substream_t *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;
+	int rate_changed;
+	u32 rbits;
 
-	/* convert to the linear position */
-	return viadev->idx_table[val].offset +
-		viadev->idx_table[val].size - count;
+	if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0)
+		return rate_changed;
+	if (rate_changed) {
+		snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+		snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
+	}
+	rbits = (0xfffff / 48000) * runtime->rate + ((0xfffff % 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[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+	outb(chip->playback_volume[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 */
+	     0xff000000,    /* STOP index is never reached */
+	     VIADEV_REG(viadev, OFFSET_STOP_IDX));
+	udelay(20);
+	snd_via82xx_codec_ready(chip, 0);
+	return 0;
 }
 
-static snd_pcm_uframes_t snd_via82xx_playback_pointer(snd_pcm_substream_t * substream)
+/*
+ * prepare callback for multi-channel playback on via823x
+ */
+static int snd_via8233_multi_prepare(snd_pcm_substream_t *substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	return bytes_to_frames(substream->runtime, snd_via82xx_cur_ptr(chip, &chip->playback));
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	unsigned int slots;
+	int fmt;
+
+	if (via_lock_rate(&chip->rates[0], runtime->rate) < 0)
+		return -EINVAL;
+	snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+	snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate);
+	snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate);
+	snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
+	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->channels << 4;
+	outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT));
+	/* set sample number to slot 3, 4, 7, 8, 6, 9 */
+	/* corresponding to FL, FR, RL, RR, C, LFE ?? */
+	switch (runtime->channels) {
+	case 1: slots = (1<<0) | (1<<4); break;
+	case 2: slots = (1<<0) | (2<<4); break;
+	case 3: slots = (1<<0) | (2<<4) | (5<<8); break;
+	case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
+	case 5: slots = (1<<0) | (2<<4) | (5<<8) | (3<<12) | (4<<16); break;
+	case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break;
+	default: slots = 0; break;
+	}
+	/* STOP index is never reached */
+	outl(0xff000000 | slots, VIADEV_REG(viadev, OFFSET_STOP_IDX));
+	udelay(20);
+	snd_via82xx_codec_ready(chip, 0);
+	return 0;
 }
 
-static snd_pcm_uframes_t snd_via82xx_capture_pointer(snd_pcm_substream_t * substream)
+/*
+ * prepare callback for capture on via823x
+ */
+static int snd_via8233_capture_prepare(snd_pcm_substream_t *substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	return bytes_to_frames(substream->runtime, snd_via82xx_cur_ptr(chip, &chip->capture));
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	if (via_lock_rate(&chip->rates[1], runtime->rate) < 0)
+		return -EINVAL;
+	snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
+	snd_via82xx_channel_reset(chip, viadev);
+	snd_via82xx_set_table_ptr(chip, viadev);
+	outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIADEV_REG(viadev, OFS_CAPTURE_FIFO));
+	outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) |
+	     (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) |
+	     0xff000000,    /* STOP index is never reached */
+	     VIADEV_REG(viadev, OFFSET_STOP_IDX));
+	udelay(20);
+	snd_via82xx_codec_ready(chip, 0);
+	return 0;
 }
 
-static snd_pcm_hardware_t snd_via82xx_playback =
+
+/*
+ * pcm hardware definition, identical for both playback and capture
+ */
+static snd_pcm_hardware_t snd_via82xx_hw =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID |
 				 SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		0,
-	.rate_min =		8000,
+	.rates =		SNDRV_PCM_RATE_48000,
+	.rate_min =		48000,
 	.rate_max =		48000,
 	.channels_min =		1,
 	.channels_max =		2,
@@ -704,151 +978,315 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_via82xx_capture =
-{
-	.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,
-	.rates =		0,
-	.rate_min =		8000,
-	.rate_max =		48000,
-	.channels_min =		1,
-	.channels_max =		2,
-	.buffer_bytes_max =	128 * 1024,
-	.period_bytes_min =	32,
-	.period_bytes_max =	128 * 1024,
-	.periods_min =		2,
-	.periods_max =		VIA_TABLE_SIZE / 2,
-	.fifo_size =		0,
-};
 
-static unsigned int channels[] = {
-	1, 2, 4, 6
-};
-
-#define CHANNELS sizeof(channels) / sizeof(channels[0])
-
-static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
-	.count = CHANNELS,
-	.list = channels,
-	.mask = 0,
-};
-
-static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
+/*
+ * open callback skeleton
+ */
+static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
+	unsigned long flags;
+	struct via_rate_lock *ratep;
+
+	runtime->hw = snd_via82xx_hw;
+	
+	/* set the hw rate condition */
+	ratep = &chip->rates[viadev->direction];
+	spin_lock_irqsave(&ratep->lock, flags);
+	ratep->used++;
+	if (! ratep->rate) {
+		int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
+		runtime->hw.rates = chip->ac97->rates[idx];
+		if (runtime->hw.rates & SNDRV_PCM_RATE_8000)
+			runtime->hw.rate_min = 8000;
+	} else {
+		/* a fixed rate */
+		runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
+		runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
+	}
+	spin_unlock_irqrestore(&ratep->lock, flags);
 
-	chip->playback.substream = substream;
-	runtime->hw = snd_via82xx_playback;
-	runtime->hw.rates = chip->ac97->rates[AC97_RATES_FRONT_DAC];
-	if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
-		runtime->hw.rate_min = 48000;
-	if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
-		return err;
 	/* we may remove following constaint when we modify table entries
 	   in interrupt */
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 		return err;
-	if (chip->chip_type == TYPE_VIA8233) {
-		runtime->hw.channels_max = 6;
-		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
-	}
+
+	runtime->private_data = viadev;
+	viadev->substream = substream;
+
 	return 0;
 }
 
-static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
+
+/*
+ * open callback for playback on via686 and via823x DSX
+ */
+static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
+
+	return snd_via82xx_pcm_open(chip, viadev, substream);
+}
+
+/*
+ * open callback for playback on via823x multi-channel
+ */
+static int snd_via8233_multi_open(snd_pcm_substream_t * substream)
+{
+	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	viadev_t *viadev = &chip->devs[chip->multi_devno];
 	int err;
+	/* channels constraint for VIA8233A
+	 * 3 and 5 channels are not supported
+	 */
+	static unsigned int channels[] = {
+		1, 2, 4, 6
+	};
+	static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list = channels,
+		.mask = 0,
+	};
 
-	chip->capture.substream = substream;
-	runtime->hw = snd_via82xx_capture;
-	runtime->hw.rates = chip->ac97->rates[AC97_RATES_ADC];
-	if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
-		runtime->hw.rate_min = 48000;
-	if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0)
-		return err;
-	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+	if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
 		return err;
+	substream->runtime->hw.channels_max = 6;
+	if (chip->chip_type == TYPE_VIA8233A)
+		snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
 	return 0;
 }
 
-static int snd_via82xx_playback_close(snd_pcm_substream_t * substream)
+/*
+ * open callback for capture on via686 and via823x
+ */
+static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	chip->playback.substream = NULL;
-	snd_pcm_sgbuf_delete(substream);
-	return 0;
+	viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
+
+	return snd_via82xx_pcm_open(chip, viadev, substream);
 }
 
-static int snd_via82xx_capture_close(snd_pcm_substream_t * substream)
+/*
+ * close callback
+ */
+static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
 {
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	chip->capture.substream = NULL;
-	snd_pcm_sgbuf_delete(substream);
+	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	unsigned long flags;
+	struct via_rate_lock *ratep;
+
+	/* release the rate lock */
+	ratep = &chip->rates[viadev->direction];
+	spin_lock_irqsave(&ratep->lock, flags);
+	ratep->used--;
+	if (! ratep->used)
+		ratep->rate = 0;
+	spin_unlock_irqrestore(&ratep->lock, flags);
+
+	viadev->substream = NULL;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_via82xx_playback_ops = {
+
+/* via686 playback callbacks */
+static snd_pcm_ops_t snd_via686_playback_ops = {
 	.open =		snd_via82xx_playback_open,
-	.close =	snd_via82xx_playback_close,
+	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_via82xx_hw_params,
 	.hw_free =	snd_via82xx_hw_free,
-	.prepare =	snd_via82xx_playback_prepare,
-	.trigger =	snd_via82xx_playback_trigger,
-	.pointer =	snd_via82xx_playback_pointer,
-	.copy =		snd_pcm_sgbuf_ops_copy_playback,
-	.silence =	snd_pcm_sgbuf_ops_silence,
+	.prepare =	snd_via686_playback_prepare,
+	.trigger =	snd_via82xx_pcm_trigger,
+	.pointer =	snd_via686_pcm_pointer,
 	.page =		snd_pcm_sgbuf_ops_page,
 };
 
-static snd_pcm_ops_t snd_via82xx_capture_ops = {
+/* via686 capture callbacks */
+static snd_pcm_ops_t snd_via686_capture_ops = {
 	.open =		snd_via82xx_capture_open,
-	.close =	snd_via82xx_capture_close,
+	.close =	snd_via82xx_pcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_via82xx_hw_params,
+	.hw_free =	snd_via82xx_hw_free,
+	.prepare =	snd_via686_capture_prepare,
+	.trigger =	snd_via82xx_pcm_trigger,
+	.pointer =	snd_via686_pcm_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
+/* via823x DSX playback callbacks */
+static snd_pcm_ops_t snd_via8233_playback_ops = {
+	.open =		snd_via82xx_playback_open,
+	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_via82xx_hw_params,
 	.hw_free =	snd_via82xx_hw_free,
-	.prepare =	snd_via82xx_capture_prepare,
-	.trigger =	snd_via82xx_capture_trigger,
-	.pointer =	snd_via82xx_capture_pointer,
-	.copy =		snd_pcm_sgbuf_ops_copy_capture,
-	.silence =	snd_pcm_sgbuf_ops_silence,
+	.prepare =	snd_via8233_playback_prepare,
+	.trigger =	snd_via82xx_pcm_trigger,
+	.pointer =	snd_via8233_pcm_pointer,
 	.page =		snd_pcm_sgbuf_ops_page,
 };
 
-static void snd_via82xx_pcm_free(snd_pcm_t *pcm)
+/* via823x multi-channel playback callbacks */
+static snd_pcm_ops_t snd_via8233_multi_ops = {
+	.open =		snd_via8233_multi_open,
+	.close =	snd_via82xx_pcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_via82xx_hw_params,
+	.hw_free =	snd_via82xx_hw_free,
+	.prepare =	snd_via8233_multi_prepare,
+	.trigger =	snd_via82xx_pcm_trigger,
+	.pointer =	snd_via8233_pcm_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
+/* via823x capture callbacks */
+static snd_pcm_ops_t snd_via8233_capture_ops = {
+	.open =		snd_via82xx_capture_open,
+	.close =	snd_via82xx_pcm_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_via82xx_hw_params,
+	.hw_free =	snd_via82xx_hw_free,
+	.prepare =	snd_via8233_capture_prepare,
+	.trigger =	snd_via82xx_pcm_trigger,
+	.pointer =	snd_via8233_pcm_pointer,
+	.page =		snd_pcm_sgbuf_ops_page,
+};
+
+
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+{
+	chip->devs[idx].reg_offset = reg_offset;
+	chip->devs[idx].direction = direction;
+	chip->devs[idx].port = chip->port + reg_offset;
+}
+
+/*
+ * create pcm instances for VIA8233, 8233C and 8235 (not 8233A)
+ */
+static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
 {
-	via82xx_t *chip = snd_magic_cast(via82xx_t, pcm->private_data, return);
-	chip->pcm = NULL;
+	snd_pcm_t *pcm;
+	int i, err;
+
+	chip->playback_devno = 0;	/* x 4 */
+	chip->multi_devno = 4;		/* x 1 */
+	chip->capture_devno = 5;	/* x 2 */
+	chip->num_devs = 7;
+	chip->intr_mask = 0x33033333; /* FLAG|EOL for rec0-1, mc, sdx0-3 */
+
+	/* PCM #0:  4 DSX playbacks and 1 capture */
+	err = snd_pcm_new(chip->card, chip->card->shortname, 0, 4, 1, &pcm);
+	if (err < 0)
+		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
+	pcm->private_data = chip;
+	strcpy(pcm->name, chip->card->shortname);
+	/* set up playbacks */
+	for (i = 0; i < 4; i++)
+		init_viadev(chip, i, 0x10 * i, 0);
+	/* capture */
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+
+	if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0)
+		return err;
+
+	/* PCM #1:  multi-channel playback and 2nd capture */
+	err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
+	pcm->private_data = chip;
+	strcpy(pcm->name, chip->card->shortname);
+	/* set up playback */
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	/* set up capture */
+	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
+
+	if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0)
+		return err;
+
+	return 0;
 }
 
-static int __devinit snd_via82xx_pcm(via82xx_t *chip, int device, snd_pcm_t ** rpcm)
+/*
+ * create pcm instances for VIA8233A
+ */
+static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
 {
 	snd_pcm_t *pcm;
 	int err;
 
-	if (rpcm)
-		*rpcm = NULL;
-	err = snd_pcm_new(chip->card, chip->card->shortname, device, 1, 1, &pcm);
+	chip->multi_devno = 0;
+	chip->playback_devno = 1;
+	chip->capture_devno = 2;
+	chip->num_devs = 3;
+	chip->intr_mask = 0x03033000; /* FLAG|EOL for rec0, mc, sdx3 */
+
+	/* PCM #0:  multi-channel playback and capture */
+	err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
 	if (err < 0)
 		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops);
+	pcm->private_data = chip;
+	strcpy(pcm->name, chip->card->shortname);
+	/* set up playback */
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	/* capture */
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
 
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via82xx_playback_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via82xx_capture_ops);
+	if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0)
+		return err;
 
+	/* PCM #1:  DXS3 playback (for spdif) */
+	err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 0, &pcm);
+	if (err < 0)
+		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops);
 	pcm->private_data = chip;
-	pcm->private_free = snd_via82xx_pcm_free;
-	pcm->info_flags = 0;
 	strcpy(pcm->name, chip->card->shortname);
-	chip->pcm = pcm;
+	/* set up playback */
+	init_viadev(chip, chip->playback_devno, 0x30, 0);
+
+	if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+ * create a pcm instance for via686a/b
+ */
+static int __devinit snd_via686_pcm_new(via82xx_t *chip)
+{
+	snd_pcm_t *pcm;
+	int err;
+
+	chip->playback_devno = 0;
+	chip->capture_devno = 1;
+	chip->num_devs = 2;
+	chip->intr_mask = 0x77; /* FLAG | EOL for PB, CP, FM */
+
+	err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+	pcm->private_data = chip;
+	strcpy(pcm->name, chip->card->shortname);
+	init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
+	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
+
+	if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0)
+		return err;
 
-	if (rpcm)
-		*rpcm = NULL;
 	return 0;
 }
 
@@ -874,23 +1312,25 @@
 static int snd_via8233_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.enumerated.item[0] = inb(VIAREG(chip, CAPTURE_CHANNEL)) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0;
+	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)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	unsigned long port = chip->port + kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL;
 	unsigned long flags;
 	u8 val, oval;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
-	oval = inb(VIAREG(chip, CAPTURE_CHANNEL));
+	oval = inb(port);
 	val = oval & ~VIA_REG_CAPTURE_CHANNEL_MIC;
 	if (ucontrol->value.enumerated.item[0])
 		val |= VIA_REG_CAPTURE_CHANNEL_MIC;
 	if (val != oval)
-		outb(val, VIAREG(chip, CAPTURE_CHANNEL));
+		outb(val, port);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	return val != oval;
 }
@@ -903,13 +1343,101 @@
 	.put = snd_via8233_capture_source_put,
 };
 
+static int snd_via8233_dxs3_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 snd_via8233_dxs3_spdif_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	u8 val;
+
+	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
+	ucontrol->value.integer.value[0] = (val & VIA8233_SPDIF_DX3) ? 1 : 0;
+	return 0;
+}
+
+static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	u8 val, oval;
+
+	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &oval);
+	val = oval & ~VIA8233_SPDIF_DX3;
+	if (ucontrol->value.integer.value[0])
+		val |= VIA8233_SPDIF_DX3;
+	if (val != oval) {
+		pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
+		return 1;
+	}
+	return 0;
+}
+
+static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = {
+	.name = "IEC958 Output Switch",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_via8233_dxs3_spdif_info,
+	.get = snd_via8233_dxs3_spdif_get,
+	.put = snd_via8233_dxs3_spdif_put,
+};
+
+static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 0xff;
+	return 0;
+}
+
+static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = 0xff - chip->playback_volume[0];
+	ucontrol->value.integer.value[1] = 0xff - chip->playback_volume[1];
+	return 0;
+}
+
+static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	unsigned char val;
+	int change;
+
+	val = 0xff - ucontrol->value.integer.value[0];
+	change = val != chip->playback_volume[0];
+	if (val)
+		chip->playback_volume[0] = val;
+	val = 0xff - ucontrol->value.integer.value[1];
+	change |= val != chip->playback_volume[1];
+	if (val)
+		chip->playback_volume[1] = val;
+	return change;
+}
+
+static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+	.name = "VIA DXS Playback Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = snd_via8233_dxs_volume_info,
+	.get = snd_via8233_dxs_volume_get,
+	.put = snd_via8233_dxs_volume_put,
+};
+
+/*
+ */
+
 static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
 {
 	via82xx_t *chip = snd_magic_cast(via82xx_t, ac97->private_data, return);
 	chip->ac97 = NULL;
 }
 
-static int __devinit snd_via82xx_mixer(via82xx_t *chip)
+static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
 {
 	ac97_t ac97;
 	int err;
@@ -923,6 +1451,12 @@
 	ac97.clock = chip->ac97_clock;
 	if ((err = snd_ac97_mixer(chip->card, &ac97, &chip->ac97)) < 0)
 		return err;
+
+	if (chip->chip_type != TYPE_VIA686) {
+		/* use slot 10/11 */
+		snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
+	}
+
 	return 0;
 }
 
@@ -944,8 +1478,8 @@
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
 	u16 val;
 
-	pci_read_config_word(chip->pci, 0x42, &val);
-	ucontrol->value.integer.value[0] = (val & 0x08) ? 1 : 0;
+	pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &val);
+	ucontrol->value.integer.value[0] = (val & VIA_FUNC_ENABLE_GAME) ? 1 : 0;
 	return 0;
 }
 
@@ -954,12 +1488,12 @@
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
 	u16 val, oval;
 
-	pci_read_config_word(chip->pci, 0x42, &oval);
-	val = oval & ~0x08;
+	pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &oval);
+	val = oval & ~VIA_FUNC_ENABLE_GAME;
 	if (ucontrol->value.integer.value[0])
-		val |= 0x08;
+		val |= VIA_FUNC_ENABLE_GAME;
 	if (val != oval) {
-		pci_write_config_word(chip->pci, 0x42, val);
+		pci_write_config_word(chip->pci, VIA_FUNC_ENABLE, val);
 		return 1;
 	}
 	return 0;
@@ -977,6 +1511,107 @@
  *
  */
 
+static int snd_via8233_init_misc(via82xx_t *chip, int dev)
+{
+	int i, err, caps;
+	unsigned char val;
+
+	caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2;
+	for (i = 0; i < caps; i++) {
+		snd_via8233_capture_source.index = i;
+		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_capture_source, chip));
+		if (err < 0)
+			return err;
+	}
+	err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip));
+	if (err < 0)
+		return err;
+	err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
+	if (err < 0)
+		return err;
+
+	/* select spdif data slot 10/11 */
+	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
+	val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
+	pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
+
+	return 0;
+}
+
+static int snd_via686_init_misc(via82xx_t *chip, int dev)
+{
+	unsigned char legacy, legacy_cfg;
+	int rev_h = 0;
+
+	legacy = chip->old_legacy;
+	legacy_cfg = chip->old_legacy_cfg;
+	legacy |= VIA_FUNC_MIDI_IRQMASK;	/* FIXME: correct? (disable MIDI) */
+	legacy &= ~VIA_FUNC_ENABLE_GAME;	/* disable joystick */
+	if (chip->revision >= VIA_REV_686_H) {
+		rev_h = 1;
+		if (check_region(pci_resource_start(chip->pci, 2), 4))
+			legacy &= ~VIA_FUNC_MIDI_PNP;	/* disable PCI I/O 2 */
+		else
+			legacy |= VIA_FUNC_MIDI_PNP;	/* enable PCI I/O 2 */
+	}
+	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
+	pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
+	if (rev_h) {
+		if (mpu_port[dev] >= 0x200) {	/* force MIDI */
+			pci_write_config_dword(chip->pci, 0x18, (mpu_port[dev] & 0xfffc) | 0x01);
+		} else if (legacy & VIA_FUNC_MIDI_PNP) {
+			mpu_port[dev] = pci_resource_start(chip->pci, 2);
+			if (mpu_port[dev] < 0x200)	/* bad value */
+				legacy &= ~VIA_FUNC_ENABLE_MIDI;	/* disable MIDI */
+		}
+		if (mpu_port[dev] >= 0x200)
+			legacy |= VIA_FUNC_ENABLE_MIDI;
+		else
+			legacy &= ~VIA_FUNC_ENABLE_MIDI;
+	} else {
+		switch (mpu_port[dev]) {	/* force MIDI */
+		case 0x300:
+		case 0x310:
+		case 0x320:
+		case 0x330:
+			legacy_cfg &= ~(3 << 2);
+			legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
+			legacy |= VIA_FUNC_ENABLE_MIDI;
+			break;
+		default:			/* no, use BIOS settings */
+			if (legacy & VIA_FUNC_ENABLE_MIDI)
+				mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
+			break;
+		}
+	}
+	if (legacy & VIA_FUNC_ENABLE_MIDI) {
+		if (check_region(mpu_port[dev], 2)) {
+			printk(KERN_WARNING "unable to get MPU-401 port at 0x%lx, skipping\n", mpu_port[dev]);
+			legacy &= ~VIA_FUNC_ENABLE_MIDI;
+		} else if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
+					       mpu_port[dev], 0,
+					       chip->irq, 0,
+					       &chip->rmidi) < 0) {
+			printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
+			legacy &= ~VIA_FUNC_ENABLE_MIDI;
+		}
+	}
+	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
+	pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
+	if (legacy & VIA_FUNC_ENABLE_MIDI) {
+		legacy &= ~VIA_FUNC_MIDI_IRQMASK;	/* enable MIDI interrupt */
+		pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
+	}
+	
+	/* card switches */
+	return snd_ctl_add(chip->card, snd_ctl_new1(&snd_via82xx_joystick_control, chip));
+}
+
+
+/*
+ *
+ */
+
 static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
 {
 	ac97_t ac97;
@@ -990,40 +1625,46 @@
 #if 0 /* broken on K7M? */
 	if (chip->chip_type == TYPE_VIA686)
 		/* disable all legacy ports */
-		pci_write_config_byte(chip->pci, 0x42, 0);
+		pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, 0);
 #endif
-	pci_read_config_byte(chip->pci, 0x40, &pval);
-	if (! (pval & 0x01)) { /* codec not ready? */
+	pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
+	if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */
 		/* deassert ACLink reset, force SYNC */
-		pci_write_config_byte(chip->pci, 0x41, 0xe0);
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
+				      VIA_ACLINK_CTRL_ENABLE |
+				      VIA_ACLINK_CTRL_RESET |
+				      VIA_ACLINK_CTRL_SYNC);
 		udelay(100);
+#if 1 /* FIXME: should we do full reset here for all chip models? */
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00);
+		udelay(100);
+#else
 		/* deassert ACLink reset, force SYNC (warm AC'97 reset) */
-		pci_write_config_byte(chip->pci, 0x41, 0x60);
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL,
+				      VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC);
 		udelay(2);
-		/* pci_write_config_byte(chip->pci, 0x41, 0x00);
-		   udelay(100);
-		*/
+#endif
 		/* ACLink on, deassert ACLink reset, VSR, SGD data out */
 		/* note - FM data out has trouble with non VRA codecs !! */
-		pci_write_config_byte(chip->pci, 0x41, 0xcc);
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
 		udelay(100);
 	}
 	
 	/* Make sure VRA is enabled, in case we didn't do a
 	 * complete codec reset, above */
-	pci_read_config_byte(chip->pci, 0x41, &pval);
-	if ((pval & 0xcc) != 0xcc) {
+	pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval);
+	if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) {
 		/* ACLink on, deassert ACLink reset, VSR, SGD data out */
 		/* note - FM data out has trouble with non VRA codecs !! */
-		pci_write_config_byte(chip->pci, 0x41, 0xcc);
+		pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT);
 		udelay(100);
 	}
 
 	/* wait until codec ready */
 	max_count = ((3 * HZ) / 4) + 1;
 	do {
-		pci_read_config_byte(chip->pci, 0x40, &pval);
-		if (pval & 0x01) /* primary codec ready */
+		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
+		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
@@ -1060,25 +1701,23 @@
 
 	if (chip->chip_type == TYPE_VIA686) {
 		/* route FM trap to IRQ, disable FM trap */
-		pci_write_config_byte(chip->pci, 0x48, 0);
+		pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0);
 		/* disable all GPI interrupts */
-		outl(0, chip->port + 0x8c);
+		outl(0, VIAREG(chip, GPI_INTR));
 	}
 
-	/* disable interrupts */
-	snd_via82xx_channel_reset(chip, &chip->playback);
-	snd_via82xx_channel_reset(chip, &chip->capture);
 	return 0;
 }
 
 static int snd_via82xx_free(via82xx_t *chip)
 {
+	unsigned int i;
+
 	if (chip->irq < 0)
 		goto __end_hw;
 	/* disable interrupts */
-	snd_via82xx_channel_reset(chip, &chip->playback);
-	snd_via82xx_channel_reset(chip, &chip->capture);
-	/* --- */
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 	synchronize_irq(chip->irq);
       __end_hw:
 	if (chip->res_port) {
@@ -1088,8 +1727,8 @@
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
 	if (chip->chip_type == TYPE_VIA686) {
-		pci_write_config_byte(chip->pci, 0x42, chip->old_legacy);
-		pci_write_config_byte(chip->pci, 0x43, chip->old_legacy_cfg);
+		pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy);
+		pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
 	}
 	snd_magic_kfree(chip);
 	return 0;
@@ -1104,6 +1743,7 @@
 static int __devinit snd_via82xx_create(snd_card_t * card,
 					struct pci_dev *pci,
 					int chip_type,
+					int revision,
 					unsigned int ac97_clock,
 					via82xx_t ** r_via)
 {
@@ -1120,15 +1760,18 @@
 		return -ENOMEM;
 
 	chip->chip_type = chip_type;
+	chip->revision = revision;
 
 	spin_lock_init(&chip->reg_lock);
 	spin_lock_init(&chip->ac97_lock);
+	spin_lock_init(&chip->rates[0].lock);
+	spin_lock_init(&chip->rates[1].lock);
 	chip->card = card;
 	chip->pci = pci;
 	chip->irq = -1;
 
-	pci_read_config_byte(pci, 0x42, &chip->old_legacy);
-	pci_read_config_byte(pci, 0x43, &chip->old_legacy_cfg);
+	pci_read_config_byte(pci, VIA_FUNC_ENABLE, &chip->old_legacy);
+	pci_read_config_byte(pci, VIA_PNP_CONTROL, &chip->old_legacy_cfg);
 
 	chip->port = pci_resource_start(pci, 0);
 	if ((chip->res_port = request_region(chip->port, 256, card->driver)) == NULL) {
@@ -1145,24 +1788,8 @@
 	chip->irq = pci->irq;
 	if (ac97_clock >= 8000 && ac97_clock <= 48000)
 		chip->ac97_clock = ac97_clock;
-	pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision);
 	synchronize_irq(chip->irq);
 
-	/* initialize offsets */
-	switch (chip->chip_type) {
-	case TYPE_VIA686:
-		chip->playback.reg_offset = VIA_REG_PLAYBACK_STATUS;
-		chip->capture.reg_offset = VIA_REG_CAPTURE_STATUS;
-		break;
-	case TYPE_VIA8233:
-		/* we use multi-channel playback mode, since this mode is supported
-		 * by all VIA8233 models (and obviously suitable for our purpose).
-		 */
-		chip->playback.reg_offset = VIA_REG_MULTPLAY_STATUS;
-		chip->capture.reg_offset = VIA_REG_CAPTURE_8233_STATUS;
-		break;
-	}
-
 	if ((err = snd_via82xx_chip_init(chip)) < 0) {
 		snd_via82xx_free(chip);
 		return err;
@@ -1182,14 +1809,28 @@
 	return 0;
 }
 
+struct via823x_info {
+	int revision;
+	char *name;
+	int type;
+};
+static struct via823x_info via823x_cards[] __devinitdata = {
+	{ VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 },
+	{ VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 },
+	{ VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
+	{ VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
+	{ VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
+};
+
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
 	static int dev;
 	snd_card_t *card;
 	via82xx_t *chip;
-	int pcm_dev = 0;
-	int chip_type;
+	unsigned char revision;
+	int chip_type = 0, card_type;
+	unsigned int i;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1203,124 +1844,59 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	chip_type = pci_id->driver_data;
-	switch (chip_type) {
-	case TYPE_VIA686:
+	card_type = pci_id->driver_data;
+	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
+	switch (card_type) {
+	case TYPE_CARD_VIA686:
 		strcpy(card->driver, "VIA686A");
-		strcpy(card->shortname, "VIA 82C686A/B");
+		sprintf(card->shortname, "VIA 82C686A/B rev%x", revision);
+		chip_type = TYPE_VIA686;
 		break;
-	case TYPE_VIA8233:
-		strcpy(card->driver, "VIA8233");
-		strcpy(card->shortname, "VIA 8233A/C");
+	case TYPE_CARD_VIA8233:
+		chip_type = TYPE_VIA8233;
+		sprintf(card->shortname, "VIA 823x rev%x", revision);
+		for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) {
+			if (revision == via823x_cards[i].revision) {
+				chip_type = via823x_cards[i].type;
+				strcpy(card->shortname, via823x_cards[i].name);
+				break;
+			}
+		}
+		if (chip_type == VIA_REV_8233A)
+			strcpy(card->driver, "VIA8233A");
+		else
+			strcpy(card->driver, "VIA8233");
 		break;
 	default:
-		snd_printk(KERN_ERR "invalid chip type %d\n", chip_type);
-		snd_card_free(card);
-		return -EINVAL;
+		snd_printk(KERN_ERR "invalid card type %d\n", card_type);
+		err = -EINVAL;
+		goto __error;
 	}
 		
-	if ((err = snd_via82xx_create(card, pci, chip_type, ac97_clock[dev], &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-
-
-	if (snd_via82xx_mixer(chip) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if (snd_via82xx_pcm(chip, pcm_dev++, NULL) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-#if 0
-	if (snd_via82xx_pcm_fm(chip, pcm_dev++, NULL) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-#endif
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+		goto __error;
 
-	if (chip->chip_type == TYPE_VIA686) {
-		unsigned char legacy, legacy_cfg;
-		int rev_h = 0;
-		legacy = chip->old_legacy;
-		legacy_cfg = chip->old_legacy_cfg;
-		legacy |= 0x40;		/* disable MIDI */
-		legacy &= ~0x08;	/* disable joystick */
-		if (chip->revision >= 0x20) {
-			if (check_region(pci_resource_start(pci, 2), 4)) {
-				rev_h = 0;
-				legacy &= ~0x80;	/* disable PCI I/O 2 */
-			} else {
-				rev_h = 1;
-				legacy |= 0x80;		/* enable PCI I/O 2 */
-			}
-		}
-		pci_write_config_byte(pci, 0x42, legacy);
-		pci_write_config_byte(pci, 0x43, legacy_cfg);
-		if (rev_h && mpu_port[dev] >= 0x200) {	/* force MIDI */
-			legacy |= 0x02;	/* enable MPU */
-			pci_write_config_dword(pci, 0x18, (mpu_port[dev] & 0xfffc) | 0x01);
-		} else {
-			if (rev_h && (legacy & 0x02)) {
-				mpu_port[dev] = pci_resource_start(pci, 2);
-				if (mpu_port[dev] < 0x200)	/* bad value */
-					legacy &= ~0x02;	/* disable MIDI */
-			} else {
-				switch (mpu_port[dev]) {	/* force MIDI */
-				case 0x300:
-				case 0x310:
-				case 0x320:
-				case 0x330:
-					legacy_cfg &= ~(3 << 2);
-					legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
-					legacy |= 0x02;
-					break;
-				default:			/* no, use BIOS settings */
-					if (legacy & 0x02)
-						mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
-				}
-			}
-		}
-		pci_write_config_byte(pci, 0x42, legacy);
-		pci_write_config_byte(pci, 0x43, legacy_cfg);
-		if (legacy & 0x02) {
-			if (check_region(mpu_port[dev], 2)) {
-				printk(KERN_WARNING "unable to get MPU-401 port at 0x%lx, skipping\n", mpu_port[dev]);
-				legacy &= ~0x02;
-				pci_write_config_byte(pci, 0x42, legacy);
-				goto __skip_mpu;
-			}
-			if (snd_mpu401_uart_new(card, 0, MPU401_HW_VIA686A,
-						mpu_port[dev], 0,
-						pci->irq, 0,
-						&chip->rmidi) < 0) {
-				printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
-				legacy &= ~0x02;
-				pci_write_config_byte(pci, 0x42, legacy);
-				goto __skip_mpu;
-			}
-			legacy &= ~0x40;	/* enable MIDI interrupt */
-			pci_write_config_byte(pci, 0x42, legacy);
-		__skip_mpu:
-			;
-		}
-	
-		/* card switches */
-		err = snd_ctl_add(card, snd_ctl_new1(&snd_via82xx_joystick_control, chip));
-		if (err < 0) {
-			snd_card_free(card);
-			return err;
-		}
+	if ((err = snd_via82xx_mixer_new(chip)) < 0)
+		goto __error;
 
+	if (chip_type == TYPE_VIA686) {
+		if ((err = snd_via686_pcm_new(chip)) < 0 ||
+		    (err = snd_via686_init_misc(chip, dev)) < 0)
+			goto __error;
 	} else {
-		/* VIA8233 */
-		err = snd_ctl_add(card, snd_ctl_new1(&snd_via8233_capture_source, chip));
-		if (err < 0) {
-			snd_card_free(card);
-			return err;
+		if (chip_type == VIA_REV_8233A) {
+			if ((err = snd_via8233a_pcm_new(chip)) < 0)
+				goto __error;
+		} else {
+			if ((err = snd_via8233_pcm_new(chip)) < 0)
+				goto __error;
 		}
+		if ((err = snd_via8233_init_misc(chip, dev)) < 0)
+			goto __error;
 	}
+	/* disable interrupts */
+	for (i = 0; i < chip->num_devs; i++)
+		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 
 	sprintf(card->longname, "%s at 0x%lx, irq %d",
 		card->shortname, chip->port, chip->irq);
@@ -1332,6 +1908,10 @@
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ __error:
+	snd_card_free(card);
+	return err;
 }
 
 static void __devexit snd_via82xx_remove(struct pci_dev *pci)
@@ -1391,4 +1971,3 @@
 __setup("snd-via82xx=", alsa_card_via82xx_setup);
 
 #endif /* ifndef MODULE */
- 
diff -Nru a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
--- a/sound/pci/ymfpci/ymfpci_main.c	Mon Feb 10 10:39:31 2003
+++ b/sound/pci/ymfpci/ymfpci_main.c	Mon Feb 10 10:39:31 2003
@@ -624,7 +624,7 @@
 	// ymfpci_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	ymfpci_pcm_t *ypcm = snd_magic_cast(ymfpci_pcm_t, runtime->private_data, return -ENXIO);
-	int nvoice;
+	unsigned int nvoice;
 
 	ypcm->period_size = runtime->period_size;
 	ypcm->buffer_size = runtime->buffer_size;
@@ -926,7 +926,7 @@
 			  snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2);
 	ymfpci_open_extension(chip);
 	chip->spdif_pcm_bits = chip->spdif_bits;
-	snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
+	snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits);
 	chip->spdif_opened++;
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 
@@ -1170,6 +1170,7 @@
 {
 	ymfpci_t *chip = snd_magic_cast(ymfpci_t, pcm->private_data, return);
 	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)
@@ -1190,6 +1191,9 @@
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "YMFPCI - IEC958");
 	chip->pcm_spdif = pcm;
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 256*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1210,6 +1214,7 @@
 {
 	ymfpci_t *chip = snd_magic_cast(ymfpci_t, pcm->private_data, return);
 	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)
@@ -1230,6 +1235,9 @@
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "YMFPCI - Rear PCM");
 	chip->pcm_4ch = pcm;
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 256*1024);
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1306,8 +1314,8 @@
 static snd_kcontrol_new_t snd_ymfpci_spdif_mask __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
-	.iface =		SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =           SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
 	.info =		snd_ymfpci_spdif_mask_info,
 	.get =		snd_ymfpci_spdif_mask_get,
 };
@@ -1354,8 +1362,8 @@
 static snd_kcontrol_new_t snd_ymfpci_spdif_stream __devinitdata =
 {
 	.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),
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
 	.info =		snd_ymfpci_spdif_stream_info,
 	.get =		snd_ymfpci_spdif_stream_get,
 	.put =		snd_ymfpci_spdif_stream_put
@@ -1654,7 +1662,8 @@
 {
 	ac97_t ac97;
 	snd_kcontrol_t *kctl;
-	int err, idx;
+	unsigned int idx;
+	int err;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.write = snd_ymfpci_codec_write;
@@ -1766,16 +1775,16 @@
 static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.integer.value[0] = chip->joystick_port;
+	ucontrol->value.enumerated.item[0] = chip->joystick_port;
 	return 0;
 }
 
 static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	if (ucontrol->value.integer.value[0] != chip->joystick_port) {
-		snd_assert(ucontrol->value.integer.value[0] >= 0 && ucontrol->value.integer.value[0] < 4, return -EINVAL);
-		chip->joystick_port = ucontrol->value.integer.value[0];
+	if (ucontrol->value.enumerated.item[0] != chip->joystick_port) {
+		snd_assert(ucontrol->value.enumerated.item[0] >= 0 && ucontrol->value.enumerated.item[0] < 4, return -EINVAL);
+		chip->joystick_port = ucontrol->value.enumerated.item[0];
 		setup_joystick_base(chip);
 		return 1;
 	}
@@ -1827,26 +1836,8 @@
 {
 	snd_info_entry_t *entry;
 	
-	entry = snd_info_create_card_entry(card, "ymfpci", card->proc_root);
-	if (entry) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = chip;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 4096;
-		entry->c.text.read = snd_ymfpci_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_unregister(entry);
-			entry = NULL;
-		}
-	}
-	chip->proc_entry = entry;
-	return 0;
-}
-
-static int snd_ymfpci_proc_done(ymfpci_t *chip)
-{
-	if (chip->proc_entry)
-		snd_info_unregister((snd_info_entry_t *) chip->proc_entry);
+	if (! snd_card_proc_new(card, "ymfpci", &entry))
+		snd_info_set_text_ops(entry, chip, snd_ymfpci_proc_read);
 	return 0;
 }
 
@@ -2037,7 +2028,6 @@
 	u16 ctrl;
 
 	snd_assert(chip != NULL, return -EINVAL);
-	snd_ymfpci_proc_done(chip);
 
 	if (chip->res_reg_area) {	/* don't touch busy hardware */
 		snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
@@ -2125,11 +2115,10 @@
 void snd_ymfpci_suspend(ymfpci_t *chip)
 {
 	snd_card_t *card = chip->card;
-	int i;
+	unsigned int i;
 	
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 	snd_pcm_suspend_all(chip->pcm);
 	snd_pcm_suspend_all(chip->pcm2);
 	snd_pcm_suspend_all(chip->pcm_spdif);
@@ -2140,19 +2129,15 @@
 	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
 	snd_ymfpci_disable_dsp(chip);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 void snd_ymfpci_resume(ymfpci_t *chip)
 {
 	snd_card_t *card = chip->card;
-	int i;
-
-	snd_power_lock(card);
+	unsigned int i;
 
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	pci_enable_device(chip->pci);
 	pci_set_master(chip->pci);
@@ -2174,8 +2159,6 @@
 		spin_unlock(&chip->reg_lock);
 	}
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static int snd_ymfpci_set_power_state(snd_card_t *card, unsigned int power_state)
diff -Nru a/sound/ppc/keywest.c b/sound/ppc/keywest.c
--- a/sound/ppc/keywest.c	Mon Feb 10 10:39:33 2003
+++ b/sound/ppc/keywest.c	Mon Feb 10 10:39:33 2003
@@ -22,6 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/delay.h>
 #include <linux/i2c-dev.h>
 #include <linux/slab.h>
 #include <sound/core.h>
diff -Nru a/sound/ppc/pmac.c b/sound/ppc/pmac.c
--- a/sound/ppc/pmac.c	Mon Feb 10 10:39:33 2003
+++ b/sound/ppc/pmac.c	Mon Feb 10 10:39:33 2003
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <sound/core.h>
 #include "pmac.h"
 #include <sound/pcm_params.h>
@@ -695,6 +696,7 @@
 }
 
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 
 /*
  * beep stuff
@@ -931,6 +933,8 @@
 	return 0;
 }
 
+#endif /* beep stuff */
+
 static void snd_pmac_dbdma_reset(pmac_t *chip)
 {
 	out_le32(&chip->playback.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
@@ -1460,9 +1464,8 @@
 	unsigned long flags;
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		goto __skip;
+		return;
 
 	if (chip->suspend)
 		chip->suspend(chip);
@@ -1476,17 +1479,14 @@
 	disable_irq(chip->rx_irq);
 	snd_pmac_sound_feature(chip, 0);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 static void snd_pmac_resume(pmac_t *chip)
 {
 	snd_card_t *card = chip->card;
 
-	snd_power_lock(card);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
-		goto __skip;
+		return;
 
 	snd_pmac_sound_feature(chip, 1);
 	if (chip->resume)
@@ -1505,8 +1505,6 @@
 	enable_irq(chip->rx_irq);
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-      __skip:
-      	snd_power_unlock(card);
 }
 
 /* the chip is stored statically by snd_pmac_register_sleep_notifier
diff -Nru a/sound/ppc/powermac.c b/sound/ppc/powermac.c
--- a/sound/ppc/powermac.c	Mon Feb 10 10:39:33 2003
+++ b/sound/ppc/powermac.c	Mon Feb 10 10:39:33 2003
@@ -129,8 +129,10 @@
 		goto __error;
 
 	chip->initialized = 1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	if (enable_beep)
 		snd_pmac_attach_beep(chip);
+#endif
 
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
@@ -151,7 +153,7 @@
 static int __init alsa_card_pmac_init(void)
 {
 	int err;
-	if ((err = snd_pmac_probe() < 0)) {
+	if ((err = snd_pmac_probe()) < 0) {
 #ifdef MODULE
 		printk(KERN_ERR "no PMac soundchip found\n");
 #endif
diff -Nru a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
--- a/sound/ppc/tumbler.c	Mon Feb 10 10:39:23 2003
+++ b/sound/ppc/tumbler.c	Mon Feb 10 10:39:23 2003
@@ -26,6 +26,7 @@
 #include <linux/i2c-dev.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <sound/core.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff -Nru a/sound/sound_firmware.c b/sound/sound_firmware.c
--- a/sound/sound_firmware.c	Mon Feb 10 10:39:23 2003
+++ b/sound/sound_firmware.c	Mon Feb 10 10:39:23 2003
@@ -1,47 +1,46 @@
 #include <linux/vmalloc.h>
-#define __KERNEL_SYSCALLS__
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/unistd.h>
 #include <asm/uaccess.h>
 
 static int do_mod_firmware_load(const char *fn, char **fp)
 {
-	int fd;
+	struct file* filp;
 	long l;
 	char *dp;
+	loff_t pos;
 
-	fd = open(fn, 0, 0);
-	if (fd == -1)
+	filp = filp_open(fn, 0, 0);
+	if (IS_ERR(filp))
 	{
 		printk(KERN_INFO "Unable to load '%s'.\n", fn);
 		return 0;
 	}
-	l = lseek(fd, 0L, 2);
+	l = filp->f_dentry->d_inode->i_size;
 	if (l <= 0 || l > 131072)
 	{
 		printk(KERN_INFO "Invalid firmware '%s'\n", fn);
-		sys_close(fd);
+		filp_close(filp, current->files);
 		return 0;
 	}
-	lseek(fd, 0L, 0);
 	dp = vmalloc(l);
 	if (dp == NULL)
 	{
 		printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
-		sys_close(fd);
+		filp_close(filp, current->files);
 		return 0;
 	}
-	if (read(fd, dp, l) != l)
+	pos = 0;
+	if (vfs_read(filp, dp, l, &pos) != l)
 	{
 		printk(KERN_INFO "Failed to read '%s'.\n", fn);
 		vfree(dp);
-		sys_close(fd);
+		filp_close(filp, current->files);
 		return 0;
 	}
-	close(fd);
+	filp_close(filp, current->files);
 	*fp = dp;
 	return (int) l;
 }
diff -Nru a/sound/synth/Makefile b/sound/synth/Makefile
--- a/sound/synth/Makefile	Mon Feb 10 10:39:23 2003
+++ b/sound/synth/Makefile	Mon Feb 10 10:39:23 2003
@@ -3,8 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := util_mem.o
-
 snd-util-mem-objs := util_mem.o
 
 # Toplevel Module Dependency
diff -Nru a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile
--- a/sound/synth/emux/Makefile	Mon Feb 10 10:39:27 2003
+++ b/sound/synth/emux/Makefile	Mon Feb 10 10:39:27 2003
@@ -3,11 +3,18 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-export-objs  := emux.o
+snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \
+		       emux_effect.o emux_proc.o soundfont.o \
+		       $(if $(CONFIG_SND_SEQUENCER_OSS),emux_oss.o)
 
-snd-emux-synth-y := emux.o emux_synth.o emux_seq.o emux_nrpn.o \
-		    emux_effect.o emux_proc.o soundfont.o
-snd-emux-synth-$(CONFIG_SND_SEQUENCER_OSS) += emux_oss.o
+#
+# this function returns:
+#   "m" - CONFIG_SND_SEQUENCER is m
+#   <empty string> - CONFIG_SND_SEQUENCER is undefined
+#   otherwise parameter #1 value
+#
+sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
 
-obj-$(CONFIG_SND_SBAWE) += snd-emux-synth.o
-obj-$(CONFIG_SND_EMU10K1) += snd-emux-synth.o
+# Toplevel Module Dependencies
+obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emux-synth.o
+obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emux-synth.o
diff -Nru a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
--- a/sound/synth/emux/emux_oss.c	Mon Feb 10 10:39:24 2003
+++ b/sound/synth/emux/emux_oss.c	Mon Feb 10 10:39:24 2003
@@ -219,7 +219,7 @@
 						 SF_CLIENT_NO(p->chset.port));
 	else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
 		soundfont_patch_info_t patch;
-		if (count < sizeof(patch))
+		if (count < (int)sizeof(patch))
 			rc = -EINVAL;
 		if (copy_from_user(&patch, buf, sizeof(patch)))
 			rc = -EFAULT;
diff -Nru a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
--- a/sound/synth/emux/emux_seq.c	Mon Feb 10 10:39:26 2003
+++ b/sound/synth/emux/emux_seq.c	Mon Feb 10 10:39:26 2003
@@ -59,9 +59,6 @@
 				 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE)
 
 /*
- */
-
-/*
  * Initialise the EMUX Synth by creating a client and registering
  * a series of ports.
  * Each of the ports will contain the 16 midi channels.  Applications
@@ -179,7 +176,7 @@
 	}
 
 	p->chset.port = snd_seq_event_port_attach(emu->client, callback,
-						  cap, type, name);
+						  cap, type, max_channels, name);
 
 	return p;
 }
@@ -292,11 +289,11 @@
 void
 snd_emux_dec_count(snd_emux_t *emu)
 {
-	module_put(emu->ops.owner);
+	module_put(emu->card->module);
 	emu->used--;
 	if (emu->used <= 0)
 		snd_emux_terminate_all(emu);
-	module_put(emu->card->module);
+	module_put(emu->ops.owner);
 }
 
 
diff -Nru a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
--- a/sound/synth/emux/soundfont.c	Mon Feb 10 10:39:30 2003
+++ b/sound/synth/emux/soundfont.c	Mon Feb 10 10:39:30 2003
@@ -122,7 +122,7 @@
 	unsigned long flags;
 	int  rc;
 
-	if (count < sizeof(patch)) {
+	if (count < (long)sizeof(patch)) {
 		snd_printk("patch record too small %ld\n", count);
 		return -EINVAL;
 	}
@@ -406,7 +406,7 @@
 	soundfont_voice_map_t map;
 
 	/* get the link info */
-	if (count < sizeof(map))
+	if (count < (int)sizeof(map))
 		return -EINVAL;
 	if (copy_from_user(&map, data, sizeof(map)))
 		return -EFAULT;
@@ -509,7 +509,7 @@
 	if (is_special_type(sf->type))
 		return -EINVAL;
 
-	if (count < sizeof(hdr)) {
+	if (count < (long)sizeof(hdr)) {
 		printk("Soundfont error: invalid patch zone length\n");
 		return -EINVAL;
 	}
@@ -524,7 +524,7 @@
 		return -EINVAL;
 	}
 
-	if (count < sizeof(soundfont_voice_info_t)*hdr.nvoices) {
+	if (count < (long)sizeof(soundfont_voice_info_t)*hdr.nvoices) {
 		printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
 		       count, hdr.nvoices);
 		return -EINVAL;
@@ -926,7 +926,7 @@
 	int note, sample_id;
 	int rc;
 
-	if (count < sizeof(patch)) {
+	if (count < (long)sizeof(patch)) {
 		snd_printk("patch record too small %ld\n", count);
 		return -EINVAL;
 	}
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	Mon Feb 10 10:39:30 2003
+++ b/sound/usb/usbaudio.c	Mon Feb 10 10:39:30 2003
@@ -36,7 +36,7 @@
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
-#include <sound/seq_device.h>
+#include <sound/pcm_params.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
@@ -89,6 +89,12 @@
 
 
 /*
+ * debug the h/w constraints
+ */
+/* #define HW_CONST_DEBUG */
+
+
+/*
  *
  */
 
@@ -104,7 +110,7 @@
 struct audioformat {
 	struct list_head list;
 	snd_pcm_format_t format;	/* format type */
-	int channels;			/* # channels */
+	unsigned int channels;		/* # channels */
 	int iface;			/* interface number */
 	unsigned char altsetting;	/* corresponding alternate setting */
 	unsigned char altset_idx;	/* array index of altenate setting */
@@ -112,9 +118,9 @@
 	unsigned char endpoint;		/* endpoint */
 	unsigned char ep_attr;		/* endpoint attributes */
 	unsigned int rates;		/* rate bitmasks */
-	int rate_min, rate_max;		/* min/max rates */
-	int nr_rates;			/* number of rate table entries */
-	int *rate_table;		/* rate table */
+	unsigned int rate_min, rate_max;	/* min/max rates */
+	unsigned int nr_rates;		/* number of rate table entries */
+	unsigned int *rate_table;	/* rate table */
 };
 
 struct snd_urb_ctx {
@@ -156,21 +162,21 @@
 
 	unsigned int running: 1;	/* running status */
 
-	int hwptr;			/* free frame position in the buffer (only for playback) */
-	int hwptr_done;			/* processed frame position in the buffer */
-	int transfer_sched;		/* scheduled frames since last period (for playback) */
-	int transfer_done;		/* processed frames since last period update */
+	unsigned int hwptr;			/* free frame position in the buffer (only for playback) */
+	unsigned int hwptr_done;			/* processed frame position in the buffer */
+	unsigned int transfer_sched;		/* scheduled frames since last period (for playback) */
+	unsigned int transfer_done;		/* processed frames since last period update */
 	unsigned long active_mask;	/* bitmask of active urbs */
 	unsigned long unlink_mask;	/* bitmask of unlinked urbs */
 
-	int nurbs;			/* # 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 */
 	char syncbuf[SYNC_URBS * NRPACKS * 3]; /* sync buffer; it's so small - let's get static */
 	char *tmpbuf;			/* temporary buffer for playback */
 
 	u64 formats;			/* format bitmasks (all or'ed) */
-	int num_formats;		/* number of supported audio formats (list) */
+	unsigned int num_formats;		/* number of supported audio formats (list) */
 	struct list_head fmt_list;	/* format list */
 	spinlock_t lock;
 
@@ -184,7 +190,6 @@
 	int pcm_index;
 	snd_usb_substream_t substream[2];
 	struct list_head list;
-	snd_info_entry_t *proc_entry;
 };
 
 #define chip_t snd_usb_stream_t
@@ -309,7 +314,8 @@
 {
 	unsigned long flags;
 	unsigned char *cp;
-	int stride, i, len, oldptr;
+	int i;
+	unsigned int stride, len, oldptr;
 
 	stride = runtime->frame_bits >> 3;
 
@@ -332,8 +338,8 @@
 		spin_unlock_irqrestore(&subs->lock, flags);
 		/* copy a data chunk */
 		if (oldptr + len > runtime->buffer_size) {
-			int cnt = runtime->buffer_size - oldptr;
-			int blen = cnt * stride;
+			unsigned int cnt = runtime->buffer_size - oldptr;
+			unsigned int blen = cnt * stride;
 			memcpy(runtime->dma_area + oldptr * stride, cp, blen);
 			memcpy(runtime->dma_area, cp + blen, len * stride - blen);
 		} else {
@@ -384,7 +390,8 @@
 				    snd_pcm_runtime_t *runtime,
 				    struct urb *urb)
 {
-	unsigned int f, i, found;
+	int i;
+	unsigned int f, found;
 	unsigned char *cp = urb->transfer_buffer;
 	unsigned long flags;
 
@@ -424,7 +431,7 @@
 				struct urb *urb)
 {
 	int i, stride, offs;
-	int counts;
+	unsigned int counts;
 	unsigned long flags;
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
 
@@ -526,11 +533,7 @@
 /*
  * complete callback from data urb
  */
-#ifndef OLD_USB
 static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
-#else
-static void snd_complete_urb(struct urb *urb)
-#endif
 {
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
 	snd_usb_substream_t *subs = ctx->subs;
@@ -542,7 +545,7 @@
 		return;
 	if (! subs->running) /* can be stopped during retire callback */
 		return;
-	if ((err = subs->ops.prepare(subs, substream->runtime, urb) < 0) ||
+	if ((err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
 	    (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
 		snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
 		snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
@@ -555,11 +558,7 @@
 /*
  * complete callback from sync urb
  */
-#ifndef OLD_USB
 static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs)
-#else
-static void snd_complete_sync_urb(struct urb *urb)
-#endif
 {
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
 	snd_usb_substream_t *subs = ctx->subs;
@@ -587,7 +586,8 @@
  */
 static int deactivate_urbs(snd_usb_substream_t *subs)
 {
-	int i, alive;
+	unsigned int i;
+	int alive;
 
 	subs->running = 0;
 
@@ -628,7 +628,8 @@
  */
 static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
 {
-	int i, err;
+	unsigned int i;
+	int err;
 
 	for (i = 0; i < subs->nurbs; i++) {
 		snd_assert(subs->dataurb[i].urb, return -EINVAL);
@@ -679,7 +680,8 @@
 static int wait_clear_urbs(snd_usb_substream_t *subs)
 {
 	int timeout = HZ;
-	int i, alive;
+	unsigned int i;
+	int alive;
 
 	do {
 		alive = 0;
@@ -780,9 +782,9 @@
  */
 static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
 {
-	int maxsize, n, i;
+	unsigned int maxsize, n, i;
 	int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
-	int npacks[MAX_URBS], total_packs;
+	unsigned int npacks[MAX_URBS], total_packs;
 
 	/* calculate the frequency in 10.14 format */
 	subs->freqn = subs->freqm = get_usb_rate(runtime->rate);
@@ -881,7 +883,7 @@
 		u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
 		u->urb->number_of_packets = u->packets;
 		u->urb->context = u;
-		u->urb->complete = (usb_complete_t)snd_complete_urb;
+		u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
 	}
 
 	if (subs->syncpipe) {
@@ -903,7 +905,7 @@
 			u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
 			u->urb->number_of_packets = u->packets;
 			u->urb->context = u;
-			u->urb->complete = (usb_complete_t)snd_complete_sync_urb;
+			u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb);
 		}
 	}
 	return 0;
@@ -928,7 +930,7 @@
 		if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
 			return fp;
 		else {
-			int i;
+			unsigned int i;
 			for (i = 0; i < fp->nr_rates; i++)
 				if (fp->rate_table[i] == runtime->rate)
 					return fp;
@@ -939,6 +941,70 @@
 
 
 /*
+ * initialize the picth control and sample rate
+ */
+static int init_usb_pitch(struct usb_device *dev, int iface,
+			  struct usb_host_interface *alts,
+			  struct audioformat *fmt)
+{
+	unsigned int ep;
+	unsigned char data[1];
+	int err;
+
+	ep = get_endpoint(alts, 0)->bEndpointAddress;
+	/* if endpoint has pitch control, enable it */
+	if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) {
+		data[0] = 1;
+		if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
+					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
+					   PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
+			snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
+				   dev->devnum, iface, ep);
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int init_usb_sample_rate(struct usb_device *dev, int iface,
+				struct usb_host_interface *alts,
+				struct audioformat *fmt, int rate)
+{
+	unsigned int ep;
+	unsigned char data[3];
+	int err;
+
+	ep = get_endpoint(alts, 0)->bEndpointAddress;
+	/* if endpoint has sampling rate control, set it */
+	if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) {
+		int crate;
+		data[0] = rate;
+		data[1] = rate >> 8;
+		data[2] = rate >> 16;
+		if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
+					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
+					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+			snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n",
+				   dev->devnum, iface, fmt->altsetting, rate, ep);
+			return err;
+		}
+		if ((err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR,
+					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
+					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+			snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n",
+				   dev->devnum, iface, fmt->altsetting, ep);
+			return err;
+		}
+		crate = data[0] | (data[1] << 8) | (data[2] << 16);
+		if (crate != rate) {
+			snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
+			// runtime->rate = crate;
+		}
+	}
+	return 0;
+}
+
+/*
  * find a matching format and set up the interface
  */
 static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
@@ -950,7 +1016,6 @@
 	struct usb_interface *iface;
 	struct audioformat *fmt;
 	unsigned int ep, attr;
-	unsigned char data[3];
 	int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
 	int err;
 
@@ -1009,8 +1074,8 @@
 			return -EINVAL;
 		}
 		ep = get_endpoint(alts, 1)->bEndpointAddress;
-		if ((is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
-		    (! is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN))) {
+		if ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
+		    (! is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN))) {
 			snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
 				   dev->devnum, fmt->iface, fmt->altsetting);
 			return -EINVAL;
@@ -1023,44 +1088,11 @@
 		subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
 	}
 
-	ep = get_endpoint(alts, 0)->bEndpointAddress;
-	/* if endpoint has pitch control, enable it */
-	if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) {
-		data[0] = 1;
-		if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
-					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
-					   PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
-			snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
-				   dev->devnum, subs->interface, ep);
-			return err;
-		}
-	}
-	/* if endpoint has sampling rate control, set it */
-	if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) {
-		int crate;
-		data[0] = runtime->rate;
-		data[1] = runtime->rate >> 8;
-		data[2] = runtime->rate >> 16;
-		if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
-					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 
-					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
-			snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n",
-				   dev->devnum, subs->interface, fmt->altsetting, runtime->rate, ep);
-			return err;
-		}
-		if ((err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR,
-					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
-					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
-			snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n",
-				   dev->devnum, subs->interface, fmt->altsetting, ep);
-			return err;
-		}
-		crate = data[0] | (data[1] << 8) | (data[2] << 16);
-		if (crate != runtime->rate) {
-			snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, runtime->rate);
-			// runtime->rate = crate;
-		}
-	}
+	if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0 ||
+	    (err = init_usb_sample_rate(dev, subs->interface, alts, fmt,
+					runtime->rate)) < 0)
+		return err;
+
 	/* always fill max packet size */
 	if (fmt->attributes & EP_CS_ATTR_FILL_MAX)
 		subs->fill_max = 1;
@@ -1140,12 +1172,239 @@
 };
 
 /*
+ * h/w constraints
+ */
+
+#ifdef HW_CONST_DEBUG
+#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
+#else
+#define hwc_debug(fmt, args...) /**/
+#endif
+
+static int hw_check_valid_format(snd_pcm_hw_params_t *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);
+
+	/* check the format */
+	if (! snd_mask_test(fmts, fp->format)) {
+		printk(KERN_DEBUG "   > check: no supported format %d\n", fp->format);
+		return 0;
+	}
+	/* check the channels */
+	if (fp->channels < ct->min || fp->channels > ct->max) {
+		hwc_debug("   > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
+		return 0;
+	}
+	/* check the rate is within the range */
+	if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
+		hwc_debug("   > check: rate_min %d > max %d\n", fp->rate_min, it->max);
+		return 0;
+	}
+	if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
+		hwc_debug("   > check: rate_max %d < min %d\n", fp->rate_max, it->min);
+		return 0;
+	}
+	return 1;
+}
+
+static int hw_rule_rate(snd_pcm_hw_params_t *params,
+			snd_pcm_hw_rule_t *rule)
+{
+	snd_usb_substream_t *subs = rule->private;
+	struct list_head *p;
+	snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	unsigned int rmin, rmax;
+	int changed;
+	
+	hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
+	changed = 0;
+	rmin = rmax = 0;
+	list_for_each(p, &subs->fmt_list) {
+		struct audioformat *fp;
+		fp = list_entry(p, struct audioformat, list);
+		if (! hw_check_valid_format(params, fp))
+			continue;
+		if (changed++) {
+			if (rmin > fp->rate_min)
+				rmin = fp->rate_min;
+			if (rmax < fp->rate_max)
+				rmax = fp->rate_max;
+		} else {
+			rmin = fp->rate_min;
+			rmax = fp->rate_max;
+		}
+	}
+
+	if (! changed) {
+		hwc_debug("  --> get empty\n");
+		it->empty = 1;
+		return -EINVAL;
+	}
+
+	changed = 0;
+	if (it->min < rmin) {
+		it->min = rmin;
+		it->openmin = 0;
+		changed = 1;
+	}
+	if (it->max > rmax) {
+		it->max = rmax;
+		it->openmax = 0;
+		changed = 1;
+	}
+	if (snd_interval_checkempty(it)) {
+		it->empty = 1;
+		return -EINVAL;
+	}
+	hwc_debug("  --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
+	return changed;
+}
+
+
+static int hw_rule_channels(snd_pcm_hw_params_t *params,
+			    snd_pcm_hw_rule_t *rule)
+{
+	snd_usb_substream_t *subs = rule->private;
+	struct list_head *p;
+	snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	unsigned int rmin, rmax;
+	int changed;
+	
+	hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
+	changed = 0;
+	rmin = rmax = 0;
+	list_for_each(p, &subs->fmt_list) {
+		struct audioformat *fp;
+		fp = list_entry(p, struct audioformat, list);
+		if (! hw_check_valid_format(params, fp))
+			continue;
+		if (changed++) {
+			if (rmin > fp->channels)
+				rmin = fp->channels;
+			if (rmax < fp->channels)
+				rmax = fp->channels;
+		} else {
+			rmin = fp->channels;
+			rmax = fp->channels;
+		}
+	}
+
+	if (! changed) {
+		hwc_debug("  --> get empty\n");
+		it->empty = 1;
+		return -EINVAL;
+	}
+
+	changed = 0;
+	if (it->min < rmin) {
+		it->min = rmin;
+		it->openmin = 0;
+		changed = 1;
+	}
+	if (it->max > rmax) {
+		it->max = rmax;
+		it->openmax = 0;
+		changed = 1;
+	}
+	if (snd_interval_checkempty(it)) {
+		it->empty = 1;
+		return -EINVAL;
+	}
+	hwc_debug("  --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
+	return changed;
+}
+
+static int hw_rule_format(snd_pcm_hw_params_t *params,
+			  snd_pcm_hw_rule_t *rule)
+{
+	snd_usb_substream_t *subs = rule->private;
+	struct list_head *p;
+	snd_mask_t *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	u64 fbits;
+	u32 oldbits[2];
+	int changed;
+	
+	hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
+	fbits = 0;
+	list_for_each(p, &subs->fmt_list) {
+		struct audioformat *fp;
+		fp = list_entry(p, struct audioformat, list);
+		if (! hw_check_valid_format(params, fp))
+			continue;
+		fbits |= (1UL << fp->format);
+	}
+
+	oldbits[0] = fmt->bits[0];
+	oldbits[1] = fmt->bits[1];
+	fmt->bits[0] &= (u32)fbits;
+	fmt->bits[1] &= (u32)(fbits >> 32);
+	if (! fmt->bits[0] && ! fmt->bits[1]) {
+		hwc_debug("  --> get empty\n");
+		return -EINVAL;
+	}
+	changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
+	hwc_debug("  --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
+	return changed;
+}
+
+/*
+ * check whether the registered audio formats need special hw-constraints
+ */
+static int check_hw_params_convention(snd_usb_substream_t *subs)
+{
+	int i;
+	u32 channels[64];
+	u32 rates[64];
+	u32 cmaster, rmaster;
+	struct list_head *p;
+
+	memset(channels, 0, sizeof(channels));
+	memset(rates, 0, sizeof(rates));
+
+	list_for_each(p, &subs->fmt_list) {
+		struct audioformat *f;
+		f = list_entry(p, struct audioformat, list);
+		/* unconventional channels? */
+		if (f->channels > 32)
+			return 1;
+		/* combination of continuous rates and fixed rates? */
+		if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) {
+			if (f->rates != rates[f->format])
+				return 1;
+		}
+		if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
+			if (rates[f->format] && rates[f->format] != f->rates)
+				return 1;
+		}
+		channels[f->format] |= (1 << f->channels);
+		rates[f->format] |= f->rates;
+	}
+	/* check whether channels and rates match for all formats */
+	cmaster = rmaster = 0;
+	for (i = 0; i < 64; i++) {
+		if (cmaster != channels[i] && cmaster && channels[i])
+			return 1;
+		if (rmaster != rates[i] && rmaster && rates[i])
+			return 1;
+		if (channels[i])
+			cmaster = channels[i];
+		if (rates[i])
+			rmaster = rates[i];
+	}
+	return 0;
+}
+
+
+/*
  * set up the runtime hardware information.
  */
 
-static void setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
+static int setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
 {
 	struct list_head *p;
+	int err;
 
 	runtime->hw.formats = subs->formats;
 
@@ -1174,9 +1433,28 @@
 				     1000 * MIN_PACKS_URB,
 				     /*(NRPACKS * MAX_URBS) * 1000*/ UINT_MAX);
 
-	/* FIXME: we need more constraints to restrict the format type,
-	 * channels and rates according to the audioformat list!
-	 */
+	if (check_hw_params_convention(subs)) {
+		hwc_debug("setting extra hw constraints...\n");
+		if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
+					       hw_rule_rate, subs,
+					       SNDRV_PCM_HW_PARAM_FORMAT,
+					       SNDRV_PCM_HW_PARAM_CHANNELS,
+					       -1)) < 0)
+			return err;
+		if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 
+					       hw_rule_channels, subs,
+					       SNDRV_PCM_HW_PARAM_FORMAT,
+					       SNDRV_PCM_HW_PARAM_RATE,
+					       -1)) < 0)
+			return err;
+		if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+					       hw_rule_format, subs,
+					       SNDRV_PCM_HW_PARAM_RATE,
+					       SNDRV_PCM_HW_PARAM_CHANNELS,
+					       -1)) < 0)
+			return err;
+	}
+	return 0;
 }
 
 static int snd_usb_pcm_open(snd_pcm_substream_t *substream, int direction,
@@ -1191,8 +1469,7 @@
 	runtime->hw = *hw;
 	runtime->private_data = subs;
 	subs->pcm_substream = substream;
-	setup_hw_info(runtime, subs);
-	return 0;
+	return setup_hw_info(runtime, subs);
 }
 
 static int snd_usb_pcm_close(snd_pcm_substream_t *substream, int direction)
@@ -1325,11 +1602,7 @@
  * entry point for linux usb interface
  */
 
-#ifdef OLD_USB
-static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
-			      const struct usb_device_id *id);
-static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
-#else
+#ifndef OLD_USB
 static int usb_audio_probe(struct usb_interface *intf,
 			   const struct usb_device_id *id);
 static void usb_audio_disconnect(struct usb_interface *intf);
@@ -1381,7 +1654,7 @@
 			snd_iprintf(buffer, "    Rates: %d - %d (continous)\n",
 				    fp->rate_min, fp->rate_max);
 		} else {
-			int i;
+			unsigned int i;
 			snd_iprintf(buffer, "    Rates: ");
 			for (i = 0; i < fp->nr_rates; i++) {
 				if (i > 0)
@@ -1396,7 +1669,7 @@
 static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffer_t *buffer)
 {
 	if (subs->running) {
-		int i;
+		unsigned int i;
 		snd_iprintf(buffer, "  Status: Running\n");
 		snd_iprintf(buffer, "    Interface = %d\n", subs->interface);
 		snd_iprintf(buffer, "    Altset = %d\n", subs->format);
@@ -1438,18 +1711,8 @@
 	snd_card_t *card = stream->chip->card;
 
 	sprintf(name, "stream%d", stream->pcm_index);
-	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = stream;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 4096;
-		entry->c.text.read = proc_pcm_format_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	stream->proc_entry = entry;
+	if (! snd_card_proc_new(card, name, &entry))
+		snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
 }
 
 
@@ -1504,10 +1767,6 @@
  */
 static void snd_usb_audio_stream_free(snd_usb_stream_t *stream)
 {
-	if (stream->proc_entry) {
-		snd_info_unregister(stream->proc_entry);
-		stream->proc_entry = NULL;
-	}
 	free_substream(&stream->substream[0]);
 	free_substream(&stream->substream[1]);
 	list_del(&stream->list);
@@ -1793,7 +2052,7 @@
 			 */
 			int r, idx, c;
 			/* this table corresponds to the SNDRV_PCM_RATE_XXX bit */
-			static int conv_rates[] = {
+			static unsigned int conv_rates[] = {
 				5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
 				64000, 88200, 96000, 176400, 192000
 			};
@@ -1807,7 +2066,7 @@
 			fp->nr_rates = nr_rates;
 			fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
 			for (r = 0, idx = 8; r < nr_rates; r++, idx += 3) {
-				int rate = fp->rate_table[r] = combine_triple(&fmt[idx]);
+				unsigned int rate = fp->rate_table[r] = combine_triple(&fmt[idx]);
 				if (rate < fp->rate_min)
 					fp->rate_min = rate;
 				else if (rate > fp->rate_max)
@@ -1820,7 +2079,7 @@
 				}
 #if 0 // FIXME - we need to define constraint
 				if (c >= 13)
-					fp->rates |= SNDRV_PCM_KNOT; /* unconventional rate */
+					fp->rates |= SNDRV_PCM_RATE_KNOT; /* unconventional rate */
 #endif
 			}
 
@@ -1840,6 +2099,10 @@
 			kfree(fp);
 			return err;
 		}
+		/* try to set the interface... */
+		usb_set_interface(chip->dev, iface_no, i);
+		init_usb_pitch(chip->dev, iface_no, alts, fp);
+		init_usb_sample_rate(chip->dev, iface_no, alts, fp, fp->rate_max);
 	}
 	return 0;
 }
@@ -1893,7 +2156,7 @@
 				snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
 				continue;
 			}
-			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
+			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
 			continue;
 		}
 		if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
@@ -1902,84 +2165,73 @@
 			/* skip non-supported classes */
 			continue;
 		}
-		parse_audio_endpoints(chip, buffer, buflen, j);
-		usb_set_interface(dev, j, 0); /* reset the current interface */
-		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
+		if (! parse_audio_endpoints(chip, buffer, buflen, j)) {
+			usb_set_interface(dev, j, 0); /* reset the current interface */
+			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
+		}
 	}
 
 	return 0;
 }
 
-static int snd_usb_roland_ua100_hack_intf(snd_usb_audio_t *chip, int ifnum)
+/*
+ * create a stream for an endpoint/altsetting without proper descriptors
+ */
+static int create_fixed_stream_quirk(snd_usb_audio_t *chip,
+				     struct usb_interface *iface,
+				     const snd_usb_audio_quirk_t *quirk)
 {
 	struct audioformat *fp;
-	int err;
+	struct usb_host_interface *alts;
+	int stream, err;
 
 	fp = kmalloc(sizeof(*fp), GFP_KERNEL);
 	if (! fp) {
 		snd_printk(KERN_ERR "cannot malloc\n");
 		return -ENOMEM;
 	}
-	memset(fp, 0, sizeof(*fp));
-	fp->format = SNDRV_PCM_FORMAT_S16_LE;
-	fp->channels = ifnum == 0 ? 4 : 2;
-	fp->iface = ifnum;
-	fp->altsetting = 1;
-	fp->altset_idx = 1;
-	fp->attributes = ifnum == 0 ? 0 : EP_CS_ATTR_FILL_MAX;
-	fp->endpoint = ifnum == 0 ? 0x01 : 0x81;
-	fp->ep_attr = ifnum == 0 ? 0x09 : 0x05;
-	fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
-	fp->rate_min = fp->rate_max = 44100;
-
-	err = add_audio_endpoint(chip, ifnum == 0 ? SNDRV_PCM_STREAM_PLAYBACK
-				 : SNDRV_PCM_STREAM_CAPTURE, fp);
+	memcpy(fp, quirk->data, sizeof(*fp));
+	stream = (fp->endpoint & USB_DIR_IN)
+		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+	err = add_audio_endpoint(chip, stream, fp);
 	if (err < 0) {
 		kfree(fp);
 		return err;
 	}
-	usb_set_interface(chip->dev, ifnum, 0);
+	alts = &iface->altsetting[fp->altset_idx];
+	usb_set_interface(chip->dev, fp->iface, 0);
+	init_usb_pitch(chip->dev, fp->iface, alts, fp);
+	init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);
 	return 0;
 }
 
-static int snd_usb_roland_ua100_hack(snd_usb_audio_t *chip)
+static int snd_usb_create_quirk(snd_usb_audio_t *chip,
+				struct usb_interface *iface,
+				const snd_usb_audio_quirk_t *quirk);
+
+/*
+ * handle the quirks for the contained interfaces
+ */
+static int create_composite_quirk(snd_usb_audio_t *chip,
+				  struct usb_interface *iface,
+				  const snd_usb_audio_quirk_t *quirk)
 {
-	static const snd_usb_midi_endpoint_info_t ep_quirk = {
-		.epnum = -1,
-		.out_cables = 0x0007,
-		.in_cables  = 0x0007
-	};
-	static const snd_usb_audio_quirk_t midi_quirk = {
-		.vendor_name = "Roland",
-		.product_name = "UA-100",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = &ep_quirk
-	};
-	struct usb_host_config *cfg = chip->dev->actconfig;
-	struct usb_interface *iface;
+	struct usb_host_config *config = chip->dev->actconfig;
+	int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
 	int err;
 
-	if (get_cfg_desc(cfg)->bNumInterfaces != 3) {
-		snd_printdd(KERN_ERR "invalid UA-100 descriptor\n");
-		return -ENXIO;
-	}
-	/* if 0: output */
-	if ((err = snd_usb_roland_ua100_hack_intf(chip, 0)) < 0)
-		return err;
-	/* if 1: input */
-	iface = &cfg->interface[1];
-	if (! usb_interface_claimed(iface)) {
-		if ((err = snd_usb_roland_ua100_hack_intf(chip, 1)) < 0)
-			return err;
-		usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1);
-	}
-	/* if 2: MIDI */
-	iface = &cfg->interface[2];
-	if (! usb_interface_claimed(iface)) {
-		if ((err = snd_usb_create_midi_interface(chip, iface, &midi_quirk)) < 0)
+	for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
+		if (quirk->ifnum >= get_cfg_desc(config)->bNumInterfaces)
+			continue;
+		iface = &config->interface[quirk->ifnum];
+		if (quirk->ifnum != probed_ifnum &&
+		    usb_interface_claimed(iface))
+			continue;
+		err = snd_usb_create_quirk(chip, iface, quirk);
+		if (err < 0)
 			return err;
-		usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1);
+		if (quirk->ifnum != probed_ifnum)
+			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
 	}
 	return 0;
 }
@@ -1993,8 +2245,10 @@
 	case QUIRK_MIDI_YAMAHA:
 	case QUIRK_MIDI_MIDIMAN:
 		return snd_usb_create_midi_interface(chip, iface, quirk);
-	case QUIRK_ROLAND_UA100:
-		return snd_usb_roland_ua100_hack(chip);
+	case QUIRK_COMPOSITE:
+		return create_composite_quirk(chip, iface, quirk);
+	case QUIRK_AUDIO_FIXED_ENDPOINT:
+		return create_fixed_stream_quirk(chip, iface, quirk);
 	default:
 		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
@@ -2046,6 +2300,7 @@
 	chip->dev = dev;
 	chip->card = card;
 	INIT_LIST_HEAD(&chip->pcm_list);
+	INIT_LIST_HEAD(&chip->midi_list);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_usb_audio_free(chip);
@@ -2097,6 +2352,13 @@
 		strncpy(card->longname + len, quirk->product_name, sizeof(card->longname) - len - 1);
 		card->longname[sizeof(card->longname) - 1] = '\0';
 	}
+	/* add device path to longname */
+	len = strlen(card->longname);
+	if (sizeof(card->longname) - len > 10) {
+		strcpy(card->longname + len, " at ");
+		len += 4;
+		usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
+	}
 
 	*rchip = chip;
 	return 0;
@@ -2265,7 +2527,7 @@
 	snd_card_t *card;
 	struct list_head *p;
 
-	if (ptr == (void *)-1)
+	if (ptr == (void *)-1L)
 		return;
 
 	chip = snd_magic_cast(snd_usb_audio_t, ptr, return);
@@ -2288,6 +2550,10 @@
 				release_substream_urbs(subs);
 			}
 		}
+		/* release the midi resources */
+		list_for_each(p, &chip->midi_list) {
+			snd_usbmidi_disconnect(p);
+		}
 		up(&register_mutex);
 		snd_card_free_in_thread(card);
 	} else {
@@ -2295,25 +2561,7 @@
 	}
 }
 
-
-#ifdef OLD_USB
-
-/*
- * 2.4 USB kernel API
- */
-static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
-			     const struct usb_device_id *id)
-{
-	return snd_usb_audio_probe(dev, usb_ifnum_to_if(dev, ifnum), id);
-}
-
-static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
-{
-	snd_usb_audio_disconnect(dev, ptr);
-}
-
-#else
-
+#ifndef OLD_USB
 /*
  * new 2.5 USB kernel API
  */
@@ -2323,7 +2571,7 @@
 	void *chip;
 	chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
 	if (chip) {
-		usb_set_intfdata(intf, chip);
+		dev_set_drvdata(&intf->dev, chip);
 		return 0;
 	} else
 		return -EIO;
@@ -2332,7 +2580,7 @@
 static void usb_audio_disconnect(struct usb_interface *intf)
 {
 	snd_usb_audio_disconnect(interface_to_usbdev(intf),
-				 usb_get_intfdata(intf));
+				 dev_get_drvdata(&intf->dev));
 }
 #endif
 
diff -Nru a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
--- a/sound/usb/usbaudio.h	Mon Feb 10 10:39:29 2003
+++ b/sound/usb/usbaudio.h	Mon Feb 10 10:39:29 2003
@@ -139,6 +139,7 @@
 	struct list_head pcm_list;	/* list of pcm streams */
 	int pcm_devs;
 
+	struct list_head midi_list;	/* list of midi interfaces */
 	int next_midi_device;
 };  
 
@@ -150,7 +151,8 @@
 #define QUIRK_MIDI_FIXED_ENDPOINT	0
 #define QUIRK_MIDI_YAMAHA		1
 #define QUIRK_MIDI_MIDIMAN		2
-#define QUIRK_ROLAND_UA100		3
+#define QUIRK_COMPOSITE			3
+#define QUIRK_AUDIO_FIXED_ENDPOINT	4
 
 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
 typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
@@ -165,7 +167,7 @@
 
 /* data for QUIRK_MIDI_FIXED_ENDPOINT */
 struct snd_usb_midi_endpoint_info {
-	int16_t epnum;		/* ep number, -1 autodetect */
+	int8_t out_ep, in_ep;	/* ep number, 0 autodetect */
 	uint16_t out_cables;	/* bitmask */
 	uint16_t in_cables;	/* bitmask */
 };
@@ -175,7 +177,10 @@
 /* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
  * structure (out_cables and in_cables only) */
 
-/* for QUIRK_ROLAND_UA100, data is NULL */
+/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
+ * structures, terminated with .ifnum = -1 */
+
+/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
 
 /*
  */
@@ -192,6 +197,7 @@
 int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffer, int buflen);
 
 int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk);
+void snd_usbmidi_disconnect(struct list_head *p);
 
 /*
  * retrieve usb_interface descriptor from the host interface
@@ -206,6 +212,10 @@
 
 #ifndef usb_pipe_needs_resubmit
 #define usb_pipe_needs_resubmit(pipe) 1
+#endif
+
+#ifndef snd_usb_complete_callback
+#define snd_usb_complete_callback(x) (x)
 #endif
 
 #endif /* __USBAUDIO_H */
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	Mon Feb 10 10:39:32 2003
+++ b/sound/usb/usbmidi.c	Mon Feb 10 10:39:32 2003
@@ -77,6 +77,7 @@
 	struct usb_interface *iface;
 	const snd_usb_audio_quirk_t *quirk;
 	snd_rawmidi_t* rmidi;
+	struct list_head list;
 
 	struct snd_usb_midi_endpoint {
 		snd_usb_midi_out_endpoint_t *out;
@@ -172,11 +173,7 @@
 /*
  * Processes the data read from the device.
  */
-#ifndef OLD_USB
 static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
-#else
-static void snd_usbmidi_in_urb_complete(struct urb* urb)
-#endif
 {
 	snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return);
 
@@ -201,11 +198,7 @@
 /*
  * Converts the data read from a Midiman device to standard USB MIDI packets.
  */
-#ifndef OLD_USB
 static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *regs)
-#else
-static void snd_usbmidi_in_midiman_complete(struct urb* urb)
-#endif
 {
 	if (urb->status == 0) {
 		uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
@@ -231,18 +224,10 @@
 			}
 		}
 	}
-#ifndef OLD_USB
 	snd_usbmidi_in_urb_complete(urb, regs);
-#else
-	snd_usbmidi_in_urb_complete(urb);
-#endif
 }
 
-#ifndef OLD_USB
 static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
-#else
-static void snd_usbmidi_out_urb_complete(struct urb* urb)
-#endif
 {
 	snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return);
 
@@ -410,7 +395,7 @@
 	unsigned long flags;
 	
 	spin_lock_irqsave(&ep->buffer_lock, flags);
-	if (urb->status == -EINPROGRESS) {
+	if (urb->status == -EINPROGRESS || ep->umidi->chip->shutdown) {
 		spin_unlock_irqrestore(&ep->buffer_lock, flags);
 		return;
 	}
@@ -467,10 +452,8 @@
 	usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data;
 
 	port->active = up;
-	if (up) {
-		if (! port->ep->umidi->chip->shutdown) /* to be sure... */
-			tasklet_hi_schedule(&port->ep->tasklet);
-	}
+	if (up)
+		tasklet_hi_schedule(&port->ep->tasklet);
 }
 
 static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream)
@@ -506,11 +489,8 @@
 static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
 {
 	if (ep->urb) {
-		if (ep->urb->transfer_buffer) {
-			if (! ep->umidi->chip->shutdown) /* to be sure */
-				usb_unlink_urb(ep->urb);
+		if (ep->urb->transfer_buffer)
 			kfree(ep->urb->transfer_buffer);
-		}
 		usb_free_urb(ep->urb);
 	}
 	snd_magic_kfree(ep);
@@ -595,9 +575,9 @@
 		return -ENOMEM;
 	}
 	if (int_epd)
-		pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->epnum);
+		pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep);
 	else
-		pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->epnum);
+		pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep);
 	length = usb_maxpacket(umidi->chip->dev, pipe, 0);
 	buffer = kmalloc(length, GFP_KERNEL);
 	if (!buffer) {
@@ -606,11 +586,11 @@
 	}
 	if (int_epd)
 		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				 (usb_complete_t)snd_usbmidi_in_urb_complete,
+				 snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
 				 ep, int_epd->bInterval);
 	else
 		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				  (usb_complete_t)snd_usbmidi_in_urb_complete,
+				  snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
 				  ep);
 
 	rep->in = ep;
@@ -635,11 +615,8 @@
 	if (ep->tasklet.func)
 		tasklet_kill(&ep->tasklet);
 	if (ep->urb) {
-		if (ep->urb->transfer_buffer) {
-			if (! ep->umidi->chip->shutdown) /* to be sure */
-				usb_unlink_urb(ep->urb);
+		if (ep->urb->transfer_buffer)
 			kfree(ep->urb->transfer_buffer);
-		}
 		usb_free_urb(ep->urb);
 	}
 	snd_magic_kfree(ep);
@@ -668,7 +645,7 @@
 		snd_usbmidi_out_endpoint_delete(ep);
 		return -ENOMEM;
 	}
-	pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->epnum);
+	pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
 	ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1) & ~3;
 	buffer = kmalloc(ep->max_transfer, GFP_KERNEL);
 	if (!buffer) {
@@ -677,7 +654,7 @@
 	}
 	usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
 			  ep->max_transfer,
-			  (usb_complete_t)snd_usbmidi_out_urb_complete, ep);
+			  snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
 
 	spin_lock_init(&ep->buffer_lock);
 	tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
@@ -709,6 +686,24 @@
 	snd_magic_kfree(umidi);
 }
 
+/*
+ * Unlinks all URBs (must be done before the usb_device is deleted).
+ */
+void snd_usbmidi_disconnect(struct list_head* p)
+{
+	snd_usb_midi_t* umidi;
+	int i;
+
+	umidi = list_entry(p, snd_usb_midi_t, list);
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		if (ep->out && ep->out->urb)
+			usb_unlink_urb(ep->out->urb);
+		if (ep->in && ep->in->urb)
+			usb_unlink_urb(ep->in->urb);
+	}
+}
+
 static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi)
 {
 	snd_usb_midi_t* umidi = snd_magic_cast(snd_usb_midi_t, rmidi->private_data, return);
@@ -753,8 +748,6 @@
 	int out_ports = 0, in_ports = 0;
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
-		if (!endpoints[i].epnum)
-			continue;
 		if (endpoints[i].out_cables) {
 			err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i],
 							      &umidi->endpoints[i]);
@@ -828,50 +821,64 @@
 		    ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
 		    ms_ep->bDescriptorSubtype != MS_GENERAL)
 			continue;
-		if (endpoints[epidx].epnum != 0 &&
-		    endpoints[epidx].epnum != (ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) {
-			++epidx;
-			if (epidx >= MIDI_MAX_ENDPOINTS) {
-				printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
-				break;
+		if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+			if (endpoints[epidx].out_ep) {
+				if (++epidx >= MIDI_MAX_ENDPOINTS) {
+					printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
+					break;
+				}
 			}
-		}
-		endpoints[epidx].epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-		if (ep->bEndpointAddress & USB_DIR_IN) {
-			endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
-		} else {
+			endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
+			printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n",
+			       ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
+		} else {
+			if (endpoints[epidx].in_ep) {
+				if (++epidx >= MIDI_MAX_ENDPOINTS) {
+					printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
+					break;
+				}
+			}
+			endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
+			printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n",
+			       ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
 		}
-		printk(KERN_INFO "snd-usb-midi: detected %d %s jack(s) on endpoint %d\n",
-		       ms_ep->bNumEmbMIDIJack,
-		       ep->bEndpointAddress & USB_DIR_IN ? "input" : "output",
-		       endpoints[epidx].epnum);
 	}
 	return 0;
 }
 
 /*
- * If the first endpoint isn't specified, use the first endpoint in the
+ * If the endpoints aren't specified, use the first bulk endpoints in the
  * first alternate setting of the interface.
  */
 static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, 
-			       	       snd_usb_midi_endpoint_info_t* endpoint)
+				       snd_usb_midi_endpoint_info_t* endpoint)
 {
 	struct usb_interface* intf;
 	struct usb_host_interface *hostif;
 	struct usb_interface_descriptor* intfd;
 	struct usb_endpoint_descriptor* epd;
+	int i;
+
+	intf = umidi->iface;
+	if (!intf || intf->num_altsetting < 1)
+		return -ENOENT;
+	hostif = intf->altsetting;
+	intfd = get_iface_desc(hostif);
+	if (intfd->bNumEndpoints < 1)
+		return -ENOENT;
 
-	if (endpoint->epnum == -1) {
-		intf = umidi->iface;
-		if (!intf || intf->num_altsetting < 1)
-			return -ENOENT;
-		hostif = intf->altsetting;
-		intfd = get_iface_desc(hostif);
-		if (intfd->bNumEndpoints < 1)
-			return -ENOENT;
-		epd = get_endpoint(hostif, 0);
-		endpoint->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	for (i = 0; i < intfd->bNumEndpoints; ++i) {
+		epd = get_endpoint(hostif, i);
+		if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
+			continue;
+		if (!endpoint->out_ep && endpoint->out_cables &&
+		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+			endpoint->out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+		if (!endpoint->in_ep && endpoint->in_cables &&
+		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+			endpoint->in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 	}
 	return 0;
 }
@@ -908,7 +915,6 @@
 	if (!endpoint->in_cables && !endpoint->out_cables)
 		return -ENOENT;
 
-	endpoint->epnum = -1;
 	return snd_usbmidi_detect_endpoint(umidi, endpoint);
 }
 
@@ -956,21 +962,21 @@
 		}
 	}
 
-	ep_info.epnum = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 	ep_info.out_cables = endpoint->out_cables & 0x5555;
 	err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
 	if (err < 0)
 		return err;
 
-	ep_info.epnum = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 	ep_info.in_cables = endpoint->in_cables;
 	err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
 	if (err < 0)
 		return err;
-	umidi->endpoints[0].in->urb->complete = (usb_complete_t)snd_usbmidi_in_midiman_complete;
+	umidi->endpoints[0].in->urb->complete = snd_usb_complete_callback(snd_usbmidi_in_midiman_complete);
 
 	if (endpoint->out_cables > 0x0001) {
-		ep_info.epnum = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+		ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 		ep_info.out_cables = endpoint->out_cables & 0xaaaa;
 		err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]);
 		if (err < 0)
@@ -999,7 +1005,7 @@
 			      out_ports, in_ports, &rmidi);
 	if (err < 0)
 		return err;
-	strcpy(rmidi->name, umidi->chip->card->longname);
+	strcpy(rmidi->name, umidi->chip->card->shortname);
 	rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
 			    SNDRV_RAWMIDI_INFO_INPUT |
 			    SNDRV_RAWMIDI_INFO_DUPLEX;
@@ -1083,6 +1089,8 @@
 		snd_usbmidi_free(umidi);
 		return err;
 	}
+
+	list_add(&umidi->list, &umidi->chip->midi_list);
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
 		if (umidi->endpoints[i].in)
diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
--- a/sound/usb/usbmixer.c	Mon Feb 10 10:39:24 2003
+++ b/sound/usb/usbmixer.c	Mon Feb 10 10:39:24 2003
@@ -751,7 +751,8 @@
 			      unsigned int ctl_mask, int control,
 			      usb_audio_term_t *iterm, int unitid)
 {
-	int len = 0, mapped_name = 0;
+	unsigned int len = 0;
+	int mapped_name = 0;
 	int nameid = desc[desc[0] - 1];
 	snd_kcontrol_t *kctl;
 	usb_mixer_elem_info_t *cval;
@@ -927,9 +928,9 @@
 				 int in_ch, int unitid)
 {
 	usb_mixer_elem_info_t *cval;
-	int num_ins = desc[4];
-	int num_outs = desc[5 + num_ins];
-	int i, len;
+	unsigned int num_ins = desc[4];
+	unsigned int num_outs = desc[5 + num_ins];
+	unsigned int i, len;
 	snd_kcontrol_t *kctl;
 	usb_audio_term_t iterm;
 
@@ -1240,7 +1241,7 @@
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
 	uinfo->value.enumerated.items = cval->max;
-	if (uinfo->value.enumerated.item >= cval->max)
+	if ((int)uinfo->value.enumerated.item >= cval->max)
 		uinfo->value.enumerated.item = cval->max - 1;
 	strcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item]);
 	return 0;
@@ -1325,8 +1326,9 @@
  */
 static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned char *desc)
 {
-	int num_ins = desc[4];
-	int i, err, nameid, len;
+	unsigned int num_ins = desc[4];
+	unsigned int i, nameid, len;
+	int err;
 	usb_mixer_elem_info_t *cval;
 	snd_kcontrol_t *kctl;
 	char **namelist;
diff -Nru a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
--- a/sound/usb/usbquirks.h	Mon Feb 10 10:39:26 2003
+++ b/sound/usb/usbquirks.h	Mon Feb 10 10:39:26 2003
@@ -162,6 +162,15 @@
 	}
 },
 {
+	USB_DEVICE(0x0499, 0x1011),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "Yamaha",
+		.product_name = "P-250",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_MIDI_YAMAHA
+	}
+},
+{
 	USB_DEVICE(0x0499, 0x1012),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Yamaha",
@@ -233,8 +242,55 @@
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "UA-100",
-		.ifnum = 0,
-		.type = QUIRK_ROLAND_UA100
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = & (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = & (const struct audioformat) {
+					.format = SNDRV_PCM_FORMAT_S16_LE,
+					.channels = 4,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = 0,
+					.endpoint = 0x01,
+					.ep_attr = 0x09,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = & (const struct audioformat) {
+					.format = SNDRV_PCM_FORMAT_S16_LE,
+					.channels = 2,
+					.iface = 1,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = EP_CS_ATTR_FILL_MAX,
+					.endpoint = 0x81,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0007,
+					.in_cables  = 0x0007
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
 	}
 },
 {
@@ -245,7 +301,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x000f,
 			.in_cables  = 0x000f
 		}
@@ -259,7 +314,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x003f,
 			.in_cables  = 0x003f
 		}
@@ -273,7 +327,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		}
@@ -287,7 +340,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		}
@@ -301,7 +353,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0013,
 			.in_cables  = 0x0013
 		}
@@ -315,7 +366,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -329,7 +379,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -343,23 +392,65 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0013,
 			.in_cables  = 0x0013
 		}
 	}
 },
 {
+	/* 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) {
 		.vendor_name = "Roland",
 		.product_name = "SC-D70",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
-			.out_cables = 0x0007,
-			.in_cables  = 0x0007
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = & (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = & (const struct audioformat) {
+					.format = SNDRV_PCM_FORMAT_S24_3LE,
+					.channels = 2,
+					.iface = 0,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = 0,
+					.endpoint = 0x01,
+					.ep_attr = 0x01,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
+			},
+			{
+				.ifnum = 1,
+				.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 = 0x81,
+					.ep_attr = 0x01,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0007,
+					.in_cables  = 0x0007
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -371,7 +462,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -385,7 +475,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x01ff,
 			.in_cables  = 0x01ff
 		}
@@ -399,7 +488,6 @@
 		.ifnum = 2,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x000f,
 			.in_cables  = 0x000f
 		}
@@ -413,7 +501,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x003f,
 			.in_cables  = 0x003f
 		}
@@ -427,7 +514,6 @@
 		.ifnum = 3,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -441,7 +527,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
@@ -455,7 +540,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x000f,
 			.in_cables  = 0x000f
 		}
@@ -469,13 +553,25 @@
 		.ifnum = 3,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		}
 	}
 },
 {
+	USB_DEVICE(0x0582, 0x002d),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "Roland",
+		.product_name = "XV-2020",
+		.ifnum = 0,
+		.type = QUIRK_MIDI_FIXED_ENDPOINT,
+		.data = & (const snd_usb_midi_endpoint_info_t) {
+			.out_cables = 0x0001,
+			.in_cables  = 0x0001
+		}
+	}
+},
+{
 	USB_DEVICE(0x0582, 0x0033),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -483,7 +579,6 @@
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.epnum = -1,
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
