diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Jun 16 21:04:35 2003
+++ b/Makefile	Wed Jun 18 04:35:28 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 72
-EXTRAVERSION =
+EXTRAVERSION = -bk1
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Mon Jun 16 13:04:32 2003
+++ b/arch/alpha/Kconfig	Sun Jun 15 08:55:30 2003
@@ -647,103 +647,7 @@
 	  This driver is also available as a module and will be called
 	  srm_env then.
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out (ECOFF) binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config OSF4_COMPAT
-	bool "OSF/1 v4 readv/writev compatibility"
-	depends on BINFMT_AOUT
-	help
-	  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
-	  with v4 shared libraries freely available from Compaq. If you're
-	  going to use shared libraries from Tru64 version 5.0 or later, say N.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
-
-config BINFMT_EM86
-	tristate "Kernel support for Linux/Intel ELF binaries"
-	---help---
-	  Say Y here if you want to be able to execute Linux/Intel ELF
-	  binaries just like native Alpha binaries on your Alpha machine. For
-	  this to work, you need to have the emulator /usr/bin/em86 in place.
-
-	  You can get the same functionality by saying N here and saying Y to
-	  "Kernel support for MISC binaries".
-
-	  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. If unsure, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/parport/Kconfig"
 
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/arm/Kconfig	Sat Jun 14 15:25:46 2003
@@ -691,81 +691,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config PM
 	bool "Power Management support"
diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/cris/Kconfig	Thu Jun 12 10:41:27 2003
@@ -25,34 +25,7 @@
 
 menu "General setup"
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
+source "fs/Kconfig.binfmt"
 
 config ETRAX_KGDB
 	bool "Use kernel gdb debugger"
diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig
--- a/arch/h8300/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/h8300/Kconfig	Thu Jun 12 10:41:27 2003
@@ -141,10 +141,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Sat Jun 14 16:15:56 2003
+++ b/arch/i386/Kconfig	Sat Jun 14 15:25:47 2003
@@ -1190,81 +1190,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	Tue Jun 10 12:04:01 2003
+++ b/arch/i386/kernel/nmi.c	Sun Jun 15 11:00:08 2003
@@ -23,17 +23,27 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/nmi.h>
 #include <linux/sysdev.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
+#include <asm/nmi.h>
 
 unsigned int nmi_watchdog = NMI_NONE;
 static unsigned int nmi_hz = HZ;
 unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
 extern void show_registers(struct pt_regs *regs);
 
+/* nmi_active:
+ * +1: the lapic NMI watchdog is active, but can be disabled
+ *  0: the lapic NMI watchdog has not been set up, and cannot
+ *     be enabled
+ * -1: the lapic NMI watchdog is disabled, but can be enabled
+ */
+static int nmi_active;
+
 #define K7_EVNTSEL_ENABLE	(1 << 22)
 #define K7_EVNTSEL_INT		(1 << 20)
 #define K7_EVNTSEL_OS		(1 << 17)
@@ -91,6 +101,7 @@
 			continue;
 		if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
 			printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+			nmi_active = 0;
 			return -1;
 		}
 	}
@@ -131,21 +142,15 @@
 	 * We can enable the IO-APIC watchdog
 	 * unconditionally.
 	 */
-	if (nmi == NMI_IO_APIC)
+	if (nmi == NMI_IO_APIC) {
+		nmi_active = 1;
 		nmi_watchdog = nmi;
+	}
 	return 1;
 }
 
 __setup("nmi_watchdog=", setup_nmi_watchdog);
 
-/* nmi_active:
- * +1: the lapic NMI watchdog is active, but can be disabled
- *  0: the lapic NMI watchdog has not been set up, and cannot
- *     be enabled
- * -1: the lapic NMI watchdog is disabled, but can be enabled
- */
-static int nmi_active;
-
 void disable_lapic_nmi_watchdog(void)
 {
 	if (nmi_active <= 0)
@@ -179,6 +184,27 @@
 	}
 }
 
+void disable_timer_nmi_watchdog(void)
+{
+	if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0))
+		return;
+
+	disable_irq(0);
+	unset_nmi_callback();
+	nmi_active = -1;
+	nmi_watchdog = NMI_NONE;
+}
+
+void enable_timer_nmi_watchdog(void)
+{
+	if (nmi_active < 0) {
+		nmi_watchdog = NMI_IO_APIC;
+		touch_nmi_watchdog();
+		nmi_active = 1;
+		enable_irq(0);
+	}
+}
+
 #ifdef CONFIG_PM
 
 static int nmi_pm_active; /* nmi_active before suspend */
@@ -429,3 +455,5 @@
 EXPORT_SYMBOL(nmi_watchdog);
 EXPORT_SYMBOL(disable_lapic_nmi_watchdog);
 EXPORT_SYMBOL(enable_lapic_nmi_watchdog);
+EXPORT_SYMBOL(disable_timer_nmi_watchdog);
+EXPORT_SYMBOL(enable_timer_nmi_watchdog);
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Sat Jun  7 15:17:53 2003
+++ b/arch/i386/kernel/setup.c	Wed Jun 11 20:06:29 2003
@@ -96,7 +96,6 @@
 extern void generic_apic_probe(char *);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
-extern int blk_nohighio;
 
 unsigned long saved_videomode;
 
@@ -994,15 +993,6 @@
 #endif
 #endif
 }
-
-static int __init highio_setup(char *str)
-{
-	printk("i386: disabling HIGHMEM block I/O\n");
-	blk_nohighio = 1;
-	return 1;
-}
-__setup("nohighio", highio_setup);
- 
 
 #include "setup_arch_post.h"
 /*
diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile
--- a/arch/i386/oprofile/Makefile	Mon Apr 28 17:11:32 2003
+++ b/arch/i386/oprofile/Makefile	Sun Jun 15 11:00:08 2003
@@ -9,3 +9,4 @@
 oprofile-y				:= $(DRIVER_OBJS) init.o
 oprofile-$(CONFIG_X86_LOCAL_APIC) 	+= nmi_int.o op_model_athlon.o \
 					   op_model_ppro.o op_model_p4.o
+oprofile-$(CONFIG_X86_IO_APIC)		+= nmi_timer_int.o
diff -Nru a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c
--- a/arch/i386/oprofile/init.c	Mon May 12 21:23:26 2003
+++ b/arch/i386/oprofile/init.c	Sun Jun 15 11:05:04 2003
@@ -16,15 +16,21 @@
  */
  
 extern int nmi_init(struct oprofile_operations ** ops);
+extern int nmi_timer_init(struct oprofile_operations **ops);
 extern void nmi_exit(void);
 
 int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
+	int ret = -ENODEV;
 #ifdef CONFIG_X86_LOCAL_APIC
-	return nmi_init(ops);
-#else
-	return -ENODEV;
+	ret = nmi_init(ops);
 #endif
+
+#ifdef CONFIG_X86_IO_APIC
+	if (ret < 0)
+		ret = nmi_timer_init(ops);
+#endif
+	return ret;
 }
 
 
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Tue Jun 10 12:06:36 2003
+++ b/arch/i386/oprofile/nmi_int.c	Sat Jun 14 18:10:08 2003
@@ -182,8 +182,8 @@
 static void nmi_shutdown(void)
 {
 	nmi_enabled = 0;
-	unset_nmi_callback();
 	on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
+	unset_nmi_callback();
 	enable_lapic_nmi_watchdog();
 }
 
diff -Nru a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/oprofile/nmi_timer_int.c	Sun Jun 15 11:04:34 2003
@@ -0,0 +1,57 @@
+/**
+ * @file nmi_timer_int.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo <zwane@linuxpower.ca>
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+#include <linux/rcupdate.h>
+
+
+#include <asm/nmi.h>
+#include <asm/apic.h>
+#include <asm/ptrace.h>
+ 
+static int nmi_timer_callback(struct pt_regs * regs, int cpu)
+{
+	unsigned long eip = instruction_pointer(regs);
+ 
+	oprofile_add_sample(eip, !user_mode(regs), 0, cpu);
+	return 1;
+}
+
+static int timer_start(void)
+{
+	disable_timer_nmi_watchdog();
+	set_nmi_callback(nmi_timer_callback);
+	return 0;
+}
+
+
+static void timer_stop(void)
+{
+	enable_timer_nmi_watchdog();
+	unset_nmi_callback();
+	synchronize_kernel();
+}
+
+
+static struct oprofile_operations nmi_timer_ops = {
+	.start	= timer_start,
+	.stop	= timer_stop,
+	.cpu_type = "timer"
+};
+
+ 
+int __init nmi_timer_init(struct oprofile_operations ** ops)
+{
+	*ops = &nmi_timer_ops;
+	printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
+	return 0;
+}
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/ia64/Kconfig	Sat Jun 14 15:25:48 2003
@@ -493,38 +493,7 @@
 	depends on SMP
 	default "64"
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  Once you have registered such a binary class with the
-	  kernel, you can start one of those programs simply by typing in its
-	  name at a shell prompt; Linux will automatically feed it to the
-	  correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 if !IA64_HP_SIM
 
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/m68k/Kconfig	Thu Jun 12 10:41:27 2003
@@ -376,81 +376,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config ZORRO
 	bool "Amiga Zorro (AutoConfig) bus support"
@@ -680,417 +606,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CD-ROM)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  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.  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 /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT for
-	  SCSI CD-ROMs.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config ST_EXTRA_DEVS
-	int "Maximum number of SCSI tapes that can be loaded as modules"
-	depends on CHR_DEV_ST
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional tapes that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  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.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config A3000_SCSI
-	tristate "A3000 WD33C93A support"
-	depends on AMIGA && SCSI
-	help
-	  If you have an Amiga 3000 and have SCSI devices connected to the
-	  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. If you want to compile it as a module, say M here
-	  and read <file:Documentation/modules.txt>.
-
-config A4000T_SCSI
-	bool "A4000T SCSI support (EXPERIMENTAL)"
-	depends on AMIGA && EXPERIMENTAL
-	help
-	  Support for the NCR53C710 SCSI controller on the Amiga 4000T.
-
-config A2091_SCSI
-	tristate "A2091 WD33C93A support"
-	depends on ZORRO && SCSI
-	help
-	  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. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config GVP11_SCSI
-	tristate "GVP Series II WD33C93A support"
-	depends on ZORRO && SCSI
-	---help---
-	  If you have a Great Valley Products Series II SCSI controller,
-	  answer Y. Also say Y if you have a later model of GVP SCSI
-	  controller (such as the GVP A4008 or a Combo board). Otherwise,
-	  answer N. This driver does NOT work for the T-Rex series of
-	  accelerators from TekMagic and GVP-M.
-
-	  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. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-config CYBERSTORM_SCSI
-	tristate "CyberStorm SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with an original (MkI) Phase5 Cyberstorm
-	  accelerator board and the optional Cyberstorm SCSI controller,
-	  answer Y. Otherwise, say N.
-
-config CYBERSTORMII_SCSI
-	tristate "CyberStorm Mk II SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with a Phase5 Cyberstorm MkII accelerator board
-	  and the optional Cyberstorm SCSI controller, say Y. Otherwise,
-	  answer N.
-
-config BLZ2060_SCSI
-	tristate "Blizzard 2060 SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with a Phase5 Blizzard 2060 accelerator board
-	  and want to use the onboard SCSI controller, say Y. Otherwise,
-	  answer N.
-
-config BLZ1230_SCSI
-	tristate "Blizzard 1230IV/1260 SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga 1200 with a Phase5 Blizzard 1230IV or Blizzard
-	  1260 accelerator, and the optional SCSI module, say Y. Otherwise,
-	  say N.
-
-config FASTLANE_SCSI
-	tristate "Fastlane SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have the Phase5 Fastlane Z3 SCSI controller, or plan to use
-	  one in the near future, say Y to this question. Otherwise, say N.
-
-config A4091_SCSI
-	bool "A4091 SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller
-	  (1993).  Very obscure -- the 4091 was part of an Amiga 4000 upgrade
-	  plan at the time the Amiga business was sold to DKB.
-
-config WARPENGINE_SCSI
-	bool "WarpEngine SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  Support for MacroSystem Development's WarpEngine Amiga SCSI-2
-	  controller. Info at
-	  <http://www.lysator.liu.se/amiga/ar/guide/ar310.guide?FEATURE5>.
-
-config BLZ603EPLUS_SCSI
-	bool "Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+
-	  accelerator, say Y. Otherwise, say N.
-
-config OKTAGON_SCSI
-	tristate "BSC Oktagon SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL && SCSI
-	help
-	  If you have the BSC Oktagon SCSI disk controller for the Amiga, say
-	  Y to this question.  If you're in doubt about whether you have one,
-	  see the picture at
-	  <http://amiga.multigraph.com/photos/oktagon.html>.
-
-#	 bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
-#	 bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI
-config ATARI_SCSI
-	tristate "Atari native SCSI support"
-	depends on ATARI && SCSI
-	---help---
-	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
-	  Falcon, ...) say Y to get it supported. Of course also, if you have
-	  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.  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
-	  NOT support other schemes, like in the Hades (without DMA).
-
-config ATARI_SCSI_TOSHIBA_DELAY
-	bool "Long delays for Toshiba CD-ROMs"
-	depends on ATARI_SCSI
-	help
-	  This option increases the delay after a SCSI arbitration to
-	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
-	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
-	  would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-	bool "Reset SCSI-devices at boottime"
-	depends on ATARI_SCSI
-	help
-	  Reset the devices on your Atari whenever it boots.  This makes the
-	  boot process fractionally longer but may assist recovery from errors
-	  that leave the devices with SCSI operations partway completed.
-
-config TT_DMA_EMUL
-	bool "Hades SCSI DMA emulator"
-	depends on ATARI_SCSI && HADES
-	help
-	  This option enables code which emulates the TT SCSI DMA chip on the
-	  Hades. This increases the SCSI transfer rates at least ten times
-	  compared to PIO transfers.
-
-config MAC_SCSI
-	bool "Macintosh NCR5380 SCSI"
-	depends on MAC
-	help
-	  This is the NCR 5380 SCSI controller included on most of the 68030
-	  based Macintoshes.  If you have one of these say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config SCSI_MAC_ESP
-	tristate "Macintosh NCR53c9[46] SCSI"
-	depends on MAC && SCSI
-	help
-	  This is the NCR 53c9x SCSI controller found on most of the 68040
-	  based Macintoshes.  If you have one of these say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  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.  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
-config MVME147_SCSI
-	bool "WD33C93 SCSI driver for MVME147"
-	depends on MVME147
-	help
-	  Support for the on-board SCSI controller on the Motorola MVME147
-	  single-board computer.
-
-config MVME16x_SCSI
-	bool "NCR53C710 SCSI driver for MVME16x"
-	depends on MVME16x
-	help
-	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
-	  SCSI controller chip.  Almost everyone using one of these boards
-	  will want to say Y to this question.
-
-config BVME6000_SCSI
-	bool "NCR53C710 SCSI driver for BVME6000"
-	depends on BVME6000
-	help
-	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
-	  SCSI controller chip.  Almost everyone using one of these boards
-	  will want to say Y to this question.
-
-config SUN3_SCSI
-	tristate "Sun3 NCR5380 SCSI"
-	depends on SUN3 && SCSI
-	help
-	  This option will enable support for the OBIO (onboard io) NCR5380
-	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
-	  "Sun3" type VME scsi controllers also based on the NCR5380.
-	  General Linux information on the Sun 3 series (now discontinued)
-	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
-config SUN3X_ESP
-	bool "Sun3x ESP SCSI"
-	depends on SUN3X
-	help
-	  The ESP was an on-board SCSI controller used on Sun 3/80
-	  machines.  Say Y here to compile in support for it.
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/m68knommu/Kconfig	Sat Jun 14 15:25:48 2003
@@ -501,16 +501,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
-
-config BINFMT_ZFLAT
-	bool "  Enable ZFLAT support"
-	depends on BINFMT_FLAT
-	help
-	  Supoprt FLAT format compressed binaries
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/mips/Kconfig	Thu Jun 12 10:41:27 2003
@@ -702,82 +702,7 @@
 	bool "ARC console support"
 	depends on ARC32
 
-config BINFMT_AOUT
-	bool
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	bool
-	default y
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/mips64/Kconfig	Thu Jun 12 10:41:27 2003
@@ -335,34 +335,7 @@
 	bool "ARC console support"
 	depends on ARC32
 
-config BINFMT_ELF
-	tristate "Kernel support for 64-bit ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
+source "fs/Kconfig.binfmt"
 
 config MIPS32_COMPAT
 	bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
@@ -378,36 +351,11 @@
 
 config BINFMT_ELF32
 	bool
-	depends on MIPS32_COMPAT
+	depends on BINFMT_ELF && MIPS32_COMPAT
 	default y
 	help
 	  This allows you to run 32-bit Linux/ELF binaries on your Ultra.
 	  Everybody wants this; say Y.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
 
 endmenu
 
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Sun May 11 22:49:49 2003
+++ b/arch/parisc/Kconfig	Thu Jun 12 10:41:27 2003
@@ -166,66 +166,7 @@
 	depends on PROC_FS
 	default y
 
-config BINFMT_SOM
-	tristate "Kernel support for SOM binaries"
-	depends on HPUX
-	help
-	  SOM is a binary executable format inherited from HP/UX.  Say Y here
-	  to be able to load and execute SOM binaries directly.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/ppc/Kconfig	Sat Jun 14 15:25:49 2003
@@ -808,42 +808,11 @@
 	  "-g" option to preserve debugging information. It is mainly used
 	  for examining kernel data structures on the live kernel.
 
-config BINFMT_ELF
-	bool
-	default y
-	help
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems.
-
 config KERNEL_ELF
 	bool
 	default y
 
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>).  Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/ppc64/Kconfig	Sat Jun 14 15:25:50 2003
@@ -191,37 +191,7 @@
 	  "-g" option to preserve debugging information. It is mainly used
 	  for examining kernel data structures on the live kernel.
 
-config BINFMT_ELF
-	bool "Kernel support for 64-bit ELF binaries"
-	help
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>).  Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	Sun Apr 20 12:56:51 2003
+++ b/arch/s390/Kconfig	Thu Jun 12 10:41:27 2003
@@ -192,78 +192,8 @@
 config KCORE_ELF
 	bool
 	default y
-	---help---
-	  If you enabled support for /proc file system then the file
-	  /proc/kcore will contain the kernel core image. This can be used
-	  in gdb:
 
-	  $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
-
-	  You have two choices here: ELF and A.OUT. Selecting ELF will make
-	  /proc/kcore appear in ELF core format as defined by the Executable
-	  and Linking Format specification. Selecting A.OUT will choose the
-	  old "a.out" format which may be necessary for some old versions
-	  of binutils or on some architectures.
-
-	  This is especially useful if you have compiled the kernel with the
-	  "-g" option to preserve debugging information. It is mainly used
-	  for examining kernel data structures on the live kernel so if you
-	  don't understand what this means or are not a kernel hacker, just
-	  leave it at its default value ELF.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config PROCESS_DEBUG
 	bool "Show crashed user process info"
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	Sat Jun 14 17:43:31 2003
+++ b/arch/sh/Kconfig	Sat Jun 14 15:35:19 2003
@@ -763,62 +763,7 @@
 
 endchoice
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_FLAT
-	tristate "Kernel support for FLAT binaries"
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/sparc/Kconfig	Thu Jun 12 10:41:27 2003
@@ -277,81 +277,7 @@
 	  don't understand what this means or are not a kernel hacker, just
 	  leave it at its default value ELF.
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  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. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config SUNOS_EMUL
 	bool "SunOS binary emulation"
@@ -576,232 +502,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CDrom)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  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.  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 /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
-	  for SCSI CD-ROMs.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config CHR_DEV_OSST
-	tristate "SCSI OnStream SC-x0 tape support"
-	depends on SCSI
-	---help---
-	  The OnStream SC-x0 SCSI tape drives can not be driven by the
-	  standard st driver, but instead need this special osst driver and
-	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage
-	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
-	  as well.  Note that there is also a second generation of OnStream
-	  tape drives (ADR-x0) that supports the standard SCSI-2 commands for
-	  tapes (QIC-157) and can be driven by the standard driver st.
-	  For more information, you may have a look at the SCSI-HOWTO
-	  <http://www.tldp.org/docs.html#howto>  and
-	  <file:Documentation/scsi/osst.txt>  in the kernel source.
-	  More info on the OnStream driver may be found on
-	  <http://linux1.onstream.nl/test/>
-	  Please also have a look at the standard st docu, as most of it
-	  applies to osst as well.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  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.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config SCSI_SUNESP
-	tristate "Sparc ESP Scsi Driver"
-	depends on SCSI
-	help
-	  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 ( = 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>.
-
-config SCSI_QLOGICPTI
-	tristate "PTI Qlogic,ISP Driver"
-	depends on SCSI
-	help
-	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
-	  controllers are known under Solaris as qpti and in the openprom as
-	  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 ( =
-	  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>.
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	Sat Jun 14 16:16:07 2003
+++ b/arch/sparc/kernel/time.c	Tue Jun 17 15:46:44 2003
@@ -408,9 +408,9 @@
 	mon = MSTK_REG_MONTH(mregs);
 	year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-	wall_to_monotonic.tv_nsec = 0;
+	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 	mregs->creg &= ~MSTK_CREG_READ;
 	spin_unlock_irq(&mostek_lock);
 #ifdef CONFIG_SUN4
@@ -441,9 +441,9 @@
 		intersil_start(iregs);
 
 		xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-		wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+		wall_to_monotonic.tv_sec = -xtime.tv_sec;
 		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		wall_to_monotonic.tv_nsec = 0;
+		wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 		printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
 	}
 #endif
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/sparc64/Kconfig	Sat Jun 14 15:25:52 2003
@@ -415,59 +415,7 @@
 	  If you want to run SunOS binaries (see SunOS binary emulation below)
 	  or other a.out binaries, say Y. If unsure, say N.
 
-config BINFMT_ELF
-	tristate "Kernel support for 64-bit ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  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. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config SUNOS_EMUL
 	bool "SunOS binary emulation"
@@ -748,642 +696,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CDrom)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  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.  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 /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
-	  for SCSI CD-ROMs.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config CHR_DEV_OSST
-	tristate "SCSI OnStream SC-x0 tape support"
-	depends on SCSI
-	---help---
-	  The OnStream SC-x0 SCSI tape drives can not be driven by the
-	  standard st driver, but instead need this special osst driver and
-	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage
-	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
-	  as well.  Note that there is also a second generation of OnStream
-	  tape drives (ADR-x0) that supports the standard SCSI-2 commands for
-	  tapes (QIC-157) and can be driven by the standard driver st.
-	  For more information, you may have a look at the SCSI-HOWTO
-	  <http://www.tldp.org/docs.html#howto>  and
-	  <file:Documentation/scsi/osst.txt>  in the kernel source.
-	  More info on the OnStream driver may be found on
-	  <http://linux1.onstream.nl/test/>
-	  Please also have a look at the standard st docu, as most of it
-	  applies to osst as well.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  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. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  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.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config SCSI_SUNESP
-	tristate "Sparc ESP Scsi Driver"
-	depends on SCSI
-	help
-	  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 ( = 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>.
-
-config SCSI_QLOGICPTI
-	tristate "PTI Qlogic, ISP Driver"
-	depends on SCSI
-	help
-	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
-	  controllers are known under Solaris as qpti and in the openprom as
-	  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 ( =
-	  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>.
-
-
-choice
-	prompt "Adaptec AIC7xxx support"
-	optional
-	depends on SCSI && PCI
-
-source "drivers/scsi/aic7xxx/Kconfig.aic7xxx"
-
-config SCSI_AIC7XXX_OLD
-	tristate "Old driver"
-	---help---
-	  WARNING This driver is an older aic7xxx driver and is no longer
-	  under active development.  Adaptec, Inc. is writing a new driver to
-	  take the place of this one, and it is recommended that whenever
-	  possible, people should use the new Adaptec written driver instead
-	  of this one.  This driver will eventually be phased out entirely.
-
-	  This is support for the various aic7xxx based Adaptec SCSI
-	  controllers. These include the 274x EISA cards; 284x VLB cards;
-	  2902, 2910, 293x, 294x, 394x, 3985 and several other PCI and
-	  motherboard based SCSI controllers from Adaptec. It does not support
-	  the AAA-13x RAID controllers from Adaptec, nor will it likely ever
-	  support them. It does not support the 2920 cards from Adaptec that
-	  use the Future Domain SCSI controller chip. For those cards, you
-	  need the "Future Domain 16xx SCSI support" driver.
-
-	  In general, if the controller is based on an Adaptec SCSI controller
-	  chip from the aic777x series or the aic78xx series, this driver
-	  should work. The only exception is the 7810 which is specifically
-	  not supported (that's the RAID controller chip on the AAA-13x
-	  cards).
-
-	  Note that the AHA2920 SCSI host adapter is *not* supported by this
-	  driver; choose "Future Domain 16xx SCSI support" instead if you have
-	  one of those.
-
-	  Information on the configuration options for this controller can be
-	  found by checking the help file for each of the available
-	  configuration options. You should read
-	  <file:Documentation/scsi/aic7xxx_old.txt> at a minimum before
-	  contacting the maintainer with any questions.  The SCSI-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>, can also
-	  be of great help.
-
-	  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.
-
-config AIC7XXX_OLD_TCQ_ON_BY_DEFAULT
-	bool "Enable Tagged Command Queueing (TCQ) by default"
-	depends on SCSI_AIC7XXX_OLD
-	---help---
-	  This option causes the aic7xxx driver to attempt to use Tagged
-	  Command Queueing (TCQ) on all devices that claim to support it.
-
-	  TCQ is a feature of SCSI-2 which improves performance: the host
-	  adapter can send several SCSI commands to a device's queue even if
-	  previous commands haven't finished yet.  Because the device is
-	  intelligent, it can optimize its operations (like head positioning)
-	  based on its own request queue.  Not all devices implement this
-	  correctly.
-
-	  If you say Y here, you can still turn off TCQ on troublesome devices
-	  with the use of the tag_info boot parameter.  See the file
-	  <file:Documentation/scsi/aic7xxx.txt> for more information on that and
-	  other aic7xxx setup commands.  If this option is turned off, you may
-	  still enable TCQ on known good devices by use of the tag_info boot
-	  parameter.
-
-	  If you are unsure about your devices then it is safest to say N
-	  here.
-
-	  However, TCQ can increase performance on some hard drives by as much
-	  as 50% or more, so it is recommended that if you say N here, you
-	  should at least read the <file:Documentation/scsi/aic7xxx.txt> file so
-	  you will know how to enable this option manually should your drives
-	  prove to be safe in regards to TCQ.
-
-	  Conversely, certain drives are known to lock up or cause bus resets
-	  when TCQ is enabled on them.  If you have a Western Digital
-	  Enterprise SCSI drive for instance, then don't even bother to enable
-	  TCQ on it as the drive will become unreliable, and it will actually
-	  reduce performance.
-
-config AIC7XXX_OLD_CMDS_PER_DEVICE
-	int "Maximum number of TCQ commands per device"
-	depends on SCSI_AIC7XXX_OLD
-	default "8"
-	---help---
-	  Specify the number of commands you would like to allocate per SCSI
-	  device when Tagged Command Queueing (TCQ) is enabled on that device.
-
-	  Reasonable figures are in the range of 8 to 24 commands per device,
-	  but depending on hardware could be increased or decreased from that
-	  figure. If the number is too high for any particular device, the
-	  driver will automatically compensate usually after only 10 minutes
-	  of uptime. It will not hinder performance if some of your devices
-	  eventually have their command depth reduced, but is a waste of
-	  memory if all of your devices end up reducing this number down to a
-	  more reasonable figure.
-
-	  NOTE: Certain very broken drives are known to lock up when given
-	  more commands than they like to deal with. Quantum Fireball drives
-	  are the most common in this category. For the Quantum Fireball
-	  drives it is suggested to use no more than 8 commands per device.
-
-	  Default: 8
-
-config AIC7XXX_OLD_PROC_STATS
-	bool "Collect statistics to report in /proc"
-	depends on SCSI_AIC7XXX_OLD
-	---help---
-	  This option tells the driver to keep track of how many commands have
-	  been sent to each particular device and report that information to
-	  the user via the /proc/scsi/aic7xxx/n file, where n is the number of
-	  the aic7xxx controller you want the information on. This adds a
-	  small amount of overhead to each and every SCSI command the aic7xxx
-	  driver handles, so if you aren't really interested in this
-	  information, it is best to leave it disabled. This will only work if
-	  you also say Y to "/proc file system support", below.
-
-	  If unsure, say N.
-
-endchoice
-
-config SCSI_SYM53C8XX_2
-	tristate "SYM53C8XX Version 2 SCSI support"
-	depends on PCI && SCSI
-	---help---
-	  This driver supports the whole NCR53C8XX/SYM53C8XX family of 
-	  PCI-SCSI controllers. It also supports the subset of LSI53C10XX 
-	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS 
-	  language. It does not support LSI53C10XX Ultra-320 PCI-X SCSI 
-	  controllers.
-
-	  If your system has problems using this new major version of the
-	  SYM53C8XX driver, you may switch back to driver version 1.
-
-	  Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
-	  information.
-
-config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
-	int "DMA addressing mode"
-	depends on SCSI_SYM53C8XX_2
-	default "1"
-	---help---
-	  This option only applies to PCI-SCSI chip that are PCI DAC capable 
-	  (875A, 895A, 896, 1010-33, 1010-66, 1000).
-
-	  When set to 0, only PCI 32 bit DMA addressing (SAC) will be performed.
-	  When set to 1, 40 bit DMA addressing (with upper 24 bits of address 
-	  set to zero) is supported. The addressable range is here 1 TB.
-	  When set to 2, full 64 bits of address for DMA are supported, but only
-	  16 segments of 4 GB can be addressed. The addressable range is so 
-	  limited to 64 GB.
-
-	  The safest value is 0 (32 bit DMA addressing) that is guessed to still 
-	  fit most of real machines.
-
-	  The preferred value 1 (40 bit DMA addressing) should make happy 
-	  properly engineered PCI DAC capable host bridges. You may configure
-	  this option for Intel platforms with more than 4 GB of memory.
-
-	  The still experimental value 2 (64 bit DMA addressing with 16 x 4GB 
-	  segments limitation) can be used on systems that require PCI address 
-	  bits past bit 39 to be set for the addressing of memory using PCI 
-	  DAC cycles.
-
-config SCSI_SYM53C8XX_DEFAULT_TAGS
-	int "default tagged command queue depth"
-	depends on SCSI_SYM53C8XX_2
-	default "16"
-	help
-	  This is the default value of the command queue depth the driver will 
-	  announce to the generic SCSI layer for devices that support tagged 
-	  command queueing. This value can be changed from the boot command line.
-	  This is a soft limit that cannot exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
-
-config SCSI_SYM53C8XX_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on SCSI_SYM53C8XX_2
-	default "64"
-	help
-	  This option allows you to specify the maximum number of commands
-	  that can be queued to any device, when tagged command queuing is
-	  possible. The driver supports up to 256 queued commands per device.
-	  This value is used as a compiled-in hard limit.
-
-config SCSI_SYM53C8XX_IOMAPPED
-	bool "use normal IO"
-	depends on SCSI_SYM53C8XX_2
-	help
-	  If you say Y here, the driver will preferently use normal IO rather than 
-	  memory mapped IO.
-
-config SCSI_NCR53C8XX
-	tristate "NCR53C8XX SCSI support"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI
-	---help---
-	  This is the BSD ncr driver adapted to Linux for the NCR53C8XX family
-	  of PCI-SCSI controllers.  This driver supports parity checking,
-	  tagged command queuing and fast synchronous data transfers up to 80
-	  MB/s with wide FAST-40 LVD devices and controllers.
-
-	  Recent versions of the 53C8XX chips are better supported by the
-	  option "SYM53C8XX SCSI support", below.
-
-	  Note: there is yet another driver for the 53c8xx family of
-	  controllers ("NCR53c7,8xx SCSI support" above).  If you want to use
-	  them both, you need to say M to both and build them as modules, but
-	  only one may be active at a time.  If you have a 53c8xx board, you
-	  probably do not want to use the "NCR53c7,8xx SCSI support".
-
-	  Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
-	  information.
-
-config SCSI_SYM53C8XX
-	tristate "SYM53C8XX SCSI support"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI
-	---help---
-	  This driver supports all the features of recent 53C8XX chips (used
-	  in PCI SCSI controllers), notably the hardware phase mismatch
-	  feature of the SYM53C896.
-
-	  Older versions of the 53C8XX chips are not supported by this
-	  driver.  If your system uses either a 810 rev. < 16, a 815, or a 825
-	  rev. < 16 PCI SCSI processor, you must use the generic NCR53C8XX
-	  driver ("NCR53C8XX SCSI support" above) or configure both the
-	  NCR53C8XX and this SYM53C8XX drivers either as module or linked to
-	  the kernel image.
-
-	  When both drivers are linked into the kernel, the SYM53C8XX driver
-	  is called first at initialization and you can use the 'excl=ioaddr'
-	  driver boot option to exclude attachment of adapters by the
-	  SYM53C8XX driver.  For example, entering
-	  'sym53c8xx=excl:0xb400,excl=0xc000' at the lilo prompt prevents
-	  adapters at io address 0xb400 and 0xc000 from being attached by the
-	  SYM53C8XX driver, thus allowing the NCR53C8XX driver to attach them.
-	  The 'excl' option is also supported by the NCR53C8XX driver.
-
-	  Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
-	  information.
-
-config SCSI_NCR53C8XX_DEFAULT_TAGS
-	int "default tagged command queue depth"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "8"
-	---help---
-	  "Tagged command queuing" is a feature of SCSI-2 which improves
-	  performance: the host adapter can send several SCSI commands to a
-	  device's queue even if previous commands haven't finished yet.
-	  Because the device is intelligent, it can optimize its operations
-	  (like head positioning) based on its own request queue. Some SCSI
-	  devices don't implement this properly; if you want to disable this
-	  feature, enter 0 or 1 here (it doesn't matter which).
-
-	  The default value is 8 and should be supported by most hard disks.
-	  This value can be overridden from the boot command line using the
-	  'tags' option as follows (example):
-	  'ncr53c8xx=tags:4/t2t3q16/t0u2q10' will set default queue depth to
-	  4, set queue depth to 16 for target 2 and target 3 on controller 0
-	  and set queue depth to 10 for target 0 / lun 2 on controller 1.
-
-	  The normal answer therefore is to go with the default 8 and to use
-	  a boot command line option for devices that need to use a different
-	  command queue depth.
-
-	  There is no safe option other than using good SCSI devices.
-
-config SCSI_NCR53C8XX_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "32"
-	---help---
-	  This option allows you to specify the maximum number of commands
-	  that can be queued to any device, when tagged command queuing is
-	  possible. The default value is 32. Minimum is 2, maximum is 64.
-	  Modern hard disks are able to support 64 tags and even more, but
-	  do not seem to be faster when more than 32 tags are being used.
-
-	  So, the normal answer here is to go with the default value 32 unless
-	  you are using very large hard disks with large cache (>= 1 MB) that
-	  are able to take advantage of more than 32 tagged commands.
-
-	  There is no safe option and the default answer is recommended.
-
-config SCSI_NCR53C8XX_SYNC
-	int "synchronous transfers frequency in MHz"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "10"
-	---help---
-	  The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
-	  rates: FAST-5, FAST-10, FAST-20, FAST-40 and FAST-80.  The numbers
-	  are respectively the maximum data transfer rates in mega-transfers
-	  per second for each class.  For example, a FAST-20 Wide 16 device is
-	  able to transfer data at 20 million 16 bit packets per second for a
-	  total rate of 40 MB/s.
-
-	  You may specify 0 if you want to only use asynchronous data
-	  transfers. This is the safest and slowest option. Otherwise, specify
-	  a value between 5 and 80, depending on the capability of your SCSI
-	  controller.  The higher the number, the faster the data transfer.
-	  Note that 80 should normally be ok since the driver decreases the
-	  value automatically according to the controller's capabilities.
-
-	  Your answer to this question is ignored for controllers with NVRAM,
-	  since the driver will get this information from the user set-up.  It
-	  also can be overridden using a boot setup option, as follows
-	  (example): 'ncr53c8xx=sync:12' will allow the driver to negotiate
-	  for FAST-20 synchronous data transfer (20 mega-transfers per
-	  second).
-
-	  The normal answer therefore is not to go with the default but to
-	  select the maximum value 80 allowing the driver to use the maximum
-	  value supported by each controller. If this causes problems with
-	  your SCSI devices, you should come back and decrease the value.
-
-	  There is no safe option other than using good cabling, right
-	  terminations and SCSI conformant devices.
-
-config SCSI_NCR53C8XX_PROFILE
-	bool "enable profiling"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	help
-	  This option allows you to enable profiling information gathering.
-	  These statistics are not very accurate due to the low frequency
-	  of the kernel clock (100 Hz on i386) and have performance impact
-	  on systems that use very fast devices.
-
-	  The normal answer therefore is N.
-
-config SCSI_NCR53C8XX_PQS_PDS
-	bool "include support for the NCR PQS/PDS SCSI card"
-	depends on (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_SYM53C8XX
-	help
-	  Say Y here if you have a special SCSI adapter produced by NCR
-	  corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need
-	  this if you do not have one of these adapters. However, since this
-	  device is detected as a specific PCI device, this option is quite
-	  safe.
-
-	  The common answer here is N, but answering Y is safe.
-
-config SCSI_NCR53C8XX_NO_DISCONNECT
-	bool "not allow targets to disconnect"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
-	help
-	  This option is only provided for safety if you suspect some SCSI
-	  device of yours to not support properly the target-disconnect
-	  feature. In that case, you would say Y here. In general however, to
-	  not allow targets to disconnect is not reasonable if there is more
-	  than 1 device on a SCSI bus. The normal answer therefore is N.
-
-config SCSI_NCR53C8XX_SYMBIOS_COMPAT
-	bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && EXPERIMENTAL
-	---help---
-	  This option allows you to enable some features depending on GPIO
-	  wiring. These General Purpose Input/Output pins can be used for
-	  vendor specific features or implementation of the standard SYMBIOS
-	  features. Genuine SYMBIOS controllers use GPIO0 in output for
-	  controller LED and GPIO3 bit as a flag indicating
-	  singled-ended/differential interface. The Tekram DC-390U/F boards
-	  uses a different GPIO wiring.
-
-	  Your answer to this question is ignored if all your controllers have
-	  NVRAM, since the driver is able to detect the board type from the
-	  NVRAM format.
-
-	  If all the controllers in your system are genuine SYMBIOS boards or
-	  use BIOS and drivers from SYMBIOS, you would want to say Y here,
-	  otherwise N. N is the safe answer.
-
-config SCSI_QLOGIC_ISP
-	tristate "Qlogic ISP SCSI support"
-	depends on PCI && SCSI
-	---help---
-	  This driver works for all QLogic PCI SCSI host adapters (IQ-PCI,
-	  IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card.  (This latter
-	  card is supported by the "AM53/79C974 PCI SCSI" driver.)
-
-	  If you say Y here, make sure to choose "BIOS" at the question "PCI
-	  access mode".
-
-	  Please read the file <file:Documentation/scsi/qlogicisp.txt>.  You
-	  should also read the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  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.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGIC_FC
-	tristate "Qlogic ISP FC SCSI support"
-	depends on PCI && SCSI
-	help
-	  This is a driver for the QLogic ISP2100 SCSI-FCP host adapter.
-
-	  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.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGIC_FC_FIRMWARE
-	bool
-	depends on SCSI_QLOGIC_FC
-	default y
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Sat Jun 14 16:15:59 2003
+++ b/arch/sparc64/kernel/time.c	Tue Jun 17 14:51:27 2003
@@ -703,9 +703,9 @@
 	}
 
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-	wall_to_monotonic.tv_nsec = 0;
+	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 
 	if (mregs) {
 		tmp = mostek_read(mregs + MOSTEK_CREG);
@@ -743,9 +743,9 @@
 			(unsigned int) (long) &unix_tod);
 		prom_feval(obp_gettod);
 		xtime.tv_sec = unix_tod;
-		wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+		wall_to_monotonic.tv_sec = -xtime.tv_sec;
 		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		wall_to_monotonic.tv_nsec = 0;
+		wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 		return;
 	}
 
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	Sat Mar  8 14:50:37 2003
+++ b/arch/um/Kconfig	Thu Jun 12 10:41:27 2003
@@ -62,14 +62,7 @@
 config NET
 	bool "Networking support"
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
+source "fs/Kconfig.binfmt"
 
 config HOSTFS
 	tristate "Host filesystem"
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/v850/Kconfig	Sat Jun 14 15:25:52 2003
@@ -243,16 +243,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
-
-config BINFMT_ZFLAT
-	bool "  Enable ZFLAT support"
-	depends on BINFMT_FLAT
-	help
-	  Support FLAT format compressed binaries
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S
--- a/arch/v850/vmlinux.lds.S	Tue May 27 00:09:43 2003
+++ b/arch/v850/vmlinux.lds.S	Mon Jun 16 22:23:12 2003
@@ -95,7 +95,10 @@
 			*(.initcall6.init)				      \
 			*(.initcall7.init)				      \
 		. = ALIGN (4) ;						      \
-		___initcall_end = . ;
+		___initcall_end = . ;					      \
+		___con_initcall_start = .;				      \
+			*(.con_initcall.init)				      \
+		___con_initcall_end = .;
 
 /* Contents of `init' section for a kernel that's loaded into RAM.  */
 #define RAMK_INIT_CONTENTS						      \
@@ -232,5 +235,15 @@
 #  include "rte_ma1_cb-rom.ld"
 # else
 #  include "rte_ma1_cb.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_NB85E
+# ifdef CONFIG_ROM_KERNEL
+#  include "rte_nb85e_cb-rom.ld"
+# elif defined(CONFIG_RTE_CB_MULTI)
+#  include "rte_nb85e_cb-multi.ld"
+# else
+#  include "rte_nb85e_cb.ld"
 # endif
 #endif
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Wed Jun 11 18:15:04 2003
+++ b/arch/x86_64/Kconfig	Sat Jun 14 15:25:52 2003
@@ -375,31 +375,7 @@
 	depends on PROC_FS
 	default y
 
-config BINFMT_ELF
-	bool
-	default y
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. Once you have registered such a binary class with the kernel, 
-	  you can start one of those programs simply by typing in its name at a shell 
-	  prompt; Linux will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  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. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config IA32_EMULATION
 	bool "IA32 Emulation"
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	Mon May 12 07:33:45 2003
+++ b/drivers/block/cciss_scsi.c	Mon Jun  2 17:42:21 2003
@@ -698,7 +698,7 @@
 {
 	struct Scsi_Host *sh;
 
-	sh = scsi_register(&cciss_driver_template, sizeof(struct ctlr_info *));
+	sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
 	if (sh == NULL)
 		return 0;
 
@@ -1357,7 +1357,7 @@
 	if (sa->registered) {
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 		scsi_remove_host(sa->scsi_host);
-		scsi_unregister(sa->scsi_host);
+		scsi_host_put(sa->scsi_host);
 		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
 	}
 
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Thu Jun  5 06:22:28 2003
+++ b/drivers/block/ll_rw_blk.c	Mon Jun  2 18:32:46 2003
@@ -49,8 +49,6 @@
 static int queue_nr_requests;
 
 unsigned long blk_max_low_pfn, blk_max_pfn;
-int blk_nohighio = 0;
-
 static wait_queue_head_t congestion_wqh[2];
 
 /*
@@ -2334,7 +2332,6 @@
 EXPORT_SYMBOL(blk_queue_segment_boundary);
 EXPORT_SYMBOL(blk_queue_dma_alignment);
 EXPORT_SYMBOL(blk_rq_map_sg);
-EXPORT_SYMBOL(blk_nohighio);
 EXPORT_SYMBOL(blk_dump_rq_flags);
 EXPORT_SYMBOL(submit_bio);
 EXPORT_SYMBOL(blk_phys_contig_segment);
diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c	Wed Jun 11 12:32:40 2003
+++ b/drivers/char/moxa.c	Tue Jun 17 20:34:45 2003
@@ -339,7 +339,6 @@
 {
 	int i, n, numBoards;
 	struct moxa_str *ch;
-	int ret1, ret2;
 
 	printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
 	moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
@@ -615,7 +614,7 @@
 	}
 	ch->asyncflags |= ASYNC_CLOSING;
 
-	ch->cflag = *tty->termios->c_cflag;
+	ch->cflag = tty->termios->c_cflag;
 	if (ch->asyncflags & ASYNC_INITIALIZED) {
 		setup_empty_event(tty);
 		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Wed May 28 17:50:03 2003
+++ b/drivers/ieee1394/sbp2.c	Mon Jun  2 17:42:21 2003
@@ -707,7 +707,7 @@
 		return hi;
 
 	/* Register our host with the SCSI stack. */
-	scsi_host = scsi_register (&scsi_driver_template, 0);
+	scsi_host = scsi_host_alloc(&scsi_driver_template, 0);
 	if (!scsi_host) {
 		SBP2_ERR("failed to register scsi host");
 		return NULL;
@@ -716,7 +716,7 @@
 	hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi));
 	if (!hi) {
 		SBP2_ERR("failed to allocate hostinfo");
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 	}
 
 	hpsb_set_hostinfo_key(&sbp2_highlevel, host, (unsigned long)scsi_host);
@@ -732,7 +732,7 @@
 	 * enabled (scsi-host uses classdata member of the device). */
 	if (scsi_add_host(hi->scsi_host, NULL)) {
 		SBP2_ERR("failed to add scsi host");
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 		hpsb_destroy_hostinfo(&sbp2_highlevel, host);
 	}
 
@@ -753,7 +753,7 @@
 
 	if (hi) {
 		scsi_remove_host(hi->scsi_host);
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 	}
 }
 
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	Sat Jun 14 16:16:11 2003
+++ b/drivers/md/dm-ioctl.c	Mon Jun 16 13:20:05 2003
@@ -297,13 +297,14 @@
 	/*
 	 * rename and move the name cell.
 	 */
+	unregister_with_devfs(hc);
+
 	list_del(&hc->name_list);
 	old_name = hc->name;
 	hc->name = new_name;
 	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
 
 	/* rename the device node in devfs */
-	unregister_with_devfs(hc);
 	register_with_devfs(hc);
 
 	up_write(&_hash_lock);
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	Thu Mar 13 17:14:29 2003
+++ b/drivers/message/i2o/i2o_scsi.c	Sun Jun  8 12:18:41 2003
@@ -866,34 +866,6 @@
 }
 
 /**
- *	internal_done	-	legacy scsi glue
- *	@SCPnt: command
- *
- *	Completion function for a synchronous command
- */
-
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-/**
- *	i2o_scsi_command	-	issue a scsi command and wait
- *	@SCPnt: command
- *
- *	Issue a SCSI command and wait for it to complete.
- */
- 
-static int i2o_scsi_command(Scsi_Cmnd * SCpnt)
-{
-	i2o_scsi_queuecommand(SCpnt, internal_done);
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
-/**
  *	i2o_scsi_abort	-	abort a running command
  *	@SCpnt: command to abort
  *
@@ -1091,7 +1063,6 @@
 	.detect			= i2o_scsi_detect,
 	.release		= i2o_scsi_release,
 	.info			= i2o_scsi_info,
-	.command		= i2o_scsi_command,
 	.queuecommand		= i2o_scsi_queuecommand,
 	.eh_abort_handler	= i2o_scsi_abort,
 	.eh_bus_reset_handler	= i2o_scsi_bus_reset,
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	Mon May 26 21:45:02 2003
+++ b/drivers/net/bonding/bond_main.c	Mon Jun 16 16:12:58 2003
@@ -952,8 +952,6 @@
 		add_timer(alb_timer);
 	}
 
-	MOD_INC_USE_COUNT;
-
 	if (miimon > 0) {  /* link check interval, in milliseconds. */
 		init_timer(timer);
 		timer->expires  = jiffies + (miimon * HZ / 1000);
@@ -1027,7 +1025,6 @@
 		bond_alb_deinitialize(bond);
 	}
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -3694,6 +3691,8 @@
 		kfree(bond);
 		return -ENOMEM;
 	}
+	bond->bond_proc_dir->owner = THIS_MODULE;
+
 	bond->bond_proc_info_file = 
 		create_proc_info_entry("info", 0, bond->bond_proc_dir, 
 					bond_get_info);
@@ -3705,6 +3704,7 @@
 		kfree(bond);
 		return -ENOMEM;
 	}
+	bond->bond_proc_info_file->owner = THIS_MODULE;
 #endif /* CONFIG_PROC_FS */
 
 	if (first_pass == 1) {
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	Thu Apr  3 07:19:43 2003
+++ b/drivers/net/shaper.c	Mon Jun 16 14:26:40 2003
@@ -630,7 +630,7 @@
  *	Add a shaper device to the system
  */
  
-static int __init shaper_probe(struct net_device *dev)
+static void __init shaper_setup(struct net_device *dev)
 {
 	/*
 	 *	Set up the shaper.
@@ -642,6 +642,7 @@
 
 	dev->open		= shaper_open;
 	dev->stop		= shaper_close;
+	dev->destructor 	= (void (*)(struct net_device *))kfree;
 	dev->hard_start_xmit 	= shaper_start_xmit;
 	dev->get_stats 		= shaper_get_stats;
 	dev->set_multicast_list = NULL;
@@ -669,12 +670,6 @@
 	dev->addr_len		= 0;
 	dev->tx_queue_len	= 10;
 	dev->flags		= 0;
-		
-	/*
-	 *	Shaper is ok
-	 */	
-	 
-	return 0;
 }
  
 static int shapers = 1;
@@ -695,35 +690,38 @@
 
 #endif /* MODULE */
 
-static struct net_device *devs;
+static struct net_device **devs;
 
 static unsigned int shapers_registered = 0;
 
 static int __init shaper_init(void)
 {
-	int i, err;
+	int i;
 	size_t alloc_size;
-	struct shaper *sp;
+	struct net_device *dev;
+	char name[IFNAMSIZ];
 
 	if (shapers < 1)
 		return -ENODEV;
 
-	alloc_size = (sizeof(*devs) * shapers) +
-		     (sizeof(struct shaper) * shapers);
+	alloc_size = sizeof(*dev) * shapers;
 	devs = kmalloc(alloc_size, GFP_KERNEL);
 	if (!devs)
 		return -ENOMEM;
 	memset(devs, 0, alloc_size);
-	sp = (struct shaper *) &devs[shapers];
 
 	for (i = 0; i < shapers; i++) {
-		err = dev_alloc_name(&devs[i], "shaper%d");
-		if (err < 0)
+
+		snprintf(name, IFNAMSIZ, "shaper%d", i);
+		dev = alloc_netdev(sizeof(struct shaper), name,
+				   shaper_setup);
+		if (!dev) 
 			break;
-		devs[i].init = shaper_probe;
-		devs[i].priv = &sp[i];
-		if (register_netdev(&devs[i]))
+
+		if (register_netdev(dev))
 			break;
+
+		devs[i] = dev;
 		shapers_registered++;
 	}
 
@@ -740,7 +738,8 @@
 	int i;
 
 	for (i = 0; i < shapers_registered; i++)
-		unregister_netdev(&devs[i]);
+		if (devs[i])
+			unregister_netdev(devs[i]);
 
 	kfree(devs);
 	devs = NULL;
diff -Nru a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
--- a/drivers/net/wan/syncppp.c	Wed Nov 27 11:25:41 2002
+++ b/drivers/net/wan/syncppp.c	Fri May 30 12:33:58 2003
@@ -132,6 +132,9 @@
 static struct timer_list sppp_keepalive_timer;
 static spinlock_t spppq_lock = SPIN_LOCK_UNLOCKED;
 
+/* global xmit queue for sending packets while spinlock is held */
+static struct sk_buff_head tx_queue;
+
 static void sppp_keepalive (unsigned long dummy);
 static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
 	u8 ident, u16 len, void *data);
@@ -150,6 +153,20 @@
 
 static int debug;
 
+/* Flush global outgoing packet queue to dev_queue_xmit().
+ *
+ * dev_queue_xmit() must be called with interrupts enabled
+ * which means it can't be called with spinlocks held.
+ * If a packet needs to be sent while a spinlock is held,
+ * then put the packet into tx_queue, and call sppp_flush_xmit()
+ * after spinlock is released.
+ */
+static void sppp_flush_xmit()
+{
+	struct sk_buff *skb;
+	while ((skb = skb_dequeue(&tx_queue)) != NULL)
+		dev_queue_xmit(skb);
+}
 
 /*
  *	Interface down stub
@@ -207,7 +224,8 @@
 {
 	struct ppp_header *h;
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	
+	unsigned long flags;
+
 	skb->dev=dev;
 	skb->mac.raw=skb->data;
 
@@ -223,7 +241,7 @@
 		if (sp->pp_flags & PP_DEBUG)
 			printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",
 				dev->name, skb->len);
-drop:           kfree_skb(skb);
+		kfree_skb(skb);
 		return;
 	}
 
@@ -231,13 +249,11 @@
 	h = (struct ppp_header *)skb->data;
 	skb_pull(skb,sizeof(struct ppp_header));
 
+	spin_lock_irqsave(&sp->lock, flags);
+	
 	switch (h->address) {
 	default:        /* Invalid PPP packet. */
-invalid:        if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",
-				dev->name,
-				h->address, h->control, ntohs (h->protocol));
-		goto drop;
+		goto invalid;
 	case PPP_ALLSTATIONS:
 		if (h->control != PPP_UI)
 			goto invalid;
@@ -261,15 +277,13 @@
 			goto drop;
 		case PPP_LCP:
 			sppp_lcp_input (sp, skb);
-			kfree_skb(skb);
-			return;
+			goto drop;
 		case PPP_IPCP:
 			if (sp->lcp.state == LCP_STATE_OPENED)
 				sppp_ipcp_input (sp, skb);
 			else
 				printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n");
-			kfree_skb(skb);
-			return;
+			goto drop;
 		case PPP_IP:
 			if (sp->ipcp.state == IPCP_STATE_OPENED) {
 				if(sp->pp_flags&PP_DEBUG)
@@ -277,7 +291,7 @@
 				skb->protocol=htons(ETH_P_IP);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				return;
+				goto done;
 			}
 			break;
 #ifdef IPX
@@ -287,7 +301,7 @@
 				skb->protocol=htons(ETH_P_IPX);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				return;
+				goto done;
 			}
 			break;
 #endif
@@ -308,26 +322,36 @@
 			goto invalid;
 		case CISCO_KEEPALIVE:
 			sppp_cisco_input (sp, skb);
-			kfree_skb(skb);
-			return;
+			goto drop;
 #ifdef CONFIG_INET
 		case ETH_P_IP:
 			skb->protocol=htons(ETH_P_IP);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			return;
+			goto done;
 #endif
 #ifdef CONFIG_IPX
 		case ETH_P_IPX:
 			skb->protocol=htons(ETH_P_IPX);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			return;
+			goto done;
 #endif
 		}
 		break;
 	}
+	goto drop;
+
+invalid:
+	if (sp->pp_flags & PP_DEBUG)
+		printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",
+			dev->name, h->address, h->control, ntohs (h->protocol));
+drop:
 	kfree_skb(skb);
+done:
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
+	return;
 }
 
 EXPORT_SYMBOL(sppp_input);
@@ -394,10 +418,14 @@
 		    ! (dev->flags & IFF_UP))
 			continue;
 
+		spin_lock(&sp->lock);
+
 		/* No keepalive in PPP mode if LCP not opened yet. */
 		if (! (sp->pp_flags & PP_CISCO) &&
-		    sp->lcp.state != LCP_STATE_OPENED)
+		    sp->lcp.state != LCP_STATE_OPENED) {
+			spin_unlock(&sp->lock);
 			continue;
+		}
 
 		if (sp->pp_alivecnt == MAXALIVECNT) {
 			/* No keepalive packets got.  Stop the interface. */
@@ -424,8 +452,11 @@
 			sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ,
 				sp->lcp.echoid, 4, &nmagic);
 		}
+
+		spin_unlock(&sp->lock);
 	}
 	spin_unlock_irqrestore(&spppq_lock, flags);
+	sppp_flush_xmit();
 	sppp_keepalive_timer.expires=jiffies+10*HZ;
 	add_timer(&sppp_keepalive_timer);
 }
@@ -757,6 +788,7 @@
 	}
 }
 
+
 /*
  * Send PPP LCP packet.
  */
@@ -804,7 +836,7 @@
 	/* Control is high priority so it doesn't get queued behind data */
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
-	dev_queue_xmit(skb);
+	skb_queue_tail(&tx_queue, skb);
 }
 
 /*
@@ -846,7 +878,7 @@
 	sp->obytes += skb->len;
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
-	dev_queue_xmit(skb);
+	skb_queue_tail(&tx_queue, skb);
 }
 
 /**
@@ -861,10 +893,15 @@
 int sppp_close (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sp->lock, flags);
 	sp->pp_link_state = SPPP_LINK_DOWN;
 	sp->lcp.state = LCP_STATE_CLOSED;
 	sp->ipcp.state = IPCP_STATE_CLOSED;
 	sppp_clear_timeout (sp);
+	spin_unlock_irqrestore(&sp->lock, flags);
+
 	return 0;
 }
 
@@ -883,11 +920,18 @@
 int sppp_open (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
 	sppp_close(dev);
+
+	spin_lock_irqsave(&sp->lock, flags);
 	if (!(sp->pp_flags & PP_CISCO)) {
 		sppp_lcp_open (sp);
 	}
 	sp->pp_link_state = SPPP_LINK_DOWN;
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
+
 	return 0;
 }
 
@@ -912,7 +956,11 @@
 int sppp_reopen (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
 	sppp_close(dev);
+
+	spin_lock_irqsave(&sp->lock, flags);
 	if (!(sp->pp_flags & PP_CISCO))
 	{
 		sp->lcp.magic = jiffies;
@@ -923,6 +971,8 @@
 		sppp_set_timeout (sp, 1);
 	} 
 	sp->pp_link_state=SPPP_LINK_DOWN;
+	spin_unlock_irqrestore(&sp->lock, flags);
+
 	return 0;
 }
 
@@ -1040,6 +1090,7 @@
 	sp->lcp.state = LCP_STATE_CLOSED;
 	sp->ipcp.state = IPCP_STATE_CLOSED;
 	sp->pp_if = dev;
+	spin_lock_init(&sp->lock);
 	
 	/* 
 	 *	Device specific setup. All but interrupt handler and
@@ -1290,11 +1341,11 @@
 	struct sppp *sp = (struct sppp*) arg;
 	unsigned long flags;
 
-	spin_lock_irqsave(&spppq_lock, flags);
+	spin_lock_irqsave(&sp->lock, flags);
 
 	sp->pp_flags &= ~PP_TIMO;
 	if (! (sp->pp_if->flags & IFF_UP) || (sp->pp_flags & PP_CISCO)) {
-		spin_unlock_irqrestore(&spppq_lock, flags);
+		spin_unlock_irqrestore(&sp->lock, flags);
 		return;
 	}
 	switch (sp->lcp.state) {
@@ -1333,7 +1384,8 @@
 		}
 		break;
 	}
-	spin_unlock_irqrestore(&spppq_lock, flags);
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
 }
 
 static char *sppp_lcp_type_name (u8 type)
@@ -1393,6 +1445,8 @@
 
 static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p)
 {
+	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+		return NET_RX_DROP;
 	sppp_input(dev,skb);
 	return 0;
 }
@@ -1400,6 +1454,7 @@
 struct packet_type sppp_packet_type = {
 	.type	= __constant_htons(ETH_P_WAN_PPP),
 	.func	= sppp_rcv,
+	.data   = (void*)1, /* must be non-NULL to indicate 'new' protocol */
 };
 
 static char banner[] __initdata = 
@@ -1412,6 +1467,7 @@
 	if(debug)
 		debug=PP_DEBUG;
 	printk(banner);
+	skb_queue_head_init(&tx_queue);
 	dev_add_pack(&sppp_packet_type);
 	return 0;
 }
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Wed Jun 11 18:05:19 2003
+++ b/drivers/oprofile/buffer_sync.c	Sun Jun 15 07:34:47 2003
@@ -425,7 +425,7 @@
 {
 	struct mm_struct * mm = 0;
 	struct task_struct * new;
-	unsigned long cookie;
+	unsigned long cookie = 0;
 	int in_kernel = 1;
 	unsigned int i;
  
@@ -442,13 +442,15 @@
 				in_kernel = s->event;
 				add_kernel_ctx_switch(s->event);
 			} else {
+				struct mm_struct * oldmm = mm;
+
 				/* userspace context switch */
 				new = (struct task_struct *)s->event;
 
-				release_mm(mm);
+				release_mm(oldmm);
 				mm = take_tasks_mm(new);
-
-				cookie = get_exec_dcookie(mm);
+				if (mm != oldmm)
+					cookie = get_exec_dcookie(mm);
 				add_user_ctx_switch(new, cookie);
 			}
 		} else {
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	Wed Jun 11 14:52:42 2003
+++ b/drivers/pcmcia/Makefile	Mon Jun 16 08:06:42 2003
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_PCMCIA)				+= pcmcia_core.o ds.o
-obj-$(CONFIG_YENTA) 				+= yenta.o
+obj-$(CONFIG_YENTA) 				+= yenta_socket.o
 
 obj-$(CONFIG_I82365)				+= i82365.o
 obj-$(CONFIG_I82092)				+= i82092.o
diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
--- a/drivers/pcmcia/cistpl.c	Sun Jun 15 08:20:51 2003
+++ b/drivers/pcmcia/cistpl.c	Mon Jun 16 08:46:25 2003
@@ -106,11 +106,10 @@
     pccard_mem_map *mem = &s->cis_mem;
     if (!(s->features & SS_CAP_STATIC_MAP) &&
 	mem->sys_start == 0) {
-	int low = !(s->features & SS_CAP_PAGE_REGS);
 	validate_mem(s);
 	mem->sys_start = 0;
 	if (find_mem_region(&mem->sys_start, s->map_size,
-			    s->map_size, low, "card services", s)) {
+			    s->map_size, 0, "card services", s)) {
 	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
 	    return NULL;
 	}
diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c	Sun Jun 15 09:58:50 2003
+++ b/drivers/pcmcia/cs.c	Tue Jun 17 01:06:34 2003
@@ -816,7 +816,8 @@
 				if ((skt->state & SOCKET_PRESENT) &&
 				     !(status & SS_DETECT))
 					socket_shutdown(skt);
-				if (status & SS_DETECT)
+				if (!(skt->state & SOCKET_PRESENT) &&
+				    (status & SS_DETECT))
 					socket_insert(skt);
 			}
 			if (events & SS_BATDEAD)
@@ -2043,8 +2044,7 @@
 
     if (!(s->features & SS_CAP_STATIC_MAP) &&
 	find_mem_region(&win->base, win->size, align,
-			(req->Attributes & WIN_MAP_BELOW_1MB) ||
-			!(s->features & SS_CAP_PAGE_REGS),
+			(req->Attributes & WIN_MAP_BELOW_1MB),
 			(*handle)->dev_info, s))
 	return CS_IN_USE;
     (*handle)->state |= CLIENT_WIN_REQ(w);
diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
--- a/drivers/pcmcia/cs_internal.h	Sun Jun 15 04:42:53 2003
+++ b/drivers/pcmcia/cs_internal.h	Mon Jun 16 08:46:25 2003
@@ -168,7 +168,7 @@
 int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
 		   char *name, struct pcmcia_socket *s);
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name, struct pcmcia_socket *s);
+		    int low, char *name, struct pcmcia_socket *s);
 int try_irq(u_int Attributes, int irq, int specific);
 void undo_irq(u_int Attributes, int irq);
 int adjust_resource_info(client_handle_t handle, adjust_t *adj);
diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c	Sun Jun 15 08:20:52 2003
+++ b/drivers/pcmcia/rsrc_mgr.c	Mon Jun 16 08:46:26 2003
@@ -139,22 +139,6 @@
 	return 0;
 }
 
-/* FIXME: Fundamentally racy. */
-static inline int check_mem_resource(unsigned long b, unsigned long n,
-				     struct pci_dev *dev)
-{
-	struct resource *region;
-
-	region = __request_region(resource_parent(b, n, IORESOURCE_MEM, dev),
-				  b, n, "check_mem_resource");
-	if (!region)
-		return -EBUSY;
-
-	release_resource(region);
-	kfree(region);
-	return 0;
-}
-
 static struct resource *make_resource(unsigned long b, unsigned long n,
 				      int flags, char *name)
 {
@@ -340,52 +324,103 @@
 ======================================================================*/
 
 /* Validation function for cards with a valid CIS */
-static int cis_readable(struct pcmcia_socket *s, u_long base)
+static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
 {
-    cisinfo_t info1, info2;
-    int ret;
-    s->cis_mem.sys_start = base;
-    s->cis_mem.sys_stop = base+s->map_size-1;
-    s->cis_virt = ioremap(base, s->map_size);
-    ret = pcmcia_validate_cis(s->clients, &info1);
-    /* invalidate mapping and CIS cache */
-    iounmap(s->cis_virt);
-    destroy_cis_cache(s);
-    if ((ret != 0) || (info1.Chains == 0))
-	return 0;
-    s->cis_mem.sys_start = base+s->map_size;
-    s->cis_mem.sys_stop = base+2*s->map_size-1;
-    s->cis_virt = ioremap(base+s->map_size, s->map_size);
-    ret = pcmcia_validate_cis(s->clients, &info2);
-    iounmap(s->cis_virt);
-    destroy_cis_cache(s);
-    return ((ret == 0) && (info1.Chains == info2.Chains));
+	int ret = -1;
+
+	s->cis_mem.sys_start = res->start;
+	s->cis_mem.sys_stop = res->end;
+	s->cis_virt = ioremap(res->start, s->map_size);
+	if (s->cis_virt) {
+		ret = pcmcia_validate_cis(s->clients, info);
+		/* invalidate mapping and CIS cache */
+		iounmap(s->cis_virt);
+		s->cis_virt = NULL;
+		destroy_cis_cache(s);
+	}
+	s->cis_mem.sys_start = 0;
+	s->cis_mem.sys_stop = 0;
+	if ((ret != 0) || (info->Chains == 0))
+		return 0;
+	return 1;
 }
 
 /* Validation function for simple memory cards */
-static int checksum(struct pcmcia_socket *s, u_long base)
+static int checksum(struct pcmcia_socket *s, struct resource *res)
 {
-    int i, a, b, d;
-    s->cis_mem.sys_start = base;
-    s->cis_mem.sys_stop = base+s->map_size-1;
-    s->cis_virt = ioremap(base, s->map_size);
-    s->cis_mem.card_start = 0;
-    s->cis_mem.flags = MAP_ACTIVE;
-    s->ss_entry->set_mem_map(s, &s->cis_mem);
-    /* Don't bother checking every word... */
-    a = 0; b = -1;
-    for (i = 0; i < s->map_size; i += 44) {
-	d = readl(s->cis_virt+i);
-	a += d; b &= d;
-    }
-    iounmap(s->cis_virt);
-    return (b == -1) ? -1 : (a>>1);
+	pccard_mem_map map;
+	int i, a = 0, b = -1, d;
+	void *virt;
+
+	virt = ioremap(res->start, s->map_size);
+	if (virt) {
+		map.map = 0;
+		map.flags = MAP_ACTIVE;
+		map.speed = 0;
+		map.sys_start = res->start;
+		map.sys_stop = res->end;
+		map.card_start = 0;
+		s->ss_entry->set_mem_map(s, &map);
+
+		/* Don't bother checking every word... */
+		for (i = 0; i < s->map_size; i += 44) {
+			d = readl(virt+i);
+			a += d;
+			b &= d;
+		}
+
+		map.flags = 0;
+		s->ss_entry->set_mem_map(s, &map);
+
+		iounmap(virt);
+	}
+
+	return (b == -1) ? -1 : (a>>1);
 }
 
-static int checksum_match(struct pcmcia_socket *s, u_long base)
+static int
+cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
 {
-    int a = checksum(s, base), b = checksum(s, base+s->map_size);
-    return ((a == b) && (a >= 0));
+	struct resource *res1, *res2;
+	cisinfo_t info1, info2;
+	int ret = 0;
+
+	res1 = request_mem_region(base, size/2, "cs memory probe");
+	res2 = request_mem_region(base + size/2, size/2, "cs memory probe");
+
+	if (res1 && res2) {
+		ret = readable(s, res1, &info1);
+		ret += readable(s, res2, &info2);
+	}
+
+	if (res2)
+		release_resource(res2);
+	if (res1)
+		release_resource(res1);
+
+	return (ret == 2) && (info1.Chains == info2.Chains);
+}
+
+static int
+checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+{
+	struct resource *res1, *res2;
+	int a = -1, b = -1;
+
+	res1 = request_mem_region(base, size/2, "cs memory probe");
+	res2 = request_mem_region(base + size/2, size/2, "cs memory probe");
+
+	if (res1 && res2) {
+		a = checksum(s, res1);
+		b = checksum(s, res2);
+	}
+
+	if (res2)
+		release_resource(res2);
+	if (res1)
+		release_resource(res1);
+
+	return (a == b) && (a >= 0);
 }
 
 /*======================================================================
@@ -409,16 +444,16 @@
 	step = 2 * s->map_size;
     for (i = j = base; i < base+num; i = j + step) {
 	if (!fail) {	
-	    for (j = i; j < base+num; j += step)
-		if ((check_mem_resource(j, step, s->cb_dev) == 0) &&
-		    cis_readable(s, j))
+	    for (j = i; j < base+num; j += step) {
+		if (cis_readable(s, j, step))
 		    break;
+	    }
 	    fail = ((i == base) && (j == base+num));
 	}
 	if (fail) {
 	    for (j = i; j < base+num; j += 2*step)
-		if ((check_mem_resource(j, 2*step, s->cb_dev) == 0) &&
-		    checksum_match(s, j) && checksum_match(s, j + step))
+		if (checksum_match(s, j, step) &&
+		    checksum_match(s, j + step, step))
 		    break;
 	}
 	if (i != j) {
@@ -555,17 +590,19 @@
 }
 
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name, struct pcmcia_socket *s)
+		    int low, char *name, struct pcmcia_socket *s)
 {
     u_long try;
     resource_map_t *m;
     int ret = -1;
 
+    low = low || !(s->features & SS_CAP_PAGE_REGS);
+
     down(&rsrc_sem);
     while (1) {
 	for (m = mem_db.next; m != &mem_db; m = m->next) {
 	    /* first pass >1MB, second pass <1MB */
-	    if ((force_low != 0) ^ (m->base < 0x100000))
+	    if ((low != 0) ^ (m->base < 0x100000))
 		continue;
 
 	    try = (m->base & ~(align-1)) + *base;
@@ -581,9 +618,9 @@
 		    break;
 	    }
 	}
-	if (force_low)
+	if (low)
 	    break;
-	force_low++;
+	low++;
     }
  out:
     up(&rsrc_sem);
diff -Nru a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
--- a/drivers/pcmcia/yenta.c	Sun Jun 15 08:32:41 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,974 +0,0 @@
-/*
- * Regular cardbus driver ("yenta")
- *
- * (C) Copyright 1999, 2000 Linus Torvalds
- *
- * Changelog:
- * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
- * 	Dynamically adjust the size of the bridge resource
- * 	
- * May 2003: Dominik Brodowski <linux@brodo.de>
- * 	Merge pci_socket.c and yenta.c into one file
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/ss.h>
-#include <pcmcia/cs.h>
-
-#include <asm/io.h>
-
-#include "yenta.h"
-#include "i82365.h"
-
-
-#if 0
-#define DEBUG(x,args...)	printk("%s: " x, __FUNCTION__, ##args)
-#else
-#define DEBUG(x,args...)
-#endif
-
-/* Don't ask.. */
-#define to_cycles(ns)	((ns)/120)
-#define to_ns(cycles)	((cycles)*120)
-
-/*
- * Generate easy-to-use ways of reading a cardbus sockets
- * regular memory space ("cb_xxx"), configuration space
- * ("config_xxx") and compatibility space ("exca_xxxx")
- */
-static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
-{
-	u32 val = readl(socket->base + reg);
-	DEBUG("%p %04x %08x\n", socket, reg, val);
-	return val;
-}
-
-static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
-{
-	DEBUG("%p %04x %08x\n", socket, reg, val);
-	writel(val, socket->base + reg);
-}
-
-static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
-{
-	u8 val;
-	pci_read_config_byte(socket->dev, offset, &val);
-	DEBUG("%p %04x %02x\n", socket, offset, val);
-	return val;
-}
-
-static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
-{
-	u16 val;
-	pci_read_config_word(socket->dev, offset, &val);
-	DEBUG("%p %04x %04x\n", socket, offset, val);
-	return val;
-}
-
-static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
-{
-	u32 val;
-	pci_read_config_dword(socket->dev, offset, &val);
-	DEBUG("%p %04x %08x\n", socket, offset, val);
-	return val;
-}
-
-static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
-{
-	DEBUG("%p %04x %02x\n", socket, offset, val);
-	pci_write_config_byte(socket->dev, offset, val);
-}
-
-static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
-{
-	DEBUG("%p %04x %04x\n", socket, offset, val);
-	pci_write_config_word(socket->dev, offset, val);
-}
-
-static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
-{
-	DEBUG("%p %04x %08x\n", socket, offset, val);
-	pci_write_config_dword(socket->dev, offset, val);
-}
-
-static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
-{
-	u8 val = readb(socket->base + 0x800 + reg);
-	DEBUG("%p %04x %02x\n", socket, reg, val);
-	return val;
-}
-
-static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
-{
-	u16 val;
-	val = readb(socket->base + 0x800 + reg);
-	val |= readb(socket->base + 0x800 + reg + 1) << 8;
-	DEBUG("%p %04x %04x\n", socket, reg, val);
-	return val;
-}
-
-static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
-{
-	DEBUG("%p %04x %02x\n", socket, reg, val);
-	writeb(val, socket->base + 0x800 + reg);
-}
-
-static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
-{
-	DEBUG("%p %04x %04x\n", socket, reg, val);
-	writeb(val, socket->base + 0x800 + reg);
-	writeb(val >> 8, socket->base + 0x800 + reg + 1);
-}
-
-/*
- * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
- * on what kind of card is inserted..
- */
-static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	unsigned int val;
-	u32 state = cb_readl(socket, CB_SOCKET_STATE);
-
-	val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
-	val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
-	val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
-			 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
-
-	if (state & CB_CBCARD) {
-		val |= SS_CARDBUS;	
-		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
-		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
-		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
-	} else {
-		u8 status = exca_readb(socket, I365_STATUS);
-		val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
-		if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
-			val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
-		} else {
-			val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
-			val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
-		}
-		val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
-		val |= (status & I365_CS_READY) ? SS_READY : 0;
-		val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
-	}
-
-	*value = val;
-	return 0;
-}
-
-static int yenta_Vcc_power(u32 control)
-{
-	switch (control & CB_SC_VCC_MASK) {
-	case CB_SC_VCC_5V: return 50;
-	case CB_SC_VCC_3V: return 33;
-	default: return 0;
-	}
-}
-
-static int yenta_Vpp_power(u32 control)
-{
-	switch (control & CB_SC_VPP_MASK) {
-	case CB_SC_VPP_12V: return 120;
-	case CB_SC_VPP_5V: return 50;
-	case CB_SC_VPP_3V: return 33;
-	default: return 0;
-	}
-}
-
-static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u8 reg;
-	u32 control;
-
-	control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-	state->Vcc = yenta_Vcc_power(control);
-	state->Vpp = yenta_Vpp_power(control);
-	state->io_irq = socket->io_irq;
-
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-		if (bridge & CB_BRIDGE_CRST)
-			state->flags |= SS_RESET;
-		return 0;
-	}
-
-	/* 16-bit card state.. */
-	reg = exca_readb(socket, I365_POWER);
-	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-
-	reg = exca_readb(socket, I365_INTCTL);
-	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
-
-	reg = exca_readb(socket, I365_CSCINT);
-	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (state->flags & SS_IOCARD) {
-		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-	}
-
-	return 0;
-}
-
-static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
-{
-	u32 reg = 0;	/* CB_SC_STPCLK? */
-	switch (state->Vcc) {
-	case 33: reg = CB_SC_VCC_3V; break;
-	case 50: reg = CB_SC_VCC_5V; break;
-	default: reg = 0; break;
-	}
-	switch (state->Vpp) {
-	case 33:  reg |= CB_SC_VPP_3V; break;
-	case 50:  reg |= CB_SC_VPP_5V; break;
-	case 120: reg |= CB_SC_VPP_12V; break;
-	}
-	if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
-		cb_writel(socket, CB_SOCKET_CONTROL, reg);
-}
-
-static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u16 bridge;
-
-	if (state->flags & SS_DEBOUNCED) {
-		/* The insertion debounce period has ended.  Clear any pending insertion events */
-		socket->events &= ~SS_DETECT;
-		state->flags &= ~SS_DEBOUNCED;		/* SS_DEBOUNCED is oneshot */
-	}
-	yenta_set_power(socket, state);
-	socket->io_irq = state->io_irq;
-	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u8 intr;
-		bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
-
-		/* ISA interrupt control? */
-		intr = exca_readb(socket, I365_INTCTL);
-		intr = (intr & ~0xf);
-		if (!socket->cb_irq) {
-			intr |= state->io_irq;
-			bridge |= CB_BRIDGE_INTR;
-		}
-		exca_writeb(socket, I365_INTCTL, intr);
-	}  else {
-		u8 reg;
-
-		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
-		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
-		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-		if (state->io_irq != socket->cb_irq) {
-			reg |= state->io_irq;
-			bridge |= CB_BRIDGE_INTR;
-		}
-		exca_writeb(socket, I365_INTCTL, reg);
-
-		reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
-		reg |= I365_PWR_NORESET;
-		if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
-		if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
-		if (exca_readb(socket, I365_POWER) != reg)
-			exca_writeb(socket, I365_POWER, reg);
-
-		/* CSC interrupt: no ISA irq for CSC */
-		reg = I365_CSC_DETECT;
-		if (state->flags & SS_IOCARD) {
-			if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
-		} else {
-			if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
-			if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
-			if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
-		}
-		exca_writeb(socket, I365_CSCINT, reg);
-		exca_readb(socket, I365_CSC);
-	}
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
-	/* Socket event mask: get card insert/remove events.. */
-	cb_writel(socket, CB_SOCKET_EVENT, -1);
-	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
-	return 0;
-}
-
-static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	int map;
-	unsigned char ioctl, addr, enable;
-
-	map = io->map;
-
-	if (map > 1)
-		return -EINVAL;
-
-	enable = I365_ENA_IO(map);
-	addr = exca_readb(socket, I365_ADDRWIN);
-
-	/* Disable the window before changing it.. */
-	if (addr & enable) {
-		addr &= ~enable;
-		exca_writeb(socket, I365_ADDRWIN, addr);
-	}
-
-	exca_writew(socket, I365_IO(map)+I365_W_START, io->start);
-	exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop);
-
-	ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
-	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
-	exca_writeb(socket, I365_IOCTL, ioctl);
-
-	if (io->flags & MAP_ACTIVE)
-		exca_writeb(socket, I365_ADDRWIN, addr | enable);
-	return 0;
-}
-
-static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	int map;
-	unsigned char addr, enable;
-	unsigned int start, stop, card_start;
-	unsigned short word;
-
-	map = mem->map;
-	start = mem->sys_start;
-	stop = mem->sys_stop;
-	card_start = mem->card_start;
-
-	if (map > 4 || start > stop || ((start ^ stop) >> 24) ||
-	    (card_start >> 26) || mem->speed > 1000)
-		return -EINVAL;
-
-	enable = I365_ENA_MEM(map);
-	addr = exca_readb(socket, I365_ADDRWIN);
-	if (addr & enable) {
-		addr &= ~enable;
-		exca_writeb(socket, I365_ADDRWIN, addr);
-	}
-
-	exca_writeb(socket, CB_MEM_PAGE(map), start >> 24);
-
-	word = (start >> 12) & 0x0fff;
-	if (mem->flags & MAP_16BIT)
-		word |= I365_MEM_16BIT;
-	if (mem->flags & MAP_0WS)
-		word |= I365_MEM_0WS;
-	exca_writew(socket, I365_MEM(map) + I365_W_START, word);
-
-	word = (stop >> 12) & 0x0fff;
-	switch (to_cycles(mem->speed)) {
-		case 0: break;
-		case 1:  word |= I365_MEM_WS0; break;
-		case 2:  word |= I365_MEM_WS1; break;
-		default: word |= I365_MEM_WS1 | I365_MEM_WS0; break;
-	}
-	exca_writew(socket, I365_MEM(map) + I365_W_STOP, word);
-
-	word = ((card_start - start) >> 12) & 0x3fff;
-	if (mem->flags & MAP_WRPROT)
-		word |= I365_MEM_WRPROT;
-	if (mem->flags & MAP_ATTRIB)
-		word |= I365_MEM_REG;
-	exca_writew(socket, I365_MEM(map) + I365_W_OFF, word);
-
-	if (mem->flags & MAP_ACTIVE)
-		exca_writeb(socket, I365_ADDRWIN, addr | enable);
-	return 0;
-}
-
-
-static unsigned int yenta_events(struct yenta_socket *socket)
-{
-	u8 csc;
-	u32 cb_event;
-	unsigned int events;
-
-	/* Clear interrupt status for the event */
-	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
-	cb_writel(socket, CB_SOCKET_EVENT, cb_event);
-
-	csc = exca_readb(socket, I365_CSC);
-
-	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
-	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
-		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
-	}
-	return events;
-}
-
-
-static void yenta_bh(void *data)
-{
-	struct yenta_socket *socket = data;
-	unsigned int events;
-
-	spin_lock_irq(&socket->event_lock);
-	events = socket->events;
-	socket->events = 0;
-	spin_unlock_irq(&socket->event_lock);
-	if (socket->handler)
-		socket->handler(socket->info, events);
-}
-
-static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned int events;
-	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
-
-	events = yenta_events(socket);
-	if (events) {
-		spin_lock(&socket->event_lock);
-		socket->events |= events;
-		spin_unlock(&socket->event_lock);
-		schedule_work(&socket->tq_task);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-static void yenta_interrupt_wrapper(unsigned long data)
-{
-	struct yenta_socket *socket = (struct yenta_socket *) data;
-
-	yenta_interrupt(0, (void *)socket, NULL);
-	socket->poll_timer.expires = jiffies + HZ;
-	add_timer(&socket->poll_timer);
-}
-
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
-static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
-{
-	int i;
-	unsigned long val;
-	u16 bridge_ctrl;
-	u32 mask;
-
-	/* Set up ISA irq routing to probe the ISA irqs.. */
-	bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
-	if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
-		bridge_ctrl |= CB_BRIDGE_INTR;
-		config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-	}
-
-	/*
-	 * Probe for usable interrupts using the force
-	 * register to generate bogus card status events.
-	 */
-	cb_writel(socket, CB_SOCKET_EVENT, -1);
-	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
-	exca_writeb(socket, I365_CSCINT, 0);
-	val = probe_irq_on() & isa_irq_mask;
-	for (i = 1; i < 16; i++) {
-		if (!((val >> i) & 1))
-			continue;
-		exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
-		cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
-		udelay(100);
-		cb_writel(socket, CB_SOCKET_EVENT, -1);
-	}
-	cb_writel(socket, CB_SOCKET_MASK, 0);
-	exca_writeb(socket, I365_CSCINT, 0);
-	
-	mask = probe_irq_mask(val) & 0xffff;
-
-	bridge_ctrl &= ~CB_BRIDGE_INTR;
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-
-	return mask;
-}
-
-/*
- * Set static data that doesn't need re-initializing..
- */
-static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
-{
-	socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
-	socket->socket.map_size = 0x1000;
-	socket->socket.pci_irq = socket->cb_irq;
-	socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
-	socket->socket.cb_dev = socket->dev;
-
-	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq);
-}
-
-
-static void yenta_clear_maps(struct yenta_socket *socket)
-{
-	int i;
-	pccard_io_map io = { 0, 0, 0, 0, 1 };
-	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
-
-	mem.sys_stop = 0x0fff;
-	yenta_set_socket(&socket->socket, &dead_socket);
-	for (i = 0; i < 2; i++) {
-		io.map = i;
-		yenta_set_io_map(&socket->socket, &io);
-	}
-	for (i = 0; i < 5; i++) {
-		mem.map = i;
-		yenta_set_mem_map(&socket->socket, &mem);
-	}
-}
-
-/*
- * Initialize the standard cardbus registers
- */
-static void yenta_config_init(struct yenta_socket *socket)
-{
-	u16 bridge;
-	struct pci_dev *dev = socket->dev;
-
-	pci_set_power_state(socket->dev, 0);
-
-	config_writel(socket, CB_LEGACY_MODE_BASE, 0);
-	config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
-	config_writew(socket, PCI_COMMAND,
-			PCI_COMMAND_IO |
-			PCI_COMMAND_MEMORY |
-			PCI_COMMAND_MASTER |
-			PCI_COMMAND_WAIT);
-
-	/* MAGIC NUMBERS! Fixme */
-	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
-	config_writeb(socket, PCI_LATENCY_TIMER, 168);
-	config_writel(socket, PCI_PRIMARY_BUS,
-		(176 << 24) |			   /* sec. latency timer */
-		(dev->subordinate->subordinate << 16) | /* subordinate bus */
-		(dev->subordinate->secondary << 8) |  /* secondary bus */
-		dev->subordinate->primary);		   /* primary bus */
-
-	/*
-	 * Set up the bridging state:
-	 *  - enable write posting.
-	 *  - memory window 0 prefetchable, window 1 non-prefetchable
-	 *  - PCI interrupts enabled if a PCI interrupt exists..
-	 */
-	bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-	bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
-	bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
-	if (!socket->cb_irq)
-		bridge |= CB_BRIDGE_INTR;
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
-
-	exca_writeb(socket, I365_GBLCTL, 0x00);
-	exca_writeb(socket, I365_GENCTL, 0x00);
-
-	/* Redo card voltage interrogation */
-	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
-}
-
-/* Called at resume and initialization events */
-static int yenta_init(struct pcmcia_socket *sock)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	yenta_config_init(socket);
-	yenta_clear_maps(socket);
-
-	/* Re-enable interrupts */
-	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
-	return 0;
-}
-
-static int yenta_suspend(struct pcmcia_socket *sock)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-
-	yenta_set_socket(sock, &dead_socket);
-
-	/* Disable interrupts */
-	cb_writel(socket, CB_SOCKET_MASK, 0x0);
-
-	/*
-	 * This does not work currently. The controller
-	 * loses too much information during D3 to come up
-	 * cleanly. We should probably fix yenta_init()
-	 * to update all the critical registers, notably
-	 * the IO and MEM bridging region data.. That is
-	 * something that pci_set_power_state() should
-	 * probably know about bridges anyway.
-	 *
-	pci_set_power_state(socket->dev, 3);
-	 */
-
-	return 0;
-}
-
-/*
- * Use an adaptive allocation for the memory resource,
- * sometimes the memory behind pci bridges is limited:
- * 1/8 of the size of the io window of the parent.
- * max 4 MB, min 16 kB.
- */
-#define BRIDGE_MEM_MAX 4*1024*1024
-#define BRIDGE_MEM_MIN 16*1024
-
-#define BRIDGE_IO_MAX 256
-#define BRIDGE_IO_MIN 32
-
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
-{
-	struct pci_bus *bus;
-	struct resource *root, *res;
-	u32 start, end;
-	u32 align, size, min;
-	unsigned offset;
-	unsigned mask;
-
-	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
-	mask = ~0xfff;
-	if (type & IORESOURCE_IO)
-		mask = ~3;
-
-	offset = 0x1c + 8*nr;
-	bus = socket->dev->subordinate;
-	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
-	res->name = bus->name;
-	res->flags = type;
-	res->start = 0;
-	res->end = 0;
-	root = pci_find_parent_resource(socket->dev, res);
-
-	if (!root)
-		return;
-
-	start = config_readl(socket, offset) & mask;
-	end = config_readl(socket, offset+4) | ~mask;
-	if (start && end > start) {
-		res->start = start;
-		res->end = end;
-		if (request_resource(root, res) == 0)
-			return;
-		printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
-				socket->dev->slot_name, nr);
-		res->start = res->end = 0;
-	}
-
-	if (type & IORESOURCE_IO) {
-		align = 1024;
-		size = BRIDGE_IO_MAX;
-		min = BRIDGE_IO_MIN;
-		start = PCIBIOS_MIN_IO;
-		end = ~0U;
-	} else {
-		unsigned long avail = root->end - root->start;
-		int i;
-		size = BRIDGE_MEM_MAX;
-		if (size > avail/8) {
-			size=(avail+1)/8;
-			/* round size down to next power of 2 */
-			i = 0;
-			while ((size /= 2) != 0)
-				i++;
-			size = 1 << i;
-		}
-		if (size < BRIDGE_MEM_MIN)
-			size = BRIDGE_MEM_MIN;
-		min = BRIDGE_MEM_MIN;
-		align = size;
-		start = PCIBIOS_MIN_MEM;
-		end = ~0U;
-	}
-	
-	do {
-		if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
-			config_writel(socket, offset, res->start);
-			config_writel(socket, offset+4, res->end);
-			return;
-		}
-		size = size/2;
-		align = size;
-	} while (size >= min);
-	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
-			socket->dev->slot_name, type);
-	res->start = res->end = 0;
-}
-
-/*
- * Allocate the bridge mappings for the device..
- */
-static void yenta_allocate_resources(struct yenta_socket *socket)
-{
-	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
-	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
-	yenta_allocate_res(socket, 2, IORESOURCE_IO);
-	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
-}
-
-
-/*
- * Free the bridge mappings for the device..
- */
-static void yenta_free_resources(struct yenta_socket *socket)
-{
-	int i;
-	for (i=0;i<4;i++) {
-		struct resource *res;
-		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
-		if (res->start != 0 && res->end != 0)
-			release_resource(res);
-		res->start = res->end = 0;
-	}
-}
-
-
-/*
- * Close it down - release our resources and go home..
- */
-static void yenta_close(struct pci_dev *dev)
-{
-	struct yenta_socket *sock = pci_get_drvdata(dev);
-
-	/* we don't want a dying socket registered */
-	pcmcia_unregister_socket(&sock->socket);
-	
-	/* Disable all events so we don't die in an IRQ storm */
-	cb_writel(sock, CB_SOCKET_MASK, 0x0);
-	exca_writeb(sock, I365_CSCINT, 0);
-
-	if (sock->cb_irq)
-		free_irq(sock->cb_irq, sock);
-	else
-		del_timer_sync(&sock->poll_timer);
-
-	if (sock->base)
-		iounmap(sock->base);
-	yenta_free_resources(sock);
-
-	pci_set_drvdata(dev, NULL);
-}
-
-
-static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-
-	socket->handler = handler;
-	socket->info = info;
-	return 0;
-}
-
-
-static struct pccard_operations yenta_socket_operations = {
-	.owner			= THIS_MODULE,
-	.init			= yenta_init,
-	.suspend		= yenta_suspend,
-	.register_callback	= yenta_register_callback,
-	.get_status		= yenta_get_status,
-	.get_socket		= yenta_get_socket,
-	.set_socket		= yenta_set_socket,
-	.set_io_map		= yenta_set_io_map,
-	.set_mem_map		= yenta_set_mem_map,
-};
-
-
-#include "ti113x.h"
-#include "ricoh.h"
-
-/*
- * Different cardbus controllers have slightly different
- * initialization sequences etc details. List them here..
- */
-#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
-struct cardbus_override_struct {
-	unsigned short vendor;
-	unsigned short device;
-	int (*override) (struct yenta_socket *socket);
-} cardbus_override[] = {
-	{ PD(TI,1130),	&ti113x_override },
-	{ PD(TI,1031),	&ti_override },
-	{ PD(TI,1131),	&ti113x_override },
-	{ PD(TI,1250),	&ti1250_override },
-	{ PD(TI,1220),	&ti_override },
-	{ PD(TI,1221),	&ti_override },
-	{ PD(TI,1210),	&ti_override },
-	{ PD(TI,1450),	&ti_override },
-	{ PD(TI,1225),	&ti_override },
-	{ PD(TI,1251A),	&ti_override },
-	{ PD(TI,1211),	&ti_override },
-	{ PD(TI,1251B),	&ti_override },
-	{ PD(TI,1410),	ti1250_override },
-	{ PD(TI,1420),	&ti_override },
-	{ PD(TI,4410),	&ti_override },
-	{ PD(TI,4451),	&ti_override },
-
-	{ PD(RICOH,RL5C465), &ricoh_override },
-	{ PD(RICOH,RL5C466), &ricoh_override },
-	{ PD(RICOH,RL5C475), &ricoh_override },
-	{ PD(RICOH,RL5C476), &ricoh_override },
-	{ PD(RICOH,RL5C478), &ricoh_override },
-
-	{ }, /* all zeroes */
-};
-
-
-/*
- * Initialize a cardbus controller. Make sure we have a usable
- * interrupt, and that we can map the cardbus area. Fill in the
- * socket information structure..
- */
-static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
-{
-	struct yenta_socket *socket;
-	struct cardbus_override_struct *d;
-	
-	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
-	if (!socket)
-		return -ENOMEM;
-	memset(socket, 0, sizeof(*socket));
-
-	/* prepare pcmcia_socket */
-	socket->socket.ss_entry = &yenta_socket_operations;
-	socket->socket.dev.dev = &dev->dev;
-	socket->socket.driver_data = socket;
-
-	/* prepare struct yenta_socket */
-	socket->dev = dev;
-	pci_set_drvdata(dev, socket);
-	spin_lock_init(&socket->event_lock);
-
-	/*
-	 * Do some basic sanity checking..
-	 */
-	if (pci_enable_device(dev))
-		return -1;
-	if (!pci_resource_start(dev, 0)) {
-		printk("No cardbus resource!\n");
-		return -1;
-	}
-
-	/*
-	 * Ok, start setup.. Map the cardbus registers,
-	 * and request the IRQ.
-	 */
-	socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
-	if (!socket->base)
-		return -1;
-
-	yenta_config_init(socket);
-
-	/* Disable all events */
-	cb_writel(socket, CB_SOCKET_MASK, 0x0);
-
-	/* Set up the bridge regions.. */
-	yenta_allocate_resources(socket);
-
-	socket->cb_irq = dev->irq;
-
-	/* Do we have special options for the device? */
-	d = cardbus_override;
-	while (d->override) {
-		if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
-			int retval = d->override(socket);
-			if (retval < 0)
-				return retval;
-		}
-		d++;
-	}
-
-	/* We must finish initialization here */
-
-	INIT_WORK(&socket->tq_task, yenta_bh, socket);
-
-	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
-		/* No IRQ or request_irq failed. Poll */
-		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
-		init_timer(&socket->poll_timer);
-		socket->poll_timer.function = yenta_interrupt_wrapper;
-		socket->poll_timer.data = (unsigned long)socket;
-		socket->poll_timer.expires = jiffies + HZ;
-		add_timer(&socket->poll_timer);
-	}
-
-	/* Figure out what the dang thing can do for the PCMCIA layer... */
-	yenta_get_socket_capabilities(socket, isa_interrupts);
-	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
-
-	/* Register it with the pcmcia layer.. */
-	return pcmcia_register_socket(&socket->socket);
-}
-
-
-static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
-}
-
-
-static int yenta_dev_resume (struct pci_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
-}
-
-
-static struct pci_device_id yenta_table [] __devinitdata = { {
-	.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
-	.class_mask	= ~0,
-
-	.vendor		= PCI_ANY_ID,
-	.device		= PCI_ANY_ID,
-	.subvendor	= PCI_ANY_ID,
-	.subdevice	= PCI_ANY_ID,
-}, { /* all zeroes */ }
-};
-MODULE_DEVICE_TABLE(pci, yenta_table);
-
-
-static struct pci_driver yenta_cardbus_driver = {
-	.name		= "yenta_cardbus",
-	.id_table	= yenta_table,
-	.probe		= yenta_probe,
-	.remove		= __devexit_p(yenta_close),
-	.suspend	= yenta_dev_suspend,
-	.resume		= yenta_dev_resume,
-};
-
-
-static int __init yenta_socket_init(void)
-{
-	return pci_register_driver (&yenta_cardbus_driver);
-}
-
-
-static void __exit yenta_socket_exit (void)
-{
-	pci_unregister_driver (&yenta_cardbus_driver);
-}
-
-
-module_init(yenta_socket_init);
-module_exit(yenta_socket_exit);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/yenta.h b/drivers/pcmcia/yenta.h
--- a/drivers/pcmcia/yenta.h	Sun Jun 15 08:20:53 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,116 +0,0 @@
-#ifndef __YENTA_H
-#define __YENTA_H
-
-#include <asm/io.h>
-
-#define CB_SOCKET_EVENT		0x00
-#define    CB_CSTSEVENT		0x00000001	/* Card status event */
-#define    CB_CD1EVENT		0x00000002	/* Card detect 1 change event */
-#define    CB_CD2EVENT		0x00000004	/* Card detect 2 change event */
-#define    CB_PWREVENT		0x00000008	/* PWRCYCLE change event */
-
-#define CB_SOCKET_MASK		0x04
-#define    CB_CSTSMASK		0x00000001	/* Card status mask */
-#define    CB_CDMASK		0x00000006	/* Card detect 1&2 mask */
-#define    CB_PWRMASK		0x00000008	/* PWRCYCLE change mask */
-
-#define CB_SOCKET_STATE		0x08
-#define    CB_CARDSTS		0x00000001	/* CSTSCHG status */
-#define    CB_CDETECT1		0x00000002	/* Card detect status 1 */
-#define    CB_CDETECT2		0x00000004	/* Card detect status 2 */
-#define    CB_PWRCYCLE		0x00000008	/* Socket powered */
-#define    CB_16BITCARD		0x00000010	/* 16-bit card detected */
-#define    CB_CBCARD		0x00000020	/* CardBus card detected */
-#define    CB_IREQCINT		0x00000040	/* READY(xIRQ)/xCINT high */
-#define    CB_NOTACARD		0x00000080	/* Unrecognizable PC card detected */
-#define    CB_DATALOST		0x00000100	/* Potential data loss due to card removal */
-#define    CB_BADVCCREQ		0x00000200	/* Invalid Vcc request by host software */
-#define    CB_5VCARD		0x00000400	/* Card Vcc at 5.0 volts? */
-#define    CB_3VCARD		0x00000800	/* Card Vcc at 3.3 volts? */
-#define    CB_XVCARD		0x00001000	/* Card Vcc at X.X volts? */
-#define    CB_YVCARD		0x00002000	/* Card Vcc at Y.Y volts? */
-#define    CB_5VSOCKET		0x10000000	/* Socket Vcc at 5.0 volts? */
-#define    CB_3VSOCKET		0x20000000	/* Socket Vcc at 3.3 volts? */
-#define    CB_XVSOCKET		0x40000000	/* Socket Vcc at X.X volts? */
-#define    CB_YVSOCKET		0x80000000	/* Socket Vcc at Y.Y volts? */
-
-#define CB_SOCKET_FORCE		0x0C
-#define    CB_FCARDSTS		0x00000001	/* Force CSTSCHG */
-#define    CB_FCDETECT1		0x00000002	/* Force CD1EVENT */
-#define    CB_FCDETECT2		0x00000004	/* Force CD2EVENT */
-#define    CB_FPWRCYCLE		0x00000008	/* Force PWREVENT */
-#define    CB_F16BITCARD	0x00000010	/* Force 16-bit PCMCIA card */
-#define    CB_FCBCARD		0x00000020	/* Force CardBus line */
-#define    CB_FNOTACARD		0x00000080	/* Force NOTACARD */
-#define    CB_FDATALOST		0x00000100	/* Force data lost */
-#define    CB_FBADVCCREQ	0x00000200	/* Force bad Vcc request */
-#define    CB_F5VCARD		0x00000400	/* Force 5.0 volt card */
-#define    CB_F3VCARD		0x00000800	/* Force 3.3 volt card */
-#define    CB_FXVCARD		0x00001000	/* Force X.X volt card */
-#define    CB_FYVCARD		0x00002000	/* Force Y.Y volt card */
-#define    CB_CVSTEST		0x00004000	/* Card VS test */
-
-#define CB_SOCKET_CONTROL	0x10
-#define  CB_SC_VPP_MASK		0x00000007
-#define   CB_SC_VPP_OFF		0x00000000
-#define   CB_SC_VPP_12V		0x00000001
-#define   CB_SC_VPP_5V		0x00000002
-#define   CB_SC_VPP_3V		0x00000003
-#define   CB_SC_VPP_XV		0x00000004
-#define   CB_SC_VPP_YV		0x00000005
-#define  CB_SC_VCC_MASK		0x00000070
-#define   CB_SC_VCC_OFF		0x00000000
-#define   CB_SC_VCC_5V		0x00000020
-#define   CB_SC_VCC_3V		0x00000030
-#define   CB_SC_VCC_XV		0x00000040
-#define   CB_SC_VCC_YV		0x00000050
-#define  CB_SC_CCLK_STOP	0x00000080
-
-#define CB_SOCKET_POWER		0x20
-#define    CB_SKTACCES		0x02000000	/* A PC card access has occurred (clear on read) */
-#define    CB_SKTMODE		0x01000000	/* Clock frequency has changed (clear on read) */
-#define    CB_CLKCTRLEN		0x00010000	/* Clock control enabled (RW) */
-#define    CB_CLKCTRL		0x00000001	/* Stop(0) or slow(1) CB clock (RW) */
-
-/*
- * Cardbus configuration space
- */
-#define CB_BRIDGE_BASE(m)	(0x1c + 8*(m))
-#define CB_BRIDGE_LIMIT(m)	(0x20 + 8*(m))
-#define CB_BRIDGE_CONTROL	0x3e
-#define   CB_BRIDGE_CPERREN	0x00000001
-#define   CB_BRIDGE_CSERREN	0x00000002
-#define   CB_BRIDGE_ISAEN	0x00000004
-#define   CB_BRIDGE_VGAEN	0x00000008
-#define   CB_BRIDGE_MABTMODE	0x00000020
-#define   CB_BRIDGE_CRST	0x00000040
-#define   CB_BRIDGE_INTR	0x00000080
-#define   CB_BRIDGE_PREFETCH0	0x00000100
-#define   CB_BRIDGE_PREFETCH1	0x00000200
-#define   CB_BRIDGE_POSTEN	0x00000400
-#define CB_LEGACY_MODE_BASE	0x44
-
-/*
- * ExCA area extensions in Yenta
- */
-#define CB_MEM_PAGE(map)	(0x40 + (map))
-
-struct yenta_socket {
-	struct pci_dev *dev;
-	int cb_irq, io_irq;
-	void *base;
-	void (*handler)(void *, unsigned int);
-	void *info;
-	spinlock_t event_lock;
-	unsigned int events;
-	struct work_struct tq_task;
-	struct timer_list poll_timer;
-
-	struct pcmcia_socket socket;
-
-	/* A few words of private data for special stuff of overrides... */
-	unsigned int private[8];
-};
-
-
-#endif
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pcmcia/yenta_socket.c	Mon Jun 16 08:06:42 2003
@@ -0,0 +1,974 @@
+/*
+ * Regular cardbus driver ("yenta_socket")
+ *
+ * (C) Copyright 1999, 2000 Linus Torvalds
+ *
+ * Changelog:
+ * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
+ * 	Dynamically adjust the size of the bridge resource
+ * 	
+ * May 2003: Dominik Brodowski <linux@brodo.de>
+ * 	Merge pci_socket.c and yenta.c into one file
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cs.h>
+
+#include <asm/io.h>
+
+#include "yenta_socket.h"
+#include "i82365.h"
+
+
+#if 0
+#define DEBUG(x,args...)	printk("%s: " x, __FUNCTION__, ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+/* Don't ask.. */
+#define to_cycles(ns)	((ns)/120)
+#define to_ns(cycles)	((cycles)*120)
+
+/*
+ * Generate easy-to-use ways of reading a cardbus sockets
+ * regular memory space ("cb_xxx"), configuration space
+ * ("config_xxx") and compatibility space ("exca_xxxx")
+ */
+static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
+{
+	u32 val = readl(socket->base + reg);
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	return val;
+}
+
+static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	writel(val, socket->base + reg);
+}
+
+static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
+{
+	u8 val;
+	pci_read_config_byte(socket->dev, offset, &val);
+	DEBUG("%p %04x %02x\n", socket, offset, val);
+	return val;
+}
+
+static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
+{
+	u16 val;
+	pci_read_config_word(socket->dev, offset, &val);
+	DEBUG("%p %04x %04x\n", socket, offset, val);
+	return val;
+}
+
+static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
+{
+	u32 val;
+	pci_read_config_dword(socket->dev, offset, &val);
+	DEBUG("%p %04x %08x\n", socket, offset, val);
+	return val;
+}
+
+static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
+{
+	DEBUG("%p %04x %02x\n", socket, offset, val);
+	pci_write_config_byte(socket->dev, offset, val);
+}
+
+static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
+{
+	DEBUG("%p %04x %04x\n", socket, offset, val);
+	pci_write_config_word(socket->dev, offset, val);
+}
+
+static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, offset, val);
+	pci_write_config_dword(socket->dev, offset, val);
+}
+
+static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
+{
+	u8 val = readb(socket->base + 0x800 + reg);
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	return val;
+}
+
+static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
+{
+	u16 val;
+	val = readb(socket->base + 0x800 + reg);
+	val |= readb(socket->base + 0x800 + reg + 1) << 8;
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	return val;
+}
+
+static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
+{
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
+}
+
+static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
+{
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
+	writeb(val >> 8, socket->base + 0x800 + reg + 1);
+}
+
+/*
+ * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
+ * on what kind of card is inserted..
+ */
+static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	unsigned int val;
+	u32 state = cb_readl(socket, CB_SOCKET_STATE);
+
+	val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
+	val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
+	val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
+			 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+
+	if (state & CB_CBCARD) {
+		val |= SS_CARDBUS;	
+		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
+		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
+		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
+	} else {
+		u8 status = exca_readb(socket, I365_STATUS);
+		val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
+		if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
+			val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
+		} else {
+			val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
+			val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
+		}
+		val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
+		val |= (status & I365_CS_READY) ? SS_READY : 0;
+		val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
+	}
+
+	*value = val;
+	return 0;
+}
+
+static int yenta_Vcc_power(u32 control)
+{
+	switch (control & CB_SC_VCC_MASK) {
+	case CB_SC_VCC_5V: return 50;
+	case CB_SC_VCC_3V: return 33;
+	default: return 0;
+	}
+}
+
+static int yenta_Vpp_power(u32 control)
+{
+	switch (control & CB_SC_VPP_MASK) {
+	case CB_SC_VPP_12V: return 120;
+	case CB_SC_VPP_5V: return 50;
+	case CB_SC_VPP_3V: return 33;
+	default: return 0;
+	}
+}
+
+static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u8 reg;
+	u32 control;
+
+	control = cb_readl(socket, CB_SOCKET_CONTROL);
+
+	state->Vcc = yenta_Vcc_power(control);
+	state->Vpp = yenta_Vpp_power(control);
+	state->io_irq = socket->io_irq;
+
+	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
+		if (bridge & CB_BRIDGE_CRST)
+			state->flags |= SS_RESET;
+		return 0;
+	}
+
+	/* 16-bit card state.. */
+	reg = exca_readb(socket, I365_POWER);
+	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
+	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
+
+	reg = exca_readb(socket, I365_INTCTL);
+	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
+	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
+
+	reg = exca_readb(socket, I365_CSCINT);
+	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
+	if (state->flags & SS_IOCARD) {
+		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+	} else {
+		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
+		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
+	}
+
+	return 0;
+}
+
+static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
+{
+	u32 reg = 0;	/* CB_SC_STPCLK? */
+	switch (state->Vcc) {
+	case 33: reg = CB_SC_VCC_3V; break;
+	case 50: reg = CB_SC_VCC_5V; break;
+	default: reg = 0; break;
+	}
+	switch (state->Vpp) {
+	case 33:  reg |= CB_SC_VPP_3V; break;
+	case 50:  reg |= CB_SC_VPP_5V; break;
+	case 120: reg |= CB_SC_VPP_12V; break;
+	}
+	if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
+		cb_writel(socket, CB_SOCKET_CONTROL, reg);
+}
+
+static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u16 bridge;
+
+	if (state->flags & SS_DEBOUNCED) {
+		/* The insertion debounce period has ended.  Clear any pending insertion events */
+		socket->events &= ~SS_DETECT;
+		state->flags &= ~SS_DEBOUNCED;		/* SS_DEBOUNCED is oneshot */
+	}
+	yenta_set_power(socket, state);
+	socket->io_irq = state->io_irq;
+	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
+	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+		u8 intr;
+		bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
+
+		/* ISA interrupt control? */
+		intr = exca_readb(socket, I365_INTCTL);
+		intr = (intr & ~0xf);
+		if (!socket->cb_irq) {
+			intr |= state->io_irq;
+			bridge |= CB_BRIDGE_INTR;
+		}
+		exca_writeb(socket, I365_INTCTL, intr);
+	}  else {
+		u8 reg;
+
+		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
+		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
+		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
+		if (state->io_irq != socket->cb_irq) {
+			reg |= state->io_irq;
+			bridge |= CB_BRIDGE_INTR;
+		}
+		exca_writeb(socket, I365_INTCTL, reg);
+
+		reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
+		reg |= I365_PWR_NORESET;
+		if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
+		if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
+		if (exca_readb(socket, I365_POWER) != reg)
+			exca_writeb(socket, I365_POWER, reg);
+
+		/* CSC interrupt: no ISA irq for CSC */
+		reg = I365_CSC_DETECT;
+		if (state->flags & SS_IOCARD) {
+			if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
+		} else {
+			if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
+			if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
+			if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
+		}
+		exca_writeb(socket, I365_CSCINT, reg);
+		exca_readb(socket, I365_CSC);
+	}
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
+	/* Socket event mask: get card insert/remove events.. */
+	cb_writel(socket, CB_SOCKET_EVENT, -1);
+	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
+	return 0;
+}
+
+static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	int map;
+	unsigned char ioctl, addr, enable;
+
+	map = io->map;
+
+	if (map > 1)
+		return -EINVAL;
+
+	enable = I365_ENA_IO(map);
+	addr = exca_readb(socket, I365_ADDRWIN);
+
+	/* Disable the window before changing it.. */
+	if (addr & enable) {
+		addr &= ~enable;
+		exca_writeb(socket, I365_ADDRWIN, addr);
+	}
+
+	exca_writew(socket, I365_IO(map)+I365_W_START, io->start);
+	exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop);
+
+	ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
+	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
+	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
+	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+	exca_writeb(socket, I365_IOCTL, ioctl);
+
+	if (io->flags & MAP_ACTIVE)
+		exca_writeb(socket, I365_ADDRWIN, addr | enable);
+	return 0;
+}
+
+static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	int map;
+	unsigned char addr, enable;
+	unsigned int start, stop, card_start;
+	unsigned short word;
+
+	map = mem->map;
+	start = mem->sys_start;
+	stop = mem->sys_stop;
+	card_start = mem->card_start;
+
+	if (map > 4 || start > stop || ((start ^ stop) >> 24) ||
+	    (card_start >> 26) || mem->speed > 1000)
+		return -EINVAL;
+
+	enable = I365_ENA_MEM(map);
+	addr = exca_readb(socket, I365_ADDRWIN);
+	if (addr & enable) {
+		addr &= ~enable;
+		exca_writeb(socket, I365_ADDRWIN, addr);
+	}
+
+	exca_writeb(socket, CB_MEM_PAGE(map), start >> 24);
+
+	word = (start >> 12) & 0x0fff;
+	if (mem->flags & MAP_16BIT)
+		word |= I365_MEM_16BIT;
+	if (mem->flags & MAP_0WS)
+		word |= I365_MEM_0WS;
+	exca_writew(socket, I365_MEM(map) + I365_W_START, word);
+
+	word = (stop >> 12) & 0x0fff;
+	switch (to_cycles(mem->speed)) {
+		case 0: break;
+		case 1:  word |= I365_MEM_WS0; break;
+		case 2:  word |= I365_MEM_WS1; break;
+		default: word |= I365_MEM_WS1 | I365_MEM_WS0; break;
+	}
+	exca_writew(socket, I365_MEM(map) + I365_W_STOP, word);
+
+	word = ((card_start - start) >> 12) & 0x3fff;
+	if (mem->flags & MAP_WRPROT)
+		word |= I365_MEM_WRPROT;
+	if (mem->flags & MAP_ATTRIB)
+		word |= I365_MEM_REG;
+	exca_writew(socket, I365_MEM(map) + I365_W_OFF, word);
+
+	if (mem->flags & MAP_ACTIVE)
+		exca_writeb(socket, I365_ADDRWIN, addr | enable);
+	return 0;
+}
+
+
+static unsigned int yenta_events(struct yenta_socket *socket)
+{
+	u8 csc;
+	u32 cb_event;
+	unsigned int events;
+
+	/* Clear interrupt status for the event */
+	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
+	cb_writel(socket, CB_SOCKET_EVENT, cb_event);
+
+	csc = exca_readb(socket, I365_CSC);
+
+	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
+	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
+	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
+		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+	} else {
+		events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
+		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
+	}
+	return events;
+}
+
+
+static void yenta_bh(void *data)
+{
+	struct yenta_socket *socket = data;
+	unsigned int events;
+
+	spin_lock_irq(&socket->event_lock);
+	events = socket->events;
+	socket->events = 0;
+	spin_unlock_irq(&socket->event_lock);
+	if (socket->handler)
+		socket->handler(socket->info, events);
+}
+
+static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int events;
+	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
+
+	events = yenta_events(socket);
+	if (events) {
+		spin_lock(&socket->event_lock);
+		socket->events |= events;
+		spin_unlock(&socket->event_lock);
+		schedule_work(&socket->tq_task);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static void yenta_interrupt_wrapper(unsigned long data)
+{
+	struct yenta_socket *socket = (struct yenta_socket *) data;
+
+	yenta_interrupt(0, (void *)socket, NULL);
+	socket->poll_timer.expires = jiffies + HZ;
+	add_timer(&socket->poll_timer);
+}
+
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
+{
+	int i;
+	unsigned long val;
+	u16 bridge_ctrl;
+	u32 mask;
+
+	/* Set up ISA irq routing to probe the ISA irqs.. */
+	bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
+	if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
+		bridge_ctrl |= CB_BRIDGE_INTR;
+		config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
+	}
+
+	/*
+	 * Probe for usable interrupts using the force
+	 * register to generate bogus card status events.
+	 */
+	cb_writel(socket, CB_SOCKET_EVENT, -1);
+	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+	exca_writeb(socket, I365_CSCINT, 0);
+	val = probe_irq_on() & isa_irq_mask;
+	for (i = 1; i < 16; i++) {
+		if (!((val >> i) & 1))
+			continue;
+		exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
+		cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
+		udelay(100);
+		cb_writel(socket, CB_SOCKET_EVENT, -1);
+	}
+	cb_writel(socket, CB_SOCKET_MASK, 0);
+	exca_writeb(socket, I365_CSCINT, 0);
+	
+	mask = probe_irq_mask(val) & 0xffff;
+
+	bridge_ctrl &= ~CB_BRIDGE_INTR;
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
+
+	return mask;
+}
+
+/*
+ * Set static data that doesn't need re-initializing..
+ */
+static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
+{
+	socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
+	socket->socket.map_size = 0x1000;
+	socket->socket.pci_irq = socket->cb_irq;
+	socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+	socket->socket.cb_dev = socket->dev;
+
+	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq);
+}
+
+
+static void yenta_clear_maps(struct yenta_socket *socket)
+{
+	int i;
+	pccard_io_map io = { 0, 0, 0, 0, 1 };
+	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+	mem.sys_stop = 0x0fff;
+	yenta_set_socket(&socket->socket, &dead_socket);
+	for (i = 0; i < 2; i++) {
+		io.map = i;
+		yenta_set_io_map(&socket->socket, &io);
+	}
+	for (i = 0; i < 5; i++) {
+		mem.map = i;
+		yenta_set_mem_map(&socket->socket, &mem);
+	}
+}
+
+/*
+ * Initialize the standard cardbus registers
+ */
+static void yenta_config_init(struct yenta_socket *socket)
+{
+	u16 bridge;
+	struct pci_dev *dev = socket->dev;
+
+	pci_set_power_state(socket->dev, 0);
+
+	config_writel(socket, CB_LEGACY_MODE_BASE, 0);
+	config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
+	config_writew(socket, PCI_COMMAND,
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER |
+			PCI_COMMAND_WAIT);
+
+	/* MAGIC NUMBERS! Fixme */
+	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
+	config_writeb(socket, PCI_LATENCY_TIMER, 168);
+	config_writel(socket, PCI_PRIMARY_BUS,
+		(176 << 24) |			   /* sec. latency timer */
+		(dev->subordinate->subordinate << 16) | /* subordinate bus */
+		(dev->subordinate->secondary << 8) |  /* secondary bus */
+		dev->subordinate->primary);		   /* primary bus */
+
+	/*
+	 * Set up the bridging state:
+	 *  - enable write posting.
+	 *  - memory window 0 prefetchable, window 1 non-prefetchable
+	 *  - PCI interrupts enabled if a PCI interrupt exists..
+	 */
+	bridge = config_readw(socket, CB_BRIDGE_CONTROL);
+	bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
+	bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
+	if (!socket->cb_irq)
+		bridge |= CB_BRIDGE_INTR;
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
+
+	exca_writeb(socket, I365_GBLCTL, 0x00);
+	exca_writeb(socket, I365_GENCTL, 0x00);
+
+	/* Redo card voltage interrogation */
+	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+}
+
+/* Called at resume and initialization events */
+static int yenta_init(struct pcmcia_socket *sock)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	yenta_config_init(socket);
+	yenta_clear_maps(socket);
+
+	/* Re-enable interrupts */
+	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
+	return 0;
+}
+
+static int yenta_suspend(struct pcmcia_socket *sock)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	yenta_set_socket(sock, &dead_socket);
+
+	/* Disable interrupts */
+	cb_writel(socket, CB_SOCKET_MASK, 0x0);
+
+	/*
+	 * This does not work currently. The controller
+	 * loses too much information during D3 to come up
+	 * cleanly. We should probably fix yenta_init()
+	 * to update all the critical registers, notably
+	 * the IO and MEM bridging region data.. That is
+	 * something that pci_set_power_state() should
+	 * probably know about bridges anyway.
+	 *
+	pci_set_power_state(socket->dev, 3);
+	 */
+
+	return 0;
+}
+
+/*
+ * Use an adaptive allocation for the memory resource,
+ * sometimes the memory behind pci bridges is limited:
+ * 1/8 of the size of the io window of the parent.
+ * max 4 MB, min 16 kB.
+ */
+#define BRIDGE_MEM_MAX 4*1024*1024
+#define BRIDGE_MEM_MIN 16*1024
+
+#define BRIDGE_IO_MAX 256
+#define BRIDGE_IO_MIN 32
+
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
+{
+	struct pci_bus *bus;
+	struct resource *root, *res;
+	u32 start, end;
+	u32 align, size, min;
+	unsigned offset;
+	unsigned mask;
+
+	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
+	mask = ~0xfff;
+	if (type & IORESOURCE_IO)
+		mask = ~3;
+
+	offset = 0x1c + 8*nr;
+	bus = socket->dev->subordinate;
+	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
+	res->name = bus->name;
+	res->flags = type;
+	res->start = 0;
+	res->end = 0;
+	root = pci_find_parent_resource(socket->dev, res);
+
+	if (!root)
+		return;
+
+	start = config_readl(socket, offset) & mask;
+	end = config_readl(socket, offset+4) | ~mask;
+	if (start && end > start) {
+		res->start = start;
+		res->end = end;
+		if (request_resource(root, res) == 0)
+			return;
+		printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
+				socket->dev->slot_name, nr);
+		res->start = res->end = 0;
+	}
+
+	if (type & IORESOURCE_IO) {
+		align = 1024;
+		size = BRIDGE_IO_MAX;
+		min = BRIDGE_IO_MIN;
+		start = PCIBIOS_MIN_IO;
+		end = ~0U;
+	} else {
+		unsigned long avail = root->end - root->start;
+		int i;
+		size = BRIDGE_MEM_MAX;
+		if (size > avail/8) {
+			size=(avail+1)/8;
+			/* round size down to next power of 2 */
+			i = 0;
+			while ((size /= 2) != 0)
+				i++;
+			size = 1 << i;
+		}
+		if (size < BRIDGE_MEM_MIN)
+			size = BRIDGE_MEM_MIN;
+		min = BRIDGE_MEM_MIN;
+		align = size;
+		start = PCIBIOS_MIN_MEM;
+		end = ~0U;
+	}
+	
+	do {
+		if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
+			config_writel(socket, offset, res->start);
+			config_writel(socket, offset+4, res->end);
+			return;
+		}
+		size = size/2;
+		align = size;
+	} while (size >= min);
+	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
+			socket->dev->slot_name, type);
+	res->start = res->end = 0;
+}
+
+/*
+ * Allocate the bridge mappings for the device..
+ */
+static void yenta_allocate_resources(struct yenta_socket *socket)
+{
+	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
+	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
+	yenta_allocate_res(socket, 2, IORESOURCE_IO);
+	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
+}
+
+
+/*
+ * Free the bridge mappings for the device..
+ */
+static void yenta_free_resources(struct yenta_socket *socket)
+{
+	int i;
+	for (i=0;i<4;i++) {
+		struct resource *res;
+		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
+		if (res->start != 0 && res->end != 0)
+			release_resource(res);
+		res->start = res->end = 0;
+	}
+}
+
+
+/*
+ * Close it down - release our resources and go home..
+ */
+static void yenta_close(struct pci_dev *dev)
+{
+	struct yenta_socket *sock = pci_get_drvdata(dev);
+
+	/* we don't want a dying socket registered */
+	pcmcia_unregister_socket(&sock->socket);
+	
+	/* Disable all events so we don't die in an IRQ storm */
+	cb_writel(sock, CB_SOCKET_MASK, 0x0);
+	exca_writeb(sock, I365_CSCINT, 0);
+
+	if (sock->cb_irq)
+		free_irq(sock->cb_irq, sock);
+	else
+		del_timer_sync(&sock->poll_timer);
+
+	if (sock->base)
+		iounmap(sock->base);
+	yenta_free_resources(sock);
+
+	pci_set_drvdata(dev, NULL);
+}
+
+
+static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	socket->handler = handler;
+	socket->info = info;
+	return 0;
+}
+
+
+static struct pccard_operations yenta_socket_operations = {
+	.owner			= THIS_MODULE,
+	.init			= yenta_init,
+	.suspend		= yenta_suspend,
+	.register_callback	= yenta_register_callback,
+	.get_status		= yenta_get_status,
+	.get_socket		= yenta_get_socket,
+	.set_socket		= yenta_set_socket,
+	.set_io_map		= yenta_set_io_map,
+	.set_mem_map		= yenta_set_mem_map,
+};
+
+
+#include "ti113x.h"
+#include "ricoh.h"
+
+/*
+ * Different cardbus controllers have slightly different
+ * initialization sequences etc details. List them here..
+ */
+#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
+struct cardbus_override_struct {
+	unsigned short vendor;
+	unsigned short device;
+	int (*override) (struct yenta_socket *socket);
+} cardbus_override[] = {
+	{ PD(TI,1130),	&ti113x_override },
+	{ PD(TI,1031),	&ti_override },
+	{ PD(TI,1131),	&ti113x_override },
+	{ PD(TI,1250),	&ti1250_override },
+	{ PD(TI,1220),	&ti_override },
+	{ PD(TI,1221),	&ti_override },
+	{ PD(TI,1210),	&ti_override },
+	{ PD(TI,1450),	&ti_override },
+	{ PD(TI,1225),	&ti_override },
+	{ PD(TI,1251A),	&ti_override },
+	{ PD(TI,1211),	&ti_override },
+	{ PD(TI,1251B),	&ti_override },
+	{ PD(TI,1410),	ti1250_override },
+	{ PD(TI,1420),	&ti_override },
+	{ PD(TI,4410),	&ti_override },
+	{ PD(TI,4451),	&ti_override },
+
+	{ PD(RICOH,RL5C465), &ricoh_override },
+	{ PD(RICOH,RL5C466), &ricoh_override },
+	{ PD(RICOH,RL5C475), &ricoh_override },
+	{ PD(RICOH,RL5C476), &ricoh_override },
+	{ PD(RICOH,RL5C478), &ricoh_override },
+
+	{ }, /* all zeroes */
+};
+
+
+/*
+ * Initialize a cardbus controller. Make sure we have a usable
+ * interrupt, and that we can map the cardbus area. Fill in the
+ * socket information structure..
+ */
+static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct yenta_socket *socket;
+	struct cardbus_override_struct *d;
+	
+	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
+	if (!socket)
+		return -ENOMEM;
+	memset(socket, 0, sizeof(*socket));
+
+	/* prepare pcmcia_socket */
+	socket->socket.ss_entry = &yenta_socket_operations;
+	socket->socket.dev.dev = &dev->dev;
+	socket->socket.driver_data = socket;
+
+	/* prepare struct yenta_socket */
+	socket->dev = dev;
+	pci_set_drvdata(dev, socket);
+	spin_lock_init(&socket->event_lock);
+
+	/*
+	 * Do some basic sanity checking..
+	 */
+	if (pci_enable_device(dev))
+		return -1;
+	if (!pci_resource_start(dev, 0)) {
+		printk("No cardbus resource!\n");
+		return -1;
+	}
+
+	/*
+	 * Ok, start setup.. Map the cardbus registers,
+	 * and request the IRQ.
+	 */
+	socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
+	if (!socket->base)
+		return -1;
+
+	yenta_config_init(socket);
+
+	/* Disable all events */
+	cb_writel(socket, CB_SOCKET_MASK, 0x0);
+
+	/* Set up the bridge regions.. */
+	yenta_allocate_resources(socket);
+
+	socket->cb_irq = dev->irq;
+
+	/* Do we have special options for the device? */
+	d = cardbus_override;
+	while (d->override) {
+		if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
+			int retval = d->override(socket);
+			if (retval < 0)
+				return retval;
+		}
+		d++;
+	}
+
+	/* We must finish initialization here */
+
+	INIT_WORK(&socket->tq_task, yenta_bh, socket);
+
+	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
+		/* No IRQ or request_irq failed. Poll */
+		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
+		init_timer(&socket->poll_timer);
+		socket->poll_timer.function = yenta_interrupt_wrapper;
+		socket->poll_timer.data = (unsigned long)socket;
+		socket->poll_timer.expires = jiffies + HZ;
+		add_timer(&socket->poll_timer);
+	}
+
+	/* Figure out what the dang thing can do for the PCMCIA layer... */
+	yenta_get_socket_capabilities(socket, isa_interrupts);
+	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+
+	/* Register it with the pcmcia layer.. */
+	return pcmcia_register_socket(&socket->socket);
+}
+
+
+static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
+}
+
+
+static int yenta_dev_resume (struct pci_dev *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
+}
+
+
+static struct pci_device_id yenta_table [] __devinitdata = { {
+	.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
+	.class_mask	= ~0,
+
+	.vendor		= PCI_ANY_ID,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+}, { /* all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, yenta_table);
+
+
+static struct pci_driver yenta_cardbus_driver = {
+	.name		= "yenta_cardbus",
+	.id_table	= yenta_table,
+	.probe		= yenta_probe,
+	.remove		= __devexit_p(yenta_close),
+	.suspend	= yenta_dev_suspend,
+	.resume		= yenta_dev_resume,
+};
+
+
+static int __init yenta_socket_init(void)
+{
+	return pci_register_driver (&yenta_cardbus_driver);
+}
+
+
+static void __exit yenta_socket_exit (void)
+{
+	pci_unregister_driver (&yenta_cardbus_driver);
+}
+
+
+module_init(yenta_socket_init);
+module_exit(yenta_socket_exit);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/yenta_socket.h b/drivers/pcmcia/yenta_socket.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pcmcia/yenta_socket.h	Mon Jun 16 08:00:31 2003
@@ -0,0 +1,116 @@
+#ifndef __YENTA_H
+#define __YENTA_H
+
+#include <asm/io.h>
+
+#define CB_SOCKET_EVENT		0x00
+#define    CB_CSTSEVENT		0x00000001	/* Card status event */
+#define    CB_CD1EVENT		0x00000002	/* Card detect 1 change event */
+#define    CB_CD2EVENT		0x00000004	/* Card detect 2 change event */
+#define    CB_PWREVENT		0x00000008	/* PWRCYCLE change event */
+
+#define CB_SOCKET_MASK		0x04
+#define    CB_CSTSMASK		0x00000001	/* Card status mask */
+#define    CB_CDMASK		0x00000006	/* Card detect 1&2 mask */
+#define    CB_PWRMASK		0x00000008	/* PWRCYCLE change mask */
+
+#define CB_SOCKET_STATE		0x08
+#define    CB_CARDSTS		0x00000001	/* CSTSCHG status */
+#define    CB_CDETECT1		0x00000002	/* Card detect status 1 */
+#define    CB_CDETECT2		0x00000004	/* Card detect status 2 */
+#define    CB_PWRCYCLE		0x00000008	/* Socket powered */
+#define    CB_16BITCARD		0x00000010	/* 16-bit card detected */
+#define    CB_CBCARD		0x00000020	/* CardBus card detected */
+#define    CB_IREQCINT		0x00000040	/* READY(xIRQ)/xCINT high */
+#define    CB_NOTACARD		0x00000080	/* Unrecognizable PC card detected */
+#define    CB_DATALOST		0x00000100	/* Potential data loss due to card removal */
+#define    CB_BADVCCREQ		0x00000200	/* Invalid Vcc request by host software */
+#define    CB_5VCARD		0x00000400	/* Card Vcc at 5.0 volts? */
+#define    CB_3VCARD		0x00000800	/* Card Vcc at 3.3 volts? */
+#define    CB_XVCARD		0x00001000	/* Card Vcc at X.X volts? */
+#define    CB_YVCARD		0x00002000	/* Card Vcc at Y.Y volts? */
+#define    CB_5VSOCKET		0x10000000	/* Socket Vcc at 5.0 volts? */
+#define    CB_3VSOCKET		0x20000000	/* Socket Vcc at 3.3 volts? */
+#define    CB_XVSOCKET		0x40000000	/* Socket Vcc at X.X volts? */
+#define    CB_YVSOCKET		0x80000000	/* Socket Vcc at Y.Y volts? */
+
+#define CB_SOCKET_FORCE		0x0C
+#define    CB_FCARDSTS		0x00000001	/* Force CSTSCHG */
+#define    CB_FCDETECT1		0x00000002	/* Force CD1EVENT */
+#define    CB_FCDETECT2		0x00000004	/* Force CD2EVENT */
+#define    CB_FPWRCYCLE		0x00000008	/* Force PWREVENT */
+#define    CB_F16BITCARD	0x00000010	/* Force 16-bit PCMCIA card */
+#define    CB_FCBCARD		0x00000020	/* Force CardBus line */
+#define    CB_FNOTACARD		0x00000080	/* Force NOTACARD */
+#define    CB_FDATALOST		0x00000100	/* Force data lost */
+#define    CB_FBADVCCREQ	0x00000200	/* Force bad Vcc request */
+#define    CB_F5VCARD		0x00000400	/* Force 5.0 volt card */
+#define    CB_F3VCARD		0x00000800	/* Force 3.3 volt card */
+#define    CB_FXVCARD		0x00001000	/* Force X.X volt card */
+#define    CB_FYVCARD		0x00002000	/* Force Y.Y volt card */
+#define    CB_CVSTEST		0x00004000	/* Card VS test */
+
+#define CB_SOCKET_CONTROL	0x10
+#define  CB_SC_VPP_MASK		0x00000007
+#define   CB_SC_VPP_OFF		0x00000000
+#define   CB_SC_VPP_12V		0x00000001
+#define   CB_SC_VPP_5V		0x00000002
+#define   CB_SC_VPP_3V		0x00000003
+#define   CB_SC_VPP_XV		0x00000004
+#define   CB_SC_VPP_YV		0x00000005
+#define  CB_SC_VCC_MASK		0x00000070
+#define   CB_SC_VCC_OFF		0x00000000
+#define   CB_SC_VCC_5V		0x00000020
+#define   CB_SC_VCC_3V		0x00000030
+#define   CB_SC_VCC_XV		0x00000040
+#define   CB_SC_VCC_YV		0x00000050
+#define  CB_SC_CCLK_STOP	0x00000080
+
+#define CB_SOCKET_POWER		0x20
+#define    CB_SKTACCES		0x02000000	/* A PC card access has occurred (clear on read) */
+#define    CB_SKTMODE		0x01000000	/* Clock frequency has changed (clear on read) */
+#define    CB_CLKCTRLEN		0x00010000	/* Clock control enabled (RW) */
+#define    CB_CLKCTRL		0x00000001	/* Stop(0) or slow(1) CB clock (RW) */
+
+/*
+ * Cardbus configuration space
+ */
+#define CB_BRIDGE_BASE(m)	(0x1c + 8*(m))
+#define CB_BRIDGE_LIMIT(m)	(0x20 + 8*(m))
+#define CB_BRIDGE_CONTROL	0x3e
+#define   CB_BRIDGE_CPERREN	0x00000001
+#define   CB_BRIDGE_CSERREN	0x00000002
+#define   CB_BRIDGE_ISAEN	0x00000004
+#define   CB_BRIDGE_VGAEN	0x00000008
+#define   CB_BRIDGE_MABTMODE	0x00000020
+#define   CB_BRIDGE_CRST	0x00000040
+#define   CB_BRIDGE_INTR	0x00000080
+#define   CB_BRIDGE_PREFETCH0	0x00000100
+#define   CB_BRIDGE_PREFETCH1	0x00000200
+#define   CB_BRIDGE_POSTEN	0x00000400
+#define CB_LEGACY_MODE_BASE	0x44
+
+/*
+ * ExCA area extensions in Yenta
+ */
+#define CB_MEM_PAGE(map)	(0x40 + (map))
+
+struct yenta_socket {
+	struct pci_dev *dev;
+	int cb_irq, io_irq;
+	void *base;
+	void (*handler)(void *, unsigned int);
+	void *info;
+	spinlock_t event_lock;
+	unsigned int events;
+	struct work_struct tq_task;
+	struct timer_list poll_timer;
+
+	struct pcmcia_socket socket;
+
+	/* A few words of private data for special stuff of overrides... */
+	unsigned int private[8];
+};
+
+
+#endif
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Mon May 26 14:44:44 2003
+++ b/drivers/scsi/53c700.c	Sun Jun  8 15:37:49 2003
@@ -168,7 +168,6 @@
 STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_proc_directory_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
 STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
@@ -281,7 +280,6 @@
 	tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
 	tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
 	tpnt->use_clustering = DISABLE_CLUSTERING;
-	tpnt->proc_info = NCR_700_proc_directory_info;
 	tpnt->slave_configure = NCR_700_slave_configure;
 	tpnt->slave_destroy = NCR_700_slave_destroy;
 	tpnt->use_blk_tcq = 1;
@@ -293,7 +291,8 @@
 		tpnt->proc_name = "53c700";
 	
 
-	if((host = scsi_register(tpnt, 4)) == NULL)
+	host = scsi_host_alloc(tpnt, 4);
+	if (!host)
 		return NULL;
 	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
 	       * NCR_700_COMMAND_SLOTS_PER_HOST);
@@ -1707,35 +1706,6 @@
  out_unlock:
 	spin_unlock_irqrestore(host->host_lock, flags);
 	return IRQ_RETVAL(handled);
-}
-
-STATIC int
-NCR_700_proc_directory_info(struct Scsi_Host *host, char *proc_buf, char **startp,
-			 off_t offset, int bytes_available, int write)
-{
-	static char buf[4096];	/* 1 page should be sufficient */
-	int len = 0;
-	struct NCR_700_Host_Parameters *hostdata;
-	Scsi_Device *SDp;
-
-	if(write) {
-		/* FIXME: Clear internal statistics here */
-		return 0;
-	}
-	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	Active  Next Tag\n\
-======	======  ========\n");
-	list_for_each_entry(SDp, &host->my_devices, siblings) {
-		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;
-	if(len > bytes_available)
-		len = bytes_available;
-	memcpy(proc_buf, buf + offset, len);
-	return len;
 }
 
 STATIC int
diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
--- a/drivers/scsi/53c700.h	Sat Apr 26 07:28:12 2003
+++ b/drivers/scsi/53c700.h	Tue Jun 17 13:27:44 2003
@@ -12,6 +12,10 @@
 
 #include <asm/io.h>
 
+#if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED)
+#define CONFIG_53C700_BOTH_MAPPED
+#endif
+
 /* Turn on for general debugging---too verbose for normal use */
 #undef	NCR_700_DEBUG
 /* Debug the tag queues, checking hash queue allocation and deallocation
@@ -178,6 +182,9 @@
 	/* NOTHING BELOW HERE NEEDS ALTERING */
 	__u32	fast:1;		/* if we can alter the SCSI bus clock
                                    speed (so can negiotiate sync) */
+#ifdef CONFIG_53C700_BOTH_MAPPED
+	__u32	mem_mapped;	/* set if memory mapped */
+#endif
 	int	sync_clock;	/* The speed of the SYNC core */
 
 	__u32	*script;		/* pointer to script location */
@@ -428,11 +435,8 @@
 	} \
 }
 
-#endif
-
-#ifdef CONFIG_53C700_MEM_MAPPED
 static inline __u8
-NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_readb(struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -441,7 +445,7 @@
 }
 
 static inline __u32
-NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_readl(struct Scsi_Host *host, __u32 reg)
 {
 	__u32 value = __raw_readl(host->base + reg);
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
@@ -456,7 +460,7 @@
 }
 
 static inline void
-NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -465,7 +469,7 @@
 }
 
 static inline void
-NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -478,9 +482,9 @@
 
 	__raw_writel(bS_to_host(value), host->base + reg);
 }
-#elif defined(CONFIG_53C700_IO_MAPPED)
+
 static inline __u8
-NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+NCR_700_io_readb(struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -489,7 +493,7 @@
 }
 
 static inline __u32
-NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+NCR_700_io_readl(struct Scsi_Host *host, __u32 reg)
 {
 	__u32 value = inl(host->base + reg);
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
@@ -505,7 +509,7 @@
 }
 
 static inline void
-NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_io_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -514,7 +518,7 @@
 }
 
 static inline void
-NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_io_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -527,4 +531,100 @@
 
 	outl(bS_to_host(value), host->base + reg);
 }
+
+#ifdef CONFIG_53C700_BOTH_MAPPED
+
+static inline __u8
+NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+{
+	__u8 val;
+
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		val = NCR_700_mem_readb(host, reg);
+	else
+		val = NCR_700_io_readb(host, reg);
+
+	return val;
+}
+
+static inline __u32
+NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+{
+	__u32 val;
+
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		val = NCR_700_mem_readl(host, reg);
+	else
+		val = NCR_700_io_readl(host, reg);
+
+	return val;
+}
+
+static inline void
+NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		NCR_700_mem_writeb(value, host, reg);
+	else
+		NCR_700_io_writeb(value, host, reg);
+}
+
+static inline void
+NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		NCR_700_mem_writel(value, host, reg);
+	else
+		NCR_700_io_writel(value, host, reg);
+}
+
+static inline void
+NCR_700_set_mem_mapped(struct NCR_700_Host_Parameters *hostdata)
+{
+	hostdata->mem_mapped = 1;
+}
+
+static inline void
+NCR_700_set_io_mapped(struct NCR_700_Host_Parameters *hostdata)
+{
+	hostdata->mem_mapped = 0;
+}
+
+
+#elif defined(CONFIG_53C700_IO_MAPPED)
+
+#define NCR_700_readb NCR_700_io_readb
+#define NCR_700_readl NCR_700_io_readl
+#define NCR_700_writeb NCR_700_io_writeb
+#define NCR_700_writel NCR_700_io_writel
+
+#define NCR_700_set_io_mapped(x)
+#define NCR_700_set_mem_mapped(x)	error I/O mapped only
+
+#elif defined(CONFIG_53C700_MEM_MAPPED)
+
+#define NCR_700_readb NCR_700_mem_readb
+#define NCR_700_readl NCR_700_mem_readl
+#define NCR_700_writeb NCR_700_mem_writeb
+#define NCR_700_writel NCR_700_mem_writel
+
+#define NCR_700_set_io_mapped(x)	error MEM mapped only
+#define NCR_700_set_mem_mapped(x)
+
+#else
+#error neither CONFIG_53C700_MEM_MAPPED nor CONFIG_53C700_IO_MAPPED is set
+#endif
+
 #endif
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Tue May 13 03:59:32 2003
+++ b/drivers/scsi/AM53C974.c	Sun Jun  8 12:18:41 2003
@@ -817,22 +817,6 @@
 	return (info);
 }
 
-/************************************************************************** 
-* Function : int AM53C974_command (Scsi_Cmnd *SCpnt)                      *
-*                                                                         *
-* Purpose : the unqueued SCSI command function, replaced by the           *
-*           AM53C974_queue_command function                               *
-*                                                                         *
-* Inputs : SCpnt - pointer to command structure                           *
-*                                                                         *
-* Returns :status, see hosts.h for details                                *
-***************************************************************************/
-static int AM53C974_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("AM53C974_command called\n"));
-	return 0;
-}
-
 /**************************************************************************
 * Function : void initialize_SCp(Scsi_Cmnd *cmd)                          *
 *                                                                         *
@@ -2466,7 +2450,6 @@
 	.detect         	= AM53C974_pci_detect,
 	.release        	= AM53C974_release,	
 	.info			= AM53C974_info,
-	.command		= AM53C974_command,
 	.queuecommand		= AM53C974_queue_command,
 	.abort			= AM53C974_abort,
 	.reset			= AM53C974_reset,
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Wed Jun  4 22:53:09 2003
+++ b/drivers/scsi/Kconfig	Thu Jun  5 16:09:41 2003
@@ -27,8 +27,8 @@
 	  If you want to use a SCSI tape drive under Linux, say Y and read the
 	  SCSI-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT for
-	  SCSI CD-ROMs.
+	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
+	  for SCSI CD-ROMs.
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
@@ -131,11 +131,11 @@
 	depends on SCSI
 	default y
 	help
-	  If you want to build with SCSI REPORT LUNS support in the kernel, say Y here.
-	  The REPORT LUNS command is useful for devices (such as disk arrays) with
-	  large numbers of LUNs where the LUN values are not contiguous (sparse LUN).
-	  REPORT LUNS scanning is done only for SCSI-3 devices. Most users can safely
-	  answer N here.
+	  If you want support for SCSI REPORT LUNS, say Y here.
+	  The REPORT LUNS command is useful for devices (such as disk arrays)
+	  with large numbers of LUNs where the LUN values are not contiguous
+	  (sparse LUN).  REPORT LUNS scanning is done only for SCSI-3 devices.
+	  Most users can safely answer N here.
 
 config SCSI_CONSTANTS
 	bool "Verbose SCSI error reporting (kernel size +=12K)"
@@ -207,7 +207,7 @@
 
 config SCSI_7000FASST
 	tristate "7000FASST SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This driver supports the Western Digital 7000 SCSI host adapter
 	  family.  Some information is in the source:
@@ -220,7 +220,7 @@
 
 config SCSI_ACARD
 	tristate "ACARD SCSI support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This driver supports the ACARD 870U/W SCSI host adapter.
 
@@ -285,6 +285,7 @@
 
 config SCSI_AIC7XXX_OLD
 	tristate "Adaptec AIC7xxx support (old driver)"
+	depends on SCSI
 	help
 	  WARNING This driver is an older aic7xxx driver and is no longer
 	  under active development.  Adaptec, Inc. is writing a new driver to
@@ -343,7 +344,7 @@
 
 config SCSI_ADVANSYS
 	tristate "AdvanSys SCSI support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	help
 	  This is a driver for all SCSI host adapters manufactured by
 	  AdvanSys. It is documented in the kernel source in
@@ -357,7 +358,7 @@
 
 config SCSI_IN2000
 	tristate "Always IN2000 SCSI support"
-	depends on SCSI
+	depends on ISA && SCSI
 	help
 	  This is support for an ISA bus SCSI host adapter.  You'll find more
 	  information in <file:Documentation/scsi/in2000.txt>. If it doesn't work
@@ -369,10 +370,10 @@
 	  say M here and read <file:Documentation/modules.txt>.  The module
 	  will be called in2000.
 
-# does not use pci dma and seems to be isa/onboard only for old machines
+# does not use pci dma and seems to be onboard only for old machines
 config SCSI_AM53C974
 	tristate "AM53/79C974 PCI SCSI support"
-	depends on !X86_64 && SCSI && PCI
+	depends on X86 && PCI && SCSI
 	---help---
 	  This is support for the AM53/79C974 SCSI host adapters.  Please read
 	  <file:Documentation/scsi/AM53C974.txt> for details.  Also, the
@@ -390,7 +391,7 @@
 
 config SCSI_MEGARAID
 	tristate "AMI MegaRAID support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490
 	  and 467 SCSI host adapters.
@@ -402,7 +403,7 @@
 
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
-	depends on SCSI
+	depends on (PCI || ISA) && SCSI
 	---help---
 	  This is support for BusLogic MultiMaster and FlashPoint SCSI Host
 	  Adapters. Consult the SCSI-HOWTO, available from
@@ -436,7 +437,7 @@
 
 config SCSI_DMX3191D
 	tristate "DMX3191D SCSI support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for Domex DMX3191D SCSI Host Adapters.
 
@@ -447,7 +448,7 @@
 
 config SCSI_DTC3280
 	tristate "DTC3180/3280 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
 	  the SCSI-HOWTO, available from
@@ -461,7 +462,7 @@
 
 config SCSI_EATA
 	tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	---help---
 	  This driver supports all EATA/DMA-compliant SCSI host adapters.  DPT
 	  ISA and all EISA I/O addresses are probed looking for the "EATA"
@@ -527,7 +528,7 @@
 
 config SCSI_FUTURE_DOMAIN
 	tristate "Future Domain 16xx SCSI/AHA-2920A support"
-	depends on SCSI
+	depends on (ISA || PCI) && SCSI
 	---help---
 	  This is support for Future Domain's 16-bit SCSI host adapters
 	  (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
@@ -563,7 +564,7 @@
 
 config SCSI_GDTH
 	tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	---help---
 	  Formerly called GDT SCSI Disk Array Controller Support.
 
@@ -579,7 +580,7 @@
 
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using PIO. Most boards such as the Trantor T130 fit this
@@ -600,7 +601,7 @@
 
 config SCSI_GENERIC_NCR5380_MMIO
 	tristate "Generic NCR5380/53c400 SCSI MMIO support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using memory mapped I/O. 
@@ -609,10 +610,11 @@
 	  of the box, you may have to change some settings in
 	  <file:drivers/scsi/g_NCR5380.h>.
 
-	  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.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
+	  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_mmio.
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.
 
 config SCSI_GENERIC_NCR53C400
 	bool "Enable NCR53c400 extensions"
@@ -699,7 +701,7 @@
 
 config SCSI_IPS
 	tristate "IBM ServeRAID support"
-	depends on X86 && SCSI && PCI
+	depends on X86 && PCI && SCSI
 	---help---
 	  This is support for the IBM ServeRAID hardware RAID controllers.
 	  See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
@@ -715,7 +717,7 @@
 
 config SCSI_INITIO
 	tristate "Initio 9100U(W) support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for the Initio 91XXU(W) SCSI host adapter.  Please
 	  read the SCSI-HOWTO, available from
@@ -728,7 +730,7 @@
 
 config SCSI_INIA100
 	tristate "Initio INI-A100U2W support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for the Initio INI-A100U2W SCSI host adapter.
 	  Please read the SCSI-HOWTO, available from
@@ -828,7 +830,7 @@
 
 config SCSI_NCR53C406A
 	tristate "NCR53c406a SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for the NCR53c406a SCSI host adapter.  For user
 	  configurable parameters, check out <file:drivers/scsi/NCR53c406a.c>
@@ -857,14 +859,12 @@
 	default y
 
 config SCSI_LASI700
-	tristate "HP LASI SCSI support for 53c700/710"
-	depends on PARISC && SCSI
+	tristate "HP Lasi SCSI support for 53c700/710"
+	depends on GSC && SCSI
 	help
-	  This is a driver for the lasi baseboard in some parisc machines
-	  which is based on the 53c700 chip.  Will also support LASI subsystems
-	  based on the 710 chip using 700 emulation mode.
-
-	  Unless you know you have a 53c700 or 53c710 based lasi, say N here
+	  This is a driver for the SCSI controller in the Lasi chip found in
+	  many PA-RISC workstations & servers.  If you do not know whether you
+	  have a Lasi chip, it is safe to say "Y" here.
 
 config 53C700_MEM_MAPPED
 	bool
@@ -876,72 +876,15 @@
 	depends on SCSI_LASI700
 	default y
 
-config SCSI_NCR53C7xx
-	tristate "NCR53c7,8xx SCSI support"
-	depends on SCSI && PCI
-	---help---
-	  This is a driver for the 53c7 and 8xx NCR family of SCSI
-	  controllers, not to be confused with the NCR 5380 controllers.  It
-	  is explained in section 3.8 of the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
-	  of the box, you may have to change some settings in
-	  <file:drivers/scsi/53c7,8xx.h>.  Please read
-	  <file:Documentation/scsi/ncr53c7xx.txt> for the available boot time
-	  command line options.
-
-	  Note: there is another driver for the 53c8xx family of controllers
-	  ("NCR53C8XX SCSI support" below).  If you want to use them both, you
-	  need to say M to both and build them as modules, but only one may be
-	  active at a time. If you have a 53c8xx board, it's better to use the
-	  other driver.
-
-	  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.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_NCR53C7xx_sync
-	bool "always negotiate synchronous transfers"
-	depends on SCSI_NCR53C7xx
-	help
-	  In general, this is good; however, it is a bit dangerous since there
-	  are some broken SCSI devices out there. Take your chances. Safe bet
-	  is N.
-
-config SCSI_NCR53C7xx_FAST
-	bool "allow FAST-SCSI [10MHz]"
-	depends on SCSI_NCR53C7xx
-	help
-	  This will enable 10MHz FAST-SCSI transfers with your host
-	  adapter. Some systems have problems with that speed, so it's safest
-	  to say N here.
-
-config SCSI_NCR53C7xx_DISCONNECT
-	bool "allow DISCONNECT"
-	depends on SCSI_NCR53C7xx
-	help
-	  This enables the disconnect/reconnect feature of the NCR SCSI
-	  controller. When you say Y here, a slow SCSI device will not lock
-	  the SCSI bus while processing a request, allowing simultaneous use
-	  of e.g. a SCSI hard disk and SCSI tape or CD-ROM drive, and
-	  providing much better performance when using slow and fast SCSI
-	  devices at the same time. Some devices, however, do not operate
-	  properly with this option enabled, and will cause your SCSI system
-	  to hang, which might cause a system crash. The safe answer
-	  therefore is to say N.
-
 config SCSI_SYM53C8XX_2
 	tristate "SYM53C8XX Version 2 SCSI support"
 	depends on PCI && SCSI
 	---help---
-	  This driver supports the whole NCR53C8XX/SYM53C8XX family of 
-	  PCI-SCSI controllers. It also supports the subset of LSI53C10XX 
-	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS 
-	  language. It does not support LSI53C10XX Ultra-320 PCI-X SCSI 
-	  controllers.
-
-	  If your system has problems using this new major version of the
-	  SYM53C8XX driver, you may switch back to driver version 1.
+	  This driver supports the whole NCR53C8XX/SYM53C8XX family of
+	  PCI-SCSI controllers.  It also supports the subset of LSI53C10XX
+	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS
+	  language.  It does not support LSI53C10XX Ultra-320 PCI-X SCSI
+	  controllers; you need to use the Fusion MPT driver for that.
 
 	  Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
 	  information.
@@ -1216,7 +1159,7 @@
 
 config SCSI_PAS16
 	tristate "PAS16 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for a SCSI host adapter.  It is explained in section
 	  3.10 of the SCSI-HOWTO, available from
@@ -1231,7 +1174,7 @@
 
 config SCSI_PCI2000
 	tristate "PCI2000 support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the PCI2000I EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1244,7 +1187,7 @@
 
 config SCSI_PCI2220I
 	tristate "PCI2220i support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the PCI2220i EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1257,7 +1200,7 @@
 
 config SCSI_PSI240I
 	tristate "PSI240i support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for the PSI240i EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1270,7 +1213,7 @@
 
 config SCSI_QLOGIC_FAS
 	tristate "Qlogic FAS SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the ISA, VLB, and PCMCIA versions of the Qlogic
 	  FastSCSI! cards as well as any other card based on the FASXX chip
@@ -1340,6 +1283,20 @@
 	  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_QLOGICPTI
+	tristate "PTI Qlogic, ISP Driver"
+	depends on SBUS && SCSI
+	help
+	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
+	  controllers are known under Solaris as qpti and in the openprom as
+	  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 ( =
+	  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>.
+
 config SCSI_SEAGATE
 	tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support"
 	depends on X86 && ISA && SCSI
@@ -1355,10 +1312,10 @@
 	  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:
+# definitely looks not 64bit safe:
 config SCSI_SIM710
 	tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
-	depends on (EISA || MCA && !X86_64) && SCSI
+	depends on (EISA || MCA) && SCSI
 	---help---
 	  This driver for NCR53c710 based SCSI host adapters.
 
@@ -1371,7 +1328,7 @@
 
 config SCSI_SYM53C416
 	tristate "Symbios 53c416 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for the sym53c416 SCSI host adapter, the SCSI
 	  adapter that comes with some HP scanners. This driver requires that
@@ -1392,7 +1349,7 @@
 
 config SCSI_DC395x
 	tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PCI && SCSI
+	depends on PCI && SCSI && EXPERIMENTAL
 	---help---
 	  This driver supports PCI SCSI host adapters based on the ASIC
 	  TRM-S1040 chip, e.g Tekram DC395(U/UW/F) and DC315(U) variants.
@@ -1446,7 +1403,7 @@
 
 config SCSI_T128
 	tristate "Trantor T128/T128F/T228 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for a SCSI host adapter. It is explained in section
 	  3.11 of the SCSI-HOWTO, available from
@@ -1463,7 +1420,7 @@
 
 config SCSI_U14_34F
 	tristate "UltraStor 14F/34F support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
 	  The source at <file:drivers/scsi/u14-34f.c> contains some
@@ -1533,7 +1490,7 @@
 
 config SCSI_NSP32
 	tristate "Workbit NinjaSCSI-32Bi/UDE support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus
 	  SCSI host adapter. Please read the SCSI-HOWTO, available from
@@ -1606,7 +1563,7 @@
 
 config JAZZ_ESP
 	bool "MIPS JAZZ FAS216 SCSI support"
-	depends on MIPS_JAZZ
+	depends on MIPS_JAZZ && SCSI
 	help
 	  This is the driver for the onboard SCSI host adapter of MIPS Magnum
 	  4000, Acer PICA, Olivetti M700-10 and a few other identical OEM
@@ -1625,7 +1582,7 @@
 
 config A4000T_SCSI
 	bool "A4000T SCSI support (EXPERIMENTAL)"
-	depends on AMIGA && EXPERIMENTAL
+	depends on AMIGA && SCSI && EXPERIMENTAL
 	help
 	  Support for the NCR53C710 SCSI controller on the Amiga 4000T.
 
@@ -1695,7 +1652,7 @@
 
 config A4091_SCSI
 	bool "A4091 SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller
 	  (1993).  Very obscure -- the 4091 was part of an Amiga 4000 upgrade
@@ -1703,7 +1660,7 @@
 
 config WARPENGINE_SCSI
 	bool "WarpEngine SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  Support for MacroSystem Development's WarpEngine Amiga SCSI-2
 	  controller. Info at
@@ -1711,19 +1668,142 @@
 
 config BLZ603EPLUS_SCSI
 	bool "Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+
 	  accelerator, say Y. Otherwise, say N.
 
 config OKTAGON_SCSI
 	tristate "BSC Oktagon SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL && SCSI
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  If you have the BSC Oktagon SCSI disk controller for the Amiga, say
 	  Y to this question.  If you're in doubt about whether you have one,
 	  see the picture at
 	  <http://amiga.multigraph.com/photos/oktagon.html>.
+
+config ATARI_SCSI
+	tristate "Atari native SCSI support"
+	depends on ATARI && SCSI
+	---help---
+	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
+	  Falcon, ...) say Y to get it supported. Of course also, if you have
+	  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.  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
+	  NOT support other schemes, like in the Hades (without DMA).
+
+config ATARI_SCSI_TOSHIBA_DELAY
+	bool "Long delays for Toshiba CD-ROMs"
+	depends on ATARI_SCSI
+	help
+	  This option increases the delay after a SCSI arbitration to
+	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
+	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
+	  would impact performance a bit, so say N.
+
+config ATARI_SCSI_RESET_BOOT
+	bool "Reset SCSI-devices at boottime"
+	depends on ATARI_SCSI
+	help
+	  Reset the devices on your Atari whenever it boots.  This makes the
+	  boot process fractionally longer but may assist recovery from errors
+	  that leave the devices with SCSI operations partway completed.
+
+config TT_DMA_EMUL
+	bool "Hades SCSI DMA emulator"
+	depends on ATARI_SCSI && HADES
+	help
+	  This option enables code which emulates the TT SCSI DMA chip on the
+	  Hades. This increases the SCSI transfer rates at least ten times
+	  compared to PIO transfers.
+
+config MAC_SCSI
+	bool "Macintosh NCR5380 SCSI"
+	depends on MAC && SCSI
+	help
+	  This is the NCR 5380 SCSI controller included on most of the 68030
+	  based Macintoshes.  If you have one of these say Y and read the
+	  SCSI-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+config SCSI_MAC_ESP
+	tristate "Macintosh NCR53c9[46] SCSI"
+	depends on MAC && SCSI
+	help
+	  This is the NCR 53c9x SCSI controller found on most of the 68040
+	  based Macintoshes.  If you have one of these say Y and read the
+	  SCSI-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  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.  If you want to compile it as
+	  a module, say M here and read <file:Documentation/modules.txt>.
+
+config MVME147_SCSI
+	bool "WD33C93 SCSI driver for MVME147"
+	depends on MVME147 && SCSI
+	help
+	  Support for the on-board SCSI controller on the Motorola MVME147
+	  single-board computer.
+
+config MVME16x_SCSI
+	bool "NCR53C710 SCSI driver for MVME16x"
+	depends on MVME16x && SCSI
+	help
+	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
+	  SCSI controller chip.  Almost everyone using one of these boards
+	  will want to say Y to this question.
+
+config BVME6000_SCSI
+	bool "NCR53C710 SCSI driver for BVME6000"
+	depends on BVME6000 && SCSI
+	help
+	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
+	  SCSI controller chip.  Almost everyone using one of these boards
+	  will want to say Y to this question.
+
+config SCSI_NCR53C7xx_FAST
+	bool "allow FAST-SCSI [10MHz]"
+	depends on A4000T_SCSI || A4091_SCSI || BLZ603EPLUS_SCSI || WARPENGINE_SCSI || MVME16x_SCSI || BVME6000_SCSI
+	help
+	  This will enable 10MHz FAST-SCSI transfers with your host
+	  adapter. Some systems have problems with that speed, so it's safest
+	  to say N here.
+
+config SUN3_SCSI
+	tristate "Sun3 NCR5380 SCSI"
+	depends on SUN3 && SCSI
+	help
+	  This option will enable support for the OBIO (onboard io) NCR5380
+	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
+	  "Sun3" type VME scsi controllers also based on the NCR5380.
+	  General Linux information on the Sun 3 series (now discontinued)
+	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+
+config SUN3X_ESP
+	bool "Sun3x ESP SCSI"
+	depends on SUN3X && SCSI
+	help
+	  The ESP was an on-board SCSI controller used on Sun 3/80
+	  machines.  Say Y here to compile in support for it.
+
+config SCSI_SUNESP
+	tristate "Sparc ESP Scsi Driver"
+	depends on SBUS && SCSI
+	help
+	  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 ( = 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>.
 
 config SCSI_PC980155
 	tristate "NEC PC-9801-55 SCSI support"
diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c	Sat Apr 26 07:28:14 2003
+++ b/drivers/scsi/NCR53c406a.c	Sat Jun 14 08:39:19 2003
@@ -170,7 +170,6 @@
 /* Static function prototypes */
 static void NCR53c406a_intr(int, void *, struct pt_regs *);
 static irqreturn_t do_NCR53c406a_intr(int, void *, struct pt_regs *);
-static void internal_done(Scsi_Cmnd *);
 static void wait_intr(void);
 static void chip_init(void);
 static void calc_port_addr(void);
@@ -205,8 +204,6 @@
 #endif
 
 static Scsi_Cmnd *current_SC;
-static volatile int internal_done_flag;
-static volatile int internal_done_errcode;
 static char info_msg[256];
 
 /* ================================================================= */
@@ -544,10 +541,13 @@
 	} else if (irq_level == 0) {
 		tpnt->can_queue = 0;
 		DEB(printk("NCR53c406a: No interrupts detected\n"));
+		printk("NCR53c406a driver no longer supports polling interface\n");
+		printk("Please email linux-scsi@vger.kernel.org\n");
+                        
 #if USE_DMA
 		printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
-		goto err_free_scsi;
 #endif				/* USE_DMA */
+		goto err_free_scsi;
 	} else {
 		DEB(printk("NCR53c406a: Shouldn't get here!\n"));
 		goto err_free_scsi;
@@ -590,6 +590,21 @@
 	return 0;
 }
 
+static int NCR53c406a_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+#ifdef USE_DMA
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+#endif
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+
+	scsi_unregister(shost);
+	return 0;
+}
+
 /* called from init/main.c */
 static void __init NCR53c406a_setup(char *str, int *ints)
 {
@@ -649,13 +664,6 @@
 	return (info_msg);
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	internal_done_errcode = SCpnt->result;
-	++internal_done_flag;
-}
-
-
 static void wait_intr(void)
 {
 	unsigned long i = jiffies + WATCHDOG;
@@ -709,21 +717,6 @@
 	return 0;
 }
 
-static int NCR53c406a_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("NCR53c406a_command called\n"));
-	NCR53c406a_queue(SCpnt, internal_done);
-	if (irq_level)
-		while (!internal_done_flag)
-			cpu_relax();
-	else			/* interrupts not supported */
-		while (!internal_done_flag)
-			wait_intr();
-
-	internal_done_flag = 0;
-	return internal_done_errcode;
-}
-
 static int NCR53c406a_abort(Scsi_Cmnd * SCpnt)
 {
 	DEB(printk("NCR53c406a_abort called\n"));
@@ -1074,8 +1067,8 @@
      .proc_name         	= "NCR53c406a"		/* proc_name */,        
      .name              	= "NCR53c406a"		/* name */,             
      .detect            	= NCR53c406a_detect	/* detect */,           
+     .release            	= NCR53c406a_release,
      .info              	= NCR53c406a_info		/* info */,             
-     .command           	= NCR53c406a_command	/* command */,          
      .queuecommand      	= NCR53c406a_queue	/* queuecommand */,     
      .eh_abort_handler  	= NCR53c406a_abort	/* abort */,            
      .eh_bus_reset_handler      = NCR53c406a_bus_reset	/* reset */,            
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	Fri May 30 10:45:36 2003
+++ b/drivers/scsi/NCR_D700.c	Tue Jun 17 13:27:44 2003
@@ -197,6 +197,8 @@
 	hostdata->differential = (((1<<siop) & differential) != 0);
 	hostdata->clock = NCR_D700_CLOCK_MHZ;
 
+	NCR_700_set_io_mapped(hostdata);
+
 	/* and register the siop */
 	host = NCR_700_detect(&NCR_D700_driver_template, hostdata);
 	if (!host) {
@@ -223,7 +225,7 @@
 	return 0;
 
  irq_failed:
-	scsi_unregister(host);
+	scsi_host_put(host);
 	NCR_700_release(host);
  detect_failed:
 	release_region(host->base, 64);
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Mon May 12 07:26:11 2003
+++ b/drivers/scsi/aha152x.c	Sun Jun  8 12:18:41 2003
@@ -1515,16 +1515,6 @@
 		up(SCSEM(SCpnt));
 }
 
-static int aha152x_command(Scsi_Cmnd * SCpnt)
-{
-	DECLARE_MUTEX_LOCKED(sem);
-
-	aha152x_internal_queue(SCpnt, &sem, 0, 0, internal_done);
-	down(&sem);
-
-	return SUCCESS;
-}
-
 /*
  *  Abort a command
  *
@@ -3876,7 +3866,6 @@
 	.proc_name		= "aha152x",
 	.proc_info		= aha152x_proc_info,
 	.detect			= aha152x_detect,
-	.command		= aha152x_command,
 	.queuecommand		= aha152x_queue,
 	.eh_abort_handler	= aha152x_abort,
 	.eh_device_reset_handler = aha152x_device_reset,
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Thu May  8 11:24:14 2003
+++ b/drivers/scsi/aha1542.c	Sun Jun  8 12:18:41 2003
@@ -774,23 +774,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int aha1542_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
-
-	aha1542_queuecommand(SCpnt, internal_done);
-
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
 /* Initialize mailboxes */
 static void setup_mailboxes(int bse, struct Scsi_Host *shpnt)
 {
@@ -1325,6 +1308,18 @@
 	return count;
 }
 
+static int aha1542_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static int aha1542_restart(struct Scsi_Host *shost)
 {
 	int i;
@@ -1817,7 +1812,7 @@
 	.proc_name		= "aha1542",
 	.name			= "Adaptec 1542",
 	.detect			= aha1542_detect,
-	.command		= aha1542_command,
+	.release		= aha1542_release,
 	.queuecommand		= aha1542_queuecommand,
 	.eh_abort_handler	= aha1542_abort,
 	.eh_device_reset_handler= aha1542_dev_reset,
diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
--- a/drivers/scsi/aha1740.c	Mon May 12 07:26:11 2003
+++ b/drivers/scsi/aha1740.c	Tue Jun 17 15:36:55 2003
@@ -102,6 +102,7 @@
     if (len > length)
 	len = length;
     return len;
+}
 
 
 static int aha1740_makecode(unchar *sense, unchar *status)
@@ -476,23 +477,6 @@
     return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-    SCpnt->SCp.Status++;
-}
-
-static int aha1740_command(Scsi_Cmnd * SCpnt)
-{
-    aha1740_queuecommand(SCpnt, internal_done);
-    SCpnt->SCp.Status = 0;
-    while (!SCpnt->SCp.Status)
-    {
-	cpu_relax();
-	barrier();
-    }
-    return SCpnt->result;
-}
-
 /* Query the board for its irq_level.  Nothing else matters
    in enhanced mode on an EISA bus. */
 
@@ -567,6 +551,16 @@
     return count;
 }
 
+static int aha1740_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static int aha1740_biosparam(struct scsi_device *sdev, struct block_device *dev,
 		sector_t capacity, int* ip)
 {
@@ -596,7 +590,7 @@
 	.proc_info		= aha1740_proc_info,
 	.name			= "Adaptec 174x (EISA)",
 	.detect			= aha1740_detect,
-	.command		= aha1740_command,
+	.release		= aha1740_release,
 	.queuecommand		= aha1740_queuecommand,
 	.bios_param		= aha1740_biosparam,
 	.can_queue		= AHA1740_ECBS,
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Fri May 23 10:58:23 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Mon Jun  2 17:42:21 2003
@@ -2098,7 +2098,7 @@
 	u_long	target;
 
 	template->name = ahd->description;
-	host = scsi_register(template, sizeof(struct ahd_softc *));
+	host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
 	if (host == NULL)
 		return (ENOMEM);
 
@@ -2308,7 +2308,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 			scsi_remove_host(ahd->platform_data->host);
 #endif
-			scsi_unregister(ahd->platform_data->host);
+			scsi_host_put(ahd->platform_data->host);
 		}
 
 		/* destroy all of the device and target objects */
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Fri May 23 12:29:22 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Mon Jun  2 17:42:21 2003
@@ -1725,7 +1725,7 @@
 	u_int	 targ_offset;
 
 	template->name = ahc->description;
-	host = scsi_register(template, sizeof(struct ahc_softc *));
+	host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
 	if (host == NULL)
 		return (ENOMEM);
 
@@ -1978,7 +1978,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 			scsi_remove_host(ahc->platform_data->host);
 #endif
-			scsi_unregister(ahc->platform_data->host);
+			scsi_host_put(ahc->platform_data->host);
 		}
 
 		/* destroy all of the device and target objects */
diff -Nru a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
--- a/drivers/scsi/amiga7xx.c	Sun Feb  9 07:21:12 2003
+++ b/drivers/scsi/amiga7xx.c	Mon Jun  2 17:27:44 2003
@@ -134,9 +134,22 @@
     return num;
 }
 
+static int amiga7xx_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "Amiga NCR53c710 SCSI",
 	.detect			= amiga7xx_detect,
+	.release		= amiga7xx_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
--- a/drivers/scsi/arm/acornscsi.c	Mon May 19 19:40:43 2003
+++ b/drivers/scsi/arm/acornscsi.c	Mon Jun  2 17:42:21 2003
@@ -2993,7 +2993,7 @@
 	AS_Host *ashost;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&acornscsi_template, sizeof(AS_Host));
+	host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
 	if (!host)
 		goto out;
 
@@ -3060,7 +3060,7 @@
  err_2:
 	release_region(host->io_port + 0x800, 2);
  err_1:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -3089,6 +3089,7 @@
 	msgqueue_free(&ashost->scsi.msgs);
 	queue_free(&ashost->queues.disconnected);
 	queue_free(&ashost->queues.issue);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id acornscsi_cids[] = {
diff -Nru a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
--- a/drivers/scsi/arm/arxescsi.c	Mon May 19 19:40:44 2003
+++ b/drivers/scsi/arm/arxescsi.c	Sun Jun  8 12:18:41 2003
@@ -264,7 +264,6 @@
 	.proc_info			= arxescsi_proc_info,
 	.name				= "ARXE SCSI card",
 	.info				= arxescsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
--- a/drivers/scsi/arm/cumana_1.c	Mon May 19 19:40:44 2003
+++ b/drivers/scsi/arm/cumana_1.c	Mon Jun  2 17:42:21 2003
@@ -262,7 +262,7 @@
 	struct Scsi_Host *host;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		goto out;
 
@@ -304,7 +304,7 @@
  out_release:
 	release_region(host->io_port, host->n_io_port);
  out_free:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -318,7 +318,7 @@
 	scsi_remove_host(host);
 	free_irq(host->irq, host);
 	release_region(host->io_port, host->n_io_port);
-	scsi_unregister(host);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id cumanascsi1_cids[] = {
diff -Nru a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
--- a/drivers/scsi/arm/cumana_2.c	Mon May 19 19:40:45 2003
+++ b/drivers/scsi/arm/cumana_2.c	Sun Jun  8 12:18:41 2003
@@ -386,7 +386,6 @@
 	.proc_info			= cumanascsi_2_proc_info,
 	.name				= "Cumana SCSI II",
 	.info				= cumanascsi_2_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
--- a/drivers/scsi/arm/ecoscsi.c	Tue May 27 07:52:55 2003
+++ b/drivers/scsi/arm/ecoscsi.c	Mon Jun  2 17:42:21 2003
@@ -177,7 +177,7 @@
 static int __init ecoscsi_init(void)
 {
 
-	host = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		return 0;
 
@@ -211,7 +211,7 @@
 release_reg:
 	release_region(host->io_port, host->n_io_port);
 unregister_scsi:
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return -ENODEV;
 }
 
@@ -224,7 +224,7 @@
 	if (shpnt->io_port)
 		release_region(shpnt->io_port, shpnt->n_io_port);
 
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return 0;
 }
 
diff -Nru a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
--- a/drivers/scsi/arm/eesox.c	Mon May 19 19:40:46 2003
+++ b/drivers/scsi/arm/eesox.c	Sun Jun  8 12:18:41 2003
@@ -492,7 +492,6 @@
 	.proc_info			= eesoxscsi_proc_info,
 	.name				= "EESOX SCSI",
 	.info				= eesoxscsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
--- a/drivers/scsi/arm/fas216.c	Sat May 17 06:52:33 2003
+++ b/drivers/scsi/arm/fas216.c	Sun Jun  8 12:18:41 2003
@@ -225,8 +225,7 @@
 	printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
 		info->dma.transfer_type, info->dma.setup,
 		info->dma.pseudo, info->dma.stop);
-	printk("    internal_done=%X magic_end=%lX }\n",
-		info->internal_done, info->magic_end);
+	printk("    magic_end=%lX }\n", info->magic_end);
 }
 
 #ifdef CHECK_STRUCTURE
@@ -2253,74 +2252,6 @@
 	return result;
 }
 
-/**
- * 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)
-{
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
-
-	fas216_checkmagic(info);
-
-	info->internal_done = 1;
-}
-
-/**
- * fas216_command - queue 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.
- */
-int fas216_command(Scsi_Cmnd *SCpnt)
-{
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
-
-	fas216_checkmagic(info);
-
-	/*
-	 * We should only be using this if we don't have an interrupt.
-	 * Provide some "incentive" to use the queueing code.
-	 */
-	if (info->scsi.irq != NO_IRQ)
-		BUG();
-
-	info->internal_done = 0;
-	fas216_queue_command(SCpnt, fas216_internal_done);
-
-	/*
-	 * This wastes time, since we can't return until the command is
-	 * complete. We can't sleep either since we may get re-entered!
-	 * However, we must re-enable interrupts, or else we'll be
-	 * waiting forever.
-	 */
-	spin_unlock_irq(info->host->host_lock);
-
-	while (!info->internal_done) {
-		/*
-		 * If we don't have an IRQ, then we must poll the card for
-		 * it's interrupt, and use that to call this driver's
-		 * interrupt routine.  That way, we keep the command
-		 * progressing.  Maybe we can add some inteligence here
-		 * and go to sleep if we know that the device is going
-		 * to be some time (eg, disconnected).
-		 */
-		if (fas216_readb(info, REG_STAT) & STAT_INT) {
-			spin_lock_irq(info->host->host_lock);
-			fas216_intr(info);
-			spin_unlock_irq(info->host->host_lock);
-		}
-	}
-
-	spin_lock_irq(info->host->host_lock);
-
-	return SCpnt->result;
-}
-
 /*
  * Error handler timeout function.  Indicate that we timed out,
  * and wake up any error handler process so it can continue.
@@ -2942,6 +2873,7 @@
 	scsi_remove_host(host);
 
 	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	scsi_host_put(host);
 }
 
 /**
diff -Nru a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
--- a/drivers/scsi/arm/fas216.h	Thu May 15 17:33:17 2003
+++ b/drivers/scsi/arm/fas216.h	Sun Jun  8 12:18:41 2003
@@ -310,8 +310,6 @@
 	} dma;
 
 	/* miscellaneous */
-	int			internal_done;		/* flag to indicate request done */
-
 	unsigned long		magic_end;
 } FAS216_Info;
 
@@ -336,13 +334,6 @@
  * Returns : 0 - success, else error
  */
 extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-/* Function: int fas216_command (Scsi_Cmnd *SCpnt)
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- * Returns : scsi result code
- */
-extern int fas216_command (Scsi_Cmnd *);
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
diff -Nru a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
--- a/drivers/scsi/arm/oak.c	Mon May 19 19:40:46 2003
+++ b/drivers/scsi/arm/oak.c	Mon Jun  2 17:42:21 2003
@@ -135,7 +135,7 @@
 	struct Scsi_Host *host;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&oakscsi_template, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		goto out;
 
@@ -163,7 +163,7 @@
 
 	release_region(host->io_port, host->n_io_port);
  unreg:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -176,7 +176,7 @@
 	scsi_remove_host(host);
 
 	release_region(host->io_port, host->n_io_port);
-	scsi_unregister(host);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id oakscsi_cids[] = {
diff -Nru a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
--- a/drivers/scsi/arm/powertec.c	Mon May 19 19:40:47 2003
+++ b/drivers/scsi/arm/powertec.c	Sun Jun  8 12:18:41 2003
@@ -296,7 +296,6 @@
 	.proc_info			= powertecscsi_proc_info,
 	.name				= "PowerTec SCSI",
 	.info				= powertecscsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Mon Jun  9 16:02:25 2003
+++ b/drivers/scsi/atp870u.c	Wed Jun 11 20:06:30 2003
@@ -829,25 +829,6 @@
 
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int atp870u_command(Scsi_Cmnd * SCpnt)
-{
-
-	atp870u_queuecommand(SCpnt, internal_done);
-
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-	{
-		cpu_relax();
-		barrier();
-	}
-	return SCpnt->result;
-}
-
 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
 {
 	unsigned int tmport;
@@ -2728,7 +2709,6 @@
 	.detect			= atp870u_detect,
 	.release		= atp870u_release,
 	.info			= atp870u_info,
-	.command		= atp870u_command,
 	.queuecommand		= atp870u_queuecommand,
 	.eh_abort_handler	= atp870u_abort,
 	.bios_param		= atp870u_biosparam,
diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
--- a/drivers/scsi/atp870u.h	Mon May 12 07:26:11 2003
+++ b/drivers/scsi/atp870u.h	Sun Jun  8 12:18:41 2003
@@ -18,7 +18,6 @@
 #define MAX_SENSE 14
 
 static int atp870u_detect(Scsi_Host_Template *);
-static int atp870u_command(Scsi_Cmnd *);
 static int atp870u_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 static int atp870u_abort(Scsi_Cmnd *);
 static int atp870u_biosparam(struct scsi_device *, struct block_device *,
diff -Nru a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
--- a/drivers/scsi/blz1230.c	Wed Feb  5 09:05:18 2003
+++ b/drivers/scsi/blz1230.c	Sun Jun  8 12:18:41 2003
@@ -334,7 +334,6 @@
 	.name			= "Blizzard1230 SCSI IV",
 	.detect			= blz1230_esp_detect,
 	.release		= blz1230_esp_release,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
--- a/drivers/scsi/bvme6000.c	Wed Nov 20 03:36:29 2002
+++ b/drivers/scsi/bvme6000.c	Mon Jun  2 17:27:44 2003
@@ -51,9 +51,22 @@
     return 1;
 }
 
+static int mvme6000_scsi_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "BVME6000 NCR53c710 SCSI",
 	.detect			= bvme6000_scsi_detect,
+	.release		= bvme6000_scsi_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Fri Jan  3 10:58:49 2003
+++ b/drivers/scsi/constants.c	Sun Jun  1 14:27:22 2003
@@ -1004,16 +1004,14 @@
 #endif
 }
 
-void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
+void print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
-	print_sense_internal(devclass, SCpnt->sense_buffer,
-			     SCpnt->request);
+	print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
 }
 
-void print_req_sense(const char * devclass, Scsi_Request * SRpnt)
+void print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
-	print_sense_internal(devclass, SRpnt->sr_sense_buffer,
-			     SRpnt->sr_request);
+	print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
 }
 
 #if (CONSTANTS & CONST_MSG) 
@@ -1116,13 +1114,13 @@
     return len;
 }
 
-void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
+void print_Scsi_Cmnd(struct scsi_cmnd *cmd) {
     printk("scsi%d : destination target %d, lun %d\n", 
 	   cmd->device->host->host_no, 
 	   cmd->device->id, 
 	   cmd->device->lun);
     printk("        command = ");
-    print_command (cmd->cmnd);
+    print_command(cmd->cmnd);
 }
 
 #if (CONSTANTS & CONST_HOST)
diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c	Wed May 28 03:05:43 2003
+++ b/drivers/scsi/dc395x.c	Fri Jun  6 04:28:47 2003
@@ -5726,9 +5726,9 @@
 	/*
 	 *$$$$$$$$$$$  MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK $$$$$$$$$$$$
 	 */
-	host = scsi_register(host_template, sizeof(struct AdapterCtlBlk));
+	host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk));
 	if (!host) {
-		dprintkl(KERN_INFO, "pSH scsi_register ERROR\n");
+		dprintkl(KERN_INFO, "pSH scsi_host_alloc ERROR\n");
 		return 0;
 	}
 	DC395x_print_eeprom_settings(index);
@@ -5736,7 +5736,7 @@
 	pACB = (struct AdapterCtlBlk *) host->hostdata;
 
 	if (DC395x_initACB(host, io_port, irq, index)) {
-		scsi_unregister(host);
+		scsi_host_put(host);
 		return 0;
 	}
 	DC395x_print_config(pACB);
@@ -5755,7 +5755,7 @@
 
 	} else {
 		dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
-		scsi_unregister(host);
+		scsi_host_put(host);
 		host = NULL;
 	}
 	return host;
diff -Nru a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
--- a/drivers/scsi/dec_esp.c	Sun Dec 22 02:33:54 2002
+++ b/drivers/scsi/dec_esp.c	Sun Jun  8 12:18:41 2003
@@ -109,13 +109,23 @@
 
 int dec_esp_detect(Scsi_Host_Template * tpnt);
 
+static int dec_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.proc_name		= "esp",
 	.proc_info		= &esp_proc_info,
 	.name			= "NCR53C94",
 	.detect			= dec_esp_detect,
+	.release		= dec_esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Sat Jun 14 16:16:14 2003
+++ b/drivers/scsi/dpt_i2o.c	Mon Jun 16 17:22:17 2003
@@ -1949,26 +1949,6 @@
 	case I2ORESCANCMD:
 		adpt_rescan(pHba);
 		break;
-	case DPT_TARGET_BUSY & 0xFFFF:
-	case DPT_TARGET_BUSY:
-	{
-		TARGET_BUSY_T busy;
-		struct adpt_device* d;
-
-		if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
-			return -EFAULT;
-		}
-
-		d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
-		if(d == NULL){
-			return -ENODEV;
-		}
-		busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
-		if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
-			return -EFAULT;
-		}
-		break;
-	}
 	default:
 		return -EINVAL;
 	}
@@ -2492,10 +2472,6 @@
 			printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
 			if (pDev->pScsi_dev) {
 				pDev->pScsi_dev->online = FALSE;
-				if (pDev->pScsi_dev->access_count) {
-					// A drive that was mounted is no longer there... bad!
-					printk(KERN_WARNING"%s:Mounted drive taken offline\n",pHba->name);
-				}
 			}
 		}
 	}
diff -Nru a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
--- a/drivers/scsi/dtc.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/dtc.c	Mon Jun  2 17:27:45 2003
@@ -447,9 +447,20 @@
 
 #include "NCR5380.c"
 
+static int dtc_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name				= "DTC 3180/3280 ",
 	.detect				= dtc_detect,
+	.release			= dtc_release,
 	.queuecommand			= dtc_queue_command,
 	.eh_abort_handler		= dtc_abort,
 	.eh_bus_reset_handler		= dtc_bus_reset,
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Mon Jun  9 16:03:59 2003
+++ b/drivers/scsi/eata.c	Tue Jun  3 10:54:22 2003
@@ -1,6 +1,36 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      03 Jun 2003 Rev. 8.10 for linux-2.5.70
+ *        + Update for new IRQ API.
+ *        + Use "goto" when appropriate.
+ *        + Drop eata.h.
+ *        + Update for new module_param API.
+ *        + Module parameters  can now be specified only in the
+ *          same format as the kernel boot options.
+ *
+ *             boot option    old module param 
+ *             -----------    ------------------
+ *             addr,...       io_port=addr,...
+ *             lc:[y|n]       linked_comm=[1|0]
+ *             mq:xx          max_queue_depth=xx
+ *             tm:[0|1|2]     tag_mode=[0|1|2]
+ *             et:[y|n]       ext_tran=[1|0]
+ *             rs:[y|n]       rev_scan=[1|0]
+ *             ip:[y|n]       isa_probe=[1|0]
+ *             ep:[y|n]       eisa_probe=[1|0]
+ *             pp:[y|n]       pci_probe=[1|0]
+ *
+ *          A valid example using the new parameter format is:
+ *          modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n"
+ *
+ *          which is equivalent to the old format:
+ *          modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \
+ *                        max_queue_depth=4 eisa_probe=0
+ *
+ *      12 Feb 2003 Rev. 8.04 for linux 2.5.60
+ *        + Release irq before calling scsi_register.
+ *
  *      12 Nov 2002 Rev. 8.02 for linux 2.5.47
  *        + Release driver_lock before calling scsi_register.
  *
@@ -279,7 +309,7 @@
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -447,31 +477,8 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
-#include <linux/version.h>
-
-#define MAX_INT_PARAM 10
-
-#if defined(MODULE)
-#include <linux/module.h>
-
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
-MODULE_PARM(linked_comm, "i");
-MODULE_PARM(link_statistics, "i");
-MODULE_PARM(max_queue_depth, "i");
-MODULE_PARM(tag_mode, "i");
-MODULE_PARM(ext_tran, "i");
-MODULE_PARM(rev_scan, "i");
-MODULE_PARM(isa_probe, "i");
-MODULE_PARM(eisa_probe, "i");
-MODULE_PARM(pci_probe, "i");
-MODULE_AUTHOR("Dario Ballabio");
-
-#endif
-
 #include <linux/config.h>
 #include <linux/string.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -491,8 +498,31 @@
 #include "hosts.h"
 #include <asm/dma.h>
 #include <asm/irq.h>
-#include "eata.h"
 
+static int eata2x_detect(Scsi_Host_Template *);
+static int eata2x_release(struct Scsi_Host *);
+static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int eata2x_eh_abort(Scsi_Cmnd *);
+static int eata2x_eh_host_reset(Scsi_Cmnd *);
+static int eata2x_bios_param(struct scsi_device *, struct block_device *,
+                             sector_t, int *);
+static int eata2x_slave_configure(Scsi_Device *);
+
+static Scsi_Host_Template driver_template = {
+                .name                    = "EATA/DMA 2.0x rev. 8.10.00 ",
+                .detect                  = eata2x_detect,
+                .release                 = eata2x_release,
+                .queuecommand            = eata2x_queuecommand,
+                .eh_abort_handler        = eata2x_eh_abort,
+                .eh_device_reset_handler = NULL,
+                .eh_bus_reset_handler    = NULL,
+                .eh_host_reset_handler   = eata2x_eh_host_reset,
+                .bios_param              = eata2x_bios_param,
+                .slave_configure         = eata2x_slave_configure,
+                .this_id                 = 7,
+                .unchecked_isa_dma       = 1,
+                .use_clustering          = ENABLE_CLUSTERING
+                };
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
 #endif
@@ -818,7 +848,6 @@
 static int link_statistics;
 static int ext_tran = FALSE;
 static int rev_scan = TRUE;
-static char *boot_options;
 
 #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
 static int tag_mode = TAG_SIMPLE;
@@ -856,6 +885,23 @@
 static int pci_probe = FALSE;
 #endif
 
+#define MAX_INT_PARAM 10
+#define MAX_BOOT_OPTIONS_SIZE 256
+static char boot_options[MAX_BOOT_OPTIONS_SIZE];
+
+#if defined(MODULE)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
+MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." \
+"            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
+MODULE_AUTHOR("Dario Ballabio");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
+
+#endif
+
 static int eata2x_slave_configure(Scsi_Device *dev) {
    int j, tqd, utqd;
    char *tag_suffix, *link_suffix;
@@ -1011,19 +1057,20 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(!request_region(port_base, REGION_SIZE, driver_name)) {
+   if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
-      return FALSE;
+      goto fail;
       }
 
+   spin_lock_irq(&driver_lock);
+
    if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
 #if defined(DEBUG_DETECT)
       printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    /* Read the info structure */
@@ -1031,8 +1078,7 @@
 #if defined(DEBUG_DETECT)
       printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    info.data_len = DEV2H(info.data_len);
@@ -1048,15 +1094,13 @@
 #if defined(DEBUG_DETECT)
       printk("%s: signature 0x%04x discarded.\n", name, info.sign);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (info.data_len < EATA_2_0A_SIZE) {
       printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, info.data_len);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
    else if (info.data_len == EATA_2_0A_SIZE)
       protocol_rev = 'A';
@@ -1097,8 +1141,7 @@
    if (!info.haaval || info.ata) {
       printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
              name, port_base, bus_type, info.haaval, info.ata);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (info.drqvld) {
@@ -1145,16 +1188,13 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
-      free_irq(irq, &sha[j]);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freeirq;
       }
 
 #if defined(FORCE_CONFIG)
@@ -1166,8 +1206,7 @@
 
    if (!cf) {
       printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    /* Set board configuration */
@@ -1178,8 +1217,7 @@
    if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
       printk("%s: busy timeout sending configuration, detaching.\n", name);
       pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    }
@@ -1191,13 +1229,7 @@
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
-
-      free_irq(irq, &sha[j]);
-
-      if (subversion == ISA) free_dma(dma_channel);
-
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    sh[j]->io_port = port_base;
@@ -1268,6 +1300,8 @@
    if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
    else                       sprintf(dma_name, "DMA %u", dma_channel);
 
+   spin_unlock_irq(&driver_lock);
+
    for (i = 0; i < sh[j]->can_queue; i++)
       HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
             &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
@@ -1277,15 +1311,13 @@
             sh[j]->sg_tablesize * sizeof(struct sg_list),
             (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
          printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         eata2x_release(sh[j]);
-         return FALSE;
+         goto release;
          }
 
    if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
          sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
       printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
-      eata2x_release(sh[j]);
-      return FALSE;
+      goto release;
       }
 
    if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
@@ -1297,7 +1329,7 @@
       tag_mode = TAG_ORDERED;
 
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2002 Dario Ballabio.\n");
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
       printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\
              "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
              YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
@@ -1342,6 +1374,20 @@
       }
 
    return TRUE;
+
+freedma:
+   if (subversion == ISA) free_dma(dma_channel);
+freeirq:
+   free_irq(irq, &sha[j]);
+freelock:
+   spin_unlock_irq(&driver_lock);
+   release_region(port_base, REGION_SIZE);
+fail:
+   return FALSE;
+
+release:
+   eata2x_release(sh[j]);
+   return FALSE;
 }
 
 static void internal_setup(char *str, int *ints) {
@@ -1440,11 +1486,9 @@
 static int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
 
-   spin_lock_irq(&driver_lock);
-
    tpnt->proc_name = "eata2x";
 
-   if(boot_options) option_setup(boot_options);
+   if(strlen(boot_options)) option_setup(boot_options);
 
 #if defined(MODULE)
    /* io_port could have been modified when loading as a module */
@@ -1478,7 +1522,6 @@
       }
 
    num_boards = j;
-   spin_unlock_irq(&driver_lock);
    return j;
 }
 
@@ -2091,7 +2134,7 @@
 
 }
 
-static void ihdlr(int irq, unsigned int j) {
+static irqreturn_t ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg;
    struct mssp *spp;
@@ -2101,7 +2144,7 @@
        panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
 
    /* Check if this board need to be serviced */
-   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) return;
+   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) goto none;
 
    HD(j)->iocount++;
 
@@ -2113,7 +2156,7 @@
       reg = inb(sh[j]->io_port + REG_STATUS);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
-      return;
+      goto none;
       }
 
    spp  = &HD(j)->sp;
@@ -2148,7 +2191,7 @@
       printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
              BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
    if (spp->eoc == FALSE || spp->cpp_index < 0
-                         || spp->cpp_index >= sh[j]->can_queue) return;
+                         || spp->cpp_index >= sh[j]->can_queue) goto handled;
 
    /* Find the mailbox to be serviced on this board */
    i = spp->cpp_index;
@@ -2156,23 +2199,23 @@
    cpp = &(HD(j)->cp[i]);
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
+   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
 #endif
 
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == LOCKED) {
       HD(j)->cp_stat[i] = FREE;
       printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == FREE) {
       printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == IN_RESET)
       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
@@ -2319,22 +2362,25 @@
    if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
                         HD(j)->iocount);
 
-   return;
+handled:
+   return IRQ_HANDLED;
+none:
+   return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-					struct pt_regs *regs) {
+                                        struct pt_regs *regs) {
    unsigned int j;
    unsigned long spin_flags;
+   irqreturn_t ret;
 
    /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
-	return IRQ_NONE;
+   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
 
    spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ihdlr(irq, j);
+   ret = ihdlr(irq, j);
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return IRQ_HANDLED;
+   return ret;
 }
 
 static int eata2x_release(struct Scsi_Host *shpnt) {
@@ -2365,22 +2411,8 @@
    return FALSE;
 }
 
-static Scsi_Host_Template driver_template = {
-	.name              	= "EATA/DMA 2.0x rev. " EATA_VERSION " ",
-	.detect                  = eata2x_detect,
-	.release                 = eata2x_release,
-	.queuecommand            = eata2x_queuecommand,
-	.eh_abort_handler        = eata2x_eh_abort,
-	.eh_host_reset_handler   = eata2x_eh_host_reset,
-	.bios_param              = eata2x_bios_param,
-	.slave_configure	 = eata2x_slave_configure,
-	.this_id                 = 7,
-	.unchecked_isa_dma       = 1,
-	.use_clustering          = ENABLE_CLUSTERING,
-};
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("eata=", option_setup);
 #endif /* end MODULE */
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/eata.h b/drivers/scsi/eata.h
--- a/drivers/scsi/eata.h	Sun May  4 02:56:43 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,15 +0,0 @@
-/*
- *        eata.h - used by the low-level driver for EATA/DMA SCSI host adapters.
- */
-
-static int eata2x_detect(Scsi_Host_Template *);
-static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int eata2x_eh_abort(Scsi_Cmnd *);
-static int eata2x_eh_host_reset(Scsi_Cmnd *);
-static int eata2x_bios_param(struct scsi_device *, struct block_device *,
-                             sector_t, int *);
-static int eata2x_slave_configure(Scsi_Device *);
-
-#define EATA_VERSION "8.03.00"
-
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Mon May 26 18:54:35 2003
+++ b/drivers/scsi/esp.c	Sun Jun  8 12:18:41 2003
@@ -1237,6 +1237,17 @@
         return 0;
 }
 
+/* this is clearly wrong for esp.. */
+static int esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /* The info function will return whatever useful
  * information the developer sees fit.  If not provided, then
  * the name field will be used instead.
@@ -1871,15 +1882,6 @@
 	return 0;
 }
 
-/* Only queuing supported in this ESP driver. */
-static int esp_command(Scsi_Cmnd *SCpnt)
-{
-	struct esp *esp = (struct esp *) SCpnt->device->host->hostdata;
-
-	ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id));
-	return -1;
-}
-
 /* Dump driver state. */
 static void esp_dump_cmd(Scsi_Cmnd *SCptr)
 {
@@ -4384,17 +4386,16 @@
 	SDptr->hostdata = NULL;
 }
 
-
 static Scsi_Host_Template driver_template = {
 	.proc_name		= "esp",
 	.proc_info		= esp_proc_info,
 	.name			= "Sun ESP 100/100a/200",
 	.detect			= esp_detect,
+	.release		= esp_release,
 	.slave_alloc		= esp_slave_alloc,
 	.slave_destroy		= esp_slave_destroy,
 	.release		= esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Mon May 12 07:26:12 2003
+++ b/drivers/scsi/fd_mcs.c	Sun Jun  8 12:18:41 2003
@@ -1186,24 +1186,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	/* flag it done */
-	SCpnt->host_scribble = (unsigned char *) 1;
-}
-
-int fd_mcs_command(Scsi_Cmnd * SCpnt)
-{
-	fd_mcs_queue(SCpnt, internal_done);
-	/* host_scribble is used for status here */
-	SCpnt->host_scribble = NULL;
-	while (!SCpnt->host_scribble) {
-		cpu_relax();
-		barrier();
-	}
-	return SCpnt->result;
-}
-
 #if DEBUG_ABORT || DEBUG_RESET
 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
 {
@@ -1431,7 +1413,6 @@
 	.detect				= fd_mcs_detect,
 	.release			= fd_mcs_release,
 	.info				= fd_mcs_info,
-	.command			= fd_mcs_command,
 	.queuecommand   		= fd_mcs_queue, 
 	.eh_abort_handler		= fd_mcs_abort,
 	.eh_bus_reset_handler		= fd_mcs_bus_reset,
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Mon May 12 07:26:12 2003
+++ b/drivers/scsi/fdomain.c	Sun Jun  8 12:18:41 2003
@@ -255,11 +255,6 @@
  be increased by changing this value to values which are close to 2.
  Please let me know if you try any different values.
 
- DO_DETECT: This activates some old scan code which was needed before the
- high level drivers got fixed.  If you are having trouble with the driver,
- turning this on should not hurt, and might help.  Please let me know if
- this is the case, since this code will be removed from future drivers.
-
  RESELECTION: This is no longer an option, since I gave up trying to
  implement it in version 4.x of this driver.  It did not improve
  performance at all and made the driver unstable (because I never found one
@@ -303,7 +298,6 @@
 #define DEBUG            0	/* Enable debugging output */
 #define ENABLE_PARITY    1	/* Enable SCSI Parity */
 #define FIFO_COUNT       2	/* Number of 512 byte blocks before INTR */
-#define DO_DETECT        0	/* Do device detection here (see scsi.c) */
 
 /* END OF USER DEFINABLE OPTIONS */
 
@@ -863,17 +857,6 @@
    int              retcode;
    struct Scsi_Host *shpnt;
    struct pci_dev *pdev = NULL;
-#if DO_DETECT
-   int i = 0;
-   int j = 0;
-   const int        buflen = 255;
-   Scsi_Cmnd        SCinit;
-   unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
-   unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
-   unsigned char    do_read_capacity[] = { READ_CAPACITY,
-					   0, 0, 0, 0, 0, 0, 0, 0, 0 };
-   unsigned char    buf[buflen];
-#endif
 
    if (setup_called) {
 #if DEBUG_DETECT
@@ -984,59 +967,6 @@
    /* Log I/O ports with kernel */
    request_region( port_base, 0x10, "fdomain" );
 
-#if DO_DETECT
-
-   /* These routines are here because of the way the SCSI bus behaves after
-      a reset.  This appropriate behavior was not handled correctly by the
-      higher level SCSI routines when I first wrote this driver.  Now,
-      however, correct scan routines are part of scsi.c and these routines
-      are no longer needed.  However, this code is still good for
-      debugging.  */
-
-   SCinit.request_buffer  = SCinit.buffer = buf;
-   SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
-   SCinit.use_sg          = 0;
-   SCinit.lun             = 0;
-
-   printk( "scsi: <fdomain> detection routine scanning for devices:\n" );
-   for (i = 0; i < 8; i++) {
-      SCinit.target = i;
-      if (i == tpnt->this_id)	/* Skip host adapter */
-	    continue;
-      memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-      retcode = fdomain_16x0_command(&SCinit);
-      if (!retcode) {
-	 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
-	 retcode = fdomain_16x0_command(&SCinit);
-	 if (!retcode) {
-	    printk( "     SCSI ID %d: ", i );
-	    for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
-		  printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
-	    memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
-	    retcode = fdomain_16x0_command(&SCinit);
-	    if (!retcode) {
-	       unsigned long blocks, size, capacity;
-	       
-	       blocks = (buf[0] << 24) | (buf[1] << 16)
-		     | (buf[2] << 8) | buf[3];
-	       size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
-	       capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
-	       
-	       printk( "%lu MB (%lu byte blocks)",
-		       ((capacity + 5L) / 10L), size );
-	    } else {
-	       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-	       retcode = fdomain_16x0_command(&SCinit);
-	    }
-	    printk ("\n" );
-	 } else {
-	    memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-	    retcode = fdomain_16x0_command(&SCinit);
-	 }
-      }
-   }
-#endif
-
    return shpnt;
 }
 
@@ -1508,31 +1438,6 @@
    return 0;
 }
 
-/* The following code, which simulates the old-style command function, was
-   taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
-   1992 Tommy Thorn. */
-
-static volatile int internal_done_flag    = 0;
-static volatile int internal_done_errcode = 0;
-
-static void internal_done(Scsi_Cmnd *SCpnt)
-{
-    internal_done_errcode = SCpnt->result;
-    ++internal_done_flag;
-}
-
-static int fdomain_16x0_command(Scsi_Cmnd *SCpnt)
-{
-    fdomain_16x0_queue(SCpnt, internal_done);
-
-    while (!internal_done_flag)
-	  cpu_relax();
-    internal_done_flag = 0;
-    return internal_done_errcode;
-}
-
-/* End of code derived from Tommy Thorn's work. */
-
 #if DEBUG_ABORT
 static void print_info(Scsi_Cmnd *SCpnt)
 {
@@ -1833,7 +1738,6 @@
 	.proc_name		= "fdomain",
 	.detect			= fdomain_16x0_detect,
 	.info			= fdomain_16x0_info,
-	.command		= fdomain_16x0_command,
 	.queuecommand		= fdomain_16x0_queue,
 	.eh_abort_handler	= fdomain_16x0_abort,
 	.eh_bus_reset_handler	= fdomain_16x0_bus_reset,
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Mon May 26 09:10:33 2003
+++ b/drivers/scsi/hosts.c	Thu Jun  5 11:52:51 2003
@@ -20,25 +20,15 @@
  *  September 04, 2002 Mike Anderson (andmike@us.ibm.com)
  */
 
-
-/*
- *  This file contains the medium level SCSI
- *  host interface initialization, as well as the scsi_hosts list of SCSI
- *  hosts currently present in the system.
- */
-
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/completion.h>
 #include <linux/unistd.h>
-#include <asm/dma.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -47,152 +37,7 @@
 #include "scsi_logging.h"
 
 
-static LIST_HEAD(scsi_host_list);
-static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
-
 static int scsi_host_next_hn;		/* host_no for next new host */
-static char *scsihosts;
-
-MODULE_PARM(scsihosts, "s");
-MODULE_PARM_DESC(scsihosts, "scsihosts=driver1,driver2,driver3");
-#ifndef MODULE
-int __init scsi_setup(char *str)
-{
-	scsihosts = str;
-	return 1;
-}
-
-__setup("scsihosts=", scsi_setup);
-#endif
-
-/**
-  * scsi_find_host_by_num - get a Scsi_Host by host no
-  *
-  * @host_no:	host number to locate
-  *
-  * Return value:
-  *	A pointer to located Scsi_Host or NULL.
-  **/
-static struct Scsi_Host *scsi_find_host_by_num(unsigned short host_no)
-{
-	struct Scsi_Host *shost, *shost_found = NULL;
-
-	spin_lock(&scsi_host_list_lock);
-	list_for_each_entry(shost, &scsi_host_list, sh_list) {
-		if (shost->host_no > host_no) {
-			/*
-			 * The list is sorted.
-			 */
-			break;
-		} else if (shost->host_no == host_no) {
-			shost_found = shost;
-			break;
-		}
-	}
-	spin_unlock(&scsi_host_list_lock);
-	return shost_found;
-}
-
-/**
- * scsi_alloc_hostnum - choose new SCSI host number based on host name.
- * @name:	String to store in name field
- *
- * Return value:
- *	Pointer to a new Scsi_Host_Name
- **/
-static int scsi_alloc_host_num(const char *name)
-{
-	int hostnum;
-	int namelen;
-	const char *start, *end;
-
-	if (name) {
-		hostnum = 0;
-		namelen = strlen(name);
-		start = scsihosts; 
-		while (1) {
-			int hostlen;
-
-			if (start && start[0] != '\0') {
-				end = strpbrk(start, ",:");
-				if (end) {
-					hostlen = (end - start);
-					end++;
-				} else
-					hostlen = strlen(start);
-				/*
-				 * Look for a match on the scsihosts list.
-				 */
-				if ((hostlen == namelen) && 
-				    (strncmp(name, start, hostlen) == 0) && 
-				    (!scsi_find_host_by_num(hostnum)))
-					return hostnum;
-				start = end;
-			} else  {
-				/*
-				 * Look for any unused numbers.
-				 */
-				if (!scsi_find_host_by_num(hostnum))
-					return hostnum;
-			}
-			hostnum++;
-		}
-	} else
-		return scsi_host_next_hn++;
-}
-
-
-/**
- * scsi_tp_for_each_host - call function for each scsi host off a template
- * @shost_tp:	a pointer to a scsi host template
- * @callback:	a pointer to callback function
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- **/
-int scsi_tp_for_each_host(Scsi_Host_Template *shost_tp, int
-			    (*callback)(struct Scsi_Host *shost))
-{
-	struct list_head *lh, *lh_sf;
-	struct Scsi_Host *shost;
-
-	spin_lock(&scsi_host_list_lock);
-
-	list_for_each_safe(lh, lh_sf, &scsi_host_list) {
-		shost = list_entry(lh, struct Scsi_Host, sh_list);
-		if (shost->hostt == shost_tp) {
-			spin_unlock(&scsi_host_list_lock);
-			callback(shost);
-			spin_lock(&scsi_host_list_lock);
-		}
-	}
-
-	spin_unlock(&scsi_host_list_lock);
-
-	return 0;
-}
-
-/**
- * scsi_host_legacy_release - default release function for hosts
- * @shost: 
- * 
- * Description:
- * 	This is the default case for the release function.  Its completely
- *	useless for anything but old ISA adapters
- **/
-static int scsi_host_legacy_release(struct Scsi_Host *shost)
-{
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
-#ifdef CONFIG_GENERIC_ISA_DMA
-	if (shost->dma_channel != 0xff)
-		free_dma(shost->dma_channel);
-#endif
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-
-	return 0;
-}
 
 /**
  * scsi_remove_host - check a scsi host for release and release
@@ -217,9 +62,6 @@
 	scsi_forget_host(shost);
 	scsi_sysfs_remove_host(shost);
 
-	if (shost->hostt->release)
-		(*shost->hostt->release)(shost);
-
 	return 0;
 }
 
@@ -233,7 +75,7 @@
  **/
 int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
 {
-	Scsi_Host_Template *sht = shost->hostt;
+	struct scsi_host_template *sht = shost->hostt;
 	int error;
 
 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
@@ -243,34 +85,17 @@
 	if (!error) {
 		scsi_proc_host_add(shost);
 		scsi_scan_host(shost);
-	};
+	}
 			
 	return error;
 }
 
 /**
- * scsi_unregister - unregister a scsi host
- * @shost:	scsi host to be unregistered
- **/
-void scsi_unregister(struct Scsi_Host *shost)
-{
-	scsi_host_put(shost);
-}
-
-/**
  * scsi_free_sdev - free a scsi hosts resources
  * @shost:	scsi host to free 
  **/
 void scsi_free_shost(struct Scsi_Host *shost)
 {
-	/* Remove shost from scsi_host_list */
-	spin_lock(&scsi_host_list_lock);
-	list_del(&shost->sh_list);
-	spin_unlock(&scsi_host_list_lock);
-
-	/*
-	 * Next, kill the kernel error recovery thread for this host.
-	 */
 	if (shost->ehandler) {
 		DECLARE_COMPLETION(sem);
 		shost->eh_notify = &sem;
@@ -286,60 +111,58 @@
 }
 
 /**
- * scsi_register - register a scsi host adapter instance.
- * @shost_tp:	pointer to scsi host template
- * @xtr_bytes:	extra bytes to allocate for driver
+ * scsi_host_alloc - register a scsi host adapter instance.
+ * @sht:	pointer to scsi host template
+ * @privsize:	extra bytes to allocate for driver
  *
  * Note:
- * 	We call this when we come across a new host adapter. We only do
- * 	this once we are 100% sure that we want to use this host adapter -
- * 	it is a pain to reverse this, so we try to avoid it 
+ * 	Allocate a new Scsi_Host and perform basic initialization.
+ * 	The host is not published to the scsi midlayer until scsi_add_host
+ * 	is called.
  *
  * Return value:
  * 	Pointer to a new Scsi_Host
  **/
-extern int blk_nohighio;
-struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
+struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 {
-	struct Scsi_Host *shost, *shost_scr;
-	int gfp_mask, rval;
-	DECLARE_COMPLETION(sem);
+	struct Scsi_Host *shost;
+	int gfp_mask = GFP_KERNEL, rval;
+	DECLARE_COMPLETION(complete);
+
+	if (sht->unchecked_isa_dma && privsize)
+		gfp_mask |= __GFP_DMA;
 
         /* Check to see if this host has any error handling facilities */
-        if(shost_tp->eh_strategy_handler == NULL &&
-           shost_tp->eh_abort_handler == NULL &&
-           shost_tp->eh_device_reset_handler == NULL &&
-           shost_tp->eh_bus_reset_handler == NULL &&
-           shost_tp->eh_host_reset_handler == NULL) {
-		printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\nERROR: This is not a safe way to run your SCSI host\nERROR: The error handling must be added to this driver\n", shost_tp->proc_name);
+        if (!sht->eh_strategy_handler && !sht->eh_abort_handler &&
+	    !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler &&
+            !sht->eh_host_reset_handler) {
+		printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n"
+				"ERROR: This is not a safe way to run your "
+				        "SCSI host\n"
+				"ERROR: The error handling must be added to "
+				"this driver\n", sht->proc_name);
 		dump_stack();
         }
-	if(shost_tp->shost_attrs == NULL)
-		/* if its not set in the template, use the default */
-		 shost_tp->shost_attrs = scsi_sysfs_shost_attrs;
-	if(shost_tp->sdev_attrs == NULL)
-		 shost_tp->sdev_attrs = scsi_sysfs_sdev_attrs;
-	gfp_mask = GFP_KERNEL;
-	if (shost_tp->unchecked_isa_dma && xtr_bytes)
-		gfp_mask |= __GFP_DMA;
-
-	shost = kmalloc(sizeof(struct Scsi_Host) + xtr_bytes, gfp_mask);
-	if (!shost) {
-		printk(KERN_ERR "%s: out of memory.\n", __FUNCTION__);
-		return NULL;
-	}
 
-	memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes);
+	/* if its not set in the template, use the default */
+	if (!sht->shost_attrs)
+		 sht->shost_attrs = scsi_sysfs_shost_attrs;
+	if (!sht->sdev_attrs)
+		 sht->sdev_attrs = scsi_sysfs_sdev_attrs;
 
-	shost->host_no = scsi_alloc_host_num(shost_tp->proc_name);
+	shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
+	if (!shost)
+		return NULL;
+	memset(shost, 0, sizeof(struct Scsi_Host) + privsize);
 
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
 	INIT_LIST_HEAD(&shost->my_devices);
 	INIT_LIST_HEAD(&shost->eh_cmd_q);
 	INIT_LIST_HEAD(&shost->starved_list);
-
 	init_waitqueue_head(&shost->host_wait);
+
+	shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */
 	shost->dma_channel = 0xff;
 
 	/* These three are default values which can be overridden */
@@ -354,54 +177,29 @@
 	 * they actually do something sensible with such commands.
 	 */
 	shost->max_cmd_len = 12;
-	shost->hostt = shost_tp;
-	shost->host_blocked = 0;
-	shost->host_self_blocked = FALSE;
-	shost->max_host_blocked = shost_tp->max_host_blocked ? shost_tp->max_host_blocked : SCSI_DEFAULT_HOST_BLOCKED;
-
-#ifdef DEBUG
-	printk("%s: %x %x: %d\n", __FUNCTION_ (int)shost,
-	       (int)shost->hostt, xtr_bytes);
-#endif
+	shost->hostt = sht;
+	shost->this_id = sht->this_id;
+	shost->can_queue = sht->can_queue;
+	shost->sg_tablesize = sht->sg_tablesize;
+	shost->cmd_per_lun = sht->cmd_per_lun;
+	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
+	shost->use_clustering = sht->use_clustering;
+	shost->use_blk_tcq = sht->use_blk_tcq;
+	shost->highmem_io = sht->highmem_io;
+
+	if (!sht->max_host_blocked)
+		shost->max_host_blocked = sht->max_host_blocked;
+	else
+		shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED;
 
 	/*
-	 * The next six are the default values which can be overridden if
-	 * need be
+	 * If the driver imposes no hard sector transfer limit, start at
+	 * machine infinity initially.
 	 */
-	shost->this_id = shost_tp->this_id;
-	shost->can_queue = shost_tp->can_queue;
-	shost->sg_tablesize = shost_tp->sg_tablesize;
-	shost->cmd_per_lun = shost_tp->cmd_per_lun;
-	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;
-	if (!shost_tp->max_sectors) {
-		/*
-		 * Driver imposes no hard sector transfer limit.
-		 * start at machine infinity initially.
-		 */
+	if (sht->max_sectors)
+		shost->max_sectors = sht->max_sectors;
+	else
 		shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
-	} else
-		shost->max_sectors = shost_tp->max_sectors;
-	shost->use_blk_tcq = shost_tp->use_blk_tcq;
-
-	spin_lock(&scsi_host_list_lock);
-	/*
-	 * FIXME When device naming is complete remove this step that
-	 * orders the scsi_host_list by host number and just do a
-	 * list_add_tail.
-	 */
-	list_for_each_entry(shost_scr, &scsi_host_list, sh_list) {
-		if (shost->host_no < shost_scr->host_no) {
-			__list_add(&shost->sh_list, shost_scr->sh_list.prev,
-				   &shost_scr->sh_list);
-			goto found;
-		}
-	}
-	list_add_tail(&shost->sh_list, &scsi_host_list);
-found:
-	spin_unlock(&scsi_host_list_lock);
 
 	rval = scsi_setup_command_freelist(shost);
 	if (rval)
@@ -409,85 +207,37 @@
 
 	scsi_sysfs_init_host(shost);
 
-	shost->eh_notify = &sem;
-	kernel_thread((int (*)(void *)) scsi_error_handler, (void *) shost, 0);
-	/*
-	 * Now wait for the kernel error thread to initialize itself
-	 * as it might be needed when we scan the bus.
-	 */
-	wait_for_completion(&sem);
+	shost->eh_notify = &complete;
+	/* XXX(hch): handle error return */
+	kernel_thread((int (*)(void *))scsi_error_handler, shost, 0);
+	wait_for_completion(&complete);
 	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);
+ fail:
 	kfree(shost);
 	return NULL;
 }
 
-/**
- * scsi_register_host - register a low level host driver
- * @shost_tp:	pointer to a scsi host driver template
- *
- * Return value:
- * 	0 on Success / 1 on Failure.
- **/
-int scsi_register_host(Scsi_Host_Template *shost_tp)
+struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
 {
-	struct Scsi_Host *shost;
-
-	BUG_ON(!shost_tp->detect);
+	struct Scsi_Host *shost = scsi_host_alloc(sht, privsize);
 
-	if (!shost_tp->release) {
-		printk(KERN_WARNING
-		    "scsi HBA driver %s didn't set a release method, "
-		    "please fix the template\n", shost_tp->name);
-		shost_tp->release = &scsi_host_legacy_release;
+	if (!sht->detect) {
+		printk(KERN_WARNING "scsi_register() called on new-style "
+				    "template for driver %s\n", sht->name);
+		dump_stack();
 	}
 
-	shost_tp->detect(shost_tp);
-	if (!shost_tp->present)
-		return 0;
-
-	/*
-	 * XXX(hch) use scsi_tp_for_each_host() once it propagates
-	 *	    error returns properly.
-	 */
-	list_for_each_entry(shost, &scsi_host_list, sh_list)
-		if (shost->hostt == shost_tp)
-			if (scsi_add_host(shost, NULL))
-				goto out_of_space;
-
-	return 0;
-
-out_of_space:
-	scsi_unregister_host(shost_tp); /* easiest way to clean up?? */
-	return 1;
+	if (shost)
+		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
+	return shost;
 }
 
-/**
- * scsi_unregister_host - unregister a low level host adapter driver
- * @shost_tp:	scsi host template to unregister.
- *
- * Description:
- * 	Similarly, this entry point should be called by a loadable module
- * 	if it is trying to remove a low level scsi driver from the system.
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- *
- * Notes:
- * 	rmmod does not care what we return here the module will be
- * 	removed.
- **/
-int scsi_unregister_host(Scsi_Host_Template *shost_tp)
+void scsi_unregister(struct Scsi_Host *shost)
 {
-	scsi_tp_for_each_host(shost_tp, scsi_remove_host);
-	return 0;
-
+	list_del(&shost->sht_legacy_list);
+	scsi_host_put(shost);
 }
 
 /**
@@ -536,50 +286,6 @@
  **/
 void scsi_host_put(struct Scsi_Host *shost)
 {
-
 	class_device_put(&shost->class_dev);
 	put_device(&shost->host_gendev);
-}
-
-/**
- * scsi_host_init - set up the scsi host number list based on any entries
- * scsihosts.
- **/
-void __init scsi_host_init(void)
-{
-	char *shost_hn;
-
-	shost_hn = scsihosts;
-	while (shost_hn) {
-		scsi_host_next_hn++;
-		shost_hn = strpbrk(shost_hn, ":,");
-		if (shost_hn)
-			shost_hn++;
-	}
-}
-
-void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	shost->host_busy++;
-	sdev->device_busy++;
-	spin_unlock_irqrestore(shost->host_lock, flags);
-}
-
-void scsi_host_busy_dec_and_test(struct Scsi_Host *shost, Scsi_Device *sdev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	shost->host_busy--;
-	if (shost->in_recovery && shost->host_failed &&
-	    (shost->host_busy == shost->host_failed))
-	{
-		up(shost->eh_wait);
-		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
-					  " thread\n"));
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
 }
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Mon May 26 03:02:43 2003
+++ b/drivers/scsi/hosts.h	Sun Jun  8 15:03:00 2003
@@ -28,519 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/types.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
- */
-#define SG_NONE 0
-#define SG_ALL 0xff
-
-#define DISABLE_CLUSTERING 0
-#define ENABLE_CLUSTERING 1
-
-/* The various choices mean:
- * NONE: Self evident.	Host adapter is not capable of scatter-gather.
- * ALL:	 Means that the host adapter module can do scatter-gather,
- *	 and that there is no limit to the size of the table to which
- *	 we scatter/gather data.
- * Anything else:  Indicates the maximum number of chains that can be
- *	 used in one scatter-gather request.
- */
-
-/*
- * The Scsi_Host_Template type has all that is needed to interface with a SCSI
- * host in a device independent matter.	 There is one entry for each different
- * type of host adapter that is supported on the system.
- */
-
-typedef struct	SHT
-{
-    /* Used with loadable modules so that we know when it is safe to unload */
-    struct module * module;
-
-    /* The pointer to the /proc/scsi directory entry */
-    struct proc_dir_entry *proc_dir;
-
-    /* proc-fs info function.
-     * Can be used to export driver statistics and other infos to the world
-     * outside the kernel ie. userspace and it also provides an interface
-     * to feed the driver with information. Check eata_dma_proc.c for reference
-     */
-    int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
-
-    /*
-     * The name pointer is a pointer to the name of the SCSI
-     * device detected.
-     */
-    const char *name;
-
-    /*
-     * The detect function shall return non zero on detection,
-     * indicating the number of host adapters of this particular
-     * type were found.	 It should also
-     * initialize all data necessary for this particular
-     * SCSI driver.  It is passed the host number, so this host
-     * knows where the first entry is in the scsi_hosts[] array.
-     *
-     * Note that the detect routine MUST not call any of the mid level
-     * functions to queue commands because things are not guaranteed
-     * to be set up yet.  The detect routine can send commands to
-     * the host adapter as long as the program control will not be
-     * passed to scsi.c in the processing of the command.  Note
-     * especially that scsi_malloc/scsi_free must not be called.
-     */
-    int (* detect)(struct SHT *);
-
-    /* Used with loadable modules to unload the host structures.  Note:
-     * there is a default action built into the modules code which may
-     * be sufficient for most host adapters.  Thus you may not have to supply
-     * this at all.
-     */
-    int (*release)(struct Scsi_Host *);
-
-    /*
-     * The info function will return whatever useful
-     * information the developer sees fit.  If not provided, then
-     * the name field will be used instead.
-     */
-    const char *(* info)(struct Scsi_Host *);
-
-    /*
-     * ioctl interface
-     */
-    int (*ioctl)(Scsi_Device *dev, int cmd, void *arg);
-
-    /*
-     * The command function takes a target, a command (this is a SCSI
-     * command formatted as per the SCSI spec, nothing strange), a
-     * data buffer pointer, and data buffer length pointer.  The return
-     * is a status int, bit fielded as follows :
-     * Byte What
-     * 0    SCSI status code
-     * 1    SCSI 1 byte message
-     * 2    host error return.
-     * 3    mid level error return
-     */
-    int (* command)(Scsi_Cmnd *);
-
-    /*
-     * The QueueCommand function works in a similar manner
-     * to the command function.	 It takes an additional parameter,
-     * void (* done)(int host, int code) which is passed the host
-     * # and exit result when the command is complete.
-     * Host number is the POSITION IN THE hosts array of THIS
-     * host adapter.
-     *
-     * if queuecommand returns 0, then the HBA has accepted the
-     * command.  The done() function must be called on the command
-     * when the driver has finished with it. (you may call done on the
-     * command before queuecommand returns, but in this case you
-     * *must* return 0 from queuecommand).
-     *
-     * queuecommand may also reject the command, in which case it may
-     * not touch the command and must not call done() for it.
-     *
-     * There are two possible rejection returns:
-     *
-     *   SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but
-     *   allow commands to other devices serviced by this host.
-     *
-     *   SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this
-     *   host temporarily.
-     *
-     *   for compatibility, any other non-zero return is treated the
-     *   same as SCSI_MLQUEUE_HOST_BUSY.
-     *
-     *   NOTE: "temporarily" means either until the next command for
-     *   this device/host completes, or a period of time determined by
-     *   I/O pressure in the system if there are no other outstanding
-     *   commands.
-     * */
-    int (* queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-    /*
-     * This is an error handling strategy routine.  You don't need to
-     * define one of these if you don't want to - there is a default
-     * routine that is present that should work in most cases.  For those
-     * driver authors that have the inclination and ability to write their
-     * own strategy routine, this is where it is specified.  Note - the
-     * strategy routine is *ALWAYS* run in the context of the kernel eh
-     * thread.  Thus you are guaranteed to *NOT* be in an interrupt handler
-     * when you execute this, and you are also guaranteed to *NOT* have any
-     * other commands being queued while you are in the strategy routine.
-     * When you return from this function, operations return to normal.
-     *
-     * See scsi_error.c scsi_unjam_host for additional comments about what
-     * this function should and should not be attempting to do.
-     */
-     int (*eh_strategy_handler)(struct Scsi_Host *);
-     int (*eh_abort_handler)(Scsi_Cmnd *);
-     int (*eh_device_reset_handler)(Scsi_Cmnd *);
-     int (*eh_bus_reset_handler)(Scsi_Cmnd *);
-     int (*eh_host_reset_handler)(Scsi_Cmnd *);
-
-    /*
-     * Old EH handlers, no longer used. Make them warn the user of old
-     * drivers by using a wrong type
-     */
-    int (*abort)(int);
-    int (*reset)(int,int);
-
-    /*
-     * slave_alloc()  -  Optional
-     * 
-     * Before the mid layer attempts to scan for a new device where none
-     * currently exists, it will call this entry in your driver.  Should
-     * your driver need to allocate any structs or perform any other init
-     * items in order to send commands to a currently unused target/lun
-     * combo, then this is where you can perform those allocations.  This
-     * is specifically so that drivers won't have to perform any kind of
-     * "is this a new device" checks in their queuecommand routine,
-     * thereby making the hot path a bit quicker.
-     *
-     * Return values: 0 on success, non-0 on failure
-     *
-     * Deallocation:  If we didn't find any devices at this ID, you will
-     * get an immediate call to slave_destroy().  If we find something here
-     * then you will get a call to slave_configure(), then the device will be
-     * used for however long it is kept around, then when the device is
-     * removed from the system (or * possibly at reboot time), you will
-     * then get a call to slave_detach().  This is assuming you implement
-     * slave_configure and slave_destroy.  However, if you allocate memory
-     * and hang it off the device struct, then you must implement the
-     * slave_destroy() routine at a minimum in order to avoid leaking memory
-     * each time a device is tore down.
-     */
-    int (* slave_alloc)(Scsi_Device *);
-
-    /*
-     * slave_configure()  -  Optional
-     * 
-     * Once the device has responded to an INQUIRY and we know the device
-     * is online, we call into the low level driver with the Scsi_Device *
-     * If the low level device driver implements this function, it *must*
-     * perform the task of setting the queue depth on the device.  All other
-     * tasks are optional and depend on what the driver supports and various
-     * implementation details.
-     * 
-     * Things currently recommended to be handled at this time include:
-     *
-     * 1.  Setting the device queue depth.  Proper setting of this is
-     *     described in the comments for scsi_adjust_queue_depth.
-     * 2.  Determining if the device supports the various synchronous
-     *     negotiation protocols.  The device struct will already have
-     *     responded to INQUIRY and the results of the standard items
-     *     will have been shoved into the various device flag bits, eg.
-     *     device->sdtr will be true if the device supports SDTR messages.
-     * 3.  Allocating command structs that the device will need.
-     * 4.  Setting the default timeout on this device (if needed).
-     * 5.  Anything else the low level driver might want to do on a device
-     *     specific setup basis...
-     * 6.  Return 0 on success, non-0 on error.  The device will be marked
-     *     as offline on error so that no access will occur.  If you return
-     *     non-0, your slave_detach routine will never get called for this
-     *     device, so don't leave any loose memory hanging around, clean
-     *     up after yourself before returning non-0
-     */
-    int (* slave_configure)(Scsi_Device *);
-
-    /*
-     * slave_destroy()  -  Optional
-     *
-     * Immediately prior to deallocating the device and after all activity
-     * has ceased the mid layer calls this point so that the low level driver
-     * may completely detach itself from the scsi device and vice versa.
-     * The low level driver is responsible for freeing any memory it allocated
-     * in the slave_alloc or slave_configure calls. 
-     */
-    void (* slave_destroy)(Scsi_Device *);
-
-    /*
-     * This function determines the bios parameters for a given
-     * harddisk.  These tend to be numbers that are made up by
-     * the host adapter.  Parameters:
-     * size, device, list (heads, sectors, cylinders)
-     */
-    int (* bios_param)(struct scsi_device *, struct block_device *,
-		    sector_t, int []);
-
-    /*
-     * This determines if we will use a non-interrupt driven
-     * or an interrupt driven scheme,  It is set to the maximum number
-     * of simultaneous commands a given host adapter will accept.
-     */
-    int can_queue;
-
-    /*
-     * In many instances, especially where disconnect / reconnect are
-     * supported, our host also has an ID on the SCSI bus.  If this is
-     * the case, then it must be reserved.  Please set this_id to -1 if
-     * your setup is in single initiator mode, and the host lacks an
-     * ID.
-     */
-    int this_id;
-
-    /*
-     * This determines the degree to which the host adapter is capable
-     * of scatter-gather.
-     */
-    short unsigned int sg_tablesize;
-
-    /*
-     * if the host adapter has limitations beside segment count
-     */
-    short unsigned int max_sectors;
-
-    /*
-     * True if this host adapter can make good use of linked commands.
-     * This will allow more than one command to be queued to a given
-     * unit on a given host.  Set this to the maximum number of command
-     * blocks to be provided for each device.  Set this to 1 for one
-     * command block per lun, 2 for two, etc.  Do not set this to 0.
-     * You should make sure that the host adapter will do the right thing
-     * before you try setting this above 1.
-     */
-    short cmd_per_lun;
-
-    /*
-     * present contains counter indicating how many boards of this
-     * type were found when we did the scan.
-     */
-    unsigned char present;
-
-    /*
-     * true if this host adapter uses unchecked DMA onto an ISA bus.
-     */
-    unsigned unchecked_isa_dma:1;
-
-    /*
-     * true if this host adapter can make good use of clustering.
-     * I originally thought that if the tablesize was large that it
-     * was a waste of CPU cycles to prepare a cluster list, but
-     * it works out that the Buslogic is faster if you use a smaller
-     * number of segments (i.e. use clustering).  I guess it is
-     * inefficient.
-     */
-    unsigned use_clustering:1;
-
-    /*
-     * True for emulated SCSI host adapters (e.g. ATAPI)
-     */
-    unsigned emulated:1;
-
-    unsigned highmem_io:1;
-
-    /* 
-     * True if the driver wishes to use the generic block layer
-     * tag queueing functions
-     */
-    unsigned use_blk_tcq:1;
-
-    /*
-     * Name of proc directory
-     */
-    char *proc_name;
-
-    /*
-     * countdown for host blocking with no commands outstanding
-     */
-    unsigned int max_host_blocked;
-
-    /*
-     * Default value for the blocking.  If the queue is empty, host_blocked
-     * counts down in the request_fn until it restarts host operations as
-     * zero is reached.  
-     *
-     * FIXME: This should probably be a value in the template */
-    #define SCSI_DEFAULT_HOST_BLOCKED	7
-
-    /*
-     * pointer to the sysfs class properties for this host
-     */
-    struct class_device_attribute **shost_attrs;
-
-    /*
-     * Pointer to the SCSI device properties for this host
-     */
-    struct device_attribute **sdev_attrs;
-
-} Scsi_Host_Template;
-
-/*
- * The scsi_hosts array is the array containing the data for all
- * possible <supported> scsi hosts.   This is similar to the
- * Scsi_Host_Template, except that we have one entry for each
- * actual physical host adapter on the system, stored as a linked
- * list.  Note that if there are 2 aha1542 boards, then there will
- * be two Scsi_Host entries, but only 1 Scsi_Host_Template entry.
- */
-
-struct Scsi_Host
-{
-/* private: */
-    /*
-     * This information is private to the scsi mid-layer.  Wrapping it in a
-     * struct private is a way of marking it in a sort of C++ type of way.
-     */
-    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 */
-    struct list_head      starved_list;
-
-    spinlock_t		  default_lock;
-    spinlock_t		  *host_lock;
-
-    struct list_head	eh_cmd_q;
-    struct task_struct    * ehandler;  /* Error recovery thread. */
-    struct semaphore      * eh_wait;   /* The error recovery thread waits on
-                                          this. */
-    struct completion     * eh_notify; /* wait for eh to begin or end */
-    struct semaphore      * eh_action; /* Wait for specific actions on the
-                                          host. */
-    unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
-                                          this is true. */
-    unsigned int            eh_kill:1; /* set when killing the eh thread */
-    wait_queue_head_t       host_wait;
-    Scsi_Host_Template    * hostt;
-    volatile unsigned short host_busy;   /* commands actually active on low-level */
-    volatile unsigned short host_failed; /* commands that failed. */
-    
-/* public: */
-    unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
-    int resetting; /* if set, it means that last_reset is a valid value */
-    unsigned long last_reset;
-
-    /*
-     *	These three parameters can be used to allow for wide scsi,
-     *	and for host adapters that support multiple busses
-     *	The first two should be set to 1 more than the actual max id
-     *	or lun (i.e. 8 for normal systems).
-     */
-    unsigned int max_id;
-    unsigned int max_lun;
-    unsigned int max_channel;
-
-    /* These parameters should be set by the detect routine */
-    unsigned long base;
-    unsigned long io_port;
-    unsigned char n_io_port;
-    unsigned char dma_channel;
-    unsigned int  irq;
-
-    /*
-     * This is a unique identifier that must be assigned so that we
-     * have some way of identifying each detected host adapter properly
-     * and uniquely.  For hosts that do not support more than one card
-     * in the system at one time, this does not need to be set.  It is
-     * initialized to 0 in scsi_register.
-     */
-    unsigned int unique_id;
-
-    /*
-     * The rest can be copied from the template, or specifically
-     * initialized, as required.
-     */
-
-    /*
-     * The maximum length of SCSI commands that this host can accept.
-     * Probably 12 for most host adapters, but could be 16 for others.
-     * For drivers that don't set this field, a value of 12 is
-     * assumed.  I am leaving this as a number rather than a bit
-     * because you never know what subsequent SCSI standards might do
-     * (i.e. could there be a 20 byte or a 24-byte command a few years
-     * down the road?).  
-     */
-    unsigned char max_cmd_len;
-
-    int this_id;
-    int can_queue;
-    short cmd_per_lun;
-    short unsigned int sg_tablesize;
-    short unsigned int max_sectors;
-
-    unsigned in_recovery:1;
-    unsigned unchecked_isa_dma:1;
-    unsigned use_clustering:1;
-    unsigned highmem_io:1;
-    unsigned use_blk_tcq:1;
-
-    /*
-     * Host has requested that no further requests come through for the
-     * time being.
-     */
-    unsigned host_self_blocked:1;
-    
-    /*
-     * Host uses correct SCSI ordering not PC ordering. The bit is
-     * set for the minority of drivers whose authors actually read the spec ;)
-     */
-    unsigned reverse_ordering:1;
-
-    /*
-     * Host has rejected a command because it was busy.
-     */
-    unsigned int host_blocked;
-
-    /*
-     * Value host_blocked counts down from
-     */
-    unsigned int max_host_blocked;
-
-    /* 
-     * Support for sysfs
-     */
-    struct device host_gendev;
-    struct class_device class_dev;
-
-    /*
-     * We should ensure that this is aligned, both for better performance
-     * and also because some compilers (m68k) don't automatically force
-     * alignment to a long boundary.
-     */
-    unsigned long hostdata[0]  /* Used for storage of host specific stuff */
-        __attribute__ ((aligned (sizeof(unsigned long))));
-};
-
-#define		dev_to_shost(d)		\
-	container_of(d, struct Scsi_Host, host_gendev)
-#define		class_to_shost(d)	\
-	container_of(d, struct Scsi_Host, class_dev)
-
-/*
- * These two functions are used to allocate and free a pseudo device
- * which will connect to the host adapter itself rather than any
- * physical device.  You must deallocate when you are done with the
- * thing.  This physical pseudo-device isn't real and won't be available
- * from any high-level drivers.
- */
-extern void scsi_free_host_dev(Scsi_Device *);
-extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
-
-extern void scsi_unblock_requests(struct Scsi_Host *);
-extern void scsi_block_requests(struct Scsi_Host *);
-extern void scsi_report_bus_reset(struct Scsi_Host *, int);
-extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
-
-static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
-{
-	shost->host_lock = lock;
-}
-
-static inline void scsi_set_device(struct Scsi_Host *shost,
-                                   struct device *dev)
-{
-        shost->host_gendev.parent = dev;
-}
-
-static inline struct device *scsi_get_device(struct Scsi_Host *shost)
-{
-        return shost->host_gendev.parent;
-}
+#include <scsi/scsi_host.h>
 
 struct scsi_driver {
 	struct module		*owner;
@@ -560,23 +48,6 @@
 #define scsi_unregister_interface(intf) \
 	class_interface_unregister(intf)
 
-/*
- * HBA allocation/freeing.
- */
-extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int);
-extern void scsi_unregister(struct Scsi_Host *);
-
-/*
- * HBA registration/unregistration.
- */
-extern int scsi_add_host(struct Scsi_Host *, struct device *);
-extern int scsi_remove_host(struct Scsi_Host *);
-
-/*
- * Legacy HBA template registration/unregistration.
- */
-extern int scsi_register_host(Scsi_Host_Template *);
-extern int scsi_unregister_host(Scsi_Host_Template *);
 
 /**
  * scsi_find_device - find a device given the host
@@ -585,9 +56,9 @@
  * @pun:	SCSI target number (physical unit number)
  * @lun:	SCSI Logical Unit Number
  **/
-static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost,
+static inline struct scsi_device *scsi_find_device(struct Scsi_Host *shost,
                                             int channel, int pun, int lun) {
-        Scsi_Device *sdev;
+        struct scsi_device *sdev;
 
 	list_for_each_entry (sdev, &shost->my_devices, siblings)
                 if (sdev->channel == channel && sdev->id == pun
@@ -595,7 +66,5 @@
                         return sdev;
         return NULL;
 }
-
-extern void scsi_sysfs_release_attributes(struct SHT *hostt);
 
 #endif
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Mon May 12 07:26:12 2003
+++ b/drivers/scsi/ibmmca.c	Sun Jun  8 12:18:41 2003
@@ -1793,15 +1793,6 @@
 	return shpnt;
 }
 
-static int ibmmca_command(Scsi_Cmnd * cmd)
-{
-	ibmmca_queuecommand(cmd, internal_done);
-	cmd->SCp.Status = 0;
-	while (!cmd->SCp.Status)
-		barrier();
-	return cmd->result;
-}
-
 static int ibmmca_release(struct Scsi_Host *shpnt)
 {
 	release_region(shpnt->io_port, shpnt->n_io_port);
@@ -2490,7 +2481,6 @@
           .name           = "IBM SCSI-Subsystem",
           .detect         = ibmmca_detect,
           .release        = ibmmca_release,
-          .command        = ibmmca_command,
           .queuecommand   = ibmmca_queuecommand,
 	  .eh_abort_handler = ibmmca_abort,
 	  .eh_host_reset_handler = ibmmca_host_reset,
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Mon May 26 03:12:22 2003
+++ b/drivers/scsi/ide-scsi.c	Mon Jun  2 17:42:21 2003
@@ -612,7 +612,7 @@
 	drive->disk->fops = ide_fops;
 
 	scsi_remove_host(scsihost);
-	scsi_unregister(scsihost);
+	scsi_host_put(scsihost);
 	return 0;
 }
 
@@ -964,7 +964,7 @@
 	if (!strstr("ide-scsi", drive->driver_req) ||
 	    !drive->present ||
 	    drive->media == ide_disk ||
-	    !(host = scsi_register(&idescsi_template,sizeof(idescsi_scsi_t))))
+	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
 		return 1;
 
 	host->max_id = 1;
@@ -984,7 +984,7 @@
 		ide_unregister_subdriver(drive);
 	}
 
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return err;
 }
 
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Tue May 27 09:05:29 2003
+++ b/drivers/scsi/imm.c	Sun Jun  8 12:18:41 2003
@@ -113,7 +113,6 @@
 	.name				= "Iomega VPI2 (imm) interface",
 	.detect				= imm_detect,
 	.release			= imm_release,
-	.command			= imm_command,
 	.queuecommand			= imm_queuecommand,
 	.eh_abort_handler               = imm_abort,
 	.eh_bus_reset_handler           = imm_reset,
@@ -856,39 +855,6 @@
 	    return 0;
     }
     return 1;			/* FINISH_RETURN */
-}
-
-/* deprecated synchronous interface */
-int imm_command(Scsi_Cmnd * cmd)
-{
-    static int first_pass = 1;
-    int host_no = cmd->device->host->unique_id;
-
-    if (first_pass) {
-	printk("imm: using non-queuing interface\n");
-	first_pass = 0;
-    }
-    if (imm_hosts[host_no].cur_cmd) {
-	printk("IMM: bug in imm_command\n");
-	return 0;
-    }
-    imm_hosts[host_no].failed = 0;
-    imm_hosts[host_no].jstart = jiffies;
-    imm_hosts[host_no].cur_cmd = cmd;
-    cmd->result = DID_ERROR << 16;	/* default return code */
-    cmd->SCp.phase = 0;
-
-    imm_pb_claim(host_no);
-
-    while (imm_engine(&imm_hosts[host_no], cmd))
-	schedule();
-
-    if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	imm_disconnect(cmd->device->host->unique_id);
-
-    imm_pb_release(host_no);
-    imm_hosts[host_no].cur_cmd = 0;
-    return cmd->result;
 }
 
 /*
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Sun May  4 02:56:43 2003
+++ b/drivers/scsi/ini9100u.c	Sun Jun  8 12:18:41 2003
@@ -147,7 +147,6 @@
 	.name		= i91u_REVID,
 	.detect		= i91u_detect,
 	.release	= i91u_release,
-	.command	= i91u_command,
 	.queuecommand	= i91u_queue,
 	.abort		= i91u_abort,
 	.reset		= i91u_reset,
@@ -555,15 +554,6 @@
 	i91uBuildSCB(pHCB, pSCB, SCpnt);
 	tul_exec_scb(pHCB, pSCB);	/* Start execute SCB            */
 	return (0);
-}
-
-/*
- *  We only support command in interrupt-driven fashion
- */
-int i91u_command(Scsi_Cmnd * SCpnt)
-{
-	printk("i91u: interrupt driven driver; use i91u_queue()\n");
-	return -1;
 }
 
 /*
diff -Nru a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
--- a/drivers/scsi/inia100.c	Mon Jun  9 16:05:03 2003
+++ b/drivers/scsi/inia100.c	Mon Jun 16 08:48:22 2003
@@ -156,11 +156,11 @@
 
 	spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
 
-	pSRB->next = NULL;	/* Pointer to next */
+	pSRB->SCp.ptr = NULL;	/* Pointer to next */
 	if (pHCB->pSRB_head == NULL)
 		pHCB->pSRB_head = pSRB;
 	else
-		pHCB->pSRB_tail->next = pSRB;	/* Pointer to next */
+		pHCB->pSRB_tail->SCp.ptr = (char *)pSRB;	/* Pointer to next */
 	pHCB->pSRB_tail = pSRB;
 	spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
 	return;
@@ -179,8 +179,8 @@
 	ULONG flags;
 	spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
 	if ((pSRB = (Scsi_Cmnd *) pHCB->pSRB_head) != NULL) {
-		pHCB->pSRB_head = pHCB->pSRB_head->next;
-		pSRB->next = NULL;
+		pHCB->pSRB_head = (Scsi_Cmnd *) pHCB->pSRB_head->SCp.ptr;
+		pSRB->SCp.ptr = NULL;
 	}
 	spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
 	return (pSRB);
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Mon May 12 07:26:13 2003
+++ b/drivers/scsi/ips.c	Thu Jun  5 11:39:39 2003
@@ -725,7 +725,7 @@
    free_irq(ha->irq, ha);
 
    IPS_REMOVE_HOST(sh);
-   scsi_unregister(sh);
+   scsi_host_put(sh);
 
    ips_released_controllers++;
 
@@ -6732,7 +6732,7 @@
 ips_register_scsi( int index){
 	struct Scsi_Host *sh;
 	ips_ha_t *ha, *oldha = ips_ha[index];
-	sh = scsi_register(&ips_driver_template, sizeof(ips_ha_t));
+	sh = scsi_host_alloc(&ips_driver_template, sizeof(ips_ha_t));
 	if(!sh) {
 		IPS_PRINTK(KERN_WARNING, oldha->pcidev, "Unable to register controller with SCSI subsystem\n");
 		return -1;
@@ -6743,7 +6743,7 @@
 	/* Install the interrupt handler with the new ha */
 	if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
 		IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n" );
-		scsi_unregister(sh);
+		scsi_host_put(sh);
 		return -1;
 	}
 
diff -Nru a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
--- a/drivers/scsi/jazz_esp.c	Mon Nov 11 13:23:24 2002
+++ b/drivers/scsi/jazz_esp.c	Sun Jun  8 12:18:41 2003
@@ -139,6 +139,18 @@
     return 0;
 }
 
+static int jazz_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /************************************************************* DMA Functions */
 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
 {
@@ -278,8 +290,8 @@
 	.proc_info		= &esp_proc_info,
 	.name			= "ESP 100/100a/200",
 	.detect			= jazz_esp_detect,
+	.release		= jazz_esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/lasi700.c	Tue Jun 17 13:27:45 2003
@@ -31,19 +31,14 @@
  * machines for me to debug the driver on.
  */
 
-#ifndef __hppa__
-#error "lasi700 only compiles on hppa architecture"
-#endif
-
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/sched.h>
-#include <linux/version.h>
-#include <linux/config.h>
 #include <linux/ioport.h>
 #include <linux/dma-mapping.h>
 
@@ -54,65 +49,27 @@
 #include <asm/parisc-device.h>
 #include <asm/delay.h>
 
-#include <linux/module.h>
-
 #include "scsi.h"
 #include "hosts.h"
 
 #include "lasi700.h"
 #include "53c700.h"
 
-#ifdef MODULE
-
-char *lasi700;			/* command line from insmod */
-
 MODULE_AUTHOR("James Bottomley");
 MODULE_DESCRIPTION("lasi700 SCSI Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(lasi700, "s");
-
-#endif
 
-#ifdef MODULE
-#define ARG_SEP ' '
-#else
-#define ARG_SEP ','
-#endif
-
-static unsigned long __initdata opt_base;
-static int __initdata opt_irq;
-
-static int __init
-param_setup(char *string)
-{
-	char *pos = string, *next;
-
-	while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
-		int val = (int)simple_strtoul(++next, NULL, 0);
-		
-		if(!strncmp(pos, "addr:", 5))
-			opt_base = val;
-		else if(!strncmp(pos, "irq:", 4))
-			opt_irq = val;
-
-		if((pos = strchr(pos, ARG_SEP)) != NULL)
-			pos++;
-	}
-	return 1;
-}
-
-#ifndef MODULE
-__setup("lasi700=", param_setup);
-#endif
-
-static Scsi_Host_Template __initdata *host_tpnt = NULL;
-static int __initdata host_count = 0;
 static struct parisc_device_id lasi700_scsi_tbl[] = {
 	LASI700_ID_TABLE,
 	LASI710_ID_TABLE,
 	{ 0 }
 };
 
+static Scsi_Host_Template lasi700_template = {
+	.name		= "LASI SCSI 53c700",
+	.proc_name	= "lasi700",
+	.this_id	= 7,
+};
 MODULE_DEVICE_TABLE(parisc, lasi700_scsi_tbl);
 
 static struct parisc_driver lasi700_driver = {
@@ -122,50 +79,36 @@
 };
 
 static int __init
-lasi700_detect(Scsi_Host_Template *tpnt)
-{
-	host_tpnt = tpnt;
-
-#ifdef MODULE
-	if(lasi700)
-		param_setup(lasi700);
-#endif
-
-	register_parisc_driver(&lasi700_driver);
-
-	return (host_count != 0);
-}
-
-static int __init
 lasi700_driver_callback(struct parisc_device *dev)
 {
 	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
-	char *driver_name;
+	struct NCR_700_Host_Parameters *hostdata;
 	struct Scsi_Host *host;
-	struct NCR_700_Host_Parameters *hostdata =
-		kmalloc(sizeof(struct NCR_700_Host_Parameters),
-			GFP_KERNEL);
-	if(dev->id.sversion == LASI_700_SVERSION) {
-		driver_name = "lasi700";
-	} else {
-		driver_name = "lasi710";
-	}
-	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", driver_name);
-	if(hostdata == NULL) {
+
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s",
+		 (dev->id.sversion == LASI_700_SVERSION) ?
+		  "lasi700" : "lasi710");
+
+	hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL);
+	if (!hostdata) {
 		printk(KERN_ERR "%s: Failed to allocate host data\n",
-		       driver_name);
+		       dev->dev.name);
 		return 1;
 	}
 	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
-	if(request_mem_region(base, 64, driver_name) == NULL) {
+
+	if (!request_mem_region(base, 64, dev->dev.name)) {
 		printk(KERN_ERR "%s: Failed to claim memory region\n",
-		       driver_name);
-		kfree(hostdata);
-		return 1;
+		       dev->dev.name);
+		goto out_kfree;
 	}
+
+	hostdata->dev = &dev->dev;
+	dma_set_mask(&dev->dev, 0xffffffffUL);
 	hostdata->base = base;
 	hostdata->differential = 0;
-	if(dev->id.sversion == LASI_700_SVERSION) {
+
+	if (dev->id.sversion == LASI_700_SVERSION) {
 		hostdata->clock = LASI700_CLOCK;
 		hostdata->force_le_on_be = 1;
 	} else {
@@ -174,26 +117,34 @@
 		hostdata->chip710 = 1;
 		hostdata->dmode_extra = DMODE_FC2;
 	}
-	hostdata->dev = &dev->dev;
-	dma_set_mask(&dev->dev, 0xffffffffUL);
-	if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) {
-		kfree(hostdata);
-		release_mem_region(host->base, 64);
-		return 1;
-	}
-	scsi_set_device(host, &dev->dev);
+
+	NCR_700_set_mem_mapped(hostdata);
+
+	host = NCR_700_detect(&lasi700_template, hostdata);
+	if (!host)
+		goto out_release_mem_region;
+
 	host->irq = dev->irq;
-	if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) {
+	if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ,
+				dev->dev.name, host)) {
 		printk(KERN_ERR "%s: irq problem, detaching\n",
-		       driver_name);
-		scsi_unregister(host);
-		NCR_700_release(host);
-		return 1;
+		       dev->dev.name);
+		goto out_put_host;
 	}
-	host_count++;
+
+	scsi_add_host(host, &dev->dev);
 	return 0;
+
+ out_put_host:
+	scsi_host_put(host);
+ out_release_mem_region:
+	release_mem_region(base, 64);
+ out_kfree:
+	kfree(hostdata);
+	return 1;
 }
 
+#if 0
 static int
 lasi700_release(struct Scsi_Host *host)
 {
@@ -207,12 +158,12 @@
 	unregister_parisc_driver(&lasi700_driver);
 	return 1;
 }
+#endif
+
+static int __init
+lasi700_init(void)
+{
+	return register_parisc_driver(&lasi700_driver);
+}
 
-static Scsi_Host_Template driver_template = {
-	.name		= "LASI SCSI 53c700",
-	.proc_name	= "lasi700",
-	.detect		= lasi700_detect,
-	.release	= lasi700_release,
-	.this_id	= 7,
-};
-#include "scsi_module.c"
+module_init(lasi700_init);
diff -Nru a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
--- a/drivers/scsi/mac_esp.c	Fri May  9 03:21:35 2003
+++ b/drivers/scsi/mac_esp.c	Sun Jun  8 12:18:41 2003
@@ -464,6 +464,16 @@
 	return chipspresent;
 }
 
+static int mac_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /*
  * I've been wondering what this is supposed to do, for some time. Talking 
  * to Allen Briggs: These machines have an extra register someplace where the
@@ -717,8 +727,8 @@
 	.proc_name		= "esp",
 	.name			= "Mac 53C9x SCSI",
 	.detect			= mac_esp_detect,
+	.release		= mac_esp_release,
 	.info			= esp_info,
-	/* .command		= esp_command, */
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Tue Jun  3 00:25:23 2003
+++ b/drivers/scsi/megaraid.c	Fri Jun  6 02:41:26 2003
@@ -723,7 +723,7 @@
 {
 	dma_addr_t	prod_info_dma_handle;
 	mega_inquiry3	*inquiry3;
-	u8	raw_mbox[sizeof(mbox_t)];
+	u8	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	int	retval;
 
@@ -732,14 +732,14 @@
 	mbox = (mbox_t *)raw_mbox;
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * Try to issue Inquiry3 command
 	 * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
 	 * update enquiry3 structure
 	 */
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
 
@@ -762,10 +762,10 @@
 
 		inq = &ext_inq->raid_inq;
 
-		mbox->xferaddr = (u32)dma_handle;
+		mbox->m_out.xferaddr = (u32)dma_handle;
 
 		/*issue old 0x04 command to adapter */
-		mbox->cmd = MEGA_MBOXCMD_ADPEXTINQ;
+		mbox->m_out.cmd = MEGA_MBOXCMD_ADPEXTINQ;
 
 		issue_scb_block(adapter, raw_mbox);
 
@@ -790,7 +790,7 @@
 				&adapter->product_info,
 				sizeof(mega_product_info), PCI_DMA_FROMDEVICE);
 
-		mbox->xferaddr = prod_info_dma_handle;
+		mbox->m_out.xferaddr = prod_info_dma_handle;
 
 		raw_mbox[0] = FC_NEW_CONFIG;	/* i.e. mbox->cmd=0xA1 */
 		raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;	/* i.e. 0x0E */
@@ -1141,10 +1141,10 @@
 			memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
 
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
 			}
 			else {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
 			}
 
 			scb->dma_direction = PCI_DMA_FROMDEVICE;
@@ -1152,7 +1152,7 @@
 			pthru->numsgelements = mega_build_sglist(adapter, scb,
 				&pthru->dataxferaddr, &pthru->dataxferlen);
 
-			mbox->xferaddr = scb->pthru_dma_addr;
+			mbox->m_out.xferaddr = scb->pthru_dma_addr;
 
 			return scb;
 
@@ -1175,19 +1175,19 @@
 			mbox = (mbox_t *)scb->raw_mbox;
 
 			memset(mbox, 0, sizeof(scb->raw_mbox));
-			mbox->logdrv = ldrv_num;
+			mbox->m_out.logdrv = ldrv_num;
 
 			/*
 			 * A little hack: 2nd bit is zero for all scsi read
 			 * commands and is set for all scsi write commands
 			 */
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = (*cmd->cmnd & 0x02) ?
+				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
 					MEGA_MBOXCMD_LWRITE64:
 					MEGA_MBOXCMD_LREAD64 ;
 			}
 			else {
-				mbox->cmd = (*cmd->cmnd & 0x02) ?
+				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
 					MEGA_MBOXCMD_LWRITE:
 					MEGA_MBOXCMD_LREAD ;
 			}
@@ -1196,13 +1196,13 @@
 			 * 6-byte READ(0x08) or WRITE(0x0A) cdb
 			 */
 			if( cmd->cmd_len == 6 ) {
-				mbox->numsectors = (u32) cmd->cmnd[4];
-				mbox->lba =
+				mbox->m_out.numsectors = (u32) cmd->cmnd[4];
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[1] << 16) |
 					((u32)cmd->cmnd[2] << 8) |
 					(u32)cmd->cmnd[3];
 
-				mbox->lba &= 0x1FFFFF;
+				mbox->m_out.lba &= 0x1FFFFF;
 
 #if MEGA_HAVE_STATS
 				/*
@@ -1213,11 +1213,11 @@
 				if (*cmd->cmnd == READ_6) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1226,10 +1226,10 @@
 			 * 10-byte READ(0x28) or WRITE(0x2A) cdb
 			 */
 			if( cmd->cmd_len == 10 ) {
-				mbox->numsectors =
+				mbox->m_out.numsectors =
 					(u32)cmd->cmnd[8] |
 					((u32)cmd->cmnd[7] << 8);
-				mbox->lba =
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[2] << 24) |
 					((u32)cmd->cmnd[3] << 16) |
 					((u32)cmd->cmnd[4] << 8) |
@@ -1239,11 +1239,11 @@
 				if (*cmd->cmnd == READ_10) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1252,13 +1252,13 @@
 			 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
 			 */
 			if( cmd->cmd_len == 12 ) {
-				mbox->lba =
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[2] << 24) |
 					((u32)cmd->cmnd[3] << 16) |
 					((u32)cmd->cmnd[4] << 8) |
 					(u32)cmd->cmnd[5];
 
-				mbox->numsectors =
+				mbox->m_out.numsectors =
 					((u32)cmd->cmnd[6] << 24) |
 					((u32)cmd->cmnd[7] << 16) |
 					((u32)cmd->cmnd[8] << 8) |
@@ -1268,11 +1268,11 @@
 				if (*cmd->cmnd == READ_12) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1288,8 +1288,8 @@
 			}
 
 			/* Calculate Scatter-Gather info */
-			mbox->numsgelements = mega_build_sglist(adapter, scb,
-					(u32 *)&mbox->xferaddr, (u32 *)&seg);
+			mbox->m_out.numsgelements = mega_build_sglist(adapter, scb,
+					(u32 *)&mbox->m_out.xferaddr, (u32 *)&seg);
 
 			return scb;
 
@@ -1357,9 +1357,9 @@
 			epthru = mega_prepare_extpassthru(adapter, scb, cmd,
 					channel, target);
 
-			mbox->cmd = MEGA_MBOXCMD_EXTPTHRU;
+			mbox->m_out.cmd = MEGA_MBOXCMD_EXTPTHRU;
 
-			mbox->xferaddr = scb->epthru_dma_addr;
+			mbox->m_out.xferaddr = scb->epthru_dma_addr;
 
 		}
 		else {
@@ -1369,13 +1369,13 @@
 
 			/* Initialize mailbox */
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
 			}
 			else {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
 			}
 
-			mbox->xferaddr = scb->pthru_dma_addr;
+			mbox->m_out.xferaddr = scb->pthru_dma_addr;
 
 		}
 		return scb;
@@ -1593,20 +1593,21 @@
 	volatile mbox_t		*mbox = adapter->mbox;
 	unsigned int	i = 0;
 
-	if(unlikely(mbox->busy)) {
+	if(unlikely(mbox->m_in.busy)) {
 		do {
 			udelay(1);
 			i++;
-		} while( mbox->busy && (i < max_mbox_busy_wait) );
+		} while( mbox->m_in.busy && (i < max_mbox_busy_wait) );
 
-		if(mbox->busy) return -1;
+		if(mbox->m_in.busy) return -1;
 	}
 
 	/* Copy mailbox data into host structure */
-	memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
+	memcpy((char *)&mbox->m_out, (char *)scb->raw_mbox, 
+			sizeof(struct mbox_out));
 
-	mbox->cmdid = scb->idx;	/* Set cmdid */
-	mbox->busy = 1;		/* Set busy */
+	mbox->m_out.cmdid = scb->idx;	/* Set cmdid */
+	mbox->m_in.busy = 1;		/* Set busy */
 
 
 	/*
@@ -1614,14 +1615,14 @@
 	 */
 	atomic_inc(&adapter->pend_cmds);
 
-	switch (mbox->cmd) {
+	switch (mbox->m_out.cmd) {
 	case MEGA_MBOXCMD_LREAD64:
 	case MEGA_MBOXCMD_LWRITE64:
 	case MEGA_MBOXCMD_PASSTHRU64:
 	case MEGA_MBOXCMD_EXTPTHRU:
-		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
 		mbox64->xfer_segment_hi = 0;
-		mbox->xferaddr = 0xFFFFFFFF;
+		mbox->m_out.xferaddr = 0xFFFFFFFF;
 		break;
 	default:
 		mbox64->xfer_segment_lo = 0;
@@ -1634,8 +1635,8 @@
 	scb->state |= SCB_ISSUED;
 
 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
-		mbox->poll = 0;
-		mbox->ack = 0;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0;
 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
 	}
 	else {
@@ -1661,24 +1662,23 @@
 	volatile mbox_t *mbox = adapter->mbox;
 	u8	byte;
 
-	raw_mbox[0x1] = 0xFE;	/* Set cmdid */
-	raw_mbox[0xF] = 1;	/* Set busy */
-
 	/* Wait until mailbox is free */
 	if(mega_busywait_mbox (adapter))
 		goto bug_blocked_mailbox;
 
 	/* Copy mailbox data into host structure */
-	memcpy((char *) mbox, raw_mbox, 16);
+	memcpy((char *) mbox, raw_mbox, sizeof(struct mbox_out));
+	mbox->m_out.cmdid = 0xFE;
+	mbox->m_in.busy = 1;
 
 	switch (raw_mbox[0]) {
 	case MEGA_MBOXCMD_LREAD64:
 	case MEGA_MBOXCMD_LWRITE64:
 	case MEGA_MBOXCMD_PASSTHRU64:
 	case MEGA_MBOXCMD_EXTPTHRU:
-		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
 		mbox64->xfer_segment_hi = 0;
-		mbox->xferaddr = 0xFFFFFFFF;
+		mbox->m_out.xferaddr = 0xFFFFFFFF;
 		break;
 	default:
 		mbox64->xfer_segment_lo = 0;
@@ -1686,22 +1686,22 @@
 	}
 
 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
-		mbox->poll = 0;
-		mbox->ack = 0;
-		mbox->numstatus = 0xFF;
-		mbox->status = 0xFF;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0;
+		mbox->m_in.numstatus = 0xFF;
+		mbox->m_in.status = 0xFF;
 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
 
-		while((volatile u8)mbox->numstatus == 0xFF)
+		while((volatile u8)mbox->m_in.numstatus == 0xFF)
 			cpu_relax();
 
-		mbox->numstatus = 0xFF;
+		mbox->m_in.numstatus = 0xFF;
 
-		while( (volatile u8)mbox->poll != 0x77 )
+		while( (volatile u8)mbox->m_in.poll != 0x77 )
 			cpu_relax();
 
-		mbox->poll = 0;
-		mbox->ack = 0x77;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0x77;
 
 		WRINDOOR(adapter, adapter->mbox_dma | 0x2);
 
@@ -1720,7 +1720,7 @@
 		irq_ack(adapter);
 	}
 
-	return mbox->status;
+	return mbox->m_in.status;
 
 bug_blocked_mailbox:
 	printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n");
@@ -1767,19 +1767,20 @@
 		}
 		set_irq_state(adapter, byte);
 
-		while((nstatus = (volatile u8)adapter->mbox->numstatus)
+		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
 				== 0xFF)
 			cpu_relax();
-		adapter->mbox->numstatus = 0xFF;
+		adapter->mbox->m_in.numstatus = 0xFF;
 
-		status = adapter->mbox->status;
+		status = adapter->mbox->m_in.status;
 
 		/*
 		 * decrement the pending queue counter
 		 */
 		atomic_sub(nstatus, &adapter->pend_cmds);
 
-		memcpy(completed, (void *)adapter->mbox->completed, nstatus);
+		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
+				nstatus);
 
 		/* Acknowledge interrupt */
 		irq_ack(adapter);
@@ -1843,20 +1844,21 @@
 		}
 		WROUTDOOR(adapter, 0x10001234);
 
-		while((nstatus = (volatile u8)adapter->mbox->numstatus)
+		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
 				== 0xFF) {
 			cpu_relax();
 		}
-		adapter->mbox->numstatus = 0xFF;
+		adapter->mbox->m_in.numstatus = 0xFF;
 
-		status = adapter->mbox->status;
+		status = adapter->mbox->m_in.status;
 
 		/*
 		 * decrement the pending queue counter
 		 */
 		atomic_sub(nstatus, &adapter->pend_cmds);
 
-		memcpy(completed, (void *)adapter->mbox->completed, nstatus);
+		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
+				nstatus);
 
 		/* Acknowledge interrupt */
 		WRINDOOR(adapter, 0x2);
@@ -1986,7 +1988,7 @@
 #if MEGA_HAVE_STATS
 			{
 
-			int	logdrv = mbox->logdrv;
+			int	logdrv = mbox->m_out.logdrv;
 
 			islogical = adapter->logdrv_chan[cmd->channel];
 			/*
@@ -2065,8 +2067,8 @@
 				   SCSI_STATUS_CHECK_CONDITION */
 
 			/* set sense_buffer and result fields */
-			if( mbox->cmd == MEGA_MBOXCMD_PASSTHRU ||
-				mbox->cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
+			if( mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU ||
+				mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
 
 				memcpy(cmd->sense_buffer, pthru->reqsensearea,
 						14);
@@ -2076,7 +2078,7 @@
 					(CHECK_CONDITION << 1);
 			}
 			else {
-				if (mbox->cmd == MEGA_MBOXCMD_EXTPTHRU) {
+				if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {
 
 					memcpy(cmd->sense_buffer,
 						epthru->reqsensearea, 14);
@@ -2233,7 +2235,7 @@
 static inline int
 mega_busywait_mbox (adapter_t *adapter)
 {
-	if (adapter->mbox->busy)
+	if (adapter->mbox->m_in.busy)
 		return __mega_busywait_mbox(adapter);
 	return 0;
 }
@@ -2245,7 +2247,7 @@
 	long counter;
 
 	for (counter = 0; counter < 10000; counter++) {
-		if (!mbox->busy)
+		if (!mbox->m_in.busy)
 			return 0;
 		udelay(100); yield();
 	}
@@ -2400,7 +2402,7 @@
 {
 	adapter_t	*adapter;
 	mbox_t	*mbox;
-	u_char	raw_mbox[sizeof(mbox_t)];
+	u_char	raw_mbox[sizeof(struct mbox_out)];
 	char	buf[12] = { 0 };
 
 	adapter = (adapter_t *)host->hostdata;
@@ -2409,7 +2411,7 @@
 	printk(KERN_NOTICE "megaraid: being unloaded...");
 
 	/* Flush adapter cache */
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	raw_mbox[0] = FLUSH_ADAPTER;
 
 	irq_disable(adapter);
@@ -2419,7 +2421,7 @@
 	issue_scb_block(adapter, raw_mbox);
 
 	/* Flush disks cache */
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	raw_mbox[0] = FLUSH_SYSTEM;
 
 	/* Issue a blocking (interrupts disabled) command to the card */
@@ -2569,35 +2571,6 @@
 	return buffer;
 }
 
-volatile static int internal_done_flag = 0;
-volatile static int internal_done_errcode = 0;
-
-static DECLARE_WAIT_QUEUE_HEAD (internal_wait);
-
-static void internal_done (Scsi_Cmnd *cmd)
-{
-	internal_done_errcode = cmd->result;
-	internal_done_flag++;
-	wake_up (&internal_wait);
-}
-
-/* shouldn't be used, but included for completeness */
-
-static int
-megaraid_command (Scsi_Cmnd *cmd)
-{
-	internal_done_flag = 0;
-
-	/* Queue command, and wait until it has completed */
-	megaraid_queue (cmd, internal_done);
-
-	while (!internal_done_flag)
-		interruptible_sleep_on (&internal_wait);
-
-	return internal_done_errcode;
-}
-
-
 /*
  * Abort a previous SCSI request. Only commands on the pending list can be
  * aborted. All the commands issued to the F/W must complete.
@@ -2979,16 +2952,24 @@
 	int	len = 0;
 
 	len = sprintf(page, "Contents of Mail Box Structure\n");
-	len += sprintf(page+len, "  Fw Command   = 0x%02x\n", mbox->cmd);
-	len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", mbox->cmdid);
-	len += sprintf(page+len, "  No of Sectors= %04d\n", mbox->numsectors);
-	len += sprintf(page+len, "  LBA          = 0x%02x\n", mbox->lba);
-	len += sprintf(page+len, "  DTA          = 0x%08x\n", mbox->xferaddr);
-	len += sprintf(page+len, "  Logical Drive= 0x%02x\n", mbox->logdrv);
+	len += sprintf(page+len, "  Fw Command   = 0x%02x\n", 
+			mbox->m_out.cmd);
+	len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", 
+			mbox->m_out.cmdid);
+	len += sprintf(page+len, "  No of Sectors= %04d\n", 
+			mbox->m_out.numsectors);
+	len += sprintf(page+len, "  LBA          = 0x%02x\n", 
+			mbox->m_out.lba);
+	len += sprintf(page+len, "  DTA          = 0x%08x\n", 
+			mbox->m_out.xferaddr);
+	len += sprintf(page+len, "  Logical Drive= 0x%02x\n", 
+			mbox->m_out.logdrv);
 	len += sprintf(page+len, "  No of SG Elmt= 0x%02x\n",
-			mbox->numsgelements);
-	len += sprintf(page+len, "  Busy         = %01x\n", mbox->busy);
-	len += sprintf(page+len, "  Status       = 0x%02x\n", mbox->status);
+			mbox->m_out.numsgelements);
+	len += sprintf(page+len, "  Busy         = %01x\n", 
+			mbox->m_in.busy);
+	len += sprintf(page+len, "  Status       = 0x%02x\n", 
+			mbox->m_in.status);
 
 	*eof = 1;
 
@@ -3881,7 +3862,7 @@
 {
 	adapter_t *adapter;
 	struct Scsi_Host *host;
-	u8 raw_mbox[sizeof(mbox_t)];
+	u8 raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int i,j;
 
@@ -3897,7 +3878,7 @@
 		mbox = (mbox_t *)raw_mbox;
 
 		/* Flush adapter cache */
-		memset(mbox, 0, sizeof(*mbox));
+		memset(&mbox->m_out, 0, sizeof(raw_mbox));
 		raw_mbox[0] = FLUSH_ADAPTER;
 
 		irq_disable(adapter);
@@ -3910,7 +3891,7 @@
 		issue_scb_block(adapter, raw_mbox);
 
 		/* Flush disks cache */
-		memset(mbox, 0, sizeof(*mbox));
+		memset(&mbox->m_out, 0, sizeof(raw_mbox));
 		raw_mbox[0] = FLUSH_SYSTEM;
 
 		issue_scb_block(adapter, raw_mbox);
@@ -4643,17 +4624,17 @@
 static int
 mega_is_bios_enabled(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	int	ret;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	raw_mbox[0] = IS_BIOS_ENABLED;
 	raw_mbox[2] = GET_BIOS;
@@ -4676,13 +4657,13 @@
 static void
 mega_enum_raid_scsi(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int i;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * issue command to find out what channels are raid/scsi
@@ -4692,7 +4673,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	/*
 	 * Non-ROMB firware fail this command, so all channels
@@ -4731,7 +4712,7 @@
 mega_get_boot_drv(adapter_t *adapter)
 {
 	struct private_bios_data	*prv_bios_data;
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	u16	cksum = 0;
 	u8	*cksum_p;
@@ -4740,14 +4721,14 @@
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(raw_mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	raw_mbox[0] = BIOS_PVT_DATA;
 	raw_mbox[2] = GET_BIOS_PVT_DATA;
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	adapter->boot_ldrv_enabled = 0;
 	adapter->boot_ldrv = 0;
@@ -4797,13 +4778,13 @@
 static int
 mega_support_random_del(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int rval;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * issue command
@@ -4826,13 +4807,13 @@
 static int
 mega_support_ext_cdb(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int rval;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	/*
 	 * issue command to find out if controller supports extended CDBs.
 	 */
@@ -4944,7 +4925,7 @@
 static void
 mega_get_max_sgl(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 
 	mbox = (mbox_t *)raw_mbox;
@@ -4953,7 +4934,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	raw_mbox[0] = MAIN_MISC_OPCODE;
 	raw_mbox[2] = GET_MAX_SG_SUPPORT;
@@ -4989,7 +4970,7 @@
 static int
 mega_support_cluster(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 
 	mbox = (mbox_t *)raw_mbox;
@@ -4998,7 +4979,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	/*
 	 * Try to get the initiator id. This command will succeed iff the
@@ -5367,7 +5348,6 @@
 	.detect =			megaraid_detect,
 	.release =			megaraid_release,
 	.info =				megaraid_info,
-	.command =			megaraid_command,
 	.queuecommand =			megaraid_queue,	
 	.bios_param =			megaraid_biosparam,
 	.max_sectors =			MAX_SECTORS_PER_IO,
diff -Nru a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
--- a/drivers/scsi/megaraid.h	Mon May 12 07:26:13 2003
+++ b/drivers/scsi/megaraid.h	Fri Jun  6 02:33:13 2003
@@ -120,8 +120,7 @@
 
 #define NVIRT_CHAN		4	/* # of virtual channels to represent
 					   up to 60 logical drives */
-
-typedef struct {
+struct mbox_out {
 	/* 0x0 */ u8 cmd;
 	/* 0x1 */ u8 cmdid;
 	/* 0x2 */ u16 numsectors;
@@ -130,12 +129,20 @@
 	/* 0xC */ u8 logdrv;
 	/* 0xD */ u8 numsgelements;
 	/* 0xE */ u8 resvd;
+} __attribute__ ((packed));
+
+struct mbox_in {
 	/* 0xF */ volatile u8 busy;
 	/* 0x10 */ volatile u8 numstatus;
 	/* 0x11 */ volatile u8 status;
 	/* 0x12 */ volatile u8 completed[MAX_FIRMWARE_STATUS];
 	volatile u8 poll;
 	volatile u8 ack;
+} __attribute__ ((packed));
+
+typedef struct {
+	struct mbox_out	m_out;
+	struct mbox_in	m_in;
 } __attribute__ ((packed)) mbox_t;
 
 typedef struct {
@@ -1001,7 +1008,6 @@
 static void mega_free_scb(adapter_t *, scb_t *);
 
 static int megaraid_release (struct Scsi_Host *);
-static int megaraid_command (Scsi_Cmnd *);
 static int megaraid_abort(Scsi_Cmnd *);
 static int megaraid_reset(Scsi_Cmnd *);
 static int megaraid_abort_and_reset(adapter_t *, Scsi_Cmnd *, int);
diff -Nru a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
--- a/drivers/scsi/mesh.c	Wed Apr 23 06:09:26 2003
+++ b/drivers/scsi/mesh.c	Sun Jun  8 12:18:41 2003
@@ -2047,11 +2047,8 @@
 	.name				= "MESH",
 	.detect				= mesh_detect,
 	.release			= mesh_release,
-	.command			= NULL,
 	.queuecommand			= mesh_queue,
 	.eh_abort_handler		= mesh_abort,
-	.eh_device_reset_handler	= NULL,
-	.eh_bus_reset_handler		= NULL,
 	.eh_host_reset_handler		= mesh_host_reset,
 	.can_queue			= 20,
 	.this_id			= 7,
diff -Nru a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
--- a/drivers/scsi/mvme16x.c	Wed Nov 20 03:36:31 2002
+++ b/drivers/scsi/mvme16x.c	Mon Jun  2 17:27:45 2003
@@ -53,9 +53,22 @@
     return 1;
 }
 
+static int mvme16x_scsi_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "MVME16x NCR53c710 SCSI",
 	.detect			= mvme16x_scsi_detect,
+	.release		= mvme16x_scsi_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Tue May 27 07:52:55 2003
+++ b/drivers/scsi/nsp32.c	Mon Jun  2 17:42:21 2003
@@ -1621,7 +1621,7 @@
 	/*
 	 * register this HBA as SCSI device
 	 */
-	host = scsi_register(&nsp32_template, sizeof(nsp32_hw_data));
+	host = scsi_host_alloc(&nsp32_template, sizeof(nsp32_hw_data));
 	if (host == NULL) {
 		nsp32_msg (KERN_ERR, "failed to scsi register");
 		goto err;
@@ -1840,7 +1840,7 @@
 	kfree(data->lunt_list);
 
  scsi_unregister:
-	scsi_unregister(host);
+	scsi_host_put(host);
 
  err:
 	return 1;
diff -Nru a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
--- a/drivers/scsi/pas16.c	Sun May  4 02:56:44 2003
+++ b/drivers/scsi/pas16.c	Mon Jun  2 17:27:44 2003
@@ -600,9 +600,22 @@
 
 #include "NCR5380.c"
 
+static int pas16_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name           = "Pro Audio Spectrum-16 SCSI",
 	.detect         = pas16_detect,
+	.release        = pas16_release,
 	.queuecommand   = pas16_queue_command,
 	.eh_abort_handler = pas16_abort,
 	.eh_bus_reset_handler = pas16_bus_reset,
diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
--- a/drivers/scsi/pci2000.c	Mon Jun  9 16:05:35 2003
+++ b/drivers/scsi/pci2000.c	Wed Jun 11 20:06:30 2003
@@ -612,41 +612,6 @@
 	return 0;
 	}
 /****************************************************************
- *	Name:	internal_done :LOCAL
- *
- *	Description:	Done handler for non-queued commands
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void internal_done (Scsi_Cmnd * SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Pci2000_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2000_Command (Scsi_Cmnd *SCpnt)
-	{
-	DEB(printk("pci2000_command: ..calling pci2000_queuecommand\n"));
-
-	Pci2000_QueueCommand (SCpnt, internal_done);
-
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
-/****************************************************************
  *	Name:	Pci2000_Detect
  *
  *	Description:	Detect and initialize our boards.
@@ -856,7 +821,6 @@
 	.name		= "PCI-2000 SCSI Intelligent Disk Controller",
 	.detect		= Pci2000_Detect,
 	.release	= Pci2000_Release,
-	.command	= Pci2000_Command,
 	.queuecommand	= Pci2000_QueueCommand,
 	.abort		= Pci2000_Abort,
 	.reset		= Pci2000_Reset,
diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
--- a/drivers/scsi/pci2220i.c	Mon Jun  9 16:06:04 2003
+++ b/drivers/scsi/pci2220i.c	Wed Jun 11 20:06:31 2003
@@ -2307,28 +2307,6 @@
 		}
 	return 0;
 	}
-static void internal_done(Scsi_Cmnd *SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Pci2220i_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2220i_Command (Scsi_Cmnd *SCpnt)
-	{
-	Pci2220i_QueueCommand (SCpnt, internal_done);
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
 /****************************************************************
  *	Name:			ReadFlash
  *
@@ -2924,7 +2902,6 @@
 	.name			= "PCI-2220I/PCI-2240I",
 	.detect			= Pci2220i_Detect,
 	.release		= Pci2220i_Release,
-	.command		= Pci2220i_Command,
 	.queuecommand		= Pci2220i_QueueCommand,
 	.abort			= Pci2220i_Abort,
 	.reset			= Pci2220i_Reset,
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Mon May 12 08:14:55 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Mon Jun  2 17:42:21 2003
@@ -1222,7 +1222,7 @@
 	DEBUG(0, "%s: this_id=%d\n", __FUNCTION__, sht->this_id);
 
 	request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
-	host		  = scsi_register(sht, 0);
+	host		  = scsi_host_alloc(sht, 0);
 	if(host == NULL)
 		return NULL;
 
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Tue May 27 08:56:01 2003
+++ b/drivers/scsi/ppa.c	Sun Jun  8 12:18:41 2003
@@ -103,7 +103,6 @@
 	.name				= "Iomega VPI0 (ppa) interface",
 	.detect				= ppa_detect,
 	.release			= ppa_release,
-	.command			= ppa_command,
 	.queuecommand			= ppa_queuecommand,
 	.eh_abort_handler		= ppa_abort,
 	.eh_bus_reset_handler		= ppa_reset,
@@ -759,39 +758,6 @@
 	    return 0;
     }
     return 1;			/* FINISH_RETURN */
-}
-
-/* deprecated synchronous interface */
-int ppa_command(Scsi_Cmnd * cmd)
-{
-    static int first_pass = 1;
-    int host_no = cmd->device->host->unique_id;
-
-    if (first_pass) {
-	printk("ppa: using non-queuing interface\n");
-	first_pass = 0;
-    }
-    if (ppa_hosts[host_no].cur_cmd) {
-	printk("PPA: bug in ppa_command\n");
-	return 0;
-    }
-    ppa_hosts[host_no].failed = 0;
-    ppa_hosts[host_no].jstart = jiffies;
-    ppa_hosts[host_no].cur_cmd = cmd;
-    cmd->result = DID_ERROR << 16;	/* default return code */
-    cmd->SCp.phase = 0;
-
-    ppa_pb_claim(host_no);
-
-    while (ppa_engine(&ppa_hosts[host_no], cmd))
-	schedule();
-
-    if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	ppa_disconnect(cmd->device->host->unique_id);
-
-    ppa_pb_release(host_no);
-    ppa_hosts[host_no].cur_cmd = 0;
-    return cmd->result;
 }
 
 /*
diff -Nru a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
--- a/drivers/scsi/psi240i.c	Sun May  4 02:56:45 2003
+++ b/drivers/scsi/psi240i.c	Sun Jun  8 12:18:41 2003
@@ -496,31 +496,6 @@
 	return 0;
 	}
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Psi240i_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Psi240i_Command (Scsi_Cmnd *SCpnt)
-	{
-	DEB(printk("psi240i_command: ..calling psi240i_queuecommand\n"));
-
-	Psi240i_QueueCommand (SCpnt, internal_done);
-
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
 /***************************************************************************
  *	Name:			ReadChipMemory
  *
@@ -655,6 +630,17 @@
 		}
 	return count;
 	}
+
+static int Psi240i_Release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /****************************************************************
  *	Name:	Psi240i_Abort
  *
@@ -722,7 +708,7 @@
 	.proc_name		= "psi240i", 
 	.name			= "PSI-240I EIDE Disk Controller",
 	.detect			= Psi240i_Detect,
-	.command		= Psi240i_Command,
+	.release		= Psi240i_Release,
 	.queuecommand		= Psi240i_QueueCommand,
 	.abort	  		= Psi240i_Abort,
 	.reset	  		= Psi240i_Reset,
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	Sat Apr 26 07:28:27 2003
+++ b/drivers/scsi/qlogicfas.c	Sun Jun  8 12:18:41 2003
@@ -544,46 +544,6 @@
 
 #if QL_USE_IRQ
 
-static void qlidone(Scsi_Cmnd * cmd)
-{
-}				/* null function */
-
-#endif
-
-/*
- *	Synchronous command processing
- */
- 
-static int qlogicfas_command(Scsi_Cmnd * cmd)
-{
-	int k;
-#if QL_USE_IRQ
-	if (qlirq >= 0) {
-		qlogicfas_queuecommand(cmd, qlidone);
-		while (qlcmd != NULL)
-		{
-			cpu_relax();
-			barrier();
-		}
-		return cmd->result;
-	}
-#endif
-
-	/*
-	 *	Non-irq version
-	 */
-	 
-	if (cmd->device->id == qinitid)
-		return (DID_BAD_TARGET << 16);
-	ql_icmd(cmd);
-	if ((k = ql_wai()))
-		return (k << 16);
-	return ql_pcmd(cmd);
-
-}
-
-#if QL_USE_IRQ
-
 /*
  *	Queued command
  */
@@ -739,6 +699,18 @@
 	return (__qlogicfas_detect(sht) != NULL);
 }
 
+static int qlogicfas_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /* 
  *	Return bios parameters 
  */
@@ -826,8 +798,8 @@
 	.name			= "qlogicfas",
 	.proc_name		= "qlogicfas",
 	.detect			= qlogicfas_detect,
+	.release		= qlogicfas_release,
 	.info			= qlogicfas_info,
-	.command		= qlogicfas_command,
 	.queuecommand		= qlogicfas_queuecommand,
 	.eh_abort_handler	= qlogicfas_abort,
 	.eh_bus_reset_handler	= qlogicfas_bus_reset,
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Mon May 26 02:50:43 2003
+++ b/drivers/scsi/scsi.c	Sun Jun  8 13:31:57 2003
@@ -38,6 +38,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -82,7 +83,6 @@
  * Data declarations.
  */
 unsigned long scsi_pid;
-struct scsi_cmnd *last_cmnd;
 static unsigned long serial_number;
 
 /*
@@ -108,26 +108,6 @@
 	"Enclosure        ",
 };
 
-MODULE_PARM(scsi_logging_level, "i");
-MODULE_PARM_DESC(scsi_logging_level, "SCSI logging level; should be zero or nonzero");
-
-#ifndef MODULE
-static int __init scsi_logging_setup(char *str)
-{
-	int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		scsi_logging_level = (tmp ? ~0 : 0);
-		return 1;
-	} else {
-		printk(KERN_INFO "scsi_logging_setup : usage scsi_logging_level=n "
-		       "(n should be 0 or non-zero)\n");
-		return 0;
-	}
-}
-__setup("scsi_logging=", scsi_logging_setup);
-#endif
-
 /*
  * Function:    scsi_allocate_request
  *
@@ -460,29 +440,18 @@
 		goto out;
 	}
 
-	if (host->can_queue) {
-		SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n",
-					   host->hostt->queuecommand));
+	SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n",
+				   host->hostt->queuecommand));
 
-		spin_lock_irqsave(host->host_lock, flags);
-		rtn = host->hostt->queuecommand(cmd, scsi_done);
-		spin_unlock_irqrestore(host->host_lock, flags);
-		if (rtn) {
-			scsi_queue_insert(cmd,
+	spin_lock_irqsave(host->host_lock, flags);
+	rtn = host->hostt->queuecommand(cmd, scsi_done);
+	spin_unlock_irqrestore(host->host_lock, flags);
+	if (rtn) {
+		scsi_queue_insert(cmd,
 				(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
-					rtn : SCSI_MLQUEUE_HOST_BUSY);
-			SCSI_LOG_MLQUEUE(3,
-			    printk("queuecommand : request rejected\n"));
-		}
-	} else {
-		SCSI_LOG_MLQUEUE(3, printk("command() :  routine at %p\n",
-					host->hostt->command));
-
-		spin_lock_irqsave(host->host_lock, flags);
-		cmd->result = host->hostt->command(cmd);
-		scsi_done(cmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
-		rtn = 0;
+				 rtn : SCSI_MLQUEUE_HOST_BUSY);
+		SCSI_LOG_MLQUEUE(3,
+		    printk("queuecommand : request rejected\n"));
 	}
 
  out:
@@ -752,16 +721,8 @@
 	struct scsi_device *sdev = cmd->device;
 	struct Scsi_Host *shost = sdev->host;
 	struct scsi_request *sreq;
-	unsigned long flags;
 
-	scsi_host_busy_dec_and_test(shost, sdev);
-
-	/*
-	 * XXX(hch): We really want a nice helper for this..
-	 */
-	spin_lock_irqsave(&sdev->sdev_lock, flags);
-	sdev->device_busy--;
-	spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+	scsi_device_unbusy(sdev);
 
         /*
          * Clear the flags which say that the device/host is no longer
@@ -983,6 +944,9 @@
 MODULE_DESCRIPTION("SCSI core");
 MODULE_LICENSE("GPL");
 
+module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
+
 static int __init init_scsi(void)
 {
 	int error, i;
@@ -1003,7 +967,6 @@
 	for (i = 0; i < NR_CPUS; i++)
 		INIT_LIST_HEAD(&done_q[i]);
 
-	scsi_host_init();
 	devfs_mk_dir("scsi");
 	open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
 	printk(KERN_NOTICE "SCSI subsystem initialized\n");
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Mon May 26 02:50:43 2003
+++ b/drivers/scsi/scsi.h	Sun Jun  8 15:03:00 2003
@@ -16,6 +16,12 @@
 #define _SCSI_H
 
 #include <linux/config.h>	    /* for CONFIG_SCSI_LOGGING */
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi.h>
 
 /*
@@ -112,19 +118,6 @@
 #define SOFT_ERROR      0x2005
 #define ADD_TO_MLQUEUE  0x2006
 
-/*
- * These are the values that scsi_cmd->state can take.
- */
-#define SCSI_STATE_TIMEOUT         0x1000
-#define SCSI_STATE_FINISHED        0x1001
-#define SCSI_STATE_FAILED          0x1002
-#define SCSI_STATE_QUEUED          0x1003
-#define SCSI_STATE_UNUSED          0x1006
-#define SCSI_STATE_DISCONNECTING   0x1008
-#define SCSI_STATE_INITIALIZING    0x1009
-#define SCSI_STATE_BHQUEUE         0x100a
-#define SCSI_STATE_MLQUEUE         0x100b
-
 #define IDENTIFY_BASE       0x80
 #define IDENTIFY(can_disconnect, lun)   (IDENTIFY_BASE |\
 		     ((can_disconnect) ?  0x40 : 0) |\
@@ -169,9 +162,6 @@
 #define DRIVER_MASK         0x0f
 #define SUGGEST_MASK        0xf0
 
-#define MAX_COMMAND_SIZE    16
-#define SCSI_SENSE_BUFFERSIZE   64
-
 /*
  *  SCSI command sets
  */
@@ -204,96 +194,20 @@
 #define ASKED_FOR_SENSE 0x20
 #define SYNC_RESET      0x40
 
-/*
- * This specifies "machine infinity" for host templates which don't
- * limit the transfer size.  Note this limit represents an absolute
- * maximum, and may be over the transfer limits allowed for individual
- * devices (e.g. 256 for SCSI-1)
- */
-#define SCSI_DEFAULT_MAX_SECTORS	1024
-
-/*
- * This is the crap from the old error handling code.  We have it in a special
- * place so that we can more easily delete it later on.
- */
-#include "scsi_obsolete.h"
-
-/*
- * Forward-declaration of structs for prototypes.
- */
 struct Scsi_Host;
+struct scsi_cmnd;
+struct scsi_device;
 struct scsi_target;
 struct scatterlist;
 
 /*
- * Add some typedefs so that we can prototyope a bunch of the functions.
- */
-typedef struct scsi_device Scsi_Device;
-typedef struct scsi_cmnd Scsi_Cmnd;
-typedef struct scsi_request Scsi_Request;
-
-/*
- * These are the error handling functions defined in scsi_error.c
- */
-extern void scsi_add_timer(Scsi_Cmnd * SCset, int timeout,
-			   void (*complete) (Scsi_Cmnd *));
-extern int scsi_delete_timer(Scsi_Cmnd * SCset);
-extern int scsi_block_when_processing_errors(Scsi_Device *);
-extern void scsi_sleep(int);
-
-/*
- * Prototypes for functions in scsicam.c
- */
-extern int  scsi_partsize(unsigned char *buf, unsigned long capacity,
-                    unsigned int *cyls, unsigned int *hds,
-                    unsigned int *secs);
-
-/*
- * Prototypes for functions in scsi_lib.c
- */
-extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
-			       int block_sectors);
-
-/*
- * Prototypes for functions in scsi.c
- */
-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_device_get(struct scsi_device *);
-extern void scsi_device_put(struct scsi_device *);
-extern void scsi_set_device_offline(struct scsi_device *);
-
-/*
- * Newer request-based interfaces.
- */
-extern Scsi_Request *scsi_allocate_request(Scsi_Device *);
-extern void scsi_release_request(Scsi_Request *);
-extern void scsi_wait_req(Scsi_Request *, const void *cmnd,
-			  void *buffer, unsigned bufflen,
-			  int timeout, int retries);
-extern void scsi_do_req(Scsi_Request *, const void *cmnd,
-			void *buffer, unsigned bufflen,
-			void (*done) (struct scsi_cmnd *),
-			int timeout, int retries);
-
-/*
- * Prototypes for functions in scsi_scan.c
- */
-extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
-		uint, uint, uint);
-extern int scsi_remove_device(struct scsi_device *);
-extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
-
-/*
  * Prototypes for functions in constants.c
  * Some of these used to live in constants.h
  */
-extern void print_Scsi_Cmnd (Scsi_Cmnd *);
+extern void print_Scsi_Cmnd(struct scsi_cmnd *);
 extern void print_command(unsigned char *);
-extern void print_sense(const char *, Scsi_Cmnd *);
-extern void print_req_sense(const char *, Scsi_Request *);
+extern void print_sense(const char *, struct scsi_cmnd *);
+extern void print_req_sense(const char *, struct scsi_request *);
 extern void print_driverbyte(int scsiresult);
 extern void print_hostbyte(int scsiresult);
 extern void print_status(unsigned char status);
@@ -301,286 +215,6 @@
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
-
-/*
- *  The scsi_device struct contains what we know about each given scsi
- *  device.
- *
- * FIXME(eric) - One of the great regrets that I have is that I failed to
- * define these structure elements as something like sdev_foo instead of foo.
- * This would make it so much easier to grep through sources and so forth.
- * I propose that all new elements that get added to these structures follow
- * this convention.  As time goes on and as people have the stomach for it,
- * it should be possible to go back and retrofit at least some of the elements
- * here with with the prefix.
- */
-
-struct scsi_device {
-	struct class_device	sdev_classdev;
-	/*
-	 * This information is private to the scsi mid-layer.
-	 */
-	struct list_head    siblings;   /* list of all devices on this host */
-	struct list_head    same_target_siblings; /* just the devices sharing same target id */
-	struct Scsi_Host *host;
-	request_queue_t *request_queue;
-	volatile unsigned short device_busy;	/* commands actually active on low-level */
-	spinlock_t sdev_lock;           /* also the request queue_lock */
-	spinlock_t list_lock;
-	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
-	struct list_head starved_entry;
-        Scsi_Cmnd *current_cmnd;	/* currently active command */
-	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
-					   jiffie count on our counter, they
-					   could all be from the same event. */
-
-	unsigned int id, lun, channel;
-
-	unsigned int manufacturer;	/* Manufacturer of device, for using 
-					 * vendor-specific cmd's */
-	unsigned sector_size;	/* size in bytes */
-
-	int access_count;	/* Count of open channels/mounts */
-
-	void *hostdata;		/* available to low-level driver */
-	char devfs_name[256];	/* devfs junk */
-	char type;
-	char scsi_level;
-	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
-	unsigned char * inquiry;	/* INQUIRY response data */
-	char * vendor;		/* [back_compat] point into 'inquiry' ... */
-	char * model;		/* ... after scan; point to static string */
-	char * rev;		/* ... "nullnullnullnull" before scan */
-	unsigned char current_tag;	/* current tag */
-//	unsigned char sync_min_period;	/* Not less than this period */
-//	unsigned char sync_max_offset;	/* Not greater than this offset */
-	struct scsi_target      *sdev_target;   /* used only for single_lun */
-
-	unsigned online:1;
-	unsigned writeable:1;
-	unsigned removable:1;
-	unsigned random:1;
-	unsigned changed:1;	/* Data invalid due to media change */
-	unsigned busy:1;	/* Used to prevent races */
-	unsigned lockable:1;	/* Able to prevent media removal */
-	unsigned locked:1;      /* Media removal disabled */
-	unsigned borken:1;	/* Tell the Seagate driver to be 
-				 * painfully slow on this device */
-	unsigned disconnect:1;	/* can disconnect */
-	unsigned soft_reset:1;	/* Uses soft reset option */
-	unsigned sdtr:1;	/* Device supports SDTR messages */
-	unsigned wdtr:1;	/* Device supports WDTR messages */
-	unsigned ppr:1;		/* Device supports PPR messages */
-	unsigned tagged_supported:1;	/* Supports SCSI-II tagged queuing */
-	unsigned tagged_queue:1;/* This is going away!!!!  Look at simple_tags
-				   instead!!!  Please fix your driver now!! */
-	unsigned simple_tags:1;	/* simple queue tag messages are enabled */
-	unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
-	unsigned single_lun:1;	/* Indicates we should only allow I/O to
-				 * one of the luns for the device at a 
-				 * time. */
-	unsigned was_reset:1;	/* There was a bus reset on the bus for 
-				 * this device */
-	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
-				     * because we did a bus reset. */
-	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
-	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
-	unsigned remap:1;	/* support remapping  */
-//	unsigned sync:1;	/* Sync transfer state, managed by host */
-//	unsigned wide:1;	/* WIDE transfer state, managed by host */
-	unsigned no_start_on_add:1;	/* do not issue start on add */
-
-	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
-
-	unsigned int max_device_blocked; /* what device_blocked counts down from  */
-  	/* default value if the device doesn't override */
-	#define SCSI_DEFAULT_DEVICE_BLOCKED	3
-
-	struct device sdev_driverfs_dev;
-};
-#define	to_scsi_device(d)	\
-	container_of(d, struct scsi_device, sdev_driverfs_dev)
-
-
-typedef struct scsi_pointer {
-	char *ptr;		/* data pointer */
-	int this_residual;	/* left in this buffer */
-	struct scatterlist *buffer;	/* which buffer */
-	int buffers_residual;	/* how many buffers left */
-
-        dma_addr_t dma_handle;
-
-	volatile int Status;
-	volatile int Message;
-	volatile int have_data_in;
-	volatile int sent_command;
-	volatile int phase;
-} Scsi_Pointer;
-
-/*
- * This is essentially a slimmed down version of Scsi_Cmnd.  The point of
- * having this is that requests that are injected into the queue as result
- * of things like ioctls and character devices shouldn't be using a
- * Scsi_Cmnd until such a time that the command is actually at the head
- * of the queue and being sent to the driver.
- */
-struct scsi_request {
-	int     sr_magic;
-	int     sr_result;	/* Status code from lower level driver */
-	unsigned char sr_sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
-						 * when CHECK CONDITION is
-						 * received on original command 
-						 * (auto-sense) */
-
-	struct Scsi_Host *sr_host;
-	Scsi_Device *sr_device;
-	Scsi_Cmnd *sr_command;
-	struct request *sr_request;	/* A copy of the command we are
-				   working on */
-	unsigned sr_bufflen;	/* Size of data buffer */
-	void *sr_buffer;		/* Data buffer */
-	int sr_allowed;
-	unsigned char sr_data_direction;
-	unsigned char sr_cmd_len;
-	unsigned char sr_cmnd[MAX_COMMAND_SIZE];
-	void (*sr_done) (struct scsi_cmnd *);	/* Mid-level done function */
-	int sr_timeout_per_command;
-	unsigned short sr_use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short sr_sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned sr_underflow;	/* Return error if less than
-				   this amount is transferred */
- 	void * upper_private_data;	/* reserved for owner (usually upper
- 					   level driver) of this request */
-};
-
-/*
- * FIXME(eric) - one of the great regrets that I have is that I failed to
- * define these structure elements as something like sc_foo instead of foo.
- * This would make it so much easier to grep through sources and so forth.
- * I propose that all new elements that get added to these structures follow
- * this convention.  As time goes on and as people have the stomach for it,
- * it should be possible to go back and retrofit at least some of the elements
- * here with with the prefix.
- */
-struct scsi_cmnd {
-	int     sc_magic;
-
-	struct scsi_device *device;
-	unsigned short state;
-	unsigned short owner;
-	Scsi_Request *sc_request;
-
-	struct list_head list;  /* scsi_cmnd participates in queue lists */
-
-	struct list_head eh_entry; /* entry for the host eh_cmd_q */
-	int eh_state;		/* Used for state tracking in error handlr */
-	int eh_eflags;		/* Used by error handlr */
-	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
-	/*
-	   A SCSI Command is assigned a nonzero serial_number when internal_cmnd
-	   passes it to the driver's queue command function.  The serial_number
-	   is cleared when scsi_done is entered indicating that the command has
-	   been completed.  If a timeout occurs, the serial number at the moment
-	   of timeout is copied into serial_number_at_timeout.  By subsequently
-	   comparing the serial_number and serial_number_at_timeout fields
-	   during abort or reset processing, we can detect whether the command
-	   has already completed.  This also detects cases where the command has
-	   completed and the SCSI Command structure has already being reused
-	   for another command, so that we can avoid incorrectly aborting or
-	   resetting the new command.
-	 */
-
-	unsigned long serial_number;
-	unsigned long serial_number_at_timeout;
-
-	int retries;
-	int allowed;
-	int timeout_per_command;
-	int timeout_total;
-	int timeout;
-
-	/*
-	 * We handle the timeout differently if it happens when a reset, 
-	 * abort, etc are in process. 
-	 */
-	unsigned volatile char internal_timeout;
-
-	unsigned char cmd_len;
-	unsigned char old_cmd_len;
-	unsigned char sc_data_direction;
-	unsigned char sc_old_data_direction;
-
-	/* These elements define the operation we are about to perform */
-	unsigned char cmnd[MAX_COMMAND_SIZE];
-	unsigned request_bufflen;	/* Actual request size */
-
-	struct timer_list eh_timeout;	/* Used to time out the command. */
-	void *request_buffer;		/* Actual requested buffer */
-
-	/* These elements define the operation we ultimately want to perform */
-	unsigned char data_cmnd[MAX_COMMAND_SIZE];
-	unsigned short old_use_sg;	/* We save  use_sg here when requesting
-					 * sense info */
-	unsigned short use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned short abort_reason;	/* If the mid-level code requests an
-					 * abort, this is the reason. */
-	unsigned bufflen;	/* Size of data buffer */
-	void *buffer;		/* Data buffer */
-
-	unsigned underflow;	/* Return error if less than
-				   this amount is transferred */
-	unsigned old_underflow;	/* save underflow here when reusing the
-				 * command for error handling */
-
-	unsigned transfersize;	/* How much we are guaranteed to
-				   transfer with each SCSI transfer
-				   (ie, between disconnect / 
-				   reconnects.   Probably == sector
-				   size */
-
-	int resid;		/* Number of bytes requested to be
-				   transferred less actual number
-				   transferred (0 if not supported) */
-
-	struct request *request;	/* The command we are
-				   	   working on */
-
-	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
-						 * when CHECK CONDITION is
-						 * received on original command 
-						 * (auto-sense) */
-
-	unsigned flags;
-
-	/* Low-level done function - can be used by low-level driver to point
-	 *        to completion function.  Not used by mid/upper level code. */
-	void (*scsi_done) (struct scsi_cmnd *);
-
-	/*
-	 * The following fields can be written to by the host specific code. 
-	 * Everything else should be left alone. 
-	 */
-
-	Scsi_Pointer SCp;	/* Scratchpad used by some host adapters */
-
-	unsigned char *host_scribble;	/* The host adapter is allowed to
-					   * call scsi_malloc and get some memory
-					   * and hang it here.     The host adapter
-					   * is also expected to call scsi_free
-					   * to release this memory.  (The memory
-					   * obtained by scsi_malloc is guaranteed
-					   * to be at an address < 16Mb). */
-
-	int result;		/* Status code from lower level driver */
-
-	unsigned char tag;	/* SCSI-II queued command tag */
-	unsigned long pid;	/* Process ID, starts at 0 */
-};
-
 /*
  * Definitions and prototypes used for scsi mid-level queue.
  */
@@ -588,104 +222,18 @@
 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
 #define SCSI_MLQUEUE_EH_RETRY    0x1057
 
-/*
- * Reset request from external source
- */
-#define SCSI_TRY_RESET_DEVICE	1
-#define SCSI_TRY_RESET_BUS	2
-#define SCSI_TRY_RESET_HOST	3
-
-extern int scsi_reset_provider(Scsi_Device *, int);
-
-#define MSG_SIMPLE_TAG	0x20
-#define MSG_HEAD_TAG	0x21
-#define MSG_ORDERED_TAG	0x22
-
-#define SCSI_NO_TAG	(-1)    /* identify no tag in use */
-
-/**
- * scsi_activate_tcq - turn on tag command queueing
- * @SDpnt:	device to turn on TCQ for
- * @depth:	queue depth
- *
- * Notes:
- *	Eventually, I hope depth would be the maximum depth
- *	the device could cope with and the real queue depth
- *	would be adjustable from 0 to depth.
- **/
-static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
-        if(SDpnt->tagged_supported) {
-		if(!blk_queue_tagged(SDpnt->request_queue))
-			blk_queue_init_tags(SDpnt->request_queue, depth);
-		scsi_adjust_queue_depth(SDpnt, MSG_ORDERED_TAG, depth);
-        }
-}
-
-/**
- * scsi_deactivate_tcq - turn off tag command queueing
- * @SDpnt:	device to turn off TCQ for
- **/
-static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt, int depth) {
-	if(blk_queue_tagged(SDpnt->request_queue))
-		blk_queue_free_tags(SDpnt->request_queue);
-	scsi_adjust_queue_depth(SDpnt, 0, depth);
-}
-
-/**
- * scsi_populate_tag_msg - place a tag message in a buffer
- * @SCpnt:	pointer to the Scsi_Cmnd for the tag
- * @msg:	pointer to the area to place the tag
- *
- * Notes:
- *	designed to create the correct type of tag message for the 
- *	particular request.  Returns the size of the tag message.
- *	May return 0 if TCQ is disabled for this device.
- **/
-static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
-        struct request *req = SCpnt->request;
-
-        if(!blk_rq_tagged(req))
-                return 0;
-
-	if (req->flags & REQ_HARDBARRIER)
-                *msg++ = MSG_ORDERED_TAG;
-        else
-                *msg++ = MSG_SIMPLE_TAG;
-
-        *msg++ = SCpnt->request->tag;
-
-        return 2;
-}
-
-/**
- * scsi_find_tag - find a tagged command by device
- * @SDpnt:	pointer to the ScSI device
- * @tag:	the tag number
- *
- * Notes:
- *	Only works with tags allocated by the generic blk layer.
- **/
-static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
-
-        struct request *req;
-
-        if(tag == SCSI_NO_TAG)
-                /* single command, look in space */
-                return SDpnt->current_cmnd;
-
-        req = blk_queue_find_tag(SDpnt->request_queue, tag);
-
-        if(req == NULL)
-                return NULL;
-
-        return (Scsi_Cmnd *)req->special;
-}
-
-int scsi_set_medium_removal(Scsi_Device *dev, char state);
-
 extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
 					    struct device_attribute *attr);
 extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
 					     struct class_device_attribute *attr);
+
+/*
+ * This is the crap from the old error handling code.  We have it in a special
+ * place so that we can more easily delete it later on.
+ */
+#include "scsi_obsolete.h"
+
+/* obsolete typedef junk. */
+#include "scsi_typedefs.h"
 
 #endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Mon May 12 07:26:14 2003
+++ b/drivers/scsi/scsi_debug.c	Mon Jun  2 17:42:21 2003
@@ -1681,7 +1681,7 @@
 
 	sdbg_host = to_sdebug_host(dev);
 
-        hpnt = scsi_register(&sdebug_driver_template, sizeof(sdbg_host));
+        hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host));
         if (NULL == hpnt) {
                 printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__);
                 error = -ENODEV;
@@ -1700,7 +1700,7 @@
         if (error) {
                 printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
                 error = -ENODEV;
-		scsi_unregister(hpnt);
+		scsi_host_put(hpnt);
         }
 
 
@@ -1726,8 +1726,6 @@
                 return -EBUSY;
         }
 
-        scsi_unregister(sdbg_host->shost);
-
         list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
                 sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
                                           dev_list);
@@ -1735,5 +1733,6 @@
                 kfree(sdbg_devinfo);
         }
 
+        scsi_host_put(sdbg_host->shost);
         return 0;
 }
diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
--- a/drivers/scsi/scsi_devinfo.c	Fri May 23 04:01:50 2003
+++ b/drivers/scsi/scsi_devinfo.c	Wed Jun 11 14:07:46 2003
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
@@ -23,9 +24,9 @@
 
 
 static const char spaces[] = "                "; /* 16 of them */
-static char *scsi_dev_flags;
 static unsigned scsi_default_dev_flags;
 static LIST_HEAD(scsi_dev_info_list);
+static __init char scsi_dev_flags[256];
 
 /*
  * scsi_static_device_list: deprecated list of devices that require
@@ -180,6 +181,7 @@
 	{"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{ NULL, NULL, NULL, 0 },
 };
 
@@ -450,35 +452,15 @@
 	return err;
 }
 
-MODULE_PARM(scsi_dev_flags, "s");
-MODULE_PARM_DESC(scsi_dev_flags,
-	 "Given scsi_dev_flags=vendor:model:flags, add a black/white list"
-	 " entry for vendor and model with an integer value of flags"
+module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0);
+MODULE_PARM_DESC(dev_flags,
+	 "Given scsi_dev_flags=vendor:model:flags[,v:m:f] add black/white"
+	 " list entries for vendor and model with an integer value of flags"
 	 " to the scsi device info list");
-MODULE_PARM(scsi_default_dev_flags, "i");
-MODULE_PARM_DESC(scsi_default_dev_flags,
-		 "scsi default device flag integer value");
 
-static int __init setup_scsi_dev_flags(char *str)
-{
-	scsi_dev_flags = str;
-	return 1;
-}
-
-static int __init setup_scsi_default_dev_flags(char *str)
-{
-	unsigned int tmp;
-	if (get_option(&str, &tmp) == 1) {
-		scsi_default_dev_flags = tmp;
-		printk(KERN_WARNING "%s %d\n", __FUNCTION__,
-		       scsi_default_dev_flags);
-		return 1;
-	} else {
-		printk(KERN_WARNING "%s: usage scsi_default_dev_flags=intr\n",
-		       __FUNCTION__);
-		return 0;
-	}
-}
+module_param_named(default_dev_flags, scsi_default_dev_flags, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_dev_flags,
+		 "scsi default device flag integer value");
 
 /**
  * scsi_dev_info_list_delete: called from scsi.c:exit_scsi to remove
@@ -540,6 +522,3 @@
 		scsi_exit_devinfo();
 	return error;
 }
-
-__setup("scsi_dev_flags=", setup_scsi_dev_flags);
-__setup("scsi_default_dev_flags=", setup_scsi_default_dev_flags);
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Mon May 12 20:52:56 2003
+++ b/drivers/scsi/scsi_error.c	Sun Jun  8 13:31:57 2003
@@ -44,6 +44,16 @@
 #define BUS_RESET_SETTLE_TIME   10*HZ
 #define HOST_RESET_SETTLE_TIME  10*HZ
 
+/* called with shost->host_lock held */
+void scsi_eh_wakeup(struct Scsi_Host *shost)
+{
+	if (shost->host_busy == shost->host_failed) {
+		up(shost->eh_wait);
+		SCSI_LOG_ERROR_RECOVERY(5,
+				printk("Waking error handler thread\n"));
+	}
+}
+
 /**
  * scsi_eh_scmd_add - add scsi cmd to error handling.
  * @scmd:	scmd to run eh on.
@@ -76,14 +86,8 @@
 	list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
 	shost->in_recovery = 1;
 	shost->host_failed++;
-	if (shost->host_busy == shost->host_failed) {
-		up(shost->eh_wait);
-		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
-					  " thread\n"));
-	}
-
+	scsi_eh_wakeup(shost);
 	spin_unlock_irqrestore(shost->host_lock, flags);
-
 	return 1;
 }
 
@@ -431,6 +435,7 @@
 static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 {
 	struct Scsi_Host *host = scmd->device->host;
+	DECLARE_MUTEX_LOCKED(sem);
 	unsigned long flags;
 	int rtn = SUCCESS;
 
@@ -444,71 +449,53 @@
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
 			(scmd->device->lun << 5 & 0xe0);
 
-	if (host->can_queue) {
-		DECLARE_MUTEX_LOCKED(sem);
+	scsi_add_timer(scmd, timeout, scsi_eh_times_out);
 
-		scsi_add_timer(scmd, timeout, scsi_eh_times_out);
+	/*
+	 * set up the semaphore so we wait for the command to complete.
+	 */
+	scmd->device->host->eh_action = &sem;
+	scmd->request->rq_status = RQ_SCSI_BUSY;
 
-		/*
-		 * set up the semaphore so we wait for the command to complete.
-		 */
-		scmd->device->host->eh_action = &sem;
-		scmd->request->rq_status = RQ_SCSI_BUSY;
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	host->hostt->queuecommand(scmd, scsi_eh_done);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
-		spin_lock_irqsave(scmd->device->host->host_lock, flags);
-		host->hostt->queuecommand(scmd, scsi_eh_done);
-		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+	down(&sem);
 
-		down(&sem);
+	scmd->device->host->eh_action = NULL;
 
-		scmd->device->host->eh_action = NULL;
+	/*
+	 * see if timeout.  if so, tell the host to forget about it.
+	 * in other words, we don't want a callback any more.
+	 */
+	if (scsi_eh_eflags_chk(scmd, SCSI_EH_REC_TIMEOUT)) {
+		scsi_eh_eflags_clr(scmd,  SCSI_EH_REC_TIMEOUT);
+		scmd->owner = SCSI_OWNER_LOWLEVEL;
 
 		/*
-		 * see if timeout.  if so, tell the host to forget about it.
-		 * in other words, we don't want a callback any more.
+		 * as far as the low level driver is
+		 * concerned, this command is still active, so
+		 * we must give the low level driver a chance
+		 * to abort it. (db) 
+		 *
+		 * FIXME(eric) - we are not tracking whether we could
+		 * abort a timed out command or not.  not sure how
+		 * we should treat them differently anyways.
 		 */
-		if (scsi_eh_eflags_chk(scmd, SCSI_EH_REC_TIMEOUT)) {
-			scsi_eh_eflags_clr(scmd,  SCSI_EH_REC_TIMEOUT);
-                        scmd->owner = SCSI_OWNER_LOWLEVEL;
-
-			/*
-			 * as far as the low level driver is
-			 * concerned, this command is still active, so
-			 * we must give the low level driver a chance
-			 * to abort it. (db) 
-			 *
-			 * FIXME(eric) - we are not tracking whether we could
-			 * abort a timed out command or not.  not sure how
-			 * we should treat them differently anyways.
-			 */
-			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);
+		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;
+		scmd->request->rq_status = RQ_SCSI_DONE;
+		scmd->owner = SCSI_OWNER_ERROR_HANDLER;
 			
-			rtn = FAILED;
-		}
-		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
-						  __FUNCTION__, scmd, rtn));
-	} else {
-		int temp;
-
-		/*
-		 * we damn well had better never use this code.  there is no
-		 * timeout protection here, since we would end up waiting in
-		 * the actual low level driver, we don't know how to wake it up.
-		 */
-		spin_lock_irqsave(host->host_lock, flags);
-		temp = host->hostt->command(scmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
-
-		scmd->result = temp;
-		/* fall through to code below to examine status. */
+		rtn = FAILED;
 	}
+
+	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
+					  __FUNCTION__, scmd, rtn));
 
 	/*
 	 * now examine the actual status codes to see whether the command
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	Sat Apr 26 13:04:25 2003
+++ b/drivers/scsi/scsi_ioctl.c	Sun Jun  1 14:27:11 2003
@@ -90,75 +90,70 @@
  * The output area is then filled in starting from the command byte. 
  */
 
-static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
+static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
 				  int timeout, int retries)
 {
+	struct scsi_request *sreq;
 	int result;
-	Scsi_Request *SRpnt;
-	Scsi_Device *SDpnt;
 
+	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
 
-	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
-	if (NULL == (SRpnt = scsi_allocate_request(dev))) {
+	sreq = scsi_allocate_request(sdev);
+	if (!sreq) {
 		printk("SCSI internal ioctl failed, no memory\n");
 		return -ENOMEM;
 	}
 
-	SRpnt->sr_data_direction = SCSI_DATA_NONE;
-        scsi_wait_req(SRpnt, cmd, NULL, 0, timeout, retries);
+	sreq->sr_data_direction = SCSI_DATA_NONE;
+        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
 
-	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", SRpnt->sr_result));
+	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
 
-	if (driver_byte(SRpnt->sr_result) != 0)
-		switch (SRpnt->sr_sense_buffer[2] & 0xf) {
+	if (driver_byte(sreq->sr_result)) {
+		switch (sreq->sr_sense_buffer[2] & 0xf) {
 		case ILLEGAL_REQUEST:
 			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
-				dev->lockable = 0;
+				sdev->lockable = 0;
 			else
 				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
 			break;
 		case NOT_READY:	/* This happens if there is no disc in drive */
-			if (dev->removable && (cmd[0] != TEST_UNIT_READY)) {
+			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
 				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
 				break;
 			}
 		case UNIT_ATTENTION:
-			if (dev->removable) {
-				dev->changed = 1;
-				SRpnt->sr_result = 0;	/* This is no longer considered an error */
-				/* gag this error, VFS will log it anyway /axboe */
-				/* printk(KERN_INFO "Disc change detected.\n"); */
+			if (sdev->removable) {
+				sdev->changed = 1;
+				sreq->sr_result = 0;	/* This is no longer considered an error */
 				break;
 			}
 		default:	/* Fall through for non-removable media */
 			printk("SCSI error: host %d id %d lun %d return code = %x\n",
-			       dev->host->host_no,
-			       dev->id,
-			       dev->lun,
-			       SRpnt->sr_result);
+			       sdev->host->host_no,
+			       sdev->id,
+			       sdev->lun,
+			       sreq->sr_result);
 			printk("\tSense class %x, sense error %x, extended sense %x\n",
-			       sense_class(SRpnt->sr_sense_buffer[0]),
-			       sense_error(SRpnt->sr_sense_buffer[0]),
-			       SRpnt->sr_sense_buffer[2] & 0xf);
+			       sense_class(sreq->sr_sense_buffer[0]),
+			       sense_error(sreq->sr_sense_buffer[0]),
+			       sreq->sr_sense_buffer[2] & 0xf);
 
 		}
+	}
 
-	result = SRpnt->sr_result;
-
+	result = sreq->sr_result;
 	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
-	SDpnt = SRpnt->sr_device;
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
-
+	scsi_release_request(sreq);
 	return result;
 }
 
-int scsi_set_medium_removal(Scsi_Device *dev, char state)
+int scsi_set_medium_removal(struct scsi_device *sdev, char state)
 {
 	char scsi_cmd[MAX_COMMAND_SIZE];
 	int ret;
 
-	if (!dev->removable || !dev->lockable)
+	if (!sdev->removable || !sdev->lockable)
 	       return 0;
 
 	scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
@@ -168,11 +163,10 @@
 	scsi_cmd[4] = state;
 	scsi_cmd[5] = 0;
 
-	ret = ioctl_internal_command(dev, scsi_cmd, IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-
+	ret = ioctl_internal_command(sdev, scsi_cmd,
+			IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
 	if (ret == 0)
-		dev->locked = state == SCSI_REMOVAL_PREVENT;
-
+		sdev->locked = (state == SCSI_REMOVAL_PREVENT);
 	return ret;
 }
 
@@ -209,13 +203,13 @@
  */
 #define OMAX_SB_LEN 16		/* Old sense buffer length */
 
-int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic)
+int scsi_ioctl_send_command(struct scsi_device *sdev,
+			    struct scsi_ioctl_command *sic)
 {
 	char *buf;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	char *cmd_in;
-	Scsi_Request *SRpnt;
-	Scsi_Device *SDpnt;
+	struct scsi_request *sreq;
 	unsigned char opcode;
 	unsigned int inlen, outlen, cmdlen;
 	unsigned int needed, buf_needed;
@@ -225,7 +219,7 @@
 	if (!sic)
 		return -EINVAL;
 
-	if (dev->host->unchecked_isa_dma)
+	if (sdev->host->unchecked_isa_dma)
 		gfp_mask |= GFP_DMA;
 
 	/*
@@ -259,11 +253,11 @@
 		buf_needed = (buf_needed + 511) & ~511;
 		if (buf_needed > MAX_BUF)
 			buf_needed = MAX_BUF;
-		buf = (char *) kmalloc(buf_needed, gfp_mask);
+		buf = kmalloc(buf_needed, gfp_mask);
 		if (!buf)
 			return -ENOMEM;
 		memset(buf, 0, buf_needed);
-		if( inlen == 0 ) {
+		if (inlen == 0) {
 			data_direction = SCSI_DATA_READ;
 		} else if (outlen == 0 ) {
 			data_direction = SCSI_DATA_WRITE;
@@ -327,62 +321,34 @@
 		break;
 	}
 
-#ifndef DEBUG_NO_CMD
-
-
-	SRpnt = scsi_allocate_request(dev);
-        if( SRpnt == NULL )
-        {
+	sreq = scsi_allocate_request(sdev);
+        if (sreq) {
                 result = -EINTR;
                 goto error;
         }
 
-	SRpnt->sr_data_direction = data_direction;
-        scsi_wait_req(SRpnt, cmd, buf, needed, timeout, retries);
+	sreq->sr_data_direction = data_direction;
+        scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
 
 	/* 
 	 * If there was an error condition, pass the info back to the user. 
 	 */
-
-	result = SRpnt->sr_result;
-
-	if (SRpnt->sr_result) {
-		int sb_len = sizeof(SRpnt->sr_sense_buffer);
+	result = sreq->sr_result;
+	if (result) {
+		int sb_len = sizeof(sreq->sr_sense_buffer);
 
 		sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
-		if (copy_to_user(cmd_in, SRpnt->sr_sense_buffer, sb_len))
+		if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len))
 			result = -EFAULT;
 	} else {
 		if (copy_to_user(cmd_in, buf, outlen))
 			result = -EFAULT;
 	}	
 
-	SDpnt = SRpnt->sr_device;
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
-
+	scsi_release_request(sreq);
 error:
-	if (buf)
-		kfree(buf);
-
-
+	kfree(buf);
 	return result;
-#else
-	{
-		int i;
-		printk("scsi_ioctl : device %d.  command = ", dev->id);
-		for (i = 0; i < cmdlen; ++i)
-			printk("%02x ", cmd[i]);
-		printk("\nbuffer =");
-		for (i = 0; i < 20; ++i)
-			printk("%02x ", buf[i]);
-		printk("\n");
-		printk("inlen = %d, outlen = %d, cmdlen = %d\n",
-		       inlen, outlen, cmdlen);
-		printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
-	}
-	return 0;
-#endif
 }
 
 /*
@@ -395,14 +361,13 @@
  *                  device)
  *          any copy_to_user() error on failure there
  */
-static int
-scsi_ioctl_get_pci(Scsi_Device * sdev, void *arg)
+static int scsi_ioctl_get_pci(struct scsi_device *sdev, void *arg)
 {
 	struct device *dev = scsi_get_device(sdev->host);
 
-        if (!dev) return -ENXIO;
-        return copy_to_user(arg, dev->bus_id,
-                            sizeof(dev->bus_id));
+        if (!dev)
+		return -ENXIO;
+        return copy_to_user(arg, dev->bus_id, sizeof(dev->bus_id));
 }
 
 
@@ -411,12 +376,12 @@
  * not take a major/minor number as the dev field.  Rather, it takes
  * a pointer to a scsi_devices[] element, a structure. 
  */
-int scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
+int scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
 {
 	char scsi_cmd[MAX_COMMAND_SIZE];
 
 	/* No idea how this happens.... */
-	if (!dev)
+	if (!sdev)
 		return -ENXIO;
 
 	/*
@@ -425,24 +390,24 @@
 	 * may try and take the device offline, in which case all further
 	 * access to the device is prohibited.
 	 */
-	if (!scsi_block_when_processing_errors(dev)) {
+	if (!scsi_block_when_processing_errors(sdev))
 		return -ENODEV;
-	}
 
 	switch (cmd) {
 	case SCSI_IOCTL_GET_IDLUN:
-		if (verify_area(VERIFY_WRITE, arg, sizeof(Scsi_Idlun)))
+		if (verify_area(VERIFY_WRITE, arg, sizeof(struct scsi_idlun)))
 			return -EFAULT;
 
-		__put_user((dev->id & 0xff)
-			 + ((dev->lun & 0xff) << 8)
-			 + ((dev->channel & 0xff) << 16)
-			 + ((dev->host->host_no & 0xff) << 24),
-			 &((Scsi_Idlun *) arg)->dev_id);
-		__put_user(dev->host->unique_id, &((Scsi_Idlun *) arg)->host_unique_id);
+		__put_user((sdev->id & 0xff)
+			 + ((sdev->lun & 0xff) << 8)
+			 + ((sdev->channel & 0xff) << 16)
+			 + ((sdev->host->host_no & 0xff) << 24),
+			 &((struct scsi_idlun *)arg)->dev_id);
+		__put_user(sdev->host->unique_id,
+			 &((struct scsi_idlun *)arg)->host_unique_id);
 		return 0;
 	case SCSI_IOCTL_GET_BUS_NUMBER:
-		return put_user(dev->host->host_no, (int *) arg);
+		return put_user(sdev->host->host_no, (int *)arg);
 	/*
 	 * The next two ioctls either need to go or need to be changed to
 	 * pass tagged queueing changes through the low level drivers.
@@ -454,61 +419,56 @@
 	case SCSI_IOCTL_TAGGED_ENABLE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (!dev->tagged_supported)
+		if (!sdev->tagged_supported)
 			return -EINVAL;
-		dev->tagged_queue = 1;
-		dev->current_tag = 1;
+		sdev->tagged_queue = 1;
+		sdev->current_tag = 1;
 		return 0;
 	case SCSI_IOCTL_TAGGED_DISABLE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (!dev->tagged_supported)
+		if (!sdev->tagged_supported)
 			return -EINVAL;
-		dev->tagged_queue = 0;
-		dev->current_tag = 0;
+		sdev->tagged_queue = 0;
+		sdev->current_tag = 0;
 		return 0;
 	case SCSI_IOCTL_PROBE_HOST:
-		return ioctl_probe(dev->host, arg);
+		return ioctl_probe(sdev->host, arg);
 	case SCSI_IOCTL_SEND_COMMAND:
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return scsi_ioctl_send_command((Scsi_Device *) dev,
-					     (Scsi_Ioctl_Command *) arg);
+		return scsi_ioctl_send_command(sdev,
+				(struct scsi_ioctl_command *)arg);
 	case SCSI_IOCTL_DOORLOCK:
-		return scsi_set_medium_removal(dev, SCSI_REMOVAL_PREVENT);
+		return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
 	case SCSI_IOCTL_DOORUNLOCK:
-		return scsi_set_medium_removal(dev, SCSI_REMOVAL_ALLOW);
+		return scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
 	case SCSI_IOCTL_TEST_UNIT_READY:
 		scsi_cmd[0] = TEST_UNIT_READY;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 0;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				   IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-		break;
 	case SCSI_IOCTL_START_UNIT:
 		scsi_cmd[0] = START_STOP;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 1;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				     START_STOP_TIMEOUT, NORMAL_RETRIES);
-		break;
 	case SCSI_IOCTL_STOP_UNIT:
 		scsi_cmd[0] = START_STOP;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 0;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				     START_STOP_TIMEOUT, NORMAL_RETRIES);
-		break;
         case SCSI_IOCTL_GET_PCI:
-                return scsi_ioctl_get_pci(dev, arg);
-                break;
+                return scsi_ioctl_get_pci(sdev, arg);
 	default:
-		if (dev->host->hostt->ioctl)
-			return dev->host->hostt->ioctl(dev, cmd, arg);
-		return -EINVAL;
+		if (sdev->host->hostt->ioctl)
+			return sdev->host->hostt->ioctl(sdev, cmd, arg);
 	}
 	return -EINVAL;
 }
@@ -518,13 +478,13 @@
  * fs segment fiddling.
  */
 
-int kernel_scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
+int kernel_scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
 {
 	mm_segment_t oldfs;
 	int tmp;
 	oldfs = get_fs();
 	set_fs(get_ds());
-	tmp = scsi_ioctl(dev, cmd, arg);
+	tmp = scsi_ioctl(sdev, cmd, arg);
 	set_fs(oldfs);
 	return tmp;
 }
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon May 26 02:50:43 2003
+++ b/drivers/scsi/scsi_lib.c	Wed Jun  4 04:43:01 2003
@@ -95,7 +95,6 @@
 {
 	struct Scsi_Host *host = cmd->device->host;
 	struct scsi_device *device = cmd->device;
-	unsigned long flags;
 
 	SCSI_LOG_MLQUEUE(1,
 		 printk("Inserting command %p into mlqueue\n", cmd));
@@ -134,10 +133,7 @@
 	 * Decrement the counters, since these commands are no longer
 	 * active on the host/device.
 	 */
-	spin_lock_irqsave(device->request_queue->queue_lock, flags);
-	device->device_busy--;
-	spin_unlock_irqrestore(device->request_queue->queue_lock, flags);
-	scsi_host_busy_dec_and_test(host, device);
+	scsi_device_unbusy(device);
 
 	/*
 	 * Insert this command at the head of the queue for it's device.
@@ -314,6 +310,21 @@
 	cmd->underflow = cmd->old_underflow;
 }
 
+void scsi_device_unbusy(struct scsi_device *sdev)
+{
+	struct Scsi_Host *shost = sdev->host;
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	shost->host_busy--;
+	if (unlikely(shost->in_recovery && shost->host_failed))
+		scsi_eh_wakeup(shost);
+	spin_unlock(shost->host_lock);
+	spin_lock(&sdev->sdev_lock);
+	sdev->device_busy--;
+	spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+}
+
 /*
  * Called for single_lun devices on IO completion. Clear starget_sdev_user,
  * and call blk_run_queue for all the scsi_devices on the target -
@@ -730,17 +741,6 @@
 	 * can choose a block to remap, etc.
 	 */
 	if (driver_byte(result) != 0) {
-		if (suggestion(result) == SUGGEST_REMAP) {
-#ifdef REMAP
-			/*
-			 * Not yet implemented.  A read will fail after being remapped,
-			 * a write will call the strategy routine again.
-			 */
-			if (cmd->device->remap) {
-				result = 0;
-			}
-#endif
-		}
 		if ((cmd->sense_buffer[0] & 0x7f) == 0x70) {
 			/*
 			 * If the device is in the process of becoming ready,
@@ -944,6 +944,18 @@
 		} else
 			cmd = req->special;
 	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+		/*
+		 * Just check to see if the device is online.  If
+		 * it isn't, we refuse to process ordinary commands
+		 * (we will allow specials just in case someone needs
+		 * to send a command to an offline device without bringing
+		 * it back online)
+		 */
+		if(!sdev->online) {
+			printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
+			       sdev->host->host_no, sdev->id, sdev->lun);
+			return BLKPREP_KILL;
+		}
 		/*
 		 * Now try and find a command block that we can use.
 		 */
diff -Nru a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c
--- a/drivers/scsi/scsi_module.c	Tue Feb  5 07:23:03 2002
+++ b/drivers/scsi/scsi_module.c	Thu Jun  5 11:52:51 2003
@@ -1,71 +1,73 @@
 /*
- *  scsi_module.c Copyright (1994, 1995) Eric Youngdale.
+ * Copyright (C) 2003 Christoph Hellwig.
+ *	Released under GPL v2.
  *
- * Support for loading low-level scsi drivers using the linux kernel loadable
- * module interface.
+ * Support for old-style host templates.
  *
- * To use, the host adapter should first define and initialize the variable
- * driver_template (datatype Scsi_Host_Template), and then include this file.
- * This should also be wrapped in a #ifdef MODULE/#endif.
- *
- * The low -level driver must also define a release function which will
- * free any irq assignments, release any dma channels, release any I/O
- * address space that might be reserved, and otherwise clean up after itself.
- * The idea is that the same driver should be able to be reloaded without
- * any difficulty.  This makes debugging new drivers easier, as you should
- * be able to load the driver, test it, unload, modify and reload.
- *
- * One *very* important caveat.  If the driver may need to do DMA on the
- * ISA bus, you must have unchecked_isa_dma set in the device template,
- * even if this might be changed during the detect routine.  This is
- * because the shpnt structure will be allocated in a special way so that
- * it will be below the appropriate DMA limit - thus if your driver uses
- * the hostdata field of shpnt, and the board must be able to access this
- * via DMA, the shpnt structure must be in a DMA accessible region of
- * memory.  This comment would be relevant for something like the buslogic
- * driver where there are many boards, only some of which do DMA onto the
- * ISA bus.  There is no convenient way of specifying whether the host
- * needs to be in a ISA DMA accessible region of memory when you call
- * scsi_register.
+ * NOTE:  Do not use this for new drivers ever.
  */
 
-#include <linux/module.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "scsi.h"
+#include "hosts.h"
+
 
 static int __init init_this_scsi_driver(void)
 {
-	driver_template.module = THIS_MODULE;
-	scsi_register_host(&driver_template);
-	if (driver_template.present)
-		return 0;
-
-	scsi_unregister_host(&driver_template);
-	return -ENODEV;
+	struct scsi_host_template *sht = &driver_template;
+	struct Scsi_Host *shost;
+	struct list_head *l;
+	int error;
+
+	if (!sht->release) {
+		printk(KERN_ERR
+		    "scsi HBA driver %s didn't set a release method.\n",
+		    sht->name);
+		return -EINVAL;
+	}
+
+	sht->module = THIS_MODULE;
+	INIT_LIST_HEAD(&sht->legacy_hosts);
+
+	sht->detect(sht);
+	if (!sht->present)
+		return -ENODEV;
+
+	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
+		error = scsi_add_host(shost, NULL);
+		if (error)
+			goto fail;
+	}
+	return 0;
+ fail:
+	l = &shost->sht_legacy_list;
+	while ((l = l->prev) != &sht->legacy_hosts)
+		scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list));
+	return error;
 }
 
 static void __exit exit_this_scsi_driver(void)
 {
-	scsi_unregister_host(&driver_template);
+	struct scsi_host_template *sht = &driver_template;
+	struct Scsi_Host *shost, *s;
+
+	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list)
+		scsi_remove_host(shost);
+	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
+		sht->release(shost);
+
+	if (list_empty(&sht->legacy_hosts))
+		return;
+
+	printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name);
+	dump_stack();
+
+	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
+		scsi_unregister(shost);
 }
 
 module_init(init_this_scsi_driver);
 module_exit(exit_this_scsi_driver);
-
-/*
- * Overrides for Emacs so that we almost 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-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	Mon May 26 09:09:20 2003
+++ b/drivers/scsi/scsi_priv.h	Thu Jun  5 11:49:12 2003
@@ -52,13 +52,6 @@
 };
 
 
-/* hosts.c */
-extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
-extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
-extern struct Scsi_Host *scsi_host_lookup(unsigned short);
-extern void scsi_host_put(struct Scsi_Host *);
-extern void scsi_host_init(void);
-
 /* scsi.c */
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
@@ -80,11 +73,13 @@
 extern void scsi_times_out(struct scsi_cmnd *cmd);
 extern void scsi_error_handler(void *host);
 extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
+extern void scsi_eh_wakeup(struct Scsi_Host *shost);
 extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
 
 /* scsi_lib.c */
 extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
 extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
+extern void scsi_device_unbusy(struct scsi_device *sdev);
 extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
 extern void scsi_next_command(struct scsi_cmnd *cmd);
 extern void scsi_run_host_queues(struct Scsi_Host *shost);
@@ -107,12 +102,11 @@
 #endif /* CONFIG_PROC_FS */
 
 /* scsi_scan.c */
-extern void scsi_scan_host(struct Scsi_Host *shost);
-extern void scsi_forget_host(struct Scsi_Host *shost);
+extern void scsi_scan_host(struct Scsi_Host *);
+extern void scsi_forget_host(struct Scsi_Host *);
 extern void scsi_free_sdev(struct scsi_device *);
 extern void scsi_free_shost(struct Scsi_Host *);
-extern void scsi_host_get(struct Scsi_Host *);
-extern void scsi_rescan_device(struct device *dev);
+extern void scsi_rescan_device(struct device *);
 
 /* scsi_sysfs.c */
 extern int scsi_device_register(struct scsi_device *);
diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
--- a/drivers/scsi/scsi_proc.c	Mon May 26 09:04:01 2003
+++ b/drivers/scsi/scsi_proc.c	Wed Jun 11 19:47:21 2003
@@ -42,48 +42,15 @@
 EXPORT_SYMBOL(proc_scsi);
 
 
-/* Used if the driver currently has no own support for /proc/scsi */
-static int generic_proc_info(char *buffer, char **start, off_t offset,
-			     int count, const char *(*info)(struct Scsi_Host *),
-			     struct Scsi_Host *shost)
-{
-	int len, pos, begin = 0;
-	static const char noprocfs[] =
-		"The driver does not yet support the proc-fs\n";
-
-	if (info && shost)
-		len = sprintf(buffer, "%s\n", info(shost));
-	else
-		len = sprintf(buffer, "%s\n", noprocfs);
-
-	pos = len;
-	if (pos < offset) {
-		len = 0;
-		begin = pos;
-	}
-
-	*start = buffer + (offset - begin);
-	len -= (offset - begin);
-	if (len > count)
-		len = count;
-
-	return len;
-}
-
 static int proc_scsi_read(char *buffer, char **start, off_t offset,
 			  int length, int *eof, void *data)
 {
 	struct Scsi_Host *shost = data;
 	int n;
 
-	if (shost->hostt->proc_info == NULL)
-		n = generic_proc_info(buffer, start, offset, length,
-				      shost->hostt->info, shost);
-	else
-		n = shost->hostt->proc_info(shost, buffer, start, offset,
-					   length, 0);
-
+	n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0);
 	*eof = (n < length);
+
 	return n;
 }
 
@@ -95,8 +62,6 @@
 	char *page;
 	char *start;
     
-	if (!shost->hostt->proc_info)
-		return -ENOSYS;
 	if (count > PROC_BLOCK_SIZE)
 		return -EOVERFLOW;
 
@@ -114,10 +79,13 @@
 
 void scsi_proc_host_add(struct Scsi_Host *shost)
 {
-	Scsi_Host_Template *sht = shost->hostt;
+	struct scsi_host_template *sht = shost->hostt;
 	struct proc_dir_entry *p;
 	char name[10];
 
+	if (!sht->proc_info)
+		return;
+
 	if (!sht->proc_dir) {
 		sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
         	if (!sht->proc_dir) {
@@ -130,27 +98,29 @@
 
 	sprintf(name,"%d", shost->host_no);
 	p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
-			shost->hostt->proc_dir, proc_scsi_read, shost);
+			sht->proc_dir, proc_scsi_read, shost);
 	if (!p) {
 		printk(KERN_ERR "%s: Failed to register host %d in"
 		       "%s\n", __FUNCTION__, shost->host_no,
-		       shost->hostt->proc_name);
+		       sht->proc_name);
 		return;
 	} 
 
 	p->write_proc = proc_scsi_write_proc;
 	p->owner = shost->hostt->module;
-
 }
 
 void scsi_proc_host_rm(struct Scsi_Host *shost)
 {
+	struct scsi_host_template *sht = shost->hostt;
 	char name[10];
 
-	sprintf(name,"%d", shost->host_no);
-	remove_proc_entry(name, shost->hostt->proc_dir);
-	if (!shost->hostt->present)
-		remove_proc_entry(shost->hostt->proc_name, proc_scsi);
+	if (sht->proc_info) {
+		sprintf(name,"%d", shost->host_no);
+		remove_proc_entry(name, sht->proc_dir);
+		if (!sht->present)
+			remove_proc_entry(sht->proc_name, proc_scsi);
+	}
 }
 
 static int proc_print_scsidevice(struct device *dev, void *data)
@@ -244,8 +214,8 @@
 	return error;
 }
 
-static int proc_scsi_write(struct file *file, const char* buf,
-                           size_t length, loff_t *ppos)
+static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
+			       size_t length, loff_t *ppos)
 {
 	int host, channel, id, lun;
 	char *buffer, *p;
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Sun Jun 15 13:38:43 2003
+++ b/drivers/scsi/scsi_scan.c	Mon Jun 16 17:22:18 2003
@@ -27,6 +27,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/blk.h>
 
@@ -72,29 +73,9 @@
 static unsigned int max_scsi_luns = 1;
 #endif
 
-#ifdef MODULE
-MODULE_PARM(max_scsi_luns, "i");
-MODULE_PARM_DESC(max_scsi_luns,
+module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(max_luns,
 		 "last scsi LUN (should be between 1 and 2^32-1)");
-#else
-
-static int __init scsi_luns_setup(char *str)
-{
-	unsigned int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		max_scsi_luns = tmp;
-		return 1;
-	} else {
-		printk(KERN_WARNING "scsi_luns_setup: usage max_scsi_luns=n "
-		       "(n should be between 1 and 2^32-1)\n");
-		return 0;
-	}
-}
-
-__setup("max_scsi_luns=", scsi_luns_setup);
-
-#endif
 
 #ifdef CONFIG_SCSI_REPORT_LUNS
 /*
@@ -106,29 +87,10 @@
  */
 static unsigned int max_scsi_report_luns = 128;
 
-#ifdef MODULE
-MODULE_PARM(max_scsi_report_luns, "i");
-MODULE_PARM_DESC(max_scsi_report_luns,
+module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(max_report_luns,
 		 "REPORT LUNS maximum number of LUNS received (should be"
 		 " between 1 and 16384)");
-#else
-static int __init scsi_report_luns_setup(char *str)
-{
-	unsigned int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		max_scsi_report_luns = tmp;
-		return 1;
-	} else {
-		printk(KERN_WARNING "scsi_report_luns_setup: usage"
-		       " max_scsi_report_luns=n (n should be between 1"
-		       " and 16384)\n");
-		return 0;
-	}
-}
-
-__setup("max_scsi_report_luns=", scsi_report_luns_setup);
-#endif
 #endif
 
 /**
@@ -141,7 +103,8 @@
  *     @sreq to unlock a device, storing the (unused) results into result.
  *     Called for BLIST_KEY devices.
  **/
-static void scsi_unlock_floptical(Scsi_Request *sreq, unsigned char *result)
+static void scsi_unlock_floptical(struct scsi_request *sreq,
+				  unsigned char *result)
 {
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 
@@ -154,8 +117,7 @@
 	scsi_cmd[5] = 0;
 	sreq->sr_cmd_len = 0;
 	sreq->sr_data_direction = SCSI_DATA_READ;
-	scsi_wait_req(sreq, (void *) scsi_cmd, (void *) result, 0x2a /* size */,
-		      SCSI_TIMEOUT, 3);
+	scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
 }
 
 /**
@@ -354,10 +316,10 @@
  *     are copied to the Scsi_Device at @sreq->sr_device (sdev);
  *     any flags value is stored in *@bflags.
  **/
-static void scsi_probe_lun(Scsi_Request *sreq, char *inq_result,
+static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
 			   int *bflags)
 {
-	Scsi_Device *sdev = sreq->sr_device;	/* a bit ugly */
+	struct scsi_device *sdev = sreq->sr_device;	/* a bit ugly */
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 	int possible_inq_resp_len;
 
@@ -522,7 +484,7 @@
  *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
  *     SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
  **/
-static int scsi_add_lun(Scsi_Device *sdev, char *inq_result, int *bflags)
+static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
 {
 	struct scsi_device *sdev_sibling;
 	struct scsi_target *starget;
@@ -578,8 +540,6 @@
 	default:
 		printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type);
 	}
-
-	sdev->random = (sdev->type == TYPE_TAPE) ? 0 : 1;
 
 	scsi_set_name(sdev, inq_result);
 
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Mon May 26 03:03:34 2003
+++ b/drivers/scsi/scsi_syms.c	Thu Jun  5 04:26:04 2003
@@ -31,10 +31,12 @@
  */
 EXPORT_SYMBOL(scsi_register_driver);
 EXPORT_SYMBOL(scsi_register_interface);
-EXPORT_SYMBOL(scsi_register_host);
-EXPORT_SYMBOL(scsi_unregister_host);
+EXPORT_SYMBOL(scsi_host_alloc);
 EXPORT_SYMBOL(scsi_add_host);
 EXPORT_SYMBOL(scsi_remove_host);
+EXPORT_SYMBOL(scsi_host_get);
+EXPORT_SYMBOL(scsi_host_put);
+EXPORT_SYMBOL(scsi_host_lookup);
 EXPORT_SYMBOL(scsi_register);
 EXPORT_SYMBOL(scsi_unregister);
 EXPORT_SYMBOL(scsicam_bios_param);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Mon May 26 08:45:44 2003
+++ b/drivers/scsi/scsi_sysfs.c	Thu Jun  5 11:52:51 2003
@@ -487,7 +487,7 @@
 }
 EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
 
-void scsi_sysfs_release_attributes(struct SHT *hostt)
+void scsi_sysfs_release_attributes(struct scsi_host_template *hostt)
 {
 	if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs)
 		kfree(hostt->sdev_attrs);
diff -Nru a/drivers/scsi/scsi_typedefs.h b/drivers/scsi/scsi_typedefs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_typedefs.h	Thu Jun  5 11:47:24 2003
@@ -0,0 +1,6 @@
+
+typedef struct scsi_host_template Scsi_Host_Template;
+typedef struct scsi_device Scsi_Device;
+typedef struct scsi_cmnd Scsi_Cmnd;
+typedef struct scsi_request Scsi_Request;
+typedef struct scsi_pointer Scsi_Pointer;
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Sun Jun 15 13:38:43 2003
+++ b/drivers/scsi/sd.c	Tue Jun 17 02:17:15 2003
@@ -76,6 +76,7 @@
 	struct scsi_driver *driver;	/* always &sd_template */
 	struct scsi_device *device;
 	struct gendisk	*disk;
+	unsigned int	openers;	/* protected by BKL for now, yuck */
 	sector_t	capacity;	/* size in 512-byte sectors */
 	u32		index;
 	u8		media_present;
@@ -87,7 +88,7 @@
 static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
 static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
 
-static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk);
+static int sd_revalidate_disk(struct gendisk *disk);
 static void sd_rw_intr(struct scsi_cmnd * SCpnt);
 
 static int sd_probe(struct device *);
@@ -95,7 +96,6 @@
 static void sd_shutdown(struct device *dev);
 static void sd_rescan(struct device *);
 static int sd_init_command(struct scsi_cmnd *);
-static int sd_synchronize_cache(struct scsi_disk *, int);
 static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 		 struct scsi_request *SRpnt, unsigned char *buffer);
 
@@ -396,9 +396,10 @@
 	if (!sdev->online)
 		goto error_out;
 
-	if (sdev->removable && sdev->access_count == 1)
+	if (!sdkp->openers++ && sdev->removable) {
 		if (scsi_block_when_processing_errors(sdev))
 			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
+	}
 
 	return 0;
 
@@ -421,13 +422,15 @@
 static int sd_release(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct scsi_device *sdev = scsi_disk(disk)->device;
+	struct scsi_disk *sdkp = scsi_disk(disk);
+	struct scsi_device *sdev = sdkp->device;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
 
-	if (sdev->removable && sdev->access_count == 1)
+	if (!--sdkp->openers && sdev->removable) {
 		if (scsi_block_when_processing_errors(sdev))
 			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
+	}
 
 	/*
 	 * XXX and what if there are packets in flight and this close()
@@ -566,7 +569,7 @@
 	 * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
 	 *
 	 * Drives that auto spin down. eg iomega jaz 1G, will be started
-	 * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever
+	 * by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
 	 * sd_revalidate() is called.
 	 */
 	retval = -ENODEV;
@@ -632,15 +635,6 @@
 	kfree(buffer);
 }
 
-static int sd_revalidate_disk(struct gendisk *disk)
-{
-	struct scsi_disk *sdkp = scsi_disk(disk);
-
-	sd_init_onedisk(sdkp, disk);
-	set_capacity(disk, sdkp->capacity);
-	return 0;
-}
-
 static struct block_device_operations sd_fops = {
 	.owner			= THIS_MODULE,
 	.open			= sd_open,
@@ -772,7 +766,7 @@
 }
 
 /*
- * spinup disk - called only in sd_init_onedisk()
+ * spinup disk - called only in sd_revalidate_disk()
  */
 static void
 sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
@@ -856,7 +850,7 @@
 				SRpnt->sr_sense_buffer[0] = 0;
 				SRpnt->sr_sense_buffer[2] = 0;
 
-				SRpnt->sr_data_direction = SCSI_DATA_READ;
+				SRpnt->sr_data_direction = SCSI_DATA_NONE;
 				scsi_wait_req(SRpnt, (void *)cmd, 
 					      (void *) buffer, 0/*512*/, 
 					      SD_TIMEOUT, SD_MAX_RETRIES);
@@ -892,7 +886,7 @@
 }
 
 /*
- * read disk capacity - called only in sd_init_onedisk()
+ * read disk capacity
  */
 static void
 sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
@@ -1105,7 +1099,7 @@
 }
 
 /*
- * read write protect setting, if possible - called only in sd_init_onedisk()
+ * read write protect setting, if possible - called only in sd_revalidate_disk()
  * called with buffer of length 512
  */
 static void
@@ -1147,7 +1141,7 @@
 }
 
 /*
- * sd_read_cache_type - called only from sd_init_onedisk()
+ * sd_read_cache_type - called only from sd_revalidate_disk()
  * called with buffer of length 512
  */
 static void
@@ -1206,71 +1200,69 @@
 }
 
 /**
- *	sd_init_onedisk - called the first time a new disk is seen,
+ *	sd_revalidate_disk - called the first time a new disk is seen,
  *	performs disk spin up, read_capacity, etc.
- *	@sdkp: pointer to associated struct scsi_disk object
- *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
- *	1->/dev/sdb, etc)
- *
- *	Note: this function is local to this driver.
+ *	@disk: struct gendisk we care about
  **/
-static void
-sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk)
+static int sd_revalidate_disk(struct gendisk *disk)
 {
+	struct scsi_disk *sdkp = scsi_disk(disk);
+	struct scsi_device *sdp = sdkp->device;
+	struct scsi_request *sreq;
 	unsigned char *buffer;
-	struct scsi_device *sdp;
-	struct scsi_request *SRpnt;
 
-	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: disk=%s\n", disk->disk_name));
+	SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
 
 	/*
 	 * If the device is offline, don't try and read capacity or any
 	 * of the other niceties.
 	 */
-	sdp = sdkp->device;
-	if (sdp->online == FALSE)
-		return;
+	if (!sdp->online)
+		goto out;
 
-	SRpnt = scsi_allocate_request(sdp);
-	if (!SRpnt) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
+	sreq = scsi_allocate_request(sdp);
+	if (!sreq) {
+		printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation "
 		       "failure.\n");
-		return;
+		goto out;
 	}
 
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA);
 	if (!buffer) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
+		printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation "
 		       "failure.\n");
-		goto leave;
+		goto out_release_request;
 	}
 
 	/* defaults, until the device tells us otherwise */
+	sdp->sector_size = 512;
 	sdkp->capacity = 0;
-	sdkp->device->sector_size = 512;
 	sdkp->media_present = 1;
 	sdkp->write_prot = 0;
 	sdkp->WCE = 0;
 	sdkp->RCD = 0;
 
-	sd_spinup_disk(sdkp, disk->disk_name, SRpnt, buffer);
+	sd_spinup_disk(sdkp, disk->disk_name, sreq, buffer);
 
-	if (sdkp->media_present)
-		sd_read_capacity(sdkp, disk->disk_name, SRpnt, buffer);
-	
-	if (sdp->removable && sdkp->media_present)
-		sd_read_write_protect_flag(sdkp, disk->disk_name, SRpnt, buffer);
-	/* without media there is no reason to ask;
-	   moreover, some devices react badly if we do */
-	if (sdkp->media_present)
-		sd_read_cache_type(sdkp, disk->disk_name, SRpnt, buffer);
+	/*
+	 * Without media there is no reason to ask; moreover, some devices
+	 * react badly if we do.
+	 */
+	if (sdkp->media_present) {
+		sd_read_capacity(sdkp, disk->disk_name, sreq, buffer);
+		if (sdp->removable)
+			sd_read_write_protect_flag(sdkp, disk->disk_name,
+					sreq, buffer);
+		sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer);
+	}
 		
-	SRpnt->sr_device->remap = 1;
-
- leave:
-	scsi_release_request(SRpnt);
-
+	set_capacity(disk, sdkp->capacity);
 	kfree(buffer);
+
+ out_release_request: 
+	scsi_release_request(sreq);
+ out:
+	return 0;
 }
 
 /**
@@ -1329,6 +1321,7 @@
 	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
 	sdkp->index = index;
+	sdkp->openers = 0;
 
 	gd->major = sd_major(index >> 4);
 	gd->first_minor = (index & 15) << 4;
@@ -1344,16 +1337,16 @@
 
 	strcpy(gd->devfs_name, sdp->devfs_name);
 
-	sd_init_onedisk(sdkp, gd);
+	gd->private_data = &sdkp->driver;
+
+	sd_revalidate_disk(gd);
 
 	gd->driverfs_dev = &sdp->sdev_driverfs_dev;
 	gd->flags = GENHD_FL_DRIVERFS;
 	if (sdp->removable)
 		gd->flags |= GENHD_FL_REMOVABLE;
-	gd->private_data = &sdkp->driver;
 	gd->queue = sdkp->device->request_queue;
 
-	set_capacity(gd, sdkp->capacity);
 	dev_set_drvdata(dev, sdkp);
 	add_disk(gd);
 
@@ -1400,16 +1393,57 @@
 	return 0;
 }
 
+/*
+ * Send a SYNCHRONIZE CACHE instruction down to the device through
+ * the normal SCSI command structure.  Wait for the command to
+ * complete.
+ */
 static void sd_shutdown(struct device *dev)
 {
+	struct scsi_device *sdp = to_scsi_device(dev);
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
+	struct scsi_request *sreq;
+	int retries, res;
 
-	if (sdkp->WCE) {
-		printk(KERN_NOTICE "Synchronizing SCSI cache: ");
-		sd_synchronize_cache(sdkp, 1);
-		printk("\n");
+	if (!sdp->online || !sdkp->WCE)
+		return;
+
+	printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: ",
+			sdkp->disk->disk_name);
+
+	sreq = scsi_allocate_request(sdp);
+	if (!sreq) {
+		printk("FAILED\n  No memory for request\n");
+		return;
 	}
-}
+
+	sreq->sr_data_direction = SCSI_DATA_NONE;
+	for (retries = 3; retries > 0; --retries) {
+		unsigned char cmd[10] = { 0 };
+
+		cmd[0] = SYNCHRONIZE_CACHE;
+		/*
+		 * Leave the rest of the command zero to indicate
+		 * flush everything.
+		 */
+		scsi_wait_req(sreq, cmd, NULL, 0, SD_TIMEOUT, SD_MAX_RETRIES);
+		if (sreq->sr_result == 0)
+			break;
+	}
+
+	res = sreq->sr_result;
+	if (res) {
+		printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
+				    "host = %d, driver = %02x\n  ",
+				    status_byte(res), msg_byte(res),
+				    host_byte(res), driver_byte(res));
+			if (driver_byte(res) & DRIVER_SENSE)
+				print_req_sense("sd", sreq);
+	}
+	
+	scsi_release_request(sreq);
+	printk("\n");
+}	
 
 /**
  *	init_sd - entry point for this driver (both when built in or when
@@ -1447,60 +1481,6 @@
 	scsi_unregister_driver(&sd_template.gendrv);
 	for (i = 0; i < SD_MAJORS; i++)
 		unregister_blkdev(sd_major(i), "sd");
-}
-
-/* send a SYNCHRONIZE CACHE instruction down to the device through the
- * normal SCSI command structure.  Wait for the command to complete (must
- * have user context) */
-static int sd_synchronize_cache(struct scsi_disk *sdkp, int verbose)
-{
-	struct scsi_request *SRpnt;
-	struct scsi_device *SDpnt = sdkp->device;
-	int retries, the_result;
-
-	if (!SDpnt->online)
-		return 0;
-
-	if (verbose)
-		printk("%s ", sdkp->disk->disk_name);
-
-	SRpnt = scsi_allocate_request(SDpnt);
-	if(!SRpnt) {
-		if(verbose)
-			printk("FAILED\n  No memory for request\n");
-		return 0;
-	}
-
-	SRpnt->sr_data_direction = SCSI_DATA_NONE;
-
-	for(retries = 3; retries > 0; --retries) {
-		unsigned char cmd[10] = { 0 };
-
-		cmd[0] = SYNCHRONIZE_CACHE;
-		/* leave the rest of the command zero to indicate 
-		 * flush everything */
-		scsi_wait_req(SRpnt, (void *)cmd, NULL, 0,
-			      SD_TIMEOUT, SD_MAX_RETRIES);
-
-		if(SRpnt->sr_result == 0)
-			break;
-	}
-
-	the_result = SRpnt->sr_result;
-	if(verbose) {
-		if(the_result != 0) {
-			printk("FAILED\n  status = %x, message = %02x, host = %d, driver = %02x\n  ",
-			       status_byte(the_result),
-			       msg_byte(the_result),
-			       host_byte(the_result),
-			       driver_byte(the_result));
-			if (driver_byte(the_result) & DRIVER_SENSE)
-				print_req_sense("sd", SRpnt);
-
-		}
-	}
-	scsi_release_request(SRpnt);
-	return (the_result == 0);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Sun May  4 02:56:46 2003
+++ b/drivers/scsi/seagate.c	Sun Jun  8 12:18:41 2003
@@ -729,13 +729,6 @@
 	return 0;
 }
 
-static int seagate_st0x_command(Scsi_Cmnd * SCpnt)
-{
-	return internal_command (SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd,
-				 SCpnt->request_buffer, SCpnt->request_bufflen,
-				 (int) NO_RECONNECT);
-}
-
 static int internal_command (unsigned char target, unsigned char lun,
 		  const void *cmnd, void *buff, int bufflen, int reselect)
 {
@@ -1704,7 +1697,6 @@
 	.detect         	= seagate_st0x_detect,
 	.release        	= seagate_st0x_release,
 	.info           	= seagate_st0x_info,
-	.command        	= seagate_st0x_command,
 	.queuecommand   	= seagate_st0x_queue_command,
 	.eh_abort_handler	= seagate_st0x_abort,
 	.eh_bus_reset_handler	= seagate_st0x_bus_reset,
diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
--- a/drivers/scsi/sim710.c	Sun May 25 17:00:00 2003
+++ b/drivers/scsi/sim710.c	Tue Jun 17 13:27:45 2003
@@ -121,6 +121,7 @@
 	hostdata->differential = differential;
 	hostdata->clock = clock;
 	hostdata->chip710 = 1;
+	NCR_700_set_io_mapped(hostdata);
 
 	/* and register the chip */
 	if((host = NCR_700_detect(&sim710_driver_template, hostdata)) == NULL) {
@@ -143,7 +144,7 @@
 	return 0;
 
  out_unregister:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out_release:
 	release_region(host->base, 64);
  out_free:
@@ -294,12 +295,17 @@
 	unsigned char irq, differential = 0, scsi_id = 7;
 
 	if(strcmp(edev->id.sig, "HWP0C80") == 0) {
+		__u8 val;
 		eisa_irqs =  eisa_hwp_irqs;
 		irq_index = (inb(io_addr + 0xc85) & 0x7) - 1;
-#if 0
-		/* this doesn't seem to work at the moment */
-		scsi_id = ffs(inb(io_addr + 0x4));
-#endif
+
+		val = inb(io_addr + 0x4);
+		scsi_id = ffs(val) - 1;
+
+		if(scsi_id > 7 || (val & ~(1<<scsi_id)) != 0) {
+			printk(KERN_ERR "sim710.c, EISA card %s has incorrect scsi_id, setting to 7\n", dev->name);
+			scsi_id = 7;
+		}
 	} else {
 		eisa_irqs = eisa_cpq_irqs;
 		irq_index = inb(io_addr + 0xc88) & 0x07;
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Sun Jun 15 13:38:43 2003
+++ b/drivers/scsi/sr.c	Mon Jun 16 17:22:18 2003
@@ -524,7 +524,6 @@
 	sprintf(cd->cdi.name, "sr%d", minor);
 
 	sdev->sector_size = 2048;	/* A guess, just in case */
-	sdev->remap = 1;
 
 	/* FIXME: need to handle a get_capabilities failure properly ?? */
 	get_capabilities(cd);
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Mon May 26 04:18:14 2003
+++ b/drivers/scsi/st.c	Thu Jun  5 11:39:47 2003
@@ -3674,22 +3674,6 @@
 
 #endif
 
-/* Driverfs file support */
-static ssize_t st_device_kdev_read(struct device *dev, char *page)
-{
-	kdev_t kdev; 
-	kdev.value=(unsigned long)dev->driver_data;
-	return sprintf(page, "%x\n",kdev.value);
-}
-static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL);
-
-static ssize_t st_device_type_read(struct device *ev, char * page)
-{
-	return sprintf (page, "CHR\n");
-}
-static DEVICE_ATTR(type,S_IRUGO,st_device_type_read,NULL);
-
-
 static struct file_operations st_fops =
 {
 	.owner =	THIS_MODULE,
diff -Nru a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c	Fri Feb  7 14:02:17 2003
+++ b/drivers/scsi/sun3x_esp.c	Sun Jun  8 12:18:41 2003
@@ -413,7 +413,6 @@
 	.slave_alloc		= esp_slave_alloc,
 	.slave_destroy		= esp_slave_destroy,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	Sun May  4 02:56:46 2003
+++ b/drivers/scsi/sym53c416.c	Sun Jun  8 12:18:41 2003
@@ -787,20 +787,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd *SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int sym53c416_command(Scsi_Cmnd *SCpnt)
-{
-	sym53c416_queuecommand(SCpnt, internal_done);
-	SCpnt->SCp.Status = 0;
-	while(!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
 static int sym53c416_abort(Scsi_Cmnd *SCpnt)
 {
 	return FAILED;
@@ -880,7 +866,6 @@
 	.name =			"Symbios Logic 53c416",
 	.detect =		sym53c416_detect,
 	.info =			sym53c416_info,	
-	.command =		sym53c416_command,
 	.queuecommand =		sym53c416_queuecommand,
 	.eh_abort_handler =	sym53c416_abort,
 	.eh_host_reset_handler =sym53c416_host_reset,
diff -Nru a/drivers/scsi/t128.c b/drivers/scsi/t128.c
--- a/drivers/scsi/t128.c	Sun May  4 02:56:46 2003
+++ b/drivers/scsi/t128.c	Mon Jun  2 17:27:45 2003
@@ -280,6 +280,16 @@
     return count;
 }
 
+static int t128_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /*
  * Function : int t128_biosparam(Disk * disk, struct block_device *dev, int *ip)
  *
@@ -403,6 +413,7 @@
 static Scsi_Host_Template driver_template = {
 	.name           = "Trantor T128/T128F/T228",
 	.detect         = t128_detect,
+	.release        = t128_release,
 	.queuecommand   = t128_queue_command,
 	.eh_abort_handler = t128_abort,
 	.eh_bus_reset_handler    = t128_bus_reset,
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/u14-34f.c	Tue Jun  3 10:54:37 2003
@@ -1,6 +1,36 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      03 Jun 2003 Rev. 8.10 for linux-2.5.70
+ *        + Update for new IRQ API.
+ *        + Use "goto" when appropriate.
+ *        + Drop u14-34f.h.
+ *        + Update for new module_param API.
+ *        + Module parameters  can now be specified only in the
+ *          same format as the kernel boot options.
+ *
+ *             boot option    old module param 
+ *             -----------    ------------------
+ *             addr,...       io_port=addr,...
+ *             lc:[y|n]       linked_comm=[1|0]
+ *             mq:xx          max_queue_depth=xx
+ *             tm:[0|1|2]     tag_mode=[0|1|2]
+ *             et:[y|n]       ext_tran=[1|0]
+ *             of:[y|n]       have_old_firmware=[1|0]
+ *
+ *          A valid example using the new parameter format is:
+ *          modprobe u14-34f "u14-34f=0x340,0x330,lc:y,tm:0,mq:4"
+ *
+ *          which is equivalent to the old format:
+ *          modprobe u14-34f io_port=0x340,0x330 linked_comm=1 tag_mode=0 \
+ *                        max_queue_depth=4
+ *
+ *          With actual module code, u14-34f and u14_34f are equivalent
+ *          as module parameter names.
+ *
+ *      12 Feb 2003 Rev. 8.04 for linux 2.5.60
+ *        + Release irq before calling scsi_register.
+ *
  *      12 Nov 2002 Rev. 8.02 for linux 2.5.47
  *        + Release driver_lock before calling scsi_register.
  *
@@ -221,7 +251,7 @@
  *
  *          Multiple U14F and/or U34F host adapters are supported.
  *
- *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -375,31 +405,8 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
-#include <linux/version.h>
-
-#ifndef LinuxVersionCode
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#endif
-
-#define MAX_INT_PARAM 10
-
-#if defined(MODULE)
-#include <linux/module.h>
-
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
-MODULE_PARM(linked_comm, "i");
-MODULE_PARM(have_old_firmware, "i");
-MODULE_PARM(link_statistics, "i");
-MODULE_PARM(max_queue_depth, "i");
-MODULE_PARM(tag_mode, "i");
-MODULE_PARM(ext_tran, "i");
-MODULE_AUTHOR("Dario Ballabio");
-
-#endif
-
+#include <linux/config.h>
 #include <linux/string.h>
-#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -408,20 +415,42 @@
 #include <asm/byteorder.h>
 #include <linux/proc_fs.h>
 #include <linux/blk.h>
+#include <linux/interrupt.h>
 #include <linux/stat.h>
-#include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <scsi/scsicam.h>
-
+#include "scsi.h"
+#include "hosts.h"
 #include <asm/dma.h>
 #include <asm/irq.h>
 
-#include "scsi.h"
-#include "hosts.h"
-#include "u14-34f.h"
+static int u14_34f_detect(Scsi_Host_Template *);
+static int u14_34f_release(struct Scsi_Host *);
+static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int u14_34f_eh_abort(Scsi_Cmnd *);
+static int u14_34f_eh_host_reset(Scsi_Cmnd *);
+static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
+                              sector_t, int *);
+static int u14_34f_slave_configure(Scsi_Device *);
+
+static Scsi_Host_Template driver_template = {
+                .name                    = "UltraStor 14F/34F rev. 8.10.00 ",
+                .detect                  = u14_34f_detect,
+                .release                 = u14_34f_release,
+                .queuecommand            = u14_34f_queuecommand,
+                .eh_abort_handler        = u14_34f_eh_abort,
+                .eh_device_reset_handler = NULL,
+                .eh_bus_reset_handler    = NULL,
+                .eh_host_reset_handler   = u14_34f_eh_host_reset,
+                .bios_param              = u14_34f_bios_param,
+                .slave_configure         = u14_34f_slave_configure,
+                .this_id                 = 7,
+                .unchecked_isa_dma       = 1,
+                .use_clustering          = ENABLE_CLUSTERING
+                };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
@@ -610,7 +639,6 @@
 static int setup_done = FALSE;
 static int link_statistics;
 static int ext_tran = FALSE;
-static char *boot_options;
 
 #if defined(HAVE_OLD_UX4F_FIRMWARE)
 static int have_old_firmware = TRUE;
@@ -636,6 +664,24 @@
 static int max_queue_depth = MAX_CMD_PER_LUN;
 #endif
 
+#define MAX_INT_PARAM 10
+#define MAX_BOOT_OPTIONS_SIZE 256
+static char boot_options[MAX_BOOT_OPTIONS_SIZE];
+
+#if defined(MODULE)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+module_param_string(u14_34f, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
+MODULE_PARM_DESC(u14_34f, " equivalent to the \"u14-34f=...\" kernel boot " \
+"option." \
+"      Example: modprobe u14-34f \"u14_34f=0x340,0x330,lc:y,tm:0,mq:4\"");
+MODULE_AUTHOR("Dario Ballabio");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("UltraStor 14F/34F SCSI Driver");
+
+#endif
+
 static int u14_34f_slave_configure(Scsi_Device *dev) {
    int j, tqd, utqd;
    char *tag_suffix, *link_suffix;
@@ -802,24 +848,20 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(!request_region(port_base, REGION_SIZE, driver_name)) {
+   if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
-      return FALSE;
+      goto fail;
       }
 
-   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) {
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
-      }
+   spin_lock_irq(&driver_lock);
+
+   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) goto freelock;
 
    in_byte = inb(port_base + REG_PRODUCT_ID2);
 
-   if ((in_byte & 0xf0) != PRODUCT_ID2) {
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
-      }
+   if ((in_byte & 0xf0) != PRODUCT_ID2) goto freelock;
 
    *(char *)&config_1 = inb(port_base + REG_CONFIG1);
    *(char *)&config_2 = inb(port_base + REG_CONFIG2);
@@ -833,16 +875,13 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
-      free_irq(irq, &sha[j]);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freeirq;
       }
 
    if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING;
@@ -853,13 +892,7 @@
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
-
-      free_irq(irq, &sha[j]);
-
-      if (subversion == ISA) free_dma(dma_channel);
-
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    sh[j]->io_port = port_base;
@@ -938,6 +971,8 @@
    if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
    else                       sprintf(dma_name, "DMA %u", dma_channel);
 
+   spin_unlock_irq(&driver_lock);
+
    for (i = 0; i < sh[j]->can_queue; i++)
       HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
             &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
@@ -947,8 +982,7 @@
             sh[j]->sg_tablesize * sizeof(struct sg_list),
             (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
          printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         u14_34f_release(sh[j]);
-         return FALSE;
+         goto release;
          }
 
    if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
@@ -960,7 +994,7 @@
       tag_mode = TAG_ORDERED;
 
    if (j == 0) {
-      printk("UltraStor 14F/34F: Copyright (C) 1994-2002 Dario Ballabio.\n");
+      printk("UltraStor 14F/34F: Copyright (C) 1994-2003 Dario Ballabio.\n");
       printk("%s config options -> of:%c, tm:%d, lc:%c, mq:%d, et:%c.\n",
              driver_name, YESNO(have_old_firmware), tag_mode,
              YESNO(linked_comm), max_queue_depth, YESNO(ext_tran));
@@ -979,6 +1013,20 @@
              BN(j), i, sh[j]->this_id);
 
    return TRUE;
+
+freedma:
+   if (subversion == ISA) free_dma(dma_channel);
+freeirq:
+   free_irq(irq, &sha[j]);
+freelock:
+   spin_unlock_irq(&driver_lock);
+   release_region(port_base, REGION_SIZE);
+fail:
+   return FALSE;
+
+release:
+   u14_34f_release(sh[j]);
+   return FALSE;
 }
 
 static void internal_setup(char *str, int *ints) {
@@ -1034,13 +1082,10 @@
 
 static int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
-   unsigned long spin_flags;
-
-   spin_lock_irqsave(&driver_lock, spin_flags);
 
    tpnt->proc_name = "u14-34f";
 
-   if(boot_options) option_setup(boot_options);
+   if(strlen(boot_options)) option_setup(boot_options);
 
 #if defined(MODULE)
    /* io_port could have been modified when loading as a module */
@@ -1060,7 +1105,6 @@
       }
 
    num_boards = j;
-   spin_unlock_irqrestore(&driver_lock, spin_flags);
    return j;
 }
 
@@ -1680,7 +1724,7 @@
 
 }
 
-static void ihdlr(int irq, unsigned int j) {
+static irqreturn_t ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg, ret;
    struct mscp *spp, *cpp;
@@ -1689,7 +1733,7 @@
        panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
 
    /* Check if this board need to be serviced */
-   if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) return;
+   if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) goto none;
 
    HD(j)->iocount++;
 
@@ -1701,7 +1745,7 @@
       outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
-      return;
+      goto none;
       }
 
    ret = inl(sh[j]->io_port + REG_ICM);
@@ -1721,23 +1765,23 @@
    spp = cpp;
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
+   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
 #endif
 
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == LOCKED) {
       HD(j)->cp_stat[i] = FREE;
       printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == FREE) {
       printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == IN_RESET)
       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
@@ -1887,23 +1931,25 @@
    if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
                         HD(j)->iocount);
 
-   return;
+handled:
+   return IRQ_HANDLED;
+none:
+   return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-					struct pt_regs *regs)
-{
+                                        struct pt_regs *regs) {
    unsigned int j;
    unsigned long spin_flags;
+   irqreturn_t ret;
 
    /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
-	   return IRQ_NONE;
+   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
 
    spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ihdlr(irq, j);
+   ret = ihdlr(irq, j);
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return IRQ_HANDLED;
+   return ret;
 }
 
 static int u14_34f_release(struct Scsi_Host *shpnt) {
@@ -1930,22 +1976,8 @@
    return FALSE;
 }
 
-static Scsi_Host_Template driver_template = {
-	.name         = "UltraStor 14F/34F rev. " U14_34F_VERSION " ",
-	.detect                  = u14_34f_detect,
-	.release                 = u14_34f_release,
-	.queuecommand            = u14_34f_queuecommand,
-	.eh_abort_handler        = u14_34f_eh_abort,
-	.eh_host_reset_handler   = u14_34f_eh_host_reset,
-	.bios_param              = u14_34f_bios_param,
-	.slave_configure         = u14_34f_slave_configure,
-	.this_id                 = 7,
-	.unchecked_isa_dma       = 1, 
-	.use_clustering          = ENABLE_CLUSTERING,
-};
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("u14-34f=", option_setup);
 #endif /* end MODULE */
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
--- a/drivers/scsi/u14-34f.h	Sun May  4 02:56:46 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/*
- *   u14-34f.h - used by the low-level driver for UltraStor 14F/34F
- */
-
-static int u14_34f_detect(Scsi_Host_Template *);
-static int u14_34f_release(struct Scsi_Host *);
-static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int u14_34f_eh_abort(Scsi_Cmnd *);
-static int u14_34f_eh_host_reset(Scsi_Cmnd *);
-static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
-                              sector_t, int *);
-static int u14_34f_slave_configure(Scsi_Device *);
-
-#define U14_34F_VERSION "8.03.00"
diff -Nru a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
--- a/drivers/scsi/ultrastor.c	Thu May  8 11:24:15 2003
+++ b/drivers/scsi/ultrastor.c	Mon Jun  2 17:27:44 2003
@@ -643,6 +643,18 @@
 	return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
 }
 
+static int ultrastor_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static const char *ultrastor_info(struct Scsi_Host * shpnt)
 {
     static char buf[64];
@@ -1177,6 +1189,7 @@
 static Scsi_Host_Template driver_template = {
 	.name              = "UltraStor 14F/24F/34F",
 	.detect            = ultrastor_detect,
+	.release	   = ultrastor_release,
 	.info              = ultrastor_info,
 	.queuecommand      = ultrastor_queuecommand,
 	.eh_abort_handler  = ultrastor_abort,
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Mon May 12 08:12:55 2003
+++ b/drivers/scsi/wd7000.c	Sun Jun  8 12:18:41 2003
@@ -1031,14 +1031,6 @@
 	return (scsierr | (hosterr << 16));
 }
 
-
-static void wd7000_scsi_done(Scsi_Cmnd * SCpnt)
-{
-	dprintk("wd7000_scsi_done: 0x%06lx\n", (long) SCpnt);
-	SCpnt->SCp.phase = 0;
-}
-
-
 #define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 
 static void wd7000_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
@@ -1188,20 +1180,6 @@
 	return 0;
 }
 
-
-static int wd7000_command(Scsi_Cmnd * SCpnt)
-{
-	wd7000_queuecommand(SCpnt, wd7000_scsi_done);
-
-	while (SCpnt->SCp.phase > 0) {
-		cpu_relax();
-		barrier();	/* phase counts scbs down to 0 */
-	}
-
-	return (SCpnt->result);
-}
-
-
 static int wd7000_diagnostics(Adapter * host, int code)
 {
 	static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
@@ -1616,6 +1594,15 @@
 	return (present);
 }
 
+static int wd7000_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
 
 /*
  *  I have absolutely NO idea how to do an abort with the WD7000...
@@ -1722,7 +1709,7 @@
 	.proc_info		= wd7000_proc_info,
 	.name			= "Western Digital WD-7000",
 	.detect			= wd7000_detect,
-	.command		= wd7000_command,
+	.release		= wd7000_release,
 	.queuecommand		= wd7000_queuecommand,
 	.eh_bus_reset_handler	= wd7000_bus_reset,
 	.eh_device_reset_handler = wd7000_device_reset,
diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c
--- a/drivers/usb/image/hpusbscsi.c	Fri Jun  6 12:51:40 2003
+++ b/drivers/usb/image/hpusbscsi.c	Wed Jun 11 20:06:31 2003
@@ -104,7 +104,7 @@
 		goto out_free_controlurb;
 
 	/* In host->hostdata we store a pointer to desc */
-	new->host = scsi_register(&hpusbscsi_scsi_host_template, sizeof(new));
+	new->host = scsi_host_alloc(&hpusbscsi_scsi_host_template, sizeof(new));
 	if (!new->host)
 		goto out_unlink_controlurb;
 
@@ -137,7 +137,7 @@
 
 	scsi_remove_host(desc->host);
 	usb_unlink_urb(desc->controlurb);
-	scsi_unregister(desc->host);
+	scsi_host_put(desc->host);
 
 	usb_free_urb(desc->controlurb);
 	usb_free_urb(desc->dataurb);
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	Thu May 29 21:51:27 2003
+++ b/drivers/usb/image/microtek.c	Thu Jun  5 11:39:39 2003
@@ -811,7 +811,7 @@
 		MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 			     (int)new_desc->ep_image );
 
-	new_desc->host = scsi_register(&mts_scsi_host_template,
+	new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
 			sizeof(new_desc));
 	if (!new_desc->host)
 		goto out_free_urb;
@@ -838,7 +838,7 @@
 
 	scsi_remove_host(desc->host);
 	usb_unlink_urb(desc->urb);
-	scsi_unregister(desc->host);
+	scsi_host_put(desc->host);
 
 	usb_free_urb(desc->urb);
 	kfree(desc);
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Sun Jun  1 12:09:08 2003
+++ b/drivers/usb/storage/scsiglue.c	Sun Jun  8 13:31:57 2003
@@ -360,29 +360,20 @@
  * this defines our host template, with which we'll allocate hosts
  */
 
-struct SHT usb_stor_host_template = {
+struct scsi_host_template 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,
@@ -391,21 +382,9 @@
 	/* 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.
@@ -414,9 +393,6 @@
 
 	/* emulated HBA */
 	.emulated =			TRUE,
-
-	/* sorry, no BIOS to help us */
-	.bios_param =			NULL,
 
 	/* module management */
 	.module =			THIS_MODULE
diff -Nru a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h
--- a/drivers/usb/storage/scsiglue.h	Sun Jan 19 06:10:31 2003
+++ b/drivers/usb/storage/scsiglue.h	Thu Jun  5 11:52:51 2003
@@ -47,7 +47,7 @@
 
 extern unsigned char usb_stor_sense_notready[18];
 extern unsigned char usb_stor_sense_invalidCDB[18];
-extern struct SHT usb_stor_host_template;
+extern struct scsi_host_template usb_stor_host_template;
 extern int usb_stor_scsiSense10to6(Scsi_Cmnd*);
 extern int usb_stor_scsiSense6to10(Scsi_Cmnd*);
 
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Sun Jun  8 07:15:45 2003
+++ b/drivers/usb/storage/usb.c	Wed Jun 11 20:19:46 2003
@@ -736,7 +736,7 @@
 	 * Since this is a new device, we need to register a SCSI
 	 * host definition with the higher SCSI layers.
 	 */
-	us->host = scsi_register(&usb_stor_host_template, sizeof(us));
+	us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us));
 	if (!us->host) {
 		printk(KERN_WARNING USB_STORAGE
 			"Unable to register the scsi host\n");
@@ -772,7 +772,7 @@
 	/* Finish the SCSI host removal sequence */
 	if (us->host) {
 		(struct us_data *) us->host->hostdata[0] = NULL;
-		scsi_unregister(us->host);
+		scsi_host_put(us->host);
 	}
 
 	/* Kill the control thread
diff -Nru a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/Kconfig.binfmt	Sun Jun 15 09:07:21 2003
@@ -0,0 +1,116 @@
+config BINFMT_ELF
+	tristate "Kernel support for ELF binaries"
+	depends on MMU
+	default y
+	---help---
+	  ELF (Executable and Linkable Format) is a format for libraries and
+	  executables used across different architectures and operating
+	  systems. Saying Y here will enable your kernel to run ELF binaries
+	  and enlarge it by about 13 KB. ELF support under Linux has now all
+	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
+	  because it is portable (this does *not* mean that you will be able
+	  to run executables from different architectures or operating systems
+	  however) and makes building run-time libraries very easy. Many new
+	  executables are distributed solely in ELF format. You definitely
+	  want to say Y here.
+
+	  Information about ELF is contained in the ELF HOWTO available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  If you find that after upgrading from Linux kernel 1.2 and saying Y
+	  here, you still can't run any ELF binaries (they just crash), then
+	  you'll have to install the newest ELF runtime libraries, including
+	  ld.so (check the file <file:Documentation/Changes> for location and
+	  latest version).
+
+	  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. Saying M or N here is dangerous because
+	  some crucial programs on your system might be in ELF format.
+
+config BINFMT_FLAT
+	tristate "Kernel support for flat binaries"
+	depends on !MMU || SUPERH
+	help
+	  Support uClinux FLAT format binaries.
+
+config BINFMT_ZFLAT
+	bool "Enable ZFLAT support"
+	depends on BINFMT_FLAT
+	help
+	  Support FLAT format compressed binaries
+
+config BINFMT_AOUT
+	tristate "Kernel support for a.out and ECOFF binaries"
+	depends on X86 || ALPHA || ARM || M68K || MIPS || SPARC
+	---help---
+	  A.out (Assembler.OUTput) is a set of formats for libraries and
+	  executables used in the earliest versions of UNIX.  Linux used
+	  the a.out formats QMAGIC and ZMAGIC until they were replaced
+	  with the ELF format.
+
+	  The conversion to ELF started in 1995.  This option is primarily
+	  provided for historical interest and for the benefit of those
+	  who need to run binaries from that era.
+
+	  Most people should answer N here.  If you think you may have
+	  occasional use for this format, enable module support above
+	  and answer M here to compile this support as a module called
+	  binfmt_aout.
+
+	  If any crucial components of your system (such as /sbin/init
+	  or /lib/ld.so) are still in a.out format, you will have to
+	  say Y here.
+
+config OSF4_COMPAT
+	bool "OSF/1 v4 readv/writev compatibility"
+	depends on ALPHA && BINFMT_AOUT
+	help
+	  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
+	  with v4 shared libraries freely available from Compaq. If you're
+	  going to use shared libraries from Tru64 version 5.0 or later, say N.
+
+config BINFMT_EM86
+	tristate "Kernel support for Linux/Intel ELF binaries"
+	depends on ALPHA
+	---help---
+	  Say Y here if you want to be able to execute Linux/Intel ELF
+	  binaries just like native Alpha binaries on your Alpha machine. For
+	  this to work, you need to have the emulator /usr/bin/em86 in place.
+
+	  You can get the same functionality by saying N here and saying Y to
+	  "Kernel support for MISC binaries".
+
+	  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. If unsure, say Y.
+
+config BINFMT_SOM
+	tristate "Kernel support for SOM binaries"
+	depends on PARISC && HPUX
+	help
+	  SOM is a binary executable format inherited from HP/UX.  Say
+	  Y here to be able to load and execute SOM binaries directly.
+
+config BINFMT_MISC
+	tristate "Kernel support for MISC binaries"
+	---help---
+	  If you say Y here, it will be possible to plug wrapper-driven binary
+	  formats into the kernel. You will like this especially when you use
+	  programs that need an interpreter to run like Java, Python or
+	  Emacs-Lisp. It's also useful if you often run DOS executables under
+	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>). Once you have
+	  registered such a binary class with the kernel, you can start one of
+	  those programs simply by typing in its name at a shell prompt; Linux
+	  will automatically feed it to the correct interpreter.
+
+	  You can do other nice things, too. Read the file
+	  <file:Documentation/binfmt_misc.txt> to learn how to use this
+	  feature, and <file:Documentation/java.txt> for information about how
+	  to include Java support.
+
+	  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. If you
+	  don't know what to answer at this point, say Y.
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Thu Jun 12 15:51:27 2003
+++ b/fs/namei.c	Mon Jun 16 22:09:04 2003
@@ -985,6 +985,8 @@
  *  7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
  *  8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
  *  9. We can't remove a root or mountpoint.
+ * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
+ *     nfs_async_unlink().
  */
 static inline int may_delete(struct inode *dir,struct dentry *victim, int isdir)
 {
@@ -1008,6 +1010,8 @@
 		return -EISDIR;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
+	if (victim->d_flags & DCACHE_NFSFS_RENAMED)
+		return -EBUSY;
 	return 0;
 }
 
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Sun May 25 19:14:31 2003
+++ b/fs/nfs/inode.c	Mon Jun 16 22:03:19 2003
@@ -715,7 +715,6 @@
 		if (fattr->valid & NFS_ATTR_FATTR_V4)
 			nfsi->change_attr = fattr->change_attr;
 		inode->i_size = nfs_size_to_loff_t(fattr->size);
-		inode->i_mode = fattr->mode;
 		inode->i_nlink = fattr->nlink;
 		inode->i_uid = fattr->uid;
 		inode->i_gid = fattr->gid;
diff -Nru a/fs/nfsd/auth.c b/fs/nfsd/auth.c
--- a/fs/nfsd/auth.c	Tue Feb  5 09:39:38 2002
+++ b/fs/nfsd/auth.c	Tue Jun 17 16:31:29 2003
@@ -17,9 +17,6 @@
 	struct svc_cred	*cred = &rqstp->rq_cred;
 	int		i;
 
-	if (rqstp->rq_userset)
-		return;
-
 	if (exp->ex_flags & NFSEXP_ALLSQUASH) {
 		cred->cr_uid = exp->ex_anon_uid;
 		cred->cr_gid = exp->ex_anon_gid;
@@ -57,5 +54,4 @@
 						  current->cap_permitted);
 	}
 
-	rqstp->rq_userset = 1;
 }
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Mon May 19 23:34:38 2003
+++ b/fs/nfsd/export.c	Tue Jun 17 16:18:16 2003
@@ -153,9 +153,13 @@
 		goto out;
 	dprintk("Path seems to be <%s>\n", buf);
 	err = 0;
-	if (len == 0)
+	if (len == 0) {
+		struct svc_expkey *ek;
 		set_bit(CACHE_NEGATIVE, &key.h.flags);
-	else {
+		ek = svc_expkey_lookup(&key, 2);
+		if (ek)
+			expkey_put(&ek->h, &svc_expkey_cache);
+	} else {
 		struct nameidata nd;
 		struct svc_expkey *ek;
 		struct svc_export *exp;
diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
--- a/fs/nfsd/nfs4proc.c	Mon May 19 23:34:38 2003
+++ b/fs/nfsd/nfs4proc.c	Tue Jun 17 16:30:53 2003
@@ -147,12 +147,6 @@
 	return 0;
 }
 
-static inline int
-nfsd4_renew(clientid_t *clientid)
-{
-	return nfs_ok;
-}
-
 /*
  * filehandle-manipulating ops.
  */
diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c	Mon May 19 23:34:37 2003
+++ b/fs/nfsd/nfs4state.c	Tue Jun 17 16:31:07 2003
@@ -43,6 +43,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
 #include <linux/mount.h>
+#include <linux/workqueue.h>
 #include <linux/nfs4.h>
 #include <linux/nfsd/state.h>
 #include <linux/nfsd/xdr4.h>
@@ -54,6 +55,7 @@
 static u32 current_clientid = 1;
 static u32 current_ownerid = 0;
 static u32 current_fileid = 0;
+static u32 nfs4_init = 0;
 
 /* debug counters */
 u32 list_add_perfile = 0; 
@@ -105,11 +107,28 @@
  *
  * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 
  * setclientid info.
+ *
+ * client_lru holds client queue ordered by nfs4_client.cl_time
+ * for lease renewal.
  */
 static struct list_head	conf_id_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	conf_str_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	unconf_str_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	unconf_id_hashtbl[CLIENT_HASH_SIZE];
+static struct list_head client_lru;
+
+static inline void
+renew_client(struct nfs4_client *clp)
+{
+	/*
+	* Move client to the end to the LRU list.
+	*/
+	dprintk("renewing client (clientid %08x/%08x)\n", 
+			clp->cl_clientid.cl_boot, 
+			clp->cl_clientid.cl_id);
+	list_move_tail(&clp->cl_lru, &client_lru);
+	clp->cl_time = get_seconds();
+}
 
 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
 static int
@@ -160,6 +179,7 @@
 	dprintk("NFSD: expire_client\n");
 	list_del(&clp->cl_idhash);
 	list_del(&clp->cl_strhash);
+	list_del(&clp->cl_lru);
 	while (!list_empty(&clp->cl_perclient)) {
 		sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
 		release_stateowner(sop);
@@ -176,6 +196,7 @@
 	INIT_LIST_HEAD(&clp->cl_idhash);
 	INIT_LIST_HEAD(&clp->cl_strhash);
 	INIT_LIST_HEAD(&clp->cl_perclient);
+	INIT_LIST_HEAD(&clp->cl_lru);
 out:
 	return clp;
 }
@@ -264,6 +285,8 @@
 	list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
 	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
 	list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
+	list_add_tail(&clp->cl_lru, &client_lru);
+	clp->cl_time = get_seconds();
 }
 
 void
@@ -271,13 +294,13 @@
 {
 	unsigned int strhashval;
 
-	printk("ANDROS: move_to_confirm nfs4_client %p\n", clp);
 	list_del_init(&clp->cl_strhash);
 	list_del_init(&clp->cl_idhash);
 	list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
 	strhashval = clientstr_hashval(clp->cl_name.data, 
 			clp->cl_name.len);
 	list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
+	renew_client(clp);
 }
 
 /*
@@ -940,9 +963,7 @@
 	open->op_stateowner = sop;
 	status = nfs_ok;
 renew:
-	/* XXX implement LRU and state recovery thread 
-	 * renew will place nfs4_client at end of LRU 
-	 */
+	renew_client(sop->so_client);
 out:
 	up(&client_sema); /*XXX need finer grained locking */
 	return status;
@@ -1048,13 +1069,98 @@
 	kfree(stp);
 	goto out;
 }
+static struct work_struct laundromat_work;
+static void laundromat_main(void *);
+static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
+
+int 
+nfsd4_renew(clientid_t *clid)
+{
+	struct nfs4_client *clp;
+	struct list_head *pos, *next;
+	unsigned int idhashval;
+	int status;
+
+	down(&client_sema);
+	printk("process_renew(%08x/%08x): starting\n", 
+			clid->cl_boot, clid->cl_id);
+	status = nfserr_stale_clientid;
+	if (STALE_CLIENTID(clid))
+		goto out;
+	status = nfs_ok;
+	idhashval = clientid_hashval(clid->cl_id);
+	list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
+		clp = list_entry(pos, struct nfs4_client, cl_idhash);
+		if (!cmp_clid(&clp->cl_clientid, clid))
+			continue;
+		renew_client(clp);
+		goto out;
+	}
+	list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) {
+		clp = list_entry(pos, struct nfs4_client, cl_idhash);
+		if (!cmp_clid(&clp->cl_clientid, clid))
+			continue;
+		renew_client(clp);
+	goto out;
+	}
+	/*
+	* Couldn't find an nfs4_client for this clientid.  
+	* Presumably this is because the client took too long to 
+	* RENEW, so return NFS4ERR_EXPIRED.
+	*/
+	printk("nfsd4_renew: clientid not found!\n");
+	status = nfserr_expired;
+out:
+	up(&client_sema);
+	return status;
+}
+
+time_t
+nfs4_laundromat(void)
+{
+	struct nfs4_client *clp;
+	struct list_head *pos, *next;
+	time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
+	time_t t, return_val = NFSD_LEASE_TIME;
+
+	down(&client_sema);
+
+	dprintk("NFSD: laundromat service - starting, examining clients\n");
+	list_for_each_safe(pos, next, &client_lru) {
+		clp = list_entry(pos, struct nfs4_client, cl_lru);
+		if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
+			t = clp->cl_time - cutoff;
+			if (return_val > t)
+				return_val = t;
+			break;
+		}
+		dprintk("NFSD: purging unused client (clientid %08x)\n",
+			clp->cl_clientid.cl_id);
+		expire_client(clp);
+	}
+	if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT)
+		return_val = NFSD_LAUNDROMAT_MINTIMEOUT;
+	up(&client_sema); 
+	return return_val;
+}
+
+void
+laundromat_main(void *not_used)
+{
+	time_t t;
+
+	t = nfs4_laundromat();
+	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
+	schedule_delayed_work(&laundromat_work, t*HZ);
+}
 
 void 
 nfs4_state_init(void)
 {
-	struct timespec 	tv;
 	int i;
 
+	if (nfs4_init)
+		return;
 	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&conf_id_hashtbl[i]);
 		INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -1067,9 +1173,13 @@
 	for (i = 0; i < OWNER_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
 	}
+	INIT_LIST_HEAD(&client_lru);
 	init_MUTEX(&client_sema);
-	tv = CURRENT_TIME;
-	boot_time = tv.tv_sec;
+	boot_time = get_seconds();
+	INIT_WORK(&laundromat_work,laundromat_main, NULL);
+	schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
+	nfs4_init = 1;
+
 }
 
 static void
@@ -1089,6 +1199,9 @@
 		}
 	}
 	release_all_files();
+	cancel_delayed_work(&laundromat_work);
+	flush_scheduled_work();
+	nfs4_init = 0;
 	dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
 			list_add_perfile, list_del_perfile);
 	dprintk("NFSD: add_perclient %d del_perclient %d\n",
diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
--- a/fs/nfsd/nfs4xdr.c	Mon May 19 23:34:36 2003
+++ b/fs/nfsd/nfs4xdr.c	Tue Jun 17 16:30:43 2003
@@ -1039,6 +1039,7 @@
 	*p++ = htonl((u32)(n));					\
 } while (0)
 #define WRITEMEM(ptr,nbytes)     do {				\
+	*(p + XDR_QUADLEN(nbytes) -1) = 0;                      \
 	memcpy(p, ptr, nbytes);					\
 	p += XDR_QUADLEN(nbytes);				\
 } while (0)
@@ -1425,6 +1426,7 @@
 	u32 *p = cd->buffer;
 	u32 *attrlenp;
 	struct dentry *dentry;
+	struct svc_export *exp = cd->rd_fhp->fh_export;
 	u32 bmval0, bmval1;
 	int nfserr = 0;
 
@@ -1454,9 +1456,7 @@
 	if ((bmval0 & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_FILEID)) || bmval1)  {
 		/*
 		 * "Heavyweight" case: we have no choice except to
-		 * call nfsd4_encode_fattr().  As far as I know,
-		 * only Windows clients will trigger this code
-		 * path.
+		 * call nfsd4_encode_fattr(). 
 		 */
 		dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
 		if (IS_ERR(dentry)) {
@@ -1464,10 +1464,25 @@
 			goto error;
 		}
 
-		nfserr = nfsd4_encode_fattr(NULL, cd->rd_fhp->fh_export,
-					    dentry, p, &buflen, cd->rd_bmval);
-		dput(dentry);
+		if (d_mountpoint(dentry)) {
+			if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry, 
+					 &exp))) {	
+			/* 
+			 * -EAGAIN is the only error returned from 
+			 * nfsd_cross_mnt() and it indicates that an 
+			 * up-call has  been initiated to fill in the export 
+			 * options on exp.  When the answer comes back,
+			 * this call will be retried.
+			 */
+				dput(dentry);
+				nfserr = nfserr_dropit;
+				goto error;
+			}
 
+		}
+
+		nfserr = nfsd4_encode_fattr(NULL, exp,
+				dentry, p, &buflen, cd->rd_bmval);
 		if (!nfserr) {
 			p += buflen;
 			goto out;
diff -Nru a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c	Sun May 25 18:48:17 2003
+++ b/fs/nfsd/nfsctl.c	Tue Jun 17 16:31:07 2003
@@ -453,7 +453,6 @@
 	nfsd_cache_init();	/* RPC reply cache */
 	nfsd_export_init();	/* Exports table */
 	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-	nfs4_state_init();      /* NFSv4 State */
 	if (proc_mkdir("fs/nfs", 0)) {
 		struct proc_dir_entry *entry;
 		entry = create_proc_entry("fs/nfs/exports", 0, NULL);
diff -Nru a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
--- a/fs/nfsd/nfsfh.c	Wed Apr  2 22:51:32 2003
+++ b/fs/nfsd/nfsfh.c	Tue Jun 17 16:31:29 2003
@@ -161,9 +161,6 @@
 			goto out;
 		}
 
-		/* Set user creds if we haven't done so already. */
-		nfsd_setuser(rqstp, exp);
-
 		/*
 		 * Look up the dentry using the NFS file handle.
 		 */
@@ -222,6 +219,10 @@
 	cache_get(&exp->h);
 
 	inode = dentry->d_inode;
+
+
+	/* Set user creds for this exportpoint */
+	nfsd_setuser(rqstp, exp);
 
 	/* Type check. The correct error return for type mismatches
 	 * does not seem to be generally agreed upon. SunOS seems to
diff -Nru a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c	Mon Jan 13 04:39:46 2003
+++ b/fs/nfsd/nfsproc.c	Tue Jun 17 16:18:16 2003
@@ -591,6 +591,7 @@
 		{ nfserr_dquot, -EDQUOT },
 #endif
 		{ nfserr_stale, -ESTALE },
+		{ nfserr_dropit, -EAGAIN },
 		{ nfserr_dropit, -ENOMEM },
 		{ -1, -EIO }
 	};
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	Tue Jun 10 23:33:23 2003
+++ b/fs/nfsd/nfssvc.c	Tue Jun 17 16:31:07 2003
@@ -91,6 +91,7 @@
 	
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
+	nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c	Sun May  4 22:49:54 2003
+++ b/fs/nfsd/vfs.c	Tue Jun 17 16:24:29 2003
@@ -74,6 +74,46 @@
 static struct raparms *		raparml;
 static struct raparms *		raparm_cache;
 
+/* 
+ * Called from nfsd_lookup and encode_dirent. Check if we have crossed 
+ * a mount point.
+ * Returns -EAGAIN leaving *dpp and *expp unchanged, 
+ *  or nfs_ok having possibly changed *dpp and *expp
+ */
+int
+nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 
+		        struct svc_export **expp)
+{
+	struct svc_export *exp = *expp, *exp2 = NULL;
+	struct dentry *dentry = *dpp;
+	struct vfsmount *mnt = mntget(exp->ex_mnt);
+	struct dentry *mounts = dget(dentry);
+	int err = nfs_ok;
+
+	while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
+
+	exp2 = exp_get_by_name(exp->ex_client, mnt, mounts, &rqstp->rq_chandle);
+	if (IS_ERR(exp2)) {
+		err = PTR_ERR(exp2);
+		dput(mounts);
+		mntput(mnt);
+		goto out;
+	}
+	if (exp2 && ((exp->ex_flags & NFSEXP_CROSSMNT) || EX_NOHIDE(exp2))) {
+		/* successfully crossed mount point */
+		exp_put(exp);
+		*expp = exp2;
+		dput(dentry);
+		*dpp = mounts;
+	} else {
+		if (exp2) exp_put(exp2);
+		dput(mounts);
+	}
+	mntput(mnt);
+out:
+	return err;
+}
+
 /*
  * Look up one component of a pathname.
  * N.B. After this call _both_ fhp and resfh need an fh_put
@@ -154,34 +194,10 @@
 		 * check if we have crossed a mount point ...
 		 */
 		if (d_mountpoint(dentry)) {
-			struct svc_export *exp2 = NULL;
-			struct vfsmount *mnt = mntget(exp->ex_mnt);
-			struct dentry *mounts = dget(dentry);
-			while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
-				;
-
-			exp2 = exp_get_by_name(exp->ex_client, mnt, 
-					       mounts, &rqstp->rq_chandle);
-			if (IS_ERR(exp2)) {
-				err = PTR_ERR(exp2);
-				dput(mounts);
-				dput(dentry);
-				mntput(mnt);
-				goto out;
-			}
-			if (exp2 &&
-			    ((exp->ex_flags & NFSEXP_CROSSMNT)
-			     || EX_NOHIDE(exp2))) {
-				/* successfully crossed mount point */
-				exp_put(exp);
-				exp = exp2;
+			if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
 				dput(dentry);
-				dentry = mounts;
-			} else {
-				if (exp2) exp_put(exp2);
-				dput(mounts);
+				goto out_nfserr;
 			}
-			mntput(mnt);
 		}
 	}
 	/*
diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h
--- a/include/asm-i386/apic.h	Sat Jun 14 17:17:28 2003
+++ b/include/asm-i386/apic.h	Sun Jun 15 11:00:08 2003
@@ -81,6 +81,8 @@
 extern void setup_apic_nmi_watchdog (void);
 extern void disable_lapic_nmi_watchdog(void);
 extern void enable_lapic_nmi_watchdog(void);
+extern void disable_timer_nmi_watchdog(void);
+extern void enable_timer_nmi_watchdog(void);
 extern inline void nmi_watchdog_tick (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
 extern void disable_APIC_timer(void);
diff -Nru a/include/asm-sparc/xor.h b/include/asm-sparc/xor.h
--- a/include/asm-sparc/xor.h	Mon Feb  4 23:53:56 2002
+++ b/include/asm-sparc/xor.h	Mon Jun 16 18:31:20 2003
@@ -250,11 +250,11 @@
 }
 
 static struct xor_block_template xor_block_SPARC = {
-	name: "SPARC",
-	do_2: sparc_2,
-	do_3: sparc_3,
-	do_4: sparc_4,
-	do_5: sparc_5,
+	.name	= "SPARC",
+	.do_2	= sparc_2,
+	.do_3	= sparc_3,
+	.do_4	= sparc_4,
+	.do_5	= sparc_5,
 };
 
 /* For grins, also test the generic routines.  */
diff -Nru a/include/asm-sparc64/xor.h b/include/asm-sparc64/xor.h
--- a/include/asm-sparc64/xor.h	Mon Feb  4 23:54:46 2002
+++ b/include/asm-sparc64/xor.h	Mon Jun 16 18:31:20 2003
@@ -388,11 +388,11 @@
 ");
 
 static struct xor_block_template xor_block_VIS = {
-        name: "VIS",
-        do_2: xor_vis_2,
-        do_3: xor_vis_3,
-        do_4: xor_vis_4,
-        do_5: xor_vis_5,
+        .name	= "VIS",
+        .do_2	= xor_vis_2,
+        .do_3	= xor_vis_3,
+        .do_4	= xor_vis_4,
+        .do_5	= xor_vis_5,
 };
 
 #define XOR_TRY_TEMPLATES       xor_speed(&xor_block_VIS)
diff -Nru a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
--- a/include/asm-v850/hardirq.h	Mon May 12 18:59:24 2003
+++ b/include/asm-v850/hardirq.h	Mon Jun 16 22:23:12 2003
@@ -80,12 +80,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()							      \
+do {									      \
+	preempt_count() -= IRQ_EXIT_OFFSET;				      \
+	if (!in_interrupt() && softirq_pending(smp_processor_id()))	      \
+		do_softirq();						      \
+	preempt_enable_no_resched();					      \
 } while (0)
 
 #ifndef CONFIG_SMP
diff -Nru a/include/asm-v850/io.h b/include/asm-v850/io.h
--- a/include/asm-v850/io.h	Fri Nov  1 08:38:12 2002
+++ b/include/asm-v850/io.h	Mon Jun 16 22:23:12 2003
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/io.h -- Misc I/O operations
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * 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
@@ -29,6 +29,13 @@
   (void)((*(volatile unsigned short *) (addr)) = (b))
 #define writel(b, addr) \
   (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
 
 #define inb(addr)	readb (addr)
 #define inw(addr)	readw (addr)
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h	Wed Jun  4 17:57:06 2003
+++ b/include/linux/atmdev.h	Tue Jun 17 11:00:05 2003
@@ -452,7 +452,7 @@
 int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci);
 int atm_pcr_goal(struct atm_trafprm *tp);
 
-void atm_async_release_vcc(struct atm_vcc *vcc,int reply);
+void vcc_release_async(struct atm_vcc *vcc, int reply);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
--- a/include/linux/nfsd/nfsd.h	Mon May 19 23:34:37 2003
+++ b/include/linux/nfsd/nfsd.h	Tue Jun 17 16:30:53 2003
@@ -69,6 +69,8 @@
 int		fh_lock_parent(struct svc_fh *, struct dentry *);
 int		nfsd_racache_init(int);
 void		nfsd_racache_shutdown(void);
+int		nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
+		                struct svc_export **expp);
 int		nfsd_lookup(struct svc_rqst *, struct svc_fh *,
 				const char *, int, struct svc_fh *);
 int		nfsd_setattr(struct svc_rqst *, struct svc_fh *,
@@ -226,6 +228,7 @@
 #define COMPOUND_ERR_SLACK_SPACE	12     /* OP_SETATTR */
 
 #define NFSD_LEASE_TIME			60  /* seconds */
+#define NFSD_LAUNDROMAT_MINTIMEOUT      10   /* seconds */
 
 /*
  * The following attributes are currently not supported by the NFSv4 server:
diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
--- a/include/linux/nfsd/state.h	Mon May 19 23:34:37 2003
+++ b/include/linux/nfsd/state.h	Tue Jun 17 16:30:53 2003
@@ -73,13 +73,18 @@
 	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
 	struct list_head	cl_strhash; 	/* hash by cl_name */
 	struct list_head	cl_perclient; 	/* list: stateowners */
+	struct list_head        cl_lru;         /* tail queue */
 	struct xdr_netobj	cl_name; 	/* id generated by client */
 	nfs4_verifier		cl_verifier; 	/* generated by client */
+	time_t                  cl_time;        /* time of last lease renewal */
 	u32			cl_addr; 	/* client ipaddress */
 	struct svc_cred		cl_cred; 	/* setclientid principal */
 	clientid_t		cl_clientid;	/* generated by server */
 	nfs4_verifier		cl_confirm;	/* generated by server */
 };
+
+extern time_t nfs4_laundromat(void);
+int nfsd4_renew(clientid_t *clid);
 
 static inline void
 update_stateid(stateid_t *stateid)
diff -Nru a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
--- a/include/linux/sunrpc/cache.h	Tue Mar 11 20:03:48 2003
+++ b/include/linux/sunrpc/cache.h	Tue Jun 17 16:18:16 2003
@@ -115,6 +115,8 @@
 	struct list_head	recent; /* on fifo */
 	struct cache_head	*item;  /* cache item we wait on */
 	time_t			recv_time;
+	void			*owner; /* we might need to discard all defered requests
+					 * owned by someone */
 	void			(*revisit)(struct cache_deferred_req *req,
 					   int too_many);
 };
@@ -168,12 +170,14 @@
 		tmp = container_of(*hp, RTN, MEMBER);					\
 		if (TEST) { /* found a match */						\
 											\
+			if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
+				break;							\
+											\
 			atomic_inc(&tmp->MEMBER.refcnt);				\
 			if (set) {							\
-				if (set!= 2 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
+				if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
 				{ /* need to swap in new */				\
 					RTN *t2;					\
-					if (!new) break;				\
 											\
 					new->MEMBER.next = tmp->MEMBER.next;		\
 					*hp = &new->MEMBER;				\
@@ -242,6 +246,7 @@
 
 extern void cache_defer_req(struct cache_req *req, struct cache_head *item);
 extern void cache_revisit_request(struct cache_head *item);
+extern void cache_clean_deferred(void *owner);
 
 static inline struct cache_head  *cache_get(struct cache_head *h)
 {
diff -Nru a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h	Tue May  6 07:20:53 2003
+++ b/include/linux/sunrpc/svc.h	Tue Jun 17 16:31:29 2003
@@ -125,7 +125,6 @@
 	u32			rq_proc;	/* procedure number */
 	u32			rq_prot;	/* IP protocol */
 	unsigned short
-				rq_userset : 1,	/* auth->setuser OK */
 				rq_secure  : 1;	/* secure port */
 
 
@@ -196,14 +195,14 @@
 
 static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
 {
-        while (rqstp->rq_resused) {
+	while (rqstp->rq_resused &&
+	       rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
+
 		if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
 			rqstp->rq_argpages[rqstp->rq_arghi++] =
 				rqstp->rq_respages[rqstp->rq_resused];
 			rqstp->rq_respages[rqstp->rq_resused] = NULL;
 		}
-		if (rqstp->rq_res.pages == &rqstp->rq_respages[rqstp->rq_resused])
-			break;
 	}
 }
 
@@ -218,7 +217,6 @@
 }
 
 struct svc_deferred_req {
-	struct svc_serv		*serv;
 	u32			prot;	/* protocol (UDP or TCP) */
 	struct sockaddr_in	addr;
 	struct svc_sock		*svsk;	/* where reply must go */
diff -Nru a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h	Fri Jun  6 07:22:29 2003
+++ b/include/linux/tcp.h	Tue Jun 17 09:35:27 2003
@@ -219,7 +219,7 @@
  	__u32	snd_sml;	/* Last byte of the most recently transmitted small packet */
 	__u32	rcv_tstamp;	/* timestamp of last received ACK (for keepalives) */
 	__u32	lsndtime;	/* timestamp of last sent data packet (for restart window) */
-
+	struct tcp_bind_bucket *bind_hash;
 	/* Delayed ACK control data */
 	struct {
 		__u8	pending;	/* ACK is pending */
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Mon Jun 16 08:11:36 2003
+++ b/include/net/sctp/structs.h	Tue Jun 17 09:35:27 2003
@@ -313,6 +313,7 @@
 	/* What is our base endpointer? */
 	struct sctp_endpoint *ep;
 
+	struct sctp_bind_bucket *bind_hash;
 	/* Various Socket Options.  */
 	__u16 default_stream;
 	__u32 default_ppid;
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	Mon Jun 16 08:11:36 2003
+++ b/include/net/sock.h	Tue Jun 17 09:35:27 2003
@@ -133,7 +133,6 @@
   *	@sk_forward_alloc - space allocated forward
   *	@sk_allocation - allocation mode
   *	@sk_sndbuf - size of send buffer in bytes
-  *	@sk_prev - pointer to previous sock in the list this sock is in
   *	@sk_flags - %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
   *	@sk_no_check - %SO_NO_CHECK setting, wether or not checkup packets
   *	@sk_debug - %SO_DEBUG setting
@@ -206,7 +205,6 @@
 	int			sk_forward_alloc;
 	unsigned int		sk_allocation;
 	int			sk_sndbuf;
-	struct sock		*sk_prev;
 	unsigned long 		sk_flags;
 	char		 	sk_no_check;
 	unsigned char		sk_debug;
diff -Nru a/include/net/syncppp.h b/include/net/syncppp.h
--- a/include/net/syncppp.h	Mon Feb  4 23:40:24 2002
+++ b/include/net/syncppp.h	Fri May 30 12:35:20 2003
@@ -48,6 +48,7 @@
 	struct timer_list	pp_timer;
 	struct net_device	*pp_if;
 	char		pp_link_state;	/* Link status */
+	spinlock_t      lock;
 };
 
 struct ppp_device
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Mon Jun 16 11:44:09 2003
+++ b/include/net/tcp.h	Tue Jun 17 09:35:27 2003
@@ -1475,7 +1475,8 @@
 			TCP_INC_STATS(TcpEstabResets);
 
 		sk->sk_prot->unhash(sk);
-		if (sk->sk_prev && !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
+		if (tcp_sk(sk)->bind_hash &&
+		    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
 			tcp_put_port(sk);
 		/* fall through */
 	default:
diff -Nru a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_cmnd.h	Sun Jun  8 12:19:25 2003
@@ -0,0 +1,164 @@
+#ifndef _SCSI_SCSI_CMND_H
+#define _SCSI_SCSI_CMND_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct request;
+struct scatterlist;
+struct scsi_device;
+struct scsi_request;
+
+
+/* embedded in scsi_cmnd */
+struct scsi_pointer {
+	char *ptr;		/* data pointer */
+	int this_residual;	/* left in this buffer */
+	struct scatterlist *buffer;	/* which buffer */
+	int buffers_residual;	/* how many buffers left */
+
+        dma_addr_t dma_handle;
+
+	volatile int Status;
+	volatile int Message;
+	volatile int have_data_in;
+	volatile int sent_command;
+	volatile int phase;
+};
+
+struct scsi_cmnd {
+	int     sc_magic;
+
+	struct scsi_device *device;
+	unsigned short state;
+	unsigned short owner;
+	struct scsi_request *sc_request;
+
+	struct list_head list;  /* scsi_cmnd participates in queue lists */
+
+	struct list_head eh_entry; /* entry for the host eh_cmd_q */
+	int eh_state;		/* Used for state tracking in error handlr */
+	int eh_eflags;		/* Used by error handlr */
+	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
+
+	/*
+	 * A SCSI Command is assigned a nonzero serial_number when internal_cmnd
+	 * passes it to the driver's queue command function.  The serial_number
+	 * is cleared when scsi_done is entered indicating that the command has
+	 * been completed.  If a timeout occurs, the serial number at the moment
+	 * of timeout is copied into serial_number_at_timeout.  By subsequently
+	 * comparing the serial_number and serial_number_at_timeout fields
+	 * during abort or reset processing, we can detect whether the command
+	 * has already completed.  This also detects cases where the command has
+	 * completed and the SCSI Command structure has already being reused
+	 * for another command, so that we can avoid incorrectly aborting or
+	 * resetting the new command.
+	 */
+	unsigned long serial_number;
+	unsigned long serial_number_at_timeout;
+
+	int retries;
+	int allowed;
+	int timeout_per_command;
+	int timeout_total;
+	int timeout;
+
+	/*
+	 * We handle the timeout differently if it happens when a reset, 
+	 * abort, etc are in process. 
+	 */
+	unsigned volatile char internal_timeout;
+
+	unsigned char cmd_len;
+	unsigned char old_cmd_len;
+	unsigned char sc_data_direction;
+	unsigned char sc_old_data_direction;
+
+	/* These elements define the operation we are about to perform */
+#define MAX_COMMAND_SIZE	16
+	unsigned char cmnd[MAX_COMMAND_SIZE];
+	unsigned request_bufflen;	/* Actual request size */
+
+	struct timer_list eh_timeout;	/* Used to time out the command. */
+	void *request_buffer;		/* Actual requested buffer */
+
+	/* These elements define the operation we ultimately want to perform */
+	unsigned char data_cmnd[MAX_COMMAND_SIZE];
+	unsigned short old_use_sg;	/* We save  use_sg here when requesting
+					 * sense info */
+	unsigned short use_sg;	/* Number of pieces of scatter-gather */
+	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
+	unsigned short abort_reason;	/* If the mid-level code requests an
+					 * abort, this is the reason. */
+	unsigned bufflen;	/* Size of data buffer */
+	void *buffer;		/* Data buffer */
+
+	unsigned underflow;	/* Return error if less than
+				   this amount is transferred */
+	unsigned old_underflow;	/* save underflow here when reusing the
+				 * command for error handling */
+
+	unsigned transfersize;	/* How much we are guaranteed to
+				   transfer with each SCSI transfer
+				   (ie, between disconnect / 
+				   reconnects.   Probably == sector
+				   size */
+
+	int resid;		/* Number of bytes requested to be
+				   transferred less actual number
+				   transferred (0 if not supported) */
+
+	struct request *request;	/* The command we are
+				   	   working on */
+
+#define SCSI_SENSE_BUFFERSIZE 	64
+	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
+						 * when CHECK CONDITION is
+						 * received on original command 
+						 * (auto-sense) */
+
+	unsigned flags;
+
+	/* Low-level done function - can be used by low-level driver to point
+	 *        to completion function.  Not used by mid/upper level code. */
+	void (*scsi_done) (struct scsi_cmnd *);
+
+	/*
+	 * The following fields can be written to by the host specific code. 
+	 * Everything else should be left alone. 
+	 */
+	struct scsi_pointer SCp;	/* Scratchpad used by some host adapters */
+
+	unsigned char *host_scribble;	/* The host adapter is allowed to
+					   * call scsi_malloc and get some memory
+					   * and hang it here.     The host adapter
+					   * is also expected to call scsi_free
+					   * to release this memory.  (The memory
+					   * obtained by scsi_malloc is guaranteed
+					   * to be at an address < 16Mb). */
+
+	int result;		/* Status code from lower level driver */
+
+	unsigned char tag;	/* SCSI-II queued command tag */
+	unsigned long pid;	/* Process ID, starts at 0 */
+};
+
+/*
+ * These are the values that scsi_cmd->state can take.
+ */
+#define SCSI_STATE_TIMEOUT         0x1000
+#define SCSI_STATE_FINISHED        0x1001
+#define SCSI_STATE_FAILED          0x1002
+#define SCSI_STATE_QUEUED          0x1003
+#define SCSI_STATE_UNUSED          0x1006
+#define SCSI_STATE_DISCONNECTING   0x1008
+#define SCSI_STATE_INITIALIZING    0x1009
+#define SCSI_STATE_BHQUEUE         0x100a
+#define SCSI_STATE_MLQUEUE         0x100b
+
+
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
+extern void scsi_put_command(struct scsi_cmnd *);
+extern void scsi_io_completion(struct scsi_cmnd *, int, int);
+
+#endif /* _SCSI_SCSI_CMND_H */
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_device.h	Sun Jun  8 12:19:25 2003
@@ -0,0 +1,106 @@
+#ifndef _SCSI_SCSI_DEVICE_H
+#define _SCSI_SCSI_DEVICE_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct request_queue;
+struct scsi_cmnd;
+
+
+struct scsi_device {
+	struct class_device	sdev_classdev;
+
+	struct list_head    siblings;   /* list of all devices on this host */
+	struct list_head    same_target_siblings; /* just the devices sharing same target id */
+	struct Scsi_Host *host;
+	struct request_queue *request_queue;
+	volatile unsigned short device_busy;	/* commands actually active on low-level */
+	spinlock_t sdev_lock;           /* also the request queue_lock */
+	spinlock_t list_lock;
+	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
+	struct list_head starved_entry;
+	struct scsi_cmnd *current_cmnd;	/* currently active command */
+	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
+					   jiffie count on our counter, they
+					   could all be from the same event. */
+
+	unsigned int id, lun, channel;
+
+	unsigned int manufacturer;	/* Manufacturer of device, for using 
+					 * vendor-specific cmd's */
+	unsigned sector_size;	/* size in bytes */
+
+	int access_count;	/* Count of open channels/mounts */
+
+	void *hostdata;		/* available to low-level driver */
+	char devfs_name[256];	/* devfs junk */
+	char type;
+	char scsi_level;
+	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
+	unsigned char * inquiry;	/* INQUIRY response data */
+	char * vendor;		/* [back_compat] point into 'inquiry' ... */
+	char * model;		/* ... after scan; point to static string */
+	char * rev;		/* ... "nullnullnullnull" before scan */
+	unsigned char current_tag;	/* current tag */
+	struct scsi_target      *sdev_target;   /* used only for single_lun */
+
+	unsigned online:1;
+
+	unsigned writeable:1;
+	unsigned removable:1;
+	unsigned changed:1;	/* Data invalid due to media change */
+	unsigned busy:1;	/* Used to prevent races */
+	unsigned lockable:1;	/* Able to prevent media removal */
+	unsigned locked:1;      /* Media removal disabled */
+	unsigned borken:1;	/* Tell the Seagate driver to be 
+				 * painfully slow on this device */
+	unsigned disconnect:1;	/* can disconnect */
+	unsigned soft_reset:1;	/* Uses soft reset option */
+	unsigned sdtr:1;	/* Device supports SDTR messages */
+	unsigned wdtr:1;	/* Device supports WDTR messages */
+	unsigned ppr:1;		/* Device supports PPR messages */
+	unsigned tagged_supported:1;	/* Supports SCSI-II tagged queuing */
+	unsigned tagged_queue:1;/* This is going away!!!!  Look at simple_tags
+				   instead!!!  Please fix your driver now!! */
+	unsigned simple_tags:1;	/* simple queue tag messages are enabled */
+	unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
+	unsigned single_lun:1;	/* Indicates we should only allow I/O to
+				 * one of the luns for the device at a 
+				 * time. */
+	unsigned was_reset:1;	/* There was a bus reset on the bus for 
+				 * this device */
+	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
+				     * because we did a bus reset. */
+	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
+	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+	unsigned no_start_on_add:1;	/* do not issue start on add */
+
+	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
+
+	unsigned int max_device_blocked; /* what device_blocked counts down from  */
+#define SCSI_DEFAULT_DEVICE_BLOCKED	3
+
+	struct device sdev_driverfs_dev;
+};
+#define	to_scsi_device(d)	\
+	container_of(d, struct scsi_device, sdev_driverfs_dev)
+
+extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
+		uint, uint, uint);
+extern int scsi_remove_device(struct scsi_device *);
+extern void scsi_set_device_offline(struct scsi_device *);
+
+extern int scsi_device_get(struct scsi_device *);
+extern void scsi_device_put(struct scsi_device *);
+
+extern void scsi_adjust_queue_depth(struct scsi_device *, int, int);
+extern int scsi_track_queue_full(struct scsi_device *, int);
+
+extern int scsi_set_medium_removal(struct scsi_device *, char);
+
+#endif /* _SCSI_SCSI_DEVICE_H */
diff -Nru a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_eh.h	Sun Jun  8 15:03:00 2003
@@ -0,0 +1,21 @@
+#ifndef _SCSI_SCSI_EH_H
+#define _SCSI_SCSI_EH_H
+
+extern void scsi_add_timer(struct scsi_cmnd *, int,
+			   void (*)(struct scsi_cmnd *));
+extern int scsi_delete_timer(struct scsi_cmnd *);
+extern void scsi_report_bus_reset(struct Scsi_Host *, int);
+extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
+extern int scsi_block_when_processing_errors(struct scsi_device *);
+extern void scsi_sleep(int);
+
+/*
+ * Reset request from external source
+ */
+#define SCSI_TRY_RESET_DEVICE	1
+#define SCSI_TRY_RESET_BUS	2
+#define SCSI_TRY_RESET_HOST	3
+
+extern int scsi_reset_provider(struct scsi_device *, int);
+
+#endif /* _SCSI_SCSI_EH_H */
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_host.h	Sun Jun  8 13:31:57 2003
@@ -0,0 +1,525 @@
+#ifndef _SCSI_SCSI_HOST_H
+#define _SCSI_SCSI_HOST_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct block_device;
+struct module;
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+struct scsi_host_cmd_pool;
+
+
+/*
+ * The various choices mean:
+ * NONE: Self evident.	Host adapter is not capable of scatter-gather.
+ * ALL:	 Means that the host adapter module can do scatter-gather,
+ *	 and that there is no limit to the size of the table to which
+ *	 we scatter/gather data.
+ * Anything else:  Indicates the maximum number of chains that can be
+ *	 used in one scatter-gather request.
+ */
+#define SG_NONE 0
+#define SG_ALL 0xff
+
+
+#define DISABLE_CLUSTERING 0
+#define ENABLE_CLUSTERING 1
+
+
+struct scsi_host_template {
+	struct module *module;
+	const char *name;
+
+	/*
+	 * Used to initialize old-style drivers.  For new-style drivers
+	 * just perform all work in your module initialization function.
+	 *
+	 * Status:  OBSOLETE
+	 */
+	int (* detect)(struct scsi_host_template *);
+
+	/*
+	 * Used as unload callback for hosts with old-style drivers.
+	 *
+	 * Status: OBSOLETE
+	 */
+	int (* release)(struct Scsi_Host *);
+
+	/*
+	 * The info function will return whatever useful information the
+	 * developer sees fit.  If not provided, then the name field will
+	 * be used instead.
+	 *
+	 * Status: OPTIONAL
+	 */
+	const char *(* info)(struct Scsi_Host *);
+
+	/*
+	 * Ioctl interface
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* ioctl)(struct scsi_device *dev, int cmd, void *arg);
+	
+	/*
+	 * The queuecommand function is used to queue up a scsi
+	 * command block to the LLDD.  When the driver finished
+	 * processing the command the done callback is invoked.
+	 *
+	 * If queuecommand returns 0, then the HBA has accepted the
+	 * command.  The done() function must be called on the command
+	 * when the driver has finished with it. (you may call done on the
+	 * command before queuecommand returns, but in this case you
+	 * *must* return 0 from queuecommand).
+	 *
+	 * Queuecommand may also reject the command, in which case it may
+	 * not touch the command and must not call done() for it.
+	 *
+	 * There are two possible rejection returns:
+	 *
+	 *   SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but
+	 *   allow commands to other devices serviced by this host.
+	 *
+	 *   SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this
+	 *   host temporarily.
+	 *
+         * For compatibility, any other non-zero return is treated the
+         * same as SCSI_MLQUEUE_HOST_BUSY.
+	 *
+	 * NOTE: "temporarily" means either until the next command for#
+	 * this device/host completes, or a period of time determined by
+	 * I/O pressure in the system if there are no other outstanding
+	 * commands.
+	 *
+	 * STATUS: REQUIRED
+	 */
+	int (* queuecommand)(struct scsi_cmnd *,
+			     void (*done)(struct scsi_cmnd *));
+
+	/*
+	 * This is an error handling strategy routine.  You don't need to
+	 * define one of these if you don't want to - there is a default
+	 * routine that is present that should work in most cases.  For those
+	 * driver authors that have the inclination and ability to write their
+	 * own strategy routine, this is where it is specified.  Note - the
+	 * strategy routine is *ALWAYS* run in the context of the kernel eh
+	 * thread.  Thus you are guaranteed to *NOT* be in an interrupt
+	 * handler when you execute this, and you are also guaranteed to
+	 * *NOT* have any other commands being queued while you are in the
+	 * strategy routine. When you return from this function, operations
+	 * return to normal.
+	 *
+	 * See scsi_error.c scsi_unjam_host for additional comments about
+	 * what this function should and should not be attempting to do.
+	 *
+	 * Status: REQUIRED	(at least one of them)
+	 */
+	int (* eh_strategy_handler)(struct Scsi_Host *);
+	int (* eh_abort_handler)(struct scsi_cmnd *);
+	int (* eh_device_reset_handler)(struct scsi_cmnd *);
+	int (* eh_bus_reset_handler)(struct scsi_cmnd *);
+	int (* eh_host_reset_handler)(struct scsi_cmnd *);
+
+	/*
+	 * Old EH handlers, no longer used. Make them warn the user of old
+	 * drivers by using a wrong type
+	 *
+	 * Status: MORE THAN OBSOLETE
+	 */
+	int (* abort)(int);
+	int (* reset)(int, int);
+
+	/*
+	 * Before the mid layer attempts to scan for a new device where none
+	 * currently exists, it will call this entry in your driver.  Should
+	 * your driver need to allocate any structs or perform any other init
+	 * items in order to send commands to a currently unused target/lun
+	 * combo, then this is where you can perform those allocations.  This
+	 * is specifically so that drivers won't have to perform any kind of
+	 * "is this a new device" checks in their queuecommand routine,
+	 * thereby making the hot path a bit quicker.
+	 *
+	 * Return values: 0 on success, non-0 on failure
+	 *
+	 * Deallocation:  If we didn't find any devices at this ID, you will
+	 * get an immediate call to slave_destroy().  If we find something
+	 * here then you will get a call to slave_configure(), then the
+	 * device will be used for however long it is kept around, then when
+	 * the device is removed from the system (or * possibly at reboot
+	 * time), you will then get a call to slave_detach().  This is
+	 * assuming you implement slave_configure and slave_destroy.
+	 * However, if you allocate memory and hang it off the device struct,
+	 * then you must implement the slave_destroy() routine at a minimum
+	 * in order to avoid leaking memory
+	 * each time a device is tore down.
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* slave_alloc)(struct scsi_device *);
+
+	/*
+	 * Once the device has responded to an INQUIRY and we know the
+	 * device is online, we call into the low level driver with the
+	 * struct scsi_device *.  If the low level device driver implements
+	 * this function, it *must* perform the task of setting the queue
+	 * depth on the device.  All other tasks are optional and depend
+	 * on what the driver supports and various implementation details.
+	 * 
+	 * Things currently recommended to be handled at this time include:
+	 *
+	 * 1.  Setting the device queue depth.  Proper setting of this is
+	 *     described in the comments for scsi_adjust_queue_depth.
+	 * 2.  Determining if the device supports the various synchronous
+	 *     negotiation protocols.  The device struct will already have
+	 *     responded to INQUIRY and the results of the standard items
+	 *     will have been shoved into the various device flag bits, eg.
+	 *     device->sdtr will be true if the device supports SDTR messages.
+	 * 3.  Allocating command structs that the device will need.
+	 * 4.  Setting the default timeout on this device (if needed).
+	 * 5.  Anything else the low level driver might want to do on a device
+	 *     specific setup basis...
+	 * 6.  Return 0 on success, non-0 on error.  The device will be marked
+	 *     as offline on error so that no access will occur.  If you return
+	 *     non-0, your slave_detach routine will never get called for this
+	 *     device, so don't leave any loose memory hanging around, clean
+	 *     up after yourself before returning non-0
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* slave_configure)(struct scsi_device *);
+
+	/*
+	 * Immediately prior to deallocating the device and after all activity
+	 * has ceased the mid layer calls this point so that the low level
+	 * driver may completely detach itself from the scsi device and vice
+	 * versa.  The low level driver is responsible for freeing any memory
+	 * it allocated in the slave_alloc or slave_configure calls. 
+	 *
+	 * Status: OPTIONAL
+	 */
+	void (* slave_destroy)(struct scsi_device *);
+
+	/*
+	 * This function determines the bios parameters for a given
+	 * harddisk.  These tend to be numbers that are made up by
+	 * the host adapter.  Parameters:
+	 * size, device, list (heads, sectors, cylinders)
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* bios_param)(struct scsi_device *, struct block_device *,
+			sector_t, int []);
+
+	/*
+	 * Can be used to export driver statistics and other infos to the
+	 * world outside the kernel ie. userspace and it also provides an
+	 * interface to feed the driver with information.
+	 *
+	 * Status: OBSOLETE
+	 */
+	int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
+
+	/*
+	 * Name of proc directory
+	 */
+	char *proc_name;
+
+	/*
+	 * Used to store the procfs directory if a driver implements the
+	 * proc_info method.
+	 */
+	struct proc_dir_entry *proc_dir;
+
+	/*
+	 * This determines if we will use a non-interrupt driven
+	 * or an interrupt driven scheme,  It is set to the maximum number
+	 * of simultaneous commands a given host adapter will accept.
+	 */
+	int can_queue;
+
+	/*
+	 * In many instances, especially where disconnect / reconnect are
+	 * supported, our host also has an ID on the SCSI bus.  If this is
+	 * the case, then it must be reserved.  Please set this_id to -1 if
+	 * your setup is in single initiator mode, and the host lacks an
+	 * ID.
+	 */
+	int this_id;
+
+	/*
+	 * This determines the degree to which the host adapter is capable
+	 * of scatter-gather.
+	 */
+	unsigned short sg_tablesize;
+
+	/*
+	 * If the host adapter has limitations beside segment count
+	 */
+	unsigned short max_sectors;
+
+	/*
+	 * This specifies "machine infinity" for host templates which don't
+	 * limit the transfer size.  Note this limit represents an absolute
+	 * maximum, and may be over the transfer limits allowed for
+	 * individual devices (e.g. 256 for SCSI-1)
+	 */
+#define SCSI_DEFAULT_MAX_SECTORS	1024
+
+	/*
+	 * True if this host adapter can make good use of linked commands.
+	 * This will allow more than one command to be queued to a given
+	 * unit on a given host.  Set this to the maximum number of command
+	 * blocks to be provided for each device.  Set this to 1 for one
+	 * command block per lun, 2 for two, etc.  Do not set this to 0.
+	 * You should make sure that the host adapter will do the right thing
+	 * before you try setting this above 1.
+	 */
+	short cmd_per_lun;
+
+	/*
+	 * present contains counter indicating how many boards of this
+	 * type were found when we did the scan.
+	 */
+	unsigned char present;
+
+	/*
+	 * true if this host adapter uses unchecked DMA onto an ISA bus.
+	 */
+	unsigned unchecked_isa_dma:1;
+
+	/*
+	 * true if this host adapter can make good use of clustering.
+	 * I originally thought that if the tablesize was large that it
+	 * was a waste of CPU cycles to prepare a cluster list, but
+	 * it works out that the Buslogic is faster if you use a smaller
+	 * number of segments (i.e. use clustering).  I guess it is
+	 * inefficient.
+	 */
+	unsigned use_clustering:1;
+
+	/*
+	 * True for emulated SCSI host adapters (e.g. ATAPI)
+	 */
+	unsigned emulated:1;
+
+	unsigned highmem_io:1;
+
+	/* 
+	 * True if the driver wishes to use the generic block layer
+	 * tag queueing functions
+	 */
+	unsigned use_blk_tcq:1;
+
+	/*
+	 * Countdown for host blocking with no commands outstanding
+	 */
+	unsigned int max_host_blocked;
+
+	/*
+	 * Default value for the blocking.  If the queue is empty,
+	 * host_blocked counts down in the request_fn until it restarts
+	 * host operations as zero is reached.  
+	 *
+	 * FIXME: This should probably be a value in the template
+	 */
+#define SCSI_DEFAULT_HOST_BLOCKED	7
+
+	/*
+	 * Pointer to the sysfs class properties for this host
+	 */
+	struct class_device_attribute **shost_attrs;
+
+	/*
+	 * Pointer to the SCSI device properties for this host
+	 */
+	struct device_attribute **sdev_attrs;
+
+	/*
+	 * List of hosts per template.
+	 *
+	 * This is only for use by scsi_module.c for legacy templates.
+	 * For these access to it is synchronized implicitly by
+	 * module_init/module_exit.
+	 */
+	struct list_head legacy_hosts;
+};
+
+struct Scsi_Host {
+	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 */
+	struct list_head	starved_list;
+
+	spinlock_t		default_lock;
+	spinlock_t		*host_lock;
+
+	struct list_head	eh_cmd_q;
+	struct task_struct    * ehandler;  /* Error recovery thread. */
+	struct semaphore      * eh_wait;   /* The error recovery thread waits on
+                                          this. */
+	struct completion     * eh_notify; /* wait for eh to begin or end */
+	struct semaphore      * eh_action; /* Wait for specific actions on the
+                                          host. */
+	unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
+                                          this is true. */
+	unsigned int            eh_kill:1; /* set when killing the eh thread */
+	wait_queue_head_t       host_wait;
+	struct scsi_host_template *hostt;
+	volatile unsigned short host_busy;   /* commands actually active on low-level */
+	volatile unsigned short host_failed; /* commands that failed. */
+    
+	unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
+	int resetting; /* if set, it means that last_reset is a valid value */
+	unsigned long last_reset;
+
+	/*
+	 * These three parameters can be used to allow for wide scsi,
+	 * and for host adapters that support multiple busses
+	 * The first two should be set to 1 more than the actual max id
+	 * or lun (i.e. 8 for normal systems).
+	 */
+	unsigned int max_id;
+	unsigned int max_lun;
+	unsigned int max_channel;
+
+	/*
+	 * This is a unique identifier that must be assigned so that we
+	 * have some way of identifying each detected host adapter properly
+	 * and uniquely.  For hosts that do not support more than one card
+	 * in the system at one time, this does not need to be set.  It is
+	 * initialized to 0 in scsi_register.
+	 */
+	unsigned int unique_id;
+
+	/*
+	 * The maximum length of SCSI commands that this host can accept.
+	 * Probably 12 for most host adapters, but could be 16 for others.
+	 * For drivers that don't set this field, a value of 12 is
+	 * assumed.  I am leaving this as a number rather than a bit
+	 * because you never know what subsequent SCSI standards might do
+	 * (i.e. could there be a 20 byte or a 24-byte command a few years
+	 * down the road?).  
+	 */
+	unsigned char max_cmd_len;
+
+	int this_id;
+	int can_queue;
+	short cmd_per_lun;
+	short unsigned int sg_tablesize;
+	short unsigned int max_sectors;
+
+	unsigned in_recovery:1;
+	unsigned unchecked_isa_dma:1;
+	unsigned use_clustering:1;
+	unsigned highmem_io:1;
+	unsigned use_blk_tcq:1;
+
+	/*
+	 * Host has requested that no further requests come through for the
+	 * time being.
+	 */
+	unsigned host_self_blocked:1;
+    
+	/*
+	 * Host uses correct SCSI ordering not PC ordering. The bit is
+	 * set for the minority of drivers whose authors actually read
+	 * the spec ;)
+	 */
+	unsigned reverse_ordering:1;
+
+	/*
+	 * Host has rejected a command because it was busy.
+	 */
+	unsigned int host_blocked;
+
+	/*
+	 * Value host_blocked counts down from
+	 */
+	unsigned int max_host_blocked;
+
+	/* 
+	 * Support for sysfs
+	 */
+	struct device host_gendev;
+	struct class_device class_dev;
+
+	/* legacy crap */
+	unsigned long base;
+	unsigned long io_port;
+	unsigned char n_io_port;
+	unsigned char dma_channel;
+	unsigned int  irq;
+
+
+	/*
+	 * List of hosts per template.
+	 *
+	 * This is only for use by scsi_module.c for legacy templates.
+	 * For these access to it is synchronized implicitly by
+	 * module_init/module_exit.
+	 */
+	struct list_head sht_legacy_list;
+
+	/*
+	 * We should ensure that this is aligned, both for better performance
+	 * and also because some compilers (m68k) don't automatically force
+	 * alignment to a long boundary.
+	 */
+	unsigned long hostdata[0]  /* Used for storage of host specific stuff */
+		__attribute__ ((aligned (sizeof(unsigned long))));
+};
+#define		dev_to_shost(d)		\
+	container_of(d, struct Scsi_Host, host_gendev)
+#define		class_to_shost(d)	\
+	container_of(d, struct Scsi_Host, class_dev)
+
+extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
+extern int scsi_add_host(struct Scsi_Host *, struct device *);
+extern int scsi_remove_host(struct Scsi_Host *);
+extern void scsi_host_get(struct Scsi_Host *);
+extern void scsi_host_put(struct Scsi_Host *t);
+extern struct Scsi_Host *scsi_host_lookup(unsigned short);
+
+extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
+
+static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
+{
+	shost->host_lock = lock;
+}
+
+static inline void scsi_set_device(struct Scsi_Host *shost,
+                                   struct device *dev)
+{
+        shost->host_gendev.parent = dev;
+}
+
+static inline struct device *scsi_get_device(struct Scsi_Host *shost)
+{
+        return shost->host_gendev.parent;
+}
+
+extern void scsi_sysfs_release_attributes(struct scsi_host_template *);
+
+extern void scsi_unblock_requests(struct Scsi_Host *);
+extern void scsi_block_requests(struct Scsi_Host *);
+
+/*
+ * These two functions are used to allocate and free a pseudo device
+ * which will connect to the host adapter itself rather than any
+ * physical device.  You must deallocate when you are done with the
+ * thing.  This physical pseudo-device isn't real and won't be available
+ * from any high-level drivers.
+ */
+extern void scsi_free_host_dev(struct scsi_device *);
+extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+
+/* legacy interfaces */
+extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
+extern void scsi_unregister(struct Scsi_Host *);
+
+#endif /* _SCSI_SCSI_HOST_H */
diff -Nru a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_request.h	Sun Jun  8 15:03:00 2003
@@ -0,0 +1,58 @@
+#ifndef _SCSI_SCSI_REQUEST_H
+#define _SCSI_SCSI_REQUEST_H
+
+#include <scsi/scsi_cmnd.h>
+
+struct request;
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+
+
+/*
+ * This is essentially a slimmed down version of Scsi_Cmnd.  The point of
+ * having this is that requests that are injected into the queue as result
+ * of things like ioctls and character devices shouldn't be using a
+ * Scsi_Cmnd until such a time that the command is actually at the head
+ * of the queue and being sent to the driver.
+ */
+struct scsi_request {
+	int     sr_magic;
+	int     sr_result;	/* Status code from lower level driver */
+	unsigned char sr_sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
+						 * when CHECK CONDITION is
+						 * received on original command 
+						 * (auto-sense) */
+
+	struct Scsi_Host *sr_host;
+	struct scsi_device *sr_device;
+	struct scsi_cmnd *sr_command;
+	struct request *sr_request;	/* A copy of the command we are
+				   working on */
+	unsigned sr_bufflen;	/* Size of data buffer */
+	void *sr_buffer;		/* Data buffer */
+	int sr_allowed;
+	unsigned char sr_data_direction;
+	unsigned char sr_cmd_len;
+	unsigned char sr_cmnd[MAX_COMMAND_SIZE];
+	void (*sr_done) (struct scsi_cmnd *);	/* Mid-level done function */
+	int sr_timeout_per_command;
+	unsigned short sr_use_sg;	/* Number of pieces of scatter-gather */
+	unsigned short sr_sglist_len;	/* size of malloc'd scatter-gather list */
+	unsigned sr_underflow;	/* Return error if less than
+				   this amount is transferred */
+ 	void *upper_private_data;	/* reserved for owner (usually upper
+ 					   level driver) of this request */
+};
+
+extern struct scsi_request *scsi_allocate_request(struct scsi_device *);
+extern void scsi_release_request(struct scsi_request *);
+extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
+			  void *buffer, unsigned bufflen,
+			  int timeout, int retries);
+extern void scsi_do_req(struct scsi_request *, const void *cmnd,
+			void *buffer, unsigned bufflen,
+			void (*done) (struct scsi_cmnd *),
+			int timeout, int retries);
+
+#endif /* _SCSI_SCSI_REQUEST_H */
diff -Nru a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_tcq.h	Sun Jun  8 15:03:00 2003
@@ -0,0 +1,94 @@
+#ifndef _SCSI_SCSI_TCQ_H
+#define _SCSI_SCSI_TCQ_H
+
+#include <linux/blkdev.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+
+#define MSG_SIMPLE_TAG	0x20
+#define MSG_HEAD_TAG	0x21
+#define MSG_ORDERED_TAG	0x22
+
+#define SCSI_NO_TAG	(-1)    /* identify no tag in use */
+
+
+/**
+ * scsi_activate_tcq - turn on tag command queueing
+ * @SDpnt:	device to turn on TCQ for
+ * @depth:	queue depth
+ *
+ * Notes:
+ *	Eventually, I hope depth would be the maximum depth
+ *	the device could cope with and the real queue depth
+ *	would be adjustable from 0 to depth.
+ **/
+static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
+{
+        if (sdev->tagged_supported) {
+		if (!blk_queue_tagged(sdev->request_queue))
+			blk_queue_init_tags(sdev->request_queue, depth);
+		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+        }
+}
+
+/**
+ * scsi_deactivate_tcq - turn off tag command queueing
+ * @SDpnt:	device to turn off TCQ for
+ **/
+static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
+{
+	if (blk_queue_tagged(sdev->request_queue))
+		blk_queue_free_tags(sdev->request_queue);
+	scsi_adjust_queue_depth(sdev, 0, depth);
+}
+
+/**
+ * scsi_populate_tag_msg - place a tag message in a buffer
+ * @SCpnt:	pointer to the Scsi_Cmnd for the tag
+ * @msg:	pointer to the area to place the tag
+ *
+ * Notes:
+ *	designed to create the correct type of tag message for the 
+ *	particular request.  Returns the size of the tag message.
+ *	May return 0 if TCQ is disabled for this device.
+ **/
+static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
+{
+        struct request *req = cmd->request;
+
+        if (blk_rq_tagged(req)) {
+		if (req->flags & REQ_HARDBARRIER)
+        	        *msg++ = MSG_ORDERED_TAG;
+        	else
+        	        *msg++ = MSG_SIMPLE_TAG;
+        	*msg++ = req->tag;
+        	return 2;
+	}
+
+	return 0;
+}
+
+/**
+ * scsi_find_tag - find a tagged command by device
+ * @SDpnt:	pointer to the ScSI device
+ * @tag:	the tag number
+ *
+ * Notes:
+ *	Only works with tags allocated by the generic blk layer.
+ **/
+static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
+{
+
+        struct request *req;
+
+        if (tag != SCSI_NO_TAG) {
+        	req = blk_queue_find_tag(sdev->request_queue, tag);
+	        return req ? (struct scsi_cmnd *)req->special : NULL;
+	}
+
+	/* single command, look in space */
+	return sdev->current_cmnd;
+}
+
+#endif /* _SCSI_SCSI_TCQ_H */
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- a/kernel/compat.c	Sun Jun 15 05:27:20 2003
+++ b/kernel/compat.c	Tue Jun 17 05:37:03 2003
@@ -354,6 +354,8 @@
 
 	if (put_compat_rusage(ru, &r))
 		return -EFAULT;
+
+	return 0;
 }
 
 asmlinkage long
diff -Nru a/net/atm/clip.c b/net/atm/clip.c
--- a/net/atm/clip.c	Wed Jun  4 17:57:07 2003
+++ b/net/atm/clip.c	Tue Jun 17 11:00:05 2003
@@ -140,8 +140,8 @@
 					DPRINTK("releasing vcc %p->%p of "
 					    "entry %p\n",clip_vcc,clip_vcc->vcc,
 					    entry);
-					atm_async_release_vcc(clip_vcc->vcc,
-					    -ETIMEDOUT);
+					vcc_release_async(clip_vcc->vcc,
+							  -ETIMEDOUT);
 				}
 			if (entry->vccs ||
 			    time_before(jiffies, entry->expires)) {
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c	Wed Jun  4 17:57:07 2003
+++ b/net/atm/common.c	Tue Jun 17 11:00:05 2003
@@ -239,15 +239,16 @@
 }
 
 
-void atm_async_release_vcc(struct atm_vcc *vcc,int reply)
+void vcc_release_async(struct atm_vcc *vcc, int reply)
 {
-	set_bit(ATM_VF_CLOSE,&vcc->flags);
+	set_bit(ATM_VF_CLOSE, &vcc->flags);
 	vcc->reply = reply;
+	vcc->sk->sk_err = -reply;
 	wake_up(&vcc->sleep);
 }
 
 
-EXPORT_SYMBOL(atm_async_release_vcc);
+EXPORT_SYMBOL(vcc_release_async);
 
 
 static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
@@ -276,8 +277,8 @@
 }
 
 
-static int atm_do_connect_dev(struct atm_vcc *vcc,struct atm_dev *dev,int vpi,
-    int vci)
+static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
+			 int vci)
 {
 	int error;
 
@@ -334,29 +335,26 @@
 }
 
 
-static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
+int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
 {
 	struct atm_dev *dev;
-	int return_val;
-
-	dev = atm_dev_lookup(itf);
-	if (!dev)
-		return_val =  -ENODEV;
-	else {
-		return_val = atm_do_connect_dev(vcc,dev,vpi,vci);
-		if (return_val) atm_dev_release(dev);
-	}
-
-	return return_val;
-}
+	struct atm_vcc *vcc = ATM_SD(sock);
+	int error;
 
+	DPRINTK("vcc_connect (vpi %d, vci %d)\n",vpi,vci);
+	if (sock->state == SS_CONNECTED)
+		return -EISCONN;
+	if (sock->state != SS_UNCONNECTED)
+		return -EINVAL;
+	if (!(vpi || vci))
+		return -EINVAL;
 
-int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
-{
 	if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
 		clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-	else if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) return -EINVAL;
-	DPRINTK("atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
+	else
+		if (test_bit(ATM_VF_PARTIAL,&vcc->flags))
+			return -EINVAL;
+	DPRINTK("vcc_connect (TX: cl %d,bw %d-%d,sdu %d; "
 	    "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
 	    vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
 	    vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
@@ -364,141 +362,135 @@
 	    vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
 	    vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
 	    " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
+		return -EBADFD;
 	if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
 	    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
 		return -EINVAL;
 	if (itf != ATM_ITF_ANY) {
-		int error;
-
-		error = atm_do_connect(vcc,itf,vpi,vci);
-		if (error) return error;
-	}
-	else {
-		struct atm_dev *dev = NULL;
+		dev = atm_dev_lookup(itf);
+		error = __vcc_connect(vcc, dev, vpi, vci);
+		if (error) {
+			atm_dev_release(dev);
+			return error;
+		}
+	} else {
 		struct list_head *p, *next;
 
+		dev = NULL;
 		spin_lock(&atm_dev_lock);
 		list_for_each_safe(p, next, &atm_devs) {
 			dev = list_entry(p, struct atm_dev, dev_list);
 			atm_dev_hold(dev);
 			spin_unlock(&atm_dev_lock);
-			if (!atm_do_connect_dev(vcc,dev,vpi,vci))
+			if (!__vcc_connect(vcc, dev, vpi, vci))
 				break;
 			atm_dev_release(dev);
 			dev = NULL;
 			spin_lock(&atm_dev_lock);
 		}
 		spin_unlock(&atm_dev_lock);
-		if (!dev) return -ENODEV;
+		if (!dev)
+			return -ENODEV;
 	}
 	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
 		set_bit(ATM_VF_PARTIAL,&vcc->flags);
-	return 0;
-}
-
-
-int atm_connect(struct socket *sock,int itf,short vpi,int vci)
-{
-	int error;
-
-	DPRINTK("atm_connect (vpi %d, vci %d)\n",vpi,vci);
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state != SS_UNCONNECTED) return -EINVAL;
-	if (!(vpi || vci)) return -EINVAL;
-	error = atm_connect_vcc(ATM_SD(sock),itf,vpi,vci);
-	if (error) return error;
 	if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
 		sock->state = SS_CONNECTED;
 	return 0;
 }
 
 
-int atm_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-		int total_len, int flags)
+int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+		int size, int flags)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc;
 	struct sk_buff *skb;
-	int eff_len,error;
-	void *buff;
-	int size;
+	int copied, error = -EINVAL;
 
-	if (sock->state != SS_CONNECTED) return -ENOTCONN;
-	if (flags & ~MSG_DONTWAIT) return -EOPNOTSUPP;
-	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
-	buff = m->msg_iov->iov_base;
-	size = m->msg_iov->iov_len;
+	if (sock->state != SS_CONNECTED)
+		return -ENOTCONN;
+	if (flags & ~MSG_DONTWAIT)		/* only handle MSG_DONTWAIT */
+		return -EOPNOTSUPP;
 	vcc = ATM_SD(sock);
-	add_wait_queue(&vcc->sleep,&wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	error = 1; /* <= 0 is error */
-	while (!(skb = skb_dequeue(&vcc->sk->sk_receive_queue))) {
-		if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
-		    test_bit(ATM_VF_CLOSE,&vcc->flags)) {
-			error = vcc->reply;
-			break;
-		}
-		if (!test_bit(ATM_VF_READY,&vcc->flags)) {
-			error = 0;
-			break;
-		}
-		if (flags & MSG_DONTWAIT) {
-			error = -EAGAIN;
-			break;
-		}
-		schedule();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (signal_pending(current)) {
-			error = -ERESTARTSYS;
-			break;
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (error <= 0) return error;
-	sock_recv_timestamp(m, vcc->sk, skb);
-	eff_len = skb->len > size ? size : skb->len;
-	if (skb->len > size) /* Not fit ?  Report it... */
-		m->msg_flags |= MSG_TRUNC;
-	if (vcc->dev->ops->feedback)
-		vcc->dev->ops->feedback(vcc,skb,(unsigned long) skb->data,
-		    (unsigned long) buff,eff_len);
-	DPRINTK("RcvM %d -= %d\n", atomic_read(&vcc->sk->sk_rmem_alloc),
-		skb->truesize);
-	atm_return(vcc,skb->truesize);
-	error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0;
-	kfree_skb(skb);
-	return error ? error : eff_len;
+	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
+	    test_bit(ATM_VF_CLOSE,&vcc->flags))
+		return vcc->reply;
+	if (!test_bit(ATM_VF_READY, &vcc->flags))
+		return 0;
+
+	skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &error);
+	if (!skb)
+		return error;
+
+	copied = skb->len; 
+	if (copied > size) {
+		copied = size; 
+		msg->msg_flags |= MSG_TRUNC;
+	}
+
+        error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+        if (error)
+                return error;
+        sock_recv_timestamp(msg, sk, skb);
+        if (vcc->dev->ops->feedback)
+                vcc->dev->ops->feedback(vcc, skb, (unsigned long) skb->data,
+                    (unsigned long) msg->msg_iov->iov_base, copied);
+        DPRINTK("RcvM %d -= %d\n", atomic_read(&vcc->sk->rmem_alloc), skb->truesize);
+        atm_return(vcc, skb->truesize);
+        skb_free_datagram(sk, skb);
+        return copied;
 }
 
 
-int atm_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 		int total_len)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	struct sock *sk = sock->sk;
+	DEFINE_WAIT(wait);
 	struct atm_vcc *vcc;
 	struct sk_buff *skb;
 	int eff,error;
 	const void *buff;
 	int size;
 
-	if (sock->state != SS_CONNECTED) return -ENOTCONN;
-	if (m->msg_name) return -EISCONN;
-	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
+	lock_sock(sk);
+	if (sock->state != SS_CONNECTED) {
+		error = -ENOTCONN;
+		goto out;
+	}
+	if (m->msg_name) {
+		error = -EISCONN;
+		goto out;
+	}
+	if (m->msg_iovlen != 1) {
+		error = -ENOSYS; /* fix this later @@@ */
+		goto out;
+	}
 	buff = m->msg_iov->iov_base;
 	size = m->msg_iov->iov_len;
 	vcc = ATM_SD(sock);
-	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
-	    test_bit(ATM_VF_CLOSE,&vcc->flags))
-		return vcc->reply;
-	if (!test_bit(ATM_VF_READY,&vcc->flags)) return -EPIPE;
-	if (!size) return 0;
-	if (size < 0 || size > vcc->qos.txtp.max_sdu) return -EMSGSIZE;
+	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
+	    test_bit(ATM_VF_CLOSE, &vcc->flags)) {
+		error = vcc->reply;
+		goto out;
+	}
+	if (!test_bit(ATM_VF_READY, &vcc->flags)) {
+		error = -EPIPE;
+		goto out;
+	}
+	if (!size) {
+		error = 0;
+		goto out;
+	}
+	if (size < 0 || size > vcc->qos.txtp.max_sdu) {
+		error = -EMSGSIZE;
+		goto out;
+	}
 	/* verify_area is done by net/socket.c */
 	eff = (size+3) & ~3; /* align to word boundary */
-	add_wait_queue(&vcc->sleep,&wait);
-	set_current_state(TASK_INTERRUPTIBLE);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 	error = 0;
 	while (!(skb = alloc_tx(vcc,eff))) {
 		if (m->msg_flags & MSG_DONTWAIT) {
@@ -506,7 +498,6 @@
 			break;
 		}
 		schedule();
-		set_current_state(TASK_INTERRUPTIBLE);
 		if (signal_pending(current)) {
 			error = -ERESTARTSYS;
 			break;
@@ -520,19 +511,24 @@
 			error = -EPIPE;
 			break;
 		}
+		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (error) return error;
+	finish_wait(&vcc->sleep, &wait);
+	if (error)
+		goto out;
 	skb->dev = NULL; /* for paths shared with net_device interfaces */
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 	if (copy_from_user(skb_put(skb,size),buff,size)) {
 		kfree_skb(skb);
-		return -EFAULT;
+		error = -EFAULT;
+		goto out;
 	}
 	if (eff != size) memset(skb->data+size,0,eff-size);
 	error = vcc->dev->ops->send(vcc,skb);
-	return error ? error : size;
+	error = error ? error : size;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -563,129 +559,51 @@
 }
 
 
-static void copy_aal_stats(struct k_atm_aal_stats *from,
-    struct atm_aal_stats *to)
-{
-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
-	__AAL_STAT_ITEMS
-#undef __HANDLE_ITEM
-}
-
-
-static void subtract_aal_stats(struct k_atm_aal_stats *from,
-    struct atm_aal_stats *to)
-{
-#define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
-	__AAL_STAT_ITEMS
-#undef __HANDLE_ITEM
-}
-
-
-static int fetch_stats(struct atm_dev *dev,struct atm_dev_stats *arg,int zero)
+int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	struct atm_dev_stats tmp;
-	int error = 0;
-
-	copy_aal_stats(&dev->stats.aal0,&tmp.aal0);
-	copy_aal_stats(&dev->stats.aal34,&tmp.aal34);
-	copy_aal_stats(&dev->stats.aal5,&tmp.aal5);
-	if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
-	if (zero && !error) {
-		subtract_aal_stats(&dev->stats.aal0,&tmp.aal0);
-		subtract_aal_stats(&dev->stats.aal34,&tmp.aal34);
-		subtract_aal_stats(&dev->stats.aal5,&tmp.aal5);
-	}
-	return error ? -EFAULT : 0;
-}
-
-
-int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
-{
-	struct atm_dev *dev;
-	struct list_head *p;
 	struct atm_vcc *vcc;
-	int *tmp_buf, *tmp_p;
-	void *buf;
-	int error,len,size,number, ret_val;
+	int error;
 
-	ret_val = 0;
 	vcc = ATM_SD(sock);
 	switch (cmd) {
 		case SIOCOUTQ:
 			if (sock->state != SS_CONNECTED ||
-			    !test_bit(ATM_VF_READY,&vcc->flags)) {
-				ret_val =  -EINVAL;
+			    !test_bit(ATM_VF_READY, &vcc->flags)) {
+				error =  -EINVAL;
 				goto done;
 			}
-			ret_val = put_user(vcc->sk->sk_sndbuf -
-					   atomic_read(&vcc->sk->sk_wmem_alloc),
-			    (int *) arg) ? -EFAULT : 0;
+			error = put_user(vcc->sk->sk_sndbuf -
+					 atomic_read(&vcc->sk->sk_wmem_alloc),
+					 (int *) arg) ? -EFAULT : 0;
 			goto done;
 		case SIOCINQ:
 			{
 				struct sk_buff *skb;
 
 				if (sock->state != SS_CONNECTED) {
-					ret_val = -EINVAL;
+					error = -EINVAL;
 					goto done;
 				}
 				skb = skb_peek(&vcc->sk->sk_receive_queue);
-				ret_val = put_user(skb ? skb->len : 0,(int *) arg)
-				    ? -EFAULT : 0;
+				error = put_user(skb ? skb->len : 0,
+					 	 (int *) arg) ? -EFAULT : 0;
 				goto done;
 			}
-		case ATM_GETNAMES:
-			if (get_user(buf,
-				     &((struct atm_iobuf *) arg)->buffer)) {
-				ret_val = -EFAULT;
-				goto done;
-			}
-			if (get_user(len,
-				     &((struct atm_iobuf *) arg)->length)) {
-				ret_val = -EFAULT;
-				goto done;
-			}
-			size = 0;
-			spin_lock(&atm_dev_lock);
-			list_for_each(p, &atm_devs)
-				size += sizeof(int);
-			if (size > len) {
-				spin_unlock(&atm_dev_lock);
-				ret_val = -E2BIG;
-				goto done;
-			}
-			tmp_buf = kmalloc(size, GFP_ATOMIC);
-			if (!tmp_buf) {
-				spin_unlock(&atm_dev_lock);
-				ret_val = -ENOMEM;
-				goto done;
-			}
-			tmp_p = tmp_buf;
-			list_for_each(p, &atm_devs) {
-				dev = list_entry(p, struct atm_dev, dev_list);
-				*tmp_p++ = dev->number;
-			}
-			spin_unlock(&atm_dev_lock);
-		        ret_val = ((copy_to_user(buf, tmp_buf, size)) ||
-			    put_user(size, &((struct atm_iobuf *) arg)->length)
-			    ) ? -EFAULT : 0;
-			kfree(tmp_buf);
-			goto done;
 		case SIOCGSTAMP: /* borrowed from IP */
 			if (!vcc->sk->sk_stamp.tv_sec) {
-				ret_val = -ENOENT;
+				error = -ENOENT;
 				goto done;
 			}
-			ret_val = copy_to_user((void *)arg, &vcc->sk->sk_stamp,
-			    sizeof(struct timeval)) ? -EFAULT : 0;
+			error = copy_to_user((void *)arg, &vcc->sk->sk_stamp,
+					     sizeof(struct timeval)) ? -EFAULT : 0;
 			goto done;
 		case ATM_SETSC:
 			printk(KERN_WARNING "ATM_SETSC is obsolete\n");
-			ret_val = 0;
+			error = 0;
 			goto done;
 		case ATMSIGD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			/*
@@ -696,28 +614,28 @@
 			 * have the same privledges that /proc/kcore needs
 			 */
 			if (!capable(CAP_SYS_RAWIO)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			error = sigd_attach(vcc);
-			if (!error) sock->state = SS_CONNECTED;
-			ret_val = error;
+			if (!error)
+				sock->state = SS_CONNECTED;
 			goto done;
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 		case SIOCMKCLIP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_create(arg);
+				error = atm_clip_ops->clip_create(arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARPD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_CLIP_MODULE)
@@ -728,48 +646,47 @@
 				error = atm_clip_ops->atm_init_atmarp(vcc);
 				if (!error)
 					sock->state = SS_CONNECTED;
-				ret_val = error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_MKIP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_mkip(vcc, arg);
+				error = atm_clip_ops->clip_mkip(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_SETENTRY:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_setentry(vcc, arg);
+				error = atm_clip_ops->clip_setentry(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_ENCAP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_encap(vcc, arg);
+				error = atm_clip_ops->clip_encap(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
                 case ATMLEC_CTRL:
                         if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_LANE_MODULE)
@@ -781,37 +698,36 @@
 				module_put(atm_lane_ops->owner);
 				if (error >= 0)
 					sock->state = SS_CONNECTED;
-				ret_val =  error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
                 case ATMLEC_MCAST:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_lane_ops()) {
-				ret_val = atm_lane_ops->mcast_attach(vcc, (int) arg);
+				error = atm_lane_ops->mcast_attach(vcc, (int) arg);
 				module_put(atm_lane_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
                 case ATMLEC_DATA:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_lane_ops()) {
-				ret_val = atm_lane_ops->vcc_attach(vcc, (void *) arg);
+				error = atm_lane_ops->vcc_attach(vcc, (void *) arg);
 				module_put(atm_lane_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
 		case ATMMPC_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_MPOA_MODULE)
@@ -823,63 +739,62 @@
 				module_put(atm_mpoa_ops->owner);
 				if (error >= 0)
 					sock->state = SS_CONNECTED;
-				ret_val = error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMMPC_DATA:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_mpoa_ops()) {
-				ret_val = atm_mpoa_ops->vcc_attach(vcc, arg);
+				error = atm_mpoa_ops->vcc_attach(vcc, arg);
 				module_put(atm_mpoa_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
 		case SIOCSIFATMTCP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.attach) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
-			fops_get (&atm_tcp_ops);
-			error = atm_tcp_ops.attach(vcc,(int) arg);
-			if (error >= 0) sock->state = SS_CONNECTED;
-			else            fops_put (&atm_tcp_ops);
-			ret_val = error;
+			fops_get(&atm_tcp_ops);
+			error = atm_tcp_ops.attach(vcc, (int) arg);
+			if (error >= 0)
+				sock->state = SS_CONNECTED;
+			else
+				fops_put (&atm_tcp_ops);
 			goto done;
 		case ATMTCP_CREATE:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.create_persistent) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
 			error = atm_tcp_ops.create_persistent((int) arg);
-			if (error < 0) fops_put (&atm_tcp_ops);
-			ret_val = error;
+			if (error < 0)
+				fops_put (&atm_tcp_ops);
 			goto done;
 		case ATMTCP_REMOVE:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.remove_persistent) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
 			error = atm_tcp_ops.remove_persistent((int) arg);
-			fops_put (&atm_tcp_ops);
-			ret_val = error;
+			fops_put(&atm_tcp_ops);
 			goto done;
 #endif
 		default:
@@ -887,182 +802,23 @@
 	}
 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
 	if (pppoatm_ioctl_hook) {
-		ret_val = pppoatm_ioctl_hook(vcc, cmd, arg);
-		if (ret_val != -ENOIOCTLCMD)
+		error = pppoatm_ioctl_hook(vcc, cmd, arg);
+		if (error != -ENOIOCTLCMD)
 			goto done;
 	}
 #endif
 #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
 	if (br2684_ioctl_hook) {
-		ret_val = br2684_ioctl_hook(vcc, cmd, arg);
-		if (ret_val != -ENOIOCTLCMD)
+		error = br2684_ioctl_hook(vcc, cmd, arg);
+		if (error != -ENOIOCTLCMD)
 			goto done;
 	}
 #endif
-	if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (get_user(len,&((struct atmif_sioc *) arg)->length)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (get_user(number,&((struct atmif_sioc *) arg)->number)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (!(dev = atm_dev_lookup(number))) {
-		ret_val = -ENODEV;
-		goto done;
-	}
-	
-	size = 0;
-	switch (cmd) {
-		case ATM_GETTYPE:
-			size = strlen(dev->type)+1;
-			if (copy_to_user(buf,dev->type,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_GETESI:
-			size = ESI_LEN;
-			if (copy_to_user(buf,dev->esi,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_SETESI:
-			{
-				int i;
 
-				for (i = 0; i < ESI_LEN; i++)
-					if (dev->esi[i]) {
-						ret_val = -EEXIST;
-						goto done_release;
-					}
-			}
-			/* fall through */
-		case ATM_SETESIF:
-			{
-				unsigned char esi[ESI_LEN];
-
-				if (!capable(CAP_NET_ADMIN)) {
-					ret_val = -EPERM;
-					goto done_release;
-				}
-				if (copy_from_user(esi,buf,ESI_LEN)) {
-					ret_val = -EFAULT;
-					goto done_release;
-				}
-				memcpy(dev->esi,esi,ESI_LEN);
-				ret_val =  ESI_LEN;
-				goto done_release;
-			}
-		case ATM_GETSTATZ:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			/* fall through */
-		case ATM_GETSTAT:
-			size = sizeof(struct atm_dev_stats);
-			error = fetch_stats(dev,buf,cmd == ATM_GETSTATZ);
-			if (error) {
-				ret_val = error;
-				goto done_release;
-			}
-			break;
-		case ATM_GETCIRANGE:
-			size = sizeof(struct atm_cirange);
-			if (copy_to_user(buf,&dev->ci_range,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_GETLINKRATE:
-			size = sizeof(int);
-			if (copy_to_user(buf,&dev->link_rate,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_RSTADDR:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			atm_reset_addr(dev);
-			break;
-		case ATM_ADDADDR:
-		case ATM_DELADDR:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			{
-				struct sockaddr_atmsvc addr;
-
-				if (copy_from_user(&addr,buf,sizeof(addr))) {
-					ret_val = -EFAULT;
-					goto done_release;
-				}
-				if (cmd == ATM_ADDADDR)
-					ret_val = atm_add_addr(dev,&addr);
-				else
-					ret_val = atm_del_addr(dev,&addr);
-				goto done_release;
-			}
-		case ATM_GETADDR:
-			size = atm_get_addr(dev,buf,len);
-			if (size < 0)
-				ret_val = size;
-			else
-			/* may return 0, but later on size == 0 means "don't
-			   write the length" */
-				ret_val = put_user(size,
-						   &((struct atmif_sioc *) arg)->length) ? -EFAULT : 0;
-			goto done_release;
-		case ATM_SETLOOP:
-			if (__ATM_LM_XTRMT((int) (long) buf) &&
-			    __ATM_LM_XTLOC((int) (long) buf) >
-			    __ATM_LM_XTRMT((int) (long) buf)) {
-				ret_val = -EINVAL;
-				goto done_release;
-			}
-			/* fall through */
-		case ATM_SETCIRANGE:
-		case SONET_GETSTATZ:
-		case SONET_SETDIAG:
-		case SONET_CLRDIAG:
-		case SONET_SETFRAMING:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			/* fall through */
-		default:
-			if (!dev->ops->ioctl) {
-				ret_val = -EINVAL;
-				goto done_release;
-			}
-			size = dev->ops->ioctl(dev,cmd,buf);
-			if (size < 0) {
-				ret_val = (size == -ENOIOCTLCMD ? -EINVAL : size);
-				goto done_release;
-			}
-	}
-	
-	if (size)
-		ret_val =  put_user(size,&((struct atmif_sioc *) arg)->length) ?
-			-EFAULT : 0;
-	else
-		ret_val = 0;
-done_release:
-	atm_dev_release(dev);
+	error = atm_dev_ioctl(cmd, arg);
 
 done:
-	return ret_val;
+	return error;
 }
 
 
@@ -1120,14 +876,16 @@
 	return check_tp(&qos->rxtp);
 }
 
-
-static int atm_do_setsockopt(struct socket *sock,int level,int optname,
-    void *optval,int optlen)
+int vcc_setsockopt(struct socket *sock, int level, int optname,
+		   char *optval, int optlen)
 {
 	struct atm_vcc *vcc;
 	unsigned long value;
 	int error;
 
+	if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
+		return -EINVAL;
+
 	vcc = ATM_SD(sock);
 	switch (optname) {
 		case SO_ATMQOS:
@@ -1161,10 +919,16 @@
 }
 
 
-static int atm_do_getsockopt(struct socket *sock,int level,int optname,
-    void *optval,int optlen)
+int vcc_getsockopt(struct socket *sock, int level, int optname,
+		   char *optval, int *optlen)
 {
 	struct atm_vcc *vcc;
+	int len;
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+	if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
+		return -EINVAL;
 
 	vcc = ATM_SD(sock);
 	switch (optname) {
@@ -1195,28 +959,7 @@
 			break;
 	}
 	if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
-	return vcc->dev->ops->getsockopt(vcc,level,optname,optval,optlen);
-}
-
-
-int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
-    int optlen)
-{
-	if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
-		return -EINVAL;
-	return atm_do_setsockopt(sock,level,optname,optval,optlen);
-}
-
-
-int atm_getsockopt(struct socket *sock,int level,int optname,
-    char *optval,int *optlen)
-{
-	int len;
-
-	if (get_user(len,optlen)) return -EFAULT;
-	if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
-		return -EINVAL;
-	return atm_do_getsockopt(sock,level,optname,optval,len);
+	return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
 }
 
 
diff -Nru a/net/atm/common.h b/net/atm/common.h
--- a/net/atm/common.h	Thu May 15 21:12:28 2003
+++ b/net/atm/common.h	Tue Jun 17 11:00:05 2003
@@ -12,19 +12,18 @@
 
 int atm_create(struct socket *sock,int protocol,int family);
 int atm_release(struct socket *sock);
-int atm_connect(struct socket *sock,int itf,short vpi,int vci);
-int atm_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-		int total_len, int flags);
-int atm_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
+int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+		int size, int flags);
+int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 		int total_len);
 unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait);
-int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg);
-int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
-    int optlen);
-int atm_getsockopt(struct socket *sock,int level,int optname,char *optval,
-    int *optlen);
+int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
+int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
+		   int optlen);
+int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval,
+		   int *optlen);
 
-int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci);
 void atm_release_vcc_sk(struct sock *sk,int free_sk);
 void atm_shutdown_dev(struct atm_dev *dev);
 
diff -Nru a/net/atm/lec.c b/net/atm/lec.c
--- a/net/atm/lec.c	Wed Jun  4 17:57:07 2003
+++ b/net/atm/lec.c	Tue Jun 17 11:00:06 2003
@@ -1079,7 +1079,7 @@
 		clear_bit(ATM_VF_READY,&entry->vcc->flags);
                 entry->vcc->push(entry->vcc, NULL);
 #endif
-		atm_async_release_vcc(entry->vcc, -EPIPE);
+		vcc_release_async(entry->vcc, -EPIPE);
                 entry->vcc = NULL;
         }
         if (entry->recv_vcc) {
@@ -1089,7 +1089,7 @@
 		clear_bit(ATM_VF_READY,&entry->recv_vcc->flags);
                 entry->recv_vcc->push(entry->recv_vcc, NULL);
 #endif
-		atm_async_release_vcc(entry->recv_vcc, -EPIPE);
+		vcc_release_async(entry->recv_vcc, -EPIPE);
                 entry->recv_vcc = NULL;
         }        
 }
diff -Nru a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
--- a/net/atm/mpoa_caches.c	Tue Feb  5 09:40:00 2002
+++ b/net/atm/mpoa_caches.c	Tue Jun 17 10:32:43 2003
@@ -212,7 +212,7 @@
 			client->eg_ops->put(eg_entry);
 			return;
 		}
-		atm_async_release_vcc(vcc, -EPIPE);
+		vcc_release_async(vcc, -EPIPE);
 	}
 
 	return;
@@ -447,7 +447,7 @@
 			client->in_ops->put(in_entry);
 			return;
 		}
-		atm_async_release_vcc(vcc, -EPIPE);
+		vcc_release_async(vcc, -EPIPE);
 	}
 
 	return;
diff -Nru a/net/atm/pvc.c b/net/atm/pvc.c
--- a/net/atm/pvc.c	Thu May 15 21:54:16 2003
+++ b/net/atm/pvc.c	Tue Jun 17 11:00:06 2003
@@ -31,20 +31,29 @@
 static int pvc_bind(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len)
 {
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmpvc *addr;
 	struct atm_vcc *vcc;
+	int error;
 
 	if (sockaddr_len != sizeof(struct sockaddr_atmpvc)) return -EINVAL;
 	addr = (struct sockaddr_atmpvc *) sockaddr;
 	if (addr->sap_family != AF_ATMPVC) return -EAFNOSUPPORT;
+	lock_sock(sk);
 	vcc = ATM_SD(sock);
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
+		error = -EBADFD;
+		goto out;
+	}
 	if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
 		if (vcc->vpi != ATM_VPI_UNSPEC) addr->sap_addr.vpi = vcc->vpi;
 		if (vcc->vci != ATM_VCI_UNSPEC) addr->sap_addr.vci = vcc->vci;
 	}
-	return atm_connect(sock,addr->sap_addr.itf,addr->sap_addr.vpi,
-	    addr->sap_addr.vci);
+	error = vcc_connect(sock, addr->sap_addr.itf, addr->sap_addr.vpi,
+			    addr->sap_addr.vci);
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -54,6 +63,31 @@
 	return pvc_bind(sock,sockaddr,sockaddr_len);
 }
 
+static int pvc_setsockopt(struct socket *sock, int level, int optname,
+			  char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	int error;
+
+	lock_sock(sk);
+	error = vcc_setsockopt(sock, level, optname, optval, optlen);
+	release_sock(sk);
+	return error;
+}
+
+
+static int pvc_getsockopt(struct socket *sock, int level, int optname,
+		          char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	int error;
+
+	lock_sock(sk);
+	error = vcc_getsockopt(sock, level, optname, optval, optlen);
+	release_sock(sk);
+	return error;
+}
+
 
 static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
     int *sockaddr_len,int peer)
@@ -72,7 +106,7 @@
 }
 
 
-static struct proto_ops SOCKOPS_WRAPPED(pvc_proto_ops) = {
+static struct proto_ops pvc_proto_ops = {
 	.family =	PF_ATMPVC,
 
 	.release =	atm_release,
@@ -82,20 +116,16 @@
 	.accept =	sock_no_accept,
 	.getname =	pvc_getname,
 	.poll =		atm_poll,
-	.ioctl =	atm_ioctl,
+	.ioctl =	vcc_ioctl,
 	.listen =	sock_no_listen,
 	.shutdown =	pvc_shutdown,
-	.setsockopt =	atm_setsockopt,
-	.getsockopt =	atm_getsockopt,
-	.sendmsg =	atm_sendmsg,
-	.recvmsg =	atm_recvmsg,
+	.setsockopt =	pvc_setsockopt,
+	.getsockopt =	pvc_getsockopt,
+	.sendmsg =	vcc_sendmsg,
+	.recvmsg =	vcc_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
-
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(pvc_proto, PF_ATMPVC);
 
 
 static int pvc_create(struct socket *sock,int protocol)
diff -Nru a/net/atm/resources.c b/net/atm/resources.c
--- a/net/atm/resources.c	Thu May 15 17:20:17 2003
+++ b/net/atm/resources.c	Tue Jun 17 11:00:06 2003
@@ -12,6 +12,7 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/atmdev.h>
+#include <linux/sonet.h>
 #include <linux/kernel.h> /* for barrier */
 #include <linux/module.h>
 #include <linux/bitops.h>
@@ -19,6 +20,7 @@
 
 #include "common.h"
 #include "resources.h"
+#include "addr.h"
 
 
 #ifndef NULL
@@ -170,6 +172,240 @@
 		dev->ops->dev_close(dev);
 	atm_dev_deregister(dev);
 }
+
+
+static void copy_aal_stats(struct k_atm_aal_stats *from,
+    struct atm_aal_stats *to)
+{
+#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
+	__AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+}
+
+
+static void subtract_aal_stats(struct k_atm_aal_stats *from,
+    struct atm_aal_stats *to)
+{
+#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
+	__AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+}
+
+
+static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
+{
+	struct atm_dev_stats tmp;
+	int error = 0;
+
+	copy_aal_stats(&dev->stats.aal0, &tmp.aal0);
+	copy_aal_stats(&dev->stats.aal34, &tmp.aal34);
+	copy_aal_stats(&dev->stats.aal5, &tmp.aal5);
+	if (arg)
+		error = copy_to_user(arg, &tmp, sizeof(tmp));
+	if (zero && !error) {
+		subtract_aal_stats(&dev->stats.aal0, &tmp.aal0);
+		subtract_aal_stats(&dev->stats.aal34, &tmp.aal34);
+		subtract_aal_stats(&dev->stats.aal5, &tmp.aal5);
+	}
+	return error ? -EFAULT : 0;
+}
+
+
+int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
+{
+	void *buf;
+	int error, len, number, size = 0;
+	struct atm_dev *dev;
+	struct list_head *p;
+	int *tmp_buf, *tmp_p;
+
+	switch (cmd) {
+		case ATM_GETNAMES:
+			if (get_user(buf, &((struct atm_iobuf *) arg)->buffer))
+				return -EFAULT;
+			if (get_user(len, &((struct atm_iobuf *) arg)->length))
+				return -EFAULT;
+			spin_lock(&atm_dev_lock);
+			list_for_each(p, &atm_devs)
+				size += sizeof(int);
+			if (size > len) {
+				spin_unlock(&atm_dev_lock);
+				return -E2BIG;
+			}
+			tmp_buf = kmalloc(size, GFP_ATOMIC);
+			if (!tmp_buf) {
+				spin_unlock(&atm_dev_lock);
+				return -ENOMEM;
+			}
+			tmp_p = tmp_buf;
+			list_for_each(p, &atm_devs) {
+				dev = list_entry(p, struct atm_dev, dev_list);
+				*tmp_p++ = dev->number;
+			}
+			spin_unlock(&atm_dev_lock);
+		        error = ((copy_to_user(buf, tmp_buf, size)) ||
+					put_user(size, &((struct atm_iobuf *) arg)->length))
+						? -EFAULT : 0;
+			kfree(tmp_buf);
+			return error;
+		default:
+			break;
+	}
+
+	if (get_user(buf, &((struct atmif_sioc *) arg)->arg))
+		return -EFAULT;
+	if (get_user(len, &((struct atmif_sioc *) arg)->length))
+		return -EFAULT;
+	if (get_user(number, &((struct atmif_sioc *) arg)->number))
+		return -EFAULT;
+
+	if (!(dev = atm_dev_lookup(number)))
+		return -ENODEV;
+	
+	switch (cmd) {
+		case ATM_GETTYPE:
+			size = strlen(dev->type) + 1;
+			if (copy_to_user(buf, dev->type, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_GETESI:
+			size = ESI_LEN;
+			if (copy_to_user(buf, dev->esi, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_SETESI:
+			{
+				int i;
+
+				for (i = 0; i < ESI_LEN; i++)
+					if (dev->esi[i]) {
+						error = -EEXIST;
+						goto done;
+					}
+			}
+			/* fall through */
+		case ATM_SETESIF:
+			{
+				unsigned char esi[ESI_LEN];
+
+				if (!capable(CAP_NET_ADMIN)) {
+					error = -EPERM;
+					goto done;
+				}
+				if (copy_from_user(esi, buf, ESI_LEN)) {
+					error = -EFAULT;
+					goto done;
+				}
+				memcpy(dev->esi, esi, ESI_LEN);
+				error =  ESI_LEN;
+				goto done;
+			}
+		case ATM_GETSTATZ:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			/* fall through */
+		case ATM_GETSTAT:
+			size = sizeof(struct atm_dev_stats);
+			error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
+			if (error)
+				goto done;
+			break;
+		case ATM_GETCIRANGE:
+			size = sizeof(struct atm_cirange);
+			if (copy_to_user(buf, &dev->ci_range, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_GETLINKRATE:
+			size = sizeof(int);
+			if (copy_to_user(buf, &dev->link_rate, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_RSTADDR:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			atm_reset_addr(dev);
+			break;
+		case ATM_ADDADDR:
+		case ATM_DELADDR:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			{
+				struct sockaddr_atmsvc addr;
+
+				if (copy_from_user(&addr, buf, sizeof(addr))) {
+					error = -EFAULT;
+					goto done;
+				}
+				if (cmd == ATM_ADDADDR)
+					error = atm_add_addr(dev, &addr);
+				else
+					error = atm_del_addr(dev, &addr);
+				goto done;
+			}
+		case ATM_GETADDR:
+			error = atm_get_addr(dev, buf, len);
+			if (error < 0)
+				goto done;
+			size = error;
+			/* may return 0, but later on size == 0 means "don't
+			   write the length" */
+			error = put_user(size, &((struct atmif_sioc *) arg)->length)
+				? -EFAULT : 0;
+			goto done;
+		case ATM_SETLOOP:
+			if (__ATM_LM_XTRMT((int) (long) buf) &&
+			    __ATM_LM_XTLOC((int) (long) buf) >
+			    __ATM_LM_XTRMT((int) (long) buf)) {
+				error = -EINVAL;
+				goto done;
+			}
+			/* fall through */
+		case ATM_SETCIRANGE:
+		case SONET_GETSTATZ:
+		case SONET_SETDIAG:
+		case SONET_CLRDIAG:
+		case SONET_SETFRAMING:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			/* fall through */
+		default:
+			if (!dev->ops->ioctl) {
+				error = -EINVAL;
+				goto done;
+			}
+			size = dev->ops->ioctl(dev, cmd, buf);
+			if (size < 0) {
+				error = (size == -ENOIOCTLCMD ? -EINVAL : size);
+				goto done;
+			}
+	}
+	
+	if (size)
+		error = put_user(size, &((struct atmif_sioc *) arg)->length)
+			? -EFAULT : 0;
+	else
+		error = 0;
+done:
+	atm_dev_release(dev);
+	return error;
+}
+
 
 struct sock *alloc_atm_vcc_sk(int family)
 {
diff -Nru a/net/atm/resources.h b/net/atm/resources.h
--- a/net/atm/resources.h	Thu May 15 17:20:17 2003
+++ b/net/atm/resources.h	Tue Jun 17 11:00:06 2003
@@ -16,6 +16,7 @@
 
 struct sock *alloc_atm_vcc_sk(int family);
 void free_atm_vcc_sk(struct sock *sk);
+int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
 
 
 #ifdef CONFIG_PROC_FS
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c	Wed Jun  4 17:57:07 2003
+++ b/net/atm/signaling.c	Tue Jun 17 11:00:06 2003
@@ -124,14 +124,16 @@
 			clear_bit(ATM_VF_REGIS,&vcc->flags);
 			clear_bit(ATM_VF_READY,&vcc->flags);
 			vcc->reply = msg->reply;
+			vcc->sk->sk_err = -msg->reply;
 			break;
 		case as_indicate:
 			vcc = *(struct atm_vcc **) &msg->listen_vcc;
 			DPRINTK("as_indicate!!!\n");
+			lock_sock(vcc->sk);
 			if (vcc->sk->sk_ack_backlog ==
 			    vcc->sk->sk_max_ack_backlog) {
 				sigd_enq(0,as_reject,vcc,NULL,NULL);
-				return 0;
+				goto as_indicate_complete;
 			}
 			vcc->sk->sk_ack_backlog++;
 			skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
@@ -140,11 +142,14 @@
 				    &vcc->sleep);
 				vcc->callback(vcc);
 			}
+as_indicate_complete:
+			release_sock(vcc->sk);
 			return 0;
 		case as_close:
 			set_bit(ATM_VF_RELEASED,&vcc->flags);
 			clear_bit(ATM_VF_READY,&vcc->flags);
 			vcc->reply = msg->reply;
+			vcc->sk->sk_err = -msg->reply;
 			break;
 		case as_modify:
 			modify_qos(vcc,msg);
@@ -202,6 +207,7 @@
 		    !test_bit(ATM_VF_META,&vcc->flags)) {
 			set_bit(ATM_VF_RELEASED,&vcc->flags);
 			vcc->reply = -EUNATCH;
+			vcc->sk->sk_err = EUNATCH;
 			wake_up(&vcc->sleep);
 		}
 		vcc = vcc->next;
diff -Nru a/net/atm/svc.c b/net/atm/svc.c
--- a/net/atm/svc.c	Wed Jun  4 17:57:07 2003
+++ b/net/atm/svc.c	Tue Jun 17 11:00:06 2003
@@ -59,18 +59,18 @@
 
 static void svc_disconnect(struct atm_vcc *vcc)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
 	struct sk_buff *skb;
 
 	DPRINTK("svc_disconnect %p\n",vcc);
 	if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
-		add_wait_queue(&vcc->sleep,&wait);
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		sigd_enq(vcc,as_close,NULL,NULL,NULL);
 		while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule();
+			prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		}
-		remove_wait_queue(&vcc->sleep,&wait);
+		finish_wait(&vcc->sleep, &wait);
 	}
 	/* beware - socket is still in use by atmsigd until the last
 	   as_indicate has been answered */
@@ -107,80 +107,138 @@
 static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmsvc *addr;
 	struct atm_vcc *vcc;
+	int error;
 
-	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) return -EINVAL;
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state != SS_UNCONNECTED) return -EINVAL;
+	if (sockaddr_len != sizeof(struct sockaddr_atmsvc))
+		return -EINVAL;
+	lock_sock(sk);
+	if (sock->state == SS_CONNECTED) {
+		error = -EISCONN;
+		goto out;
+	}
+	if (sock->state != SS_UNCONNECTED) {
+		error = -EINVAL;
+		goto out;
+	}
 	vcc = ATM_SD(sock);
-	if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
+		error = -EINVAL;
+		goto out;
+	}
 	addr = (struct sockaddr_atmsvc *) sockaddr;
-	if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
+	if (addr->sas_family != AF_ATMSVC) {
+		error = -EAFNOSUPPORT;
+		goto out;
+	}
 	clear_bit(ATM_VF_BOUND,&vcc->flags);
 	    /* failing rebind will kill old binding */
 	/* @@@ check memory (de)allocation on rebind */
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) {
+		error = -EBADFD;
+		goto out;
+	}
 	vcc->local = *addr;
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
 	while (vcc->reply == WAITING && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
+	finish_wait(&vcc->sleep, &wait);
 	clear_bit(ATM_VF_REGIS,&vcc->flags); /* doesn't count */
-	if (!sigd) return -EUNATCH;
-        if (!vcc->reply) set_bit(ATM_VF_BOUND,&vcc->flags);
-	return vcc->reply;
+	if (!sigd) {
+		error = -EUNATCH;
+		goto out;
+	}
+        if (!vcc->reply)
+		set_bit(ATM_VF_BOUND,&vcc->flags);
+	error = vcc->reply;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len,int flags)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmsvc *addr;
 	struct atm_vcc *vcc = ATM_SD(sock);
 	int error;
 
 	DPRINTK("svc_connect %p\n",vcc);
-	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) return -EINVAL;
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state == SS_CONNECTING) {
-		if (vcc->reply == WAITING) return -EALREADY;
-		sock->state = SS_UNCONNECTED;
-		if (vcc->reply) return vcc->reply;
+	lock_sock(sk);
+	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) {
+		error = -EINVAL;
+		goto out;
 	}
-	else {
-		int error;
 
-		if (sock->state != SS_UNCONNECTED) return -EINVAL;
-		if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	switch (sock->state) {
+	default:
+		error = -EINVAL;
+		goto out;
+	case SS_CONNECTED:
+		error = -EISCONN;
+		goto out;
+	case SS_CONNECTING:
+		if (vcc->reply == WAITING) {
+			error = -EALREADY;
+			goto out;
+		}
+		sock->state = SS_UNCONNECTED;
+		if (vcc->reply) {
+			error = vcc->reply;
+			goto out;
+		}
+		break;
+	case SS_UNCONNECTED:
+		if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
+			error = -EINVAL;
+			goto out;
+		}
 		addr = (struct sockaddr_atmsvc *) sockaddr;
-		if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
-		if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+		if (addr->sas_family != AF_ATMSVC) {
+			error = -EAFNOSUPPORT;
+			goto out;
+		}
+		if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
+			error = -EBADFD;
+			goto out;
+		}
 		if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
-		    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
-			return -EINVAL;
+		    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) {
+			error = -EINVAL;
+			goto out;
+		}
 		if (!vcc->qos.txtp.traffic_class &&
-		    !vcc->qos.rxtp.traffic_class) return -EINVAL;
+		    !vcc->qos.rxtp.traffic_class) {
+			error = -EINVAL;
+			goto out;
+		}
 		vcc->remote = *addr;
 		vcc->reply = WAITING;
-		add_wait_queue(&vcc->sleep,&wait);
+		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 		sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
 		if (flags & O_NONBLOCK) {
-			remove_wait_queue(&vcc->sleep,&wait);
+			finish_wait(&vcc->sleep, &wait);
 			sock->state = SS_CONNECTING;
-			return -EINPROGRESS;
+			error = -EINPROGRESS;
+			goto out;
 		}
 		error = 0;
 		while (vcc->reply == WAITING && sigd) {
-			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
-			if (!signal_pending(current)) continue;
+			if (!signal_pending(current)) {
+				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
+				continue;
+			}
 			DPRINTK("*ABORT*\n");
 			/*
 			 * This is tricky:
@@ -196,13 +254,13 @@
 			 */
 			sigd_enq(vcc,as_close,NULL,NULL,NULL);
 			while (vcc->reply == WAITING && sigd) {
-				set_current_state(TASK_UNINTERRUPTIBLE);
+				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 				schedule();
 			}
 			if (!vcc->reply)
 				while (!test_bit(ATM_VF_RELEASED,&vcc->flags)
 				    && sigd) {
-					set_current_state(TASK_UNINTERRUPTIBLE);
+					prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 					schedule();
 				}
 			clear_bit(ATM_VF_REGIS,&vcc->flags);
@@ -212,10 +270,17 @@
 			error = -EINTR;
 			break;
 		}
-		remove_wait_queue(&vcc->sleep,&wait);
-		if (error) return error;
-		if (!sigd) return -EUNATCH;
-		if (vcc->reply) return vcc->reply;
+		finish_wait(&vcc->sleep, &wait);
+		if (error)
+			goto out;
+		if (!sigd) {
+			error = -EUNATCH;
+			goto out;
+		}
+		if (vcc->reply) {
+			error = vcc->reply;
+			goto out;
+		}
 	}
 /*
  * Not supported yet
@@ -228,56 +293,73 @@
 /*
  * #endif
  */
-	if (!(error = atm_connect(sock,vcc->itf,vcc->vpi,vcc->vci)))
+	if (!(error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci)))
 		sock->state = SS_CONNECTED;
 	else (void) svc_disconnect(vcc);
+out:
+	release_sock(sk);
 	return error;
 }
 
 
 static int svc_listen(struct socket *sock,int backlog)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc = ATM_SD(sock);
+	int error;
 
 	DPRINTK("svc_listen %p\n",vcc);
+	lock_sock(sk);
 	/* let server handle listen on unbound sockets */
-	if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	if (test_bit(ATM_VF_SESSION,&vcc->flags)) {
+		error = -EINVAL;
+		goto out;
+	}
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
 	while (vcc->reply == WAITING && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
+	}
+	finish_wait(&vcc->sleep, &wait);
+	if (!sigd) {
+		error = -EUNATCH;
+		goto out;
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (!sigd) return -EUNATCH;
 	set_bit(ATM_VF_LISTEN,&vcc->flags);
 	vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog :
 						    ATM_BACKLOG_DEFAULT;
-	return vcc->reply;
+	error = vcc->reply;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
 {
+	struct sock *sk = sock->sk;
 	struct sk_buff *skb;
 	struct atmsvc_msg *msg;
 	struct atm_vcc *old_vcc = ATM_SD(sock);
 	struct atm_vcc *new_vcc;
 	int error;
 
+	lock_sock(sk);
+
 	error = svc_create(newsock,0);
 	if (error)
-		return error;
+		goto out;
 
 	new_vcc = ATM_SD(newsock);
 
 	DPRINTK("svc_accept %p -> %p\n",old_vcc,new_vcc);
 	while (1) {
-		DECLARE_WAITQUEUE(wait,current);
+		DEFINE_WAIT(wait);
 
-		add_wait_queue(&old_vcc->sleep,&wait);
+		prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 		while (!(skb = skb_dequeue(&old_vcc->sk->sk_receive_queue)) &&
 		       sigd) {
 			if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break;
@@ -289,46 +371,63 @@
 				error = -EAGAIN;
 				break;
 			}
-			set_current_state(TASK_INTERRUPTIBLE);
+			release_sock(sk);
 			schedule();
+			lock_sock(sk);
 			if (signal_pending(current)) {
 				error = -ERESTARTSYS;
 				break;
 			}
+			prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
+		}
+		finish_wait(&old_vcc->sleep, &wait);
+		if (error)
+			goto out;
+		if (!skb) {
+			error = -EUNATCH;
+			goto out;
 		}
-		remove_wait_queue(&old_vcc->sleep,&wait);
-		if (error) return error;
-		if (!skb) return -EUNATCH;
 		msg = (struct atmsvc_msg *) skb->data;
 		new_vcc->qos = msg->qos;
 		set_bit(ATM_VF_HASQOS,&new_vcc->flags);
 		new_vcc->remote = msg->svc;
 		new_vcc->local = msg->local;
 		new_vcc->sap = msg->sap;
-		error = atm_connect(newsock,msg->pvc.sap_addr.itf,
-		    msg->pvc.sap_addr.vpi,msg->pvc.sap_addr.vci);
+		error = vcc_connect(newsock, msg->pvc.sap_addr.itf,
+				    msg->pvc.sap_addr.vpi, msg->pvc.sap_addr.vci);
 		dev_kfree_skb(skb);
 		old_vcc->sk->sk_ack_backlog--;
 		if (error) {
 			sigd_enq2(NULL,as_reject,old_vcc,NULL,NULL,
 			    &old_vcc->qos,error);
-			return error == -EAGAIN ? -EBUSY : error;
+			error = error == -EAGAIN ? -EBUSY : error;
+			goto out;
 		}
 		/* wait should be short, so we ignore the non-blocking flag */
 		new_vcc->reply = WAITING;
-		add_wait_queue(&new_vcc->sleep,&wait);
+		prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
 		while (new_vcc->reply == WAITING && sigd) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
+			release_sock(sk);
 			schedule();
+			lock_sock(sk);
+			prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
+		}
+		finish_wait(&new_vcc->sleep, &wait);
+		if (!sigd) {
+			error = -EUNATCH;
+			goto out;
 		}
-		remove_wait_queue(&new_vcc->sleep,&wait);
-		if (!sigd) return -EUNATCH;
 		if (!new_vcc->reply) break;
-		if (new_vcc->reply != -ERESTARTSYS) return new_vcc->reply;
+		if (new_vcc->reply != -ERESTARTSYS) {
+			error = new_vcc->reply;
+			goto out;
+		}
 	}
 	newsock->state = SS_CONNECTED;
-	return 0;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -347,17 +446,17 @@
 
 int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
 
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
 	while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
 	    && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
+	finish_wait(&vcc->sleep, &wait);
 	if (!sigd) return -EUNATCH;
 	return vcc->reply;
 }
@@ -366,33 +465,57 @@
 static int svc_setsockopt(struct socket *sock,int level,int optname,
     char *optval,int optlen)
 {
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc;
+	int error = 0;
 
 	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP ||
-	    optlen != sizeof(struct atm_sap))
-		return atm_setsockopt(sock,level,optname,optval,optlen);
+	    optlen != sizeof(struct atm_sap)) {
+		error = vcc_setsockopt(sock, level, optname, optval, optlen);
+		goto out;
+	}
 	vcc = ATM_SD(sock);
-	if (copy_from_user(&vcc->sap,optval,optlen)) return -EFAULT;
-	set_bit(ATM_VF_HASSAP,&vcc->flags);
-	return 0;
+	if (copy_from_user(&vcc->sap, optval, optlen)) {
+		error = -EFAULT;
+		goto out;
+	}
+	set_bit(ATM_VF_HASSAP, &vcc->flags);
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_getsockopt(struct socket *sock,int level,int optname,
     char *optval,int *optlen)
 {
-	int len;
+	struct sock *sk = sock->sk;
+	int error = 0, len;
 
-	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP)
-		return atm_getsockopt(sock,level,optname,optval,optlen);
-	if (get_user(len,optlen)) return -EFAULT;
-	if (len != sizeof(struct atm_sap)) return -EINVAL;
-	return copy_to_user(optval,&ATM_SD(sock)->sap,sizeof(struct atm_sap)) ?
-	    -EFAULT : 0;
+	lock_sock(sk);
+	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
+		error = vcc_getsockopt(sock, level, optname, optval, optlen);
+		goto out;
+	}
+	if (get_user(len, optlen)) {
+		error = -EFAULT;
+		goto out;
+	}
+	if (len != sizeof(struct atm_sap)) {
+		error = -EINVAL;
+		goto out;
+	}
+	if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
+		error = -EFAULT;
+		goto out;
+	}
+out:
+	release_sock(sk);
+	return error;
 }
 
 
-static struct proto_ops SOCKOPS_WRAPPED(svc_proto_ops) = {
+static struct proto_ops svc_proto_ops = {
 	.family =	PF_ATMSVC,
 
 	.release =	svc_release,
@@ -402,20 +525,17 @@
 	.accept =	svc_accept,
 	.getname =	svc_getname,
 	.poll =		atm_poll,
-	.ioctl =	atm_ioctl,
+	.ioctl =	vcc_ioctl,
 	.listen =	svc_listen,
 	.shutdown =	svc_shutdown,
 	.setsockopt =	svc_setsockopt,
 	.getsockopt =	svc_getsockopt,
-	.sendmsg =	atm_sendmsg,
-	.recvmsg =	atm_recvmsg,
+	.sendmsg =	vcc_sendmsg,
+	.recvmsg =	vcc_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
 
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(svc_proto, PF_ATMSVC);
 
 static int svc_create(struct socket *sock,int protocol)
 {
diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c	Mon May 19 23:22:52 2003
+++ b/net/ipv4/igmp.c	Tue Jun 17 09:44:51 2003
@@ -387,8 +387,17 @@
 		if (type == IGMPV3_ALLOW_NEW_SOURCES ||
 		    type == IGMPV3_BLOCK_OLD_SOURCES)
 			return skb;
-		if (pmc->crcount || isquery)
+		if (pmc->crcount || isquery) {
+			/* make sure we have room for group header and at
+			 * least one source.
+			 */
+			if (skb && AVAILABLE(skb) < sizeof(struct igmpv3_grec)+
+			    sizeof(__u32)) {
+				igmpv3_sendpack(skb);
+				skb = 0; /* add_grhead will get a new one */
+			}
 			skb = add_grhead(skb, pmc, type, &pgr);
+		}
 		return skb;
 	}
 	pih = skb ? (struct igmpv3_report *)skb->h.igmph : 0;
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Mon Jun 16 09:53:26 2003
+++ b/net/ipv4/tcp.c	Tue Jun 17 09:35:27 2003
@@ -1909,7 +1909,7 @@
 	BUG_TRAP(sk_unhashed(sk));
 
 	/* If it has not 0 inet_sk(sk)->num, it must be bound */
-	BUG_TRAP(!inet_sk(sk)->num || sk->sk_prev);
+	BUG_TRAP(!inet_sk(sk)->num || tcp_sk(sk)->bind_hash);
 
 #ifdef TCP_DEBUG
 	if (sk->sk_zapped) {
@@ -2164,7 +2164,7 @@
 	tcp_sack_reset(tp);
 	__sk_dst_reset(sk);
 
-	BUG_TRAP(!inet->num || sk->sk_prev);
+	BUG_TRAP(!inet->num || tp->bind_hash);
 
 	sk->sk_error_report(sk);
 	return err;
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Mon Jun 16 09:53:26 2003
+++ b/net/ipv4/tcp_ipv4.c	Tue Jun 17 09:35:27 2003
@@ -156,9 +156,9 @@
 	struct tcp_bind_bucket *tb;
 
 	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *)sk->sk_prev;
+	tb = tcp_sk(sk)->bind_hash;
 	sk_add_bind_node(child, &tb->owners);
-	child->sk_prev	  = (struct sock *)tb;
+	tcp_sk(child)->bind_hash = tb;
 	spin_unlock(&head->lock);
 }
 
@@ -174,7 +174,7 @@
 {
 	inet_sk(sk)->num = snum;
 	sk_add_bind_node(sk, &tb->owners);
-	sk->sk_prev       = (struct sock *)tb;
+	tcp_sk(sk)->bind_hash = tb;
 }
 
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
@@ -279,9 +279,9 @@
 		   (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
 		tb->fastreuse = 0;
 success:
-	if (!sk->sk_prev)
+	if (!tcp_sk(sk)->bind_hash)
 		tcp_bind_hash(sk, tb, snum);
-	BUG_TRAP(sk->sk_prev == (struct sock *)tb);
+	BUG_TRAP(tcp_sk(sk)->bind_hash == tb);
  	ret = 0;
 
 fail_unlock:
@@ -301,9 +301,9 @@
 	struct tcp_bind_bucket *tb;
 
 	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *)sk->sk_prev;
+	tb = tcp_sk(sk)->bind_hash;
 	__hlist_del(&sk->sk_bind_node);
-	sk->sk_prev = NULL;
+	tcp_sk(sk)->bind_hash = NULL;
 	inet->num = 0;
 	tcp_bucket_destroy(tb);
 	spin_unlock(&head->lock);
@@ -730,7 +730,7 @@
  	}
 
  	head  = &tcp_bhash[tcp_bhashfn(snum)];
- 	tb  = (struct tcp_bind_bucket *)sk->sk_prev;
+ 	tb  = tcp_sk(sk)->bind_hash;
 	spin_lock_bh(&head->lock);
 	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
 		__tcp_v4_hash(sk, 0);
@@ -2101,7 +2101,7 @@
 	__skb_queue_purge(&tp->ucopy.prequeue);
 
 	/* Clean up a referenced TCP bind bucket. */
-	if (sk->sk_prev)
+	if (tp->bind_hash)
 		tcp_put_port(sk);
 
 	/* If sendmsg cached page exists, toss it. */
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	Mon Jun 16 11:44:09 2003
+++ b/net/ipv4/tcp_minisocks.c	Tue Jun 17 09:35:28 2003
@@ -301,8 +301,8 @@
 	 */
 	bhead = &tcp_bhash[tcp_bhashfn(inet_sk(sk)->num)];
 	spin_lock(&bhead->lock);
-	tw->tw_tb = (struct tcp_bind_bucket *)sk->sk_prev;
-	BUG_TRAP(sk->sk_prev);
+	tw->tw_tb = tcp_sk(sk)->bind_hash;
+	BUG_TRAP(tcp_sk(sk)->bind_hash);
 	tw_add_bind_node(tw, &tw->tw_tb->owners);
 	spin_unlock(&bhead->lock);
 
@@ -620,7 +620,7 @@
 
 		/* SANITY */
 		sk_node_init(&newsk->sk_node);
-		newsk->sk_prev = NULL;
+		tcp_sk(newsk)->bind_hash = NULL;
 
 		/* Clone the TCP header template */
 		inet_sk(newsk)->dport = req->rmt_port;
diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c	Mon Jun  9 07:56:44 2003
+++ b/net/ipv6/ip6_tunnel.c	Tue Jun 17 11:17:42 2003
@@ -230,8 +230,6 @@
 	dev->init = ip6ip6_tnl_dev_init;
 	memcpy(&t->parms, p, sizeof (*p));
 	t->parms.name[IFNAMSIZ - 1] = '\0';
-	if (t->parms.hop_limit > 255)
-		t->parms.hop_limit = -1;
 	strcpy(dev->name, t->parms.name);
 	if (!dev->name[0]) {
 		int i = 0;
@@ -952,7 +950,7 @@
 	ipv6_addr_copy(&t->parms.laddr, &p->laddr);
 	ipv6_addr_copy(&t->parms.raddr, &p->raddr);
 	t->parms.flags = p->flags;
-	t->parms.hop_limit = (p->hop_limit <= 255 ? p->hop_limit : -1);
+	t->parms.hop_limit = p->hop_limit;
 	t->parms.encap_limit = p->encap_limit;
 	t->parms.flowinfo = p->flowinfo;
 	ip6ip6_tnl_link_config(t);
diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c	Thu Jun 12 00:04:26 2003
+++ b/net/ipv6/mcast.c	Tue Jun 17 09:44:51 2003
@@ -1321,8 +1321,17 @@
 		if (type == MLD2_ALLOW_NEW_SOURCES ||
 		    type == MLD2_BLOCK_OLD_SOURCES)
 			return skb;
-		if (pmc->mca_crcount || isquery)
+		if (pmc->mca_crcount || isquery) {
+			/* make sure we have room for group header and at
+			 * least one source.
+			 */
+			if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+
+			    sizeof(struct in6_addr)) {
+				mld_sendpack(skb);
+				skb = 0; /* add_grhead will get a new one */
+			}
 			skb = add_grhead(skb, pmc, type, &pgr);
+		}
 		return skb;
 	}
 	pmr = skb ? (struct mld2_report *)skb->h.raw : 0;
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Mon Jun 16 09:53:26 2003
+++ b/net/ipv6/tcp_ipv6.c	Tue Jun 17 09:35:28 2003
@@ -225,9 +225,9 @@
 		tb->fastreuse = 0;
 
 success:
-	if (!sk->sk_prev)
+	if (!tcp_sk(sk)->bind_hash)
 		tcp_bind_hash(sk, tb, snum);
-	BUG_TRAP(sk->sk_prev == (struct sock *)tb);
+	BUG_TRAP(tcp_sk(sk)->bind_hash == tb);
 	ret = 0;
 
 fail_unlock:
@@ -1947,7 +1947,7 @@
 	__skb_queue_purge(&tp->ucopy.prequeue);
 
 	/* Clean up a referenced TCP bind bucket. */
-	if (sk->sk_prev)
+	if (tcp_sk(sk)->bind_hash)
 		tcp_put_port(sk);
 
 	/* If sendmsg cached page exists, toss it. */
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Mon Jun 16 08:11:36 2003
+++ b/net/ipx/af_ipx.c	Tue Jun 17 10:11:58 2003
@@ -269,7 +269,7 @@
 
 #ifdef CONFIG_IPX_INTERN
 static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
-						unsigned char *node,
+						unsigned char *ipx_node,
 						unsigned short port)
 {
 	struct sock *s;
@@ -282,7 +282,7 @@
 		struct ipx_opt *ipxs = ipx_sk(s);
 
 		if (ipxs->port == port &&
-		    !memcmp(node, ipxs->node, IPX_NODE_LEN))
+		    !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN))
 			goto found;
 	}
 	s = NULL;
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Sat Jun 21 07:36:01 2003
+++ b/net/sctp/endpointola.c	Tue Jun 17 09:35:28 2003
@@ -209,7 +209,7 @@
 	sctp_bind_addr_free(&ep->base.bind_addr);
 
 	/* Remove and free the port */
-	if (ep->base.sk->sk_prev)
+	if (sctp_sk(ep->base.sk)->bind_hash)
 		sctp_put_port(ep->base.sk);
 
 	/* Give up our hold on the sock. */
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Mon Jun 16 08:11:36 2003
+++ b/net/sctp/socket.c	Tue Jun 17 09:35:28 2003
@@ -3078,9 +3078,9 @@
 	 */
 success:
 	inet_sk(sk)->num = snum;
-	if (!sk->sk_prev) {
+	if (!sctp_sk(sk)->bind_hash) {
 		sk_add_bind_node(sk, &pp->sk_list);
-		sk->sk_prev = (struct sock *) pp;
+		sctp_sk(sk)->bind_hash = pp;
 	}
 	ret = 0;
 
@@ -3345,9 +3345,9 @@
 	struct sctp_bind_bucket *pp;
 
 	sctp_spin_lock(&head->lock);
-	pp = (struct sctp_bind_bucket *)sk->sk_prev;
+	pp = sctp_sk(sk)->bind_hash;
 	hlist_del(&sk->sk_bind_node);
-	sk->sk_prev = NULL;
+	sctp_sk(sk)->bind_hash = NULL;
 	inet_sk(sk)->num = 0;
 	sctp_bucket_destroy(pp);
 	sctp_spin_unlock(&head->lock);
diff -Nru a/net/sunrpc/cache.c b/net/sunrpc/cache.c
--- a/net/sunrpc/cache.c	Sat May 10 11:46:35 2003
+++ b/net/sunrpc/cache.c	Tue Jun 17 16:18:16 2003
@@ -310,14 +310,17 @@
 		cp = & current_detail->hash_table[current_index];
 		ch = *cp;
 		for (; ch; cp= & ch->next, ch= *cp) {
-			if (atomic_read(&ch->refcnt))
-				continue;
-			if (ch->expiry_time < get_seconds()
-			    || ch->last_refresh < current_detail->flush_time
-				)
-				break;
 			if (current_detail->nextcheck > ch->expiry_time)
 				current_detail->nextcheck = ch->expiry_time+1;
+			if (ch->expiry_time >= get_seconds()
+			    && ch->last_refresh >= current_detail->flush_time
+				)
+				continue;
+			if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
+				queue_loose(current_detail, ch);
+
+			if (atomic_read(&ch->refcnt))
+				continue;
 		}
 		if (ch) {
 			cache_get(ch);
@@ -464,6 +467,31 @@
 		dreq = list_entry(pending.next, struct cache_deferred_req, recent);
 		list_del_init(&dreq->recent);
 		dreq->revisit(dreq, 0);
+	}
+}
+
+void cache_clean_deferred(void *owner)
+{
+	struct cache_deferred_req *dreq, *tmp;
+	struct list_head pending;
+
+
+	INIT_LIST_HEAD(&pending);
+	spin_lock(&cache_defer_lock);
+	
+	list_for_each_entry_safe(dreq, tmp, &cache_defer_list, recent) {
+		if (dreq->owner == owner) {
+			list_del(&dreq->hash);
+			list_move(&dreq->recent, &pending);
+			cache_defer_cnt--;
+		}
+	}
+	spin_unlock(&cache_defer_lock);
+
+	while (!list_empty(&pending)) {
+		dreq = list_entry(pending.next, struct cache_deferred_req, recent);
+		list_del_init(&dreq->recent);
+		dreq->revisit(dreq, 1);
 	}
 }
 
diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c
--- a/net/sunrpc/svc.c	Fri Feb  7 12:25:20 2003
+++ b/net/sunrpc/svc.c	Tue Jun 17 16:18:16 2003
@@ -98,6 +98,8 @@
 				  sk_list);
 		svc_delete_socket(svsk);
 	}
+	
+	cache_clean_deferred(serv);
 
 	/* Unregister service with the portmapper */
 	svc_register(serv, 0, 0);
diff -Nru a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
--- a/net/sunrpc/svcauth_unix.c	Tue Mar 11 20:03:48 2003
+++ b/net/sunrpc/svcauth_unix.c	Tue Jun 17 16:18:16 2003
@@ -195,12 +195,12 @@
 	ipm.m_addr.s_addr =
 		htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
 	ipm.h.flags = 0;
-	if (dom)
+	if (dom) {
 		ipm.m_client = container_of(dom, struct unix_domain, h);
-	else
+		ipm.m_add_change = ipm.m_client->addr_changes;
+	} else
 		set_bit(CACHE_NEGATIVE, &ipm.h.flags);
 	ipm.h.expiry_time = expiry;
-	ipm.m_add_change = ipm.m_client->addr_changes;
 
 	ipmp = ip_map_lookup(&ipm, 1);
 	if (ipmp)
diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c	Wed Jun  4 17:57:09 2003
+++ b/net/sunrpc/svcsock.c	Tue Jun 17 16:31:29 2003
@@ -681,8 +681,17 @@
 	dprintk("svc: socket %p TCP (listen) state change %d\n",
 			sk, sk->sk_state);
 
-	if  (sk->sk_state != TCP_ESTABLISHED) {
-		/* Aborted connection, SYN_RECV or whatever... */
+	if  (sk->sk_state != TCP_LISTEN) {
+		/*
+		 * This callback may called twice when a new connection
+		 * is established as a child socket inherits everything
+		 * from a parent LISTEN socket.
+		 * 1) data_ready method of the parent socket will be called
+		 *    when one of child sockets become ESTABLISHED.
+		 * 2) data_ready method of the child socket may be called
+		 *    when it receives data before the socket is accepted.
+		 * In case of 2, we should ignore it silently.
+		 */
 		goto out;
 	}
 	if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
@@ -1060,6 +1069,8 @@
 
 		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 		set_bit(SK_DATA, &svsk->sk_flags);
+		if (sk->sk_state != TCP_ESTABLISHED) 
+			set_bit(SK_CLOSE, &svsk->sk_flags);
 	}
 }
 
@@ -1211,7 +1222,6 @@
 	}
 
 	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
-	rqstp->rq_userset = 0;
 	rqstp->rq_chandle.defer = svc_defer;
 
 	if (serv->sv_stats)
@@ -1443,7 +1453,7 @@
 static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
 {
 	struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle);
-	struct svc_serv *serv = dr->serv;
+	struct svc_serv *serv = dreq->owner;
 	struct svc_sock *svsk;
 
 	if (too_many) {
@@ -1481,7 +1491,7 @@
 		if (dr == NULL)
 			return NULL;
 
-		dr->serv = rqstp->rq_server;
+		dr->handle.owner = rqstp->rq_server;
 		dr->prot = rqstp->rq_prot;
 		dr->addr = rqstp->rq_addr;
 		dr->argslen = rqstp->rq_arg.len >> 2;
