Merge mainline to 2.5.4-pre5
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index 0b1f791..2201456 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -219,6 +219,11 @@
   2: 'F' if any module was force loaded by insmod -f, ' ' if all
      modules were loaded normally.
 
+  3: 'S' if the oops occured on an SMP kernel running on hardware that
+      hasn't been certified as safe to run multiprocessor.
+	  Currently this occurs only on various Athlons that are not
+	  SMP capable.
+
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
 occurred.  Tainting is permanent, even if an offending module is
diff --git a/Makefile b/Makefile
index f1c5436..d45179e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 4
-EXTRAVERSION =-pre3
+EXTRAVERSION =-pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -332,11 +332,13 @@
 	@echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver
 	@mv -f .ver $@
 
+comma	:= ,
+
 init/version.o: init/version.c include/linux/compile.h include/config/MARKER
-	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c
+	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c
 
 init/main.o: init/main.c include/config/MARKER
-	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
+	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $<
 
 init/do_mounts.o: init/do_mounts.c include/config/MARKER
 	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $<
diff --git a/Rules.make b/Rules.make
index d792a5c..69af527 100644
--- a/Rules.make
+++ b/Rules.make
@@ -31,6 +31,8 @@
 unexport subdir-n
 unexport subdir-
 
+comma	:= ,
+
 #
 # Get things started.
 #
@@ -54,7 +56,7 @@
 	$(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@
 
 %.o: %.c
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -c -o $@ $<
 	@ ( \
 	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; \
 	    echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
@@ -270,7 +272,7 @@
 
 ifneq "$(strip $(export-objs))" ""
 $(export-objs): $(export-objs:.o=.c) $(TOPDIR)/include/linux/modversions.h
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c)
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c)
 	@ ( \
 	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -DEXPORT_SYMTAB)),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@) -DEXPORT_SYMTAB)))' ; \
 	    echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
diff --git a/arch/cris/cris.ld b/arch/cris/cris.ld
index d0d2af1..f62b467 100644
--- a/arch/cris/cris.ld
+++ b/arch/cris/cris.ld
@@ -24,7 +24,6 @@
 		*(.fixup)
 		*(.text.__*)
 	}
-  	.text.lock : { *(.text.lock) }        /* out-of-line lock text */
 
 	_etext = . ;                  /* End of text section */ 
 	__etext = .;
diff --git a/arch/i386/Config.help b/arch/i386/Config.help
index 9b5b72e..98b4c75 100644
--- a/arch/i386/Config.help
+++ b/arch/i386/Config.help
@@ -386,7 +386,7 @@
      will run on a 386 class machine.
    - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
      SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
-   - "586" for generic Pentium CPUs, possibly lacking the TSC
+   - "586" for generic Pentium CPUs lacking the TSC
      (time stamp counter) register.
    - "Pentium-Classic" for the Intel Pentium.
    - "Pentium-MMX" for the Intel Pentium MMX.
@@ -413,12 +413,69 @@
 CONFIG_M586
   Select this for an x586 or x686 processor such as the AMD K5, the
   Intel 5x86 or 6x86, or the Intel 6x86MX.  This choice does not
-  assume the RDTSC instruction.
+  assume the RDTSC (Read Time Stamp Counter) instruction.
 
 CONFIG_M586TSC
   Select this for a Pentium Classic processor with the RDTSC (Read
   Time Stamp Counter) instruction for benchmarking.
 
+CONFIG_M586MMX
+  Select this for a Pentium with the MMX graphics/multimedia
+  extended instructions.
+
+CONFIG_M686
+  Select this for a Pro/Celeron/Pentium II.  This enables the use of
+  Pentium Pro extended instructions, and disables the init-time guard
+  against the f00f bug found in earlier Pentiums.
+
+CONFIG_MPENTIUMIII
+  Select this for Intel chips based on the Pentium-III and
+  Celeron-Coppermine core.  Enables use of some extended prefetch
+  instructions, in addition to the Pentium II extensions.
+
+CONFIG_MPENTIUM4
+  Select this for Intel Pentium 4 chips.  Presently these are
+  treated almost like Pentium IIIs, but with a different cache
+  shift.
+
+CONFIG_MCRUSOE
+  Select this for Transmeta Crusoe processor.  Treats the processor
+  like a 586 with TSC, and sets some GCC optimization flags (like a
+  Pentium Pro with no alignment requirements).
+
+CONFIG_MK6
+  Select this for an AMD K6-family processor.  Enables use of
+  some extended instructions, and passes appropriate optimization
+  flags to GCC.
+
+CONFIG_MK7
+  Select this for an AMD Athlon K7-family processor.  Enables use of
+  some extended instructions, and passes appropriate optimization
+  flags to GCC.
+
+CONFIG_MCYRIXIII
+  Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
+  treat this chip as a generic 586. Whilst the CPU is 686 class,
+  it lacks the cmov extension which gcc assumes is present when
+  generating 686 code.
+
+CONFIG_MWINCHIPC6
+  Select this for a IDT Winchip C6 chip.  Linux and GCC
+  treat this chip as a 586TSC with some extended instructions
+  and alignment requirements.
+
+CONFIG_MWINCHIP2
+  Select this for a IDT Winchip-2.  Linux and GCC
+  treat this chip as a 586TSC with some extended instructions
+  and alignment requirements.
+
+CONFIG_MWINCHIP3D
+  Select this for a IDT Winchip-2A or 3.  Linux and GCC
+  treat this chip as a 586TSC with some extended instructions
+  and alignment reqirements.  Development kernels also enable
+  out of order memory stores for this CPU, which can increase
+  performance of some operations.
+
 CONFIG_VGA_CONSOLE
   Saying Y here will allow you to use Linux in text mode through a
   display that complies with the generic VGA standard. Virtually
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index 2232776..e323873 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -32,8 +32,10 @@
 head.o: head.S
 	$(CC) $(AFLAGS) -traditional -c head.S
 
+comma	:= ,
+
 misc.o: misc.c
-	$(CC) $(CFLAGS) -c misc.c
+	$(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c misc.c
 
 piggy.o:	$(SYSTEM)
 	tmppiggy=_tmp_$$$$piggy; \
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 4f292da..0d33e70 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -436,6 +436,7 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -581,7 +582,7 @@
 CONFIG_AGP_INTEL=y
 CONFIG_AGP_I810=y
 CONFIG_AGP_VIA=y
-CONFIG_AGP_AMD=y
+# CONFIG_AGP_AMD is not set
 CONFIG_AGP_SIS=y
 CONFIG_AGP_ALI=y
 # CONFIG_AGP_SWORKS is not set
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 0e8e46d..16b69e8 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -95,6 +95,7 @@
   case 1:
     file->f_pos += offset;
     ret = file->f_pos;
+    break;
   default:
     ret = -EINVAL;
   }
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 02e1953..77d0323 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -456,12 +456,3 @@
 	.quad 0x0000000000000000	/* 0x98 not used */
 	/* Per CPU segments */
 	.fill NR_CPUS*4,8,0		/* space for TSS's and LDT's */
-		
-/*
- * This is to aid debugging, the various locking macros will be putting
- * code fragments here.  When an oops occurs we'd rather know that it's
- * inside the .text.lock section rather than as some offset from whatever
- * function happens to be last in the .text segment.
- */
-.section .text.lock
-ENTRY(stext_lock)
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
index 0732fed..a87a362 100644
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -52,7 +52,7 @@
 		asm volatile( "fnsave %0 ; fwait"
 			      : "=m" (tsk->thread.i387.fsave) );
 	}
-	clear_thread_flag(TIF_USEDFPU);
+	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
 }
 
 void save_init_fpu( struct task_struct *tsk )
@@ -63,10 +63,8 @@
 
 void kernel_fpu_begin(void)
 {
-	struct task_struct *tsk = current;
-
 	if (test_thread_flag(TIF_USEDFPU)) {
-		__save_init_fpu(tsk);
+		__save_init_fpu(current);
 		return;
 	}
 	clts();
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b955ff2..142915b 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -808,7 +808,7 @@
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
-	stack_page = (unsigned long)p;
+	stack_page = (unsigned long)p->thread_info;
 	esp = p->thread.esp;
 	if (!stack_page || esp < stack_page || esp > 8188+stack_page)
 		return 0;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index a6573e3..4afb2af 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -278,10 +278,10 @@
 		if ((unsigned long) data > _NSIG)
 			break;
 		if (request == PTRACE_SYSCALL) {
-			set_thread_flag(TIF_SYSCALL_TRACE);
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		}
 		else {
-			clear_thread_flag(TIF_SYSCALL_TRACE);
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		}
 		child->exit_code = data;
 	/* make sure the single step bit is not set. */
@@ -317,7 +317,7 @@
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			break;
-		clear_thread_flag(TIF_SYSCALL_TRACE);
+		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		if ((child->ptrace & PT_DTRACE) == 0) {
 			/* Spurious delayed TF traps may occur */
 			child->ptrace |= PT_DTRACE;
@@ -449,7 +449,7 @@
 {
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return;
-	if (current->ptrace & PT_PTRACED)
+	if (!(current->ptrace & PT_PTRACED))
 		return;
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 691cd19..d7f8e2a 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -2652,7 +2652,7 @@
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL,
+		NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
 		NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
 
 		/* Transmeta-defined */
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 66417ce..b877493 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -30,10 +30,12 @@
  *		Tigran Aivazian	:	fixed "0.00 in /proc/uptime on SMP" bug.
  *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs
  *		Martin J. Bligh	: 	Added support for multi-quad systems
+ *		Dave Jones	:	Report invalid combinations of Athlon CPUs.
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
@@ -160,6 +162,35 @@
 		 * Remember we have B step Pentia with bugs
 		 */
 		smp_b_stepping = 1;
+
+	/*
+	 * Certain Athlons might work (for various values of 'work') in SMP
+	 * but they are not certified as MP capable.
+	 */
+	if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
+
+		/* Athlon 660/661 is valid. */	
+		if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1)))
+			goto valid_k7;
+
+		/* Duron 670 is valid */
+		if ((c->x86_model==7) && (c->x86_mask==0))
+			goto valid_k7;
+
+		/* Athlon 662, Duron 671, and Athlon >model 7 have capability bit */
+		if (((c->x86_model==6) && (c->x86_mask>=2)) ||
+		    ((c->x86_model==7) && (c->x86_mask>=1)) ||
+		     (c->x86_model> 7))
+			if (cpu_has_mp)
+				goto valid_k7;
+
+		/* If we get here, it's not a certified SMP capable AMD system. */
+		printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n");
+		tainted |= TAINT_UNSAFE_SMP;
+		
+	}
+valid_k7:
+
 }
 
 /*
diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds
index 1a7da03..cd994f0 100644
--- a/arch/i386/vmlinux.lds
+++ b/arch/i386/vmlinux.lds
@@ -13,7 +13,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
 
   _etext = .;			/* End of text section */
 
diff --git a/arch/ia64/sn/fprom/Makefile b/arch/ia64/sn/fprom/Makefile
index 0b2b212..4113f06 100644
--- a/arch/ia64/sn/fprom/Makefile
+++ b/arch/ia64/sn/fprom/Makefile
@@ -18,10 +18,12 @@
 fprom: $(OBJ)
 	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
 
+comma	:= ,
+
 .S.o:
 	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 .c.o:
-	$(CC)  $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $<
+	$(CC)  $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_KERNEL) -c -o $*.o $<
 
 clean:
 	rm -f *.o fprom
diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
index f98e2d1..cdfa56f 100644
--- a/arch/ia64/tools/Makefile
+++ b/arch/ia64/tools/Makefile
@@ -31,8 +31,10 @@
 offsets.h: print_offsets
 	./print_offsets > offsets.h
 
+comma	:= ,
+
 print_offsets: print_offsets.c FORCE_RECOMPILE
-	$(CC) $(CFLAGS) print_offsets.c -o $@
+	$(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) print_offsets.c -o $@
 
 FORCE_RECOMPILE:
 
@@ -42,7 +44,7 @@
 	$(AWK) -f print_offsets.awk $^ > $@
 
 print_offsets.s: print_offsets.c
-	$(CC) $(CFLAGS) -S print_offsets.c -o $@
+	$(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S print_offsets.c -o $@
 
 endif
 
diff --git a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
index 164b11a..7894d47 100644
--- a/arch/m68k/vmlinux-sun3.lds
+++ b/arch/m68k/vmlinux-sun3.lds
@@ -10,7 +10,6 @@
 	*(.head)
 	*(.text)
 	*(.fixup)
-	*(.text.lock)		/* out-of-line lock text */
 	*(.gnu.warning)
 	} = 0x4e75
   .kstrtab : { *(.kstrtab) }
diff --git a/arch/m68k/vmlinux.lds b/arch/m68k/vmlinux.lds
index 3b9eb25..aea08a8 100644
--- a/arch/m68k/vmlinux.lds
+++ b/arch/m68k/vmlinux.lds
@@ -9,7 +9,6 @@
   .text : {
 	*(.text)
 	*(.fixup)
-	*(.text.lock)		/* out-of-line lock text */
 	*(.gnu.warning)
 	} = 0x4e75
   .rodata : { *(.rodata) *(.rodata.*) }
diff --git a/arch/s390/vmlinux-shared.lds b/arch/s390/vmlinux-shared.lds
index 4956b7c..ad32571 100644
--- a/arch/s390/vmlinux-shared.lds
+++ b/arch/s390/vmlinux-shared.lds
@@ -13,7 +13,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0700
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   .rodata : { *(.rodata) }
   .kstrtab : { *(.kstrtab) }
 
diff --git a/arch/s390/vmlinux.lds b/arch/s390/vmlinux.lds
index 1b53d5b..c1dd3ae 100644
--- a/arch/s390/vmlinux.lds
+++ b/arch/s390/vmlinux.lds
@@ -13,7 +13,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0700
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   .rodata : { *(.rodata) *(.rodata.*) }
   .kstrtab : { *(.kstrtab) }
 
diff --git a/arch/s390x/vmlinux-shared.lds b/arch/s390x/vmlinux-shared.lds
index 8f6d74e..1d22a5e 100644
--- a/arch/s390x/vmlinux-shared.lds
+++ b/arch/s390x/vmlinux-shared.lds
@@ -13,7 +13,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0700
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   .rodata : { *(.rodata) }
   .kstrtab : { *(.kstrtab) }
 
diff --git a/arch/s390x/vmlinux.lds b/arch/s390x/vmlinux.lds
index 2cc3355..f3e7b06 100644
--- a/arch/s390x/vmlinux.lds
+++ b/arch/s390x/vmlinux.lds
@@ -13,7 +13,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0700
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   .rodata : { *(.rodata) *(.rodata.*) }
   .kstrtab : { *(.kstrtab) }
 
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index fcbc7bd..0620024 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -23,7 +23,6 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0009
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
   .rodata : { *(.rodata) *(.rodata.*) }
   .kstrtab : { *(.kstrtab) }
 
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 7cfcab0..3100e0f 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -3,6 +3,11 @@
 #
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
 # General setup
 #
 CONFIG_NET=y
@@ -11,11 +16,6 @@
 CONFIG_SYSCTL=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
 # Loadable module support
 #
 CONFIG_MODULES=y
@@ -486,6 +486,7 @@
 # CONFIG_LNE390 is not set
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
+# CONFIG_NATSEMI_CABLE_MAGIC is not set
 CONFIG_NE2K_PCI=m
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
@@ -669,7 +670,7 @@
 # Network File Systems
 #
 CONFIG_CODA_FS=m
-CONFIG_INTERMEZZO_FS=m
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0cc1555..4a8b527 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -18,7 +18,10 @@
 # define DBG(x...)
 #endif
 
-static struct device * device_root;
+static struct device device_root = {
+	bus_id:		"root",
+	name:		"System Root",
+};
 
 int (*platform_notify)(struct device * dev) = NULL;
 int (*platform_notify_remove)(struct device * dev) = NULL;
@@ -49,9 +52,9 @@
 	spin_lock_init(&dev->lock);
 	atomic_set(&dev->refcount,2);
 
-	if (dev != device_root) {
+	if (dev != &device_root) {
 		if (!dev->parent)
-			dev->parent = device_root;
+			dev->parent = &device_root;
 		get_device(dev->parent);
 		list_add_tail(&dev->node,&dev->parent->children);
 	}
@@ -117,16 +120,10 @@
 
 static int __init device_init_root(void)
 {
-	device_root = kmalloc(sizeof(*device_root),GFP_KERNEL);
-	if (!device_root)
-		return -ENOMEM;
-	memset(device_root,0,sizeof(*device_root));
-	strcpy(device_root->bus_id,"root");
-	strcpy(device_root->name,"System Root");
-	return device_register(device_root);
+	return device_register(&device_root);
 }
 
-static int __init device_driver_init(void)
+static int __init device_init(void)
 {
 	int error = 0;
 
@@ -141,17 +138,12 @@
 		return error;
 	}
 
-	error = device_init_root();
-	if (error) {
+	if ((error = device_init_root()))
 		printk(KERN_ERR "%s: device root init failed!\n", __FUNCTION__);
-		return error;
-	}
-
-	DBG("DEV: Done Initialising\n");
 	return error;
 }
 
-subsys_initcall(device_driver_init);
+subsys_initcall(device_init);
 
 EXPORT_SYMBOL(device_register);
 EXPORT_SYMBOL(put_device);
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index 6358b6a..3ed5efc 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -208,7 +208,7 @@
 
 dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
 if [ "$CONFIG_AGP" != "n" ]; then
-   bool '  Intel 440LX/BX/GX and I815/I830M/I840/I850 support' CONFIG_AGP_INTEL
+   bool '  Intel 440LX/BX/GX and I815/I820/I830M/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
    bool '  VIA chipset support' CONFIG_AGP_VIA
    bool '  AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index b6b2355..a2c4ed5 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -179,6 +179,9 @@
 #ifndef PCI_DEVICE_ID_INTEL_820_0
 #define PCI_DEVICE_ID_INTEL_820_0       0x2500
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_820_UP_0
+#define PCI_DEVICE_ID_INTEL_820_UP_0    0x2501
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_840_0
 #define PCI_DEVICE_ID_INTEL_840_0		0x1a21
 #endif
@@ -189,7 +192,7 @@
 #define PCI_DEVICE_ID_INTEL_850_0     0x2530
 #endif
 #ifndef PCI_DEVICE_ID_INTEL_860_0
-#define PCI_DEVICE_ID_INTEL_860_0	0x2532
+#define PCI_DEVICE_ID_INTEL_860_0     0x2531
 #endif
 #ifndef PCI_DEVICE_ID_INTEL_810_DC100_0
 #define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122
@@ -276,6 +279,7 @@
 #define I830_RDRAM_ND(x)           (((x) & 0x20) >> 5)
 #define I830_RDRAM_DDT(x)          (((x) & 0x18) >> 3)
 
+/* This one is for I830MP w. an external graphic card */
 #define INTEL_I830_ERRSTS          0x92
 
 /* intel i820 registers */
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index 630ef9c..2f717b9 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -409,8 +409,18 @@
 	 *        AGP devices and collect their data.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
+
+	pci_for_each_dev(device)
+	{
+		/*
+		 *	Enable AGP devices. Most will be VGA display but
+		 *	some may be coprocessors on non VGA devices too
+		 */
+		 
+		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
+			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
+			continue;
+
 		pci_read_config_dword(device, 0x04, &scratch);
 
 		if (!(scratch & 0x00100000))
@@ -1826,7 +1836,7 @@
        agp_bridge.needs_scratch_page = FALSE;
        agp_bridge.configure = intel_820_configure;
        agp_bridge.fetch_size = intel_8xx_fetch_size;
-       agp_bridge.cleanup = intel_cleanup;
+       agp_bridge.cleanup = intel_820_cleanup;
        agp_bridge.tlb_flush = intel_820_tlbflush;
        agp_bridge.mask_memory = intel_mask_memory;
        agp_bridge.agp_enable = agp_generic_agp_enable;
@@ -1839,6 +1849,9 @@
        agp_bridge.free_by_type = agp_generic_free_by_type;
        agp_bridge.agp_alloc_page = agp_generic_alloc_page;
        agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+       agp_bridge.suspend = agp_generic_suspend;
+       agp_bridge.resume = agp_generic_resume;
+       agp_bridge.cant_use_aperture = 0;
 
        return 0;
 
@@ -1869,6 +1882,9 @@
        agp_bridge.free_by_type = agp_generic_free_by_type;
        agp_bridge.agp_alloc_page = agp_generic_alloc_page;
        agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+       agp_bridge.suspend = agp_generic_suspend;
+       agp_bridge.resume = agp_generic_resume;
+       agp_bridge.cant_use_aperture = 0;
 
        return 0;
 
@@ -3307,8 +3323,18 @@
 	 *        AGP devices and collect their data.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
+
+	pci_for_each_dev(device)
+	{
+		/*
+		 *	Enable AGP devices. Most will be VGA display but
+		 *	some may be coprocessors on non VGA devices too
+		 */
+		 
+		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
+			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
+			continue;
+
 		pci_read_config_dword(device, 0x04, &scratch);
 
 		if (!(scratch & 0x00100000))
@@ -3611,6 +3637,12 @@
 		"Intel",
 		"i820",
 		intel_820_setup },
+	{ PCI_DEVICE_ID_INTEL_820_UP_0,
+		PCI_VENDOR_ID_INTEL,
+		INTEL_I820,
+		"Intel",
+		"i820",
+		intel_820_setup },
 	{ PCI_DEVICE_ID_INTEL_830_M_0,
 		PCI_VENDOR_ID_INTEL,
 		INTEL_I830_M,
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
index 2c6b9f9..e603a9e 100644
--- a/drivers/char/agp/agpgart_fe.c
+++ b/drivers/char/agp/agpgart_fe.c
@@ -301,7 +301,7 @@
 	agp_memory *memory;
 
 	memory = agp_allocate_memory(pg_count, type);
-   	printk(KERN_DEBUG "memory : %p\n", memory);
+   	printk(KERN_DEBUG "agp_allocate_memory: %p\n", memory);
 	if (memory == NULL) {
 		return NULL;
 	}
diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c
index ea67cd9..9b01255 100644
--- a/drivers/char/ftape/lowlevel/fdc-io.c
+++ b/drivers/char/ftape/lowlevel/fdc-io.c
@@ -928,18 +928,6 @@
 	set_dma_mode(fdc.dma, mode);
 	set_dma_addr(fdc.dma, virt_to_bus((void*)addr));
 	set_dma_count(fdc.dma, count);
-#ifdef GCC_2_4_5_BUG
-	/*  This seemingly stupid construction confuses the gcc-2.4.5
-	 *  code generator enough to create correct code.
-	 */
-	if (1) {
-		int i;
-		
-		for (i = 0; i < 1; ++i) {
-			ftape_udelay(1);
-		}
-	}
-#endif
 	enable_dma(fdc.dma);
 }
 
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index 9a9b3c5..34b09d3 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -3095,36 +3095,52 @@
 
 	sstate = rs_table + line;
 	sstate->count++;
-	if (sstate->info) {
-		*ret_info = sstate->info;
-		return 0;
-	}
+	info = sstate->info;
+
+	/*
+	 * If the async_struct is already allocated, do the fastpath.
+	 */
+	if (info)
+		goto out;
+
 	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
 	if (!info) {
 		sstate->count--;
 		return -ENOMEM;
 	}
+
 	memset(info, 0, sizeof(struct async_struct));
 	init_waitqueue_head(&info->open_wait);
 	init_waitqueue_head(&info->close_wait);
 	init_waitqueue_head(&info->delta_msr_wait);
 	info->magic = SERIAL_MAGIC;
 	info->port = sstate->port;
+	info->hub6 = sstate->hub6;
 	info->flags = sstate->flags;
-	info->io_type = sstate->io_type;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->state = sstate;
+	info->line = line;
 	info->iomem_base = sstate->iomem_base;
 	info->iomem_reg_shift = sstate->iomem_reg_shift;
-	info->xmit_fifo_size = sstate->xmit_fifo_size;
-	info->line = line;
+	info->io_type = sstate->io_type;
 	info->tqueue.routine = do_softint;
 	info->tqueue.data = info;
-	info->state = sstate;
+
 	if (sstate->info) {
 		kfree(info);
-		*ret_info = sstate->info;
-		return 0;
+		info = sstate->info;
+	} else {
+		sstate->info = info;
 	}
-	*ret_info = sstate->info = info;
+
+out:
+	/*
+	 * If this is the first open, copy over some timeouts.
+	 */
+	if (sstate->count == 1) {
+		info->closing_wait = sstate->closing_wait;
+	}
+	*ret_info = info;
 	return 0;
 }
 
diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
index 1088215..f956de8 100644
--- a/drivers/hotplug/pci_hotplug_core.c
+++ b/drivers/hotplug/pci_hotplug_core.c
@@ -396,7 +396,7 @@
 
 static struct file_system_type pcihpfs_type = {
 	owner:		THIS_MODULE,
-	name:		"pchihpfs",
+	name:		"pcihpfs",
 	get_sb:		pcihpfs_get_sb,
 	fs_flags:	FS_LITTER,
 };
diff --git a/drivers/ide/Config.help b/drivers/ide/Config.help
index 04eff06..7cf2924 100644
--- a/drivers/ide/Config.help
+++ b/drivers/ide/Config.help
@@ -796,3 +796,61 @@
   Enable vendor-specific code for TiVo IDE disks.  Unless you are the
   IDE maintainer, you probably do not want to mess with this.
 
+CONFIG_IDEDISK_STROKE
+  Should you have a system w/ an AWARD Bios and your drives are larger
+  than 32GB and it will not boot, one is required to perform a few OEM
+  operations first.  The option is called "STROKE" because it allows
+  one to "soft clip" the drive to work around a barrier limit.  For
+  Maxtor drives it is called "jumpon.exe".  Please search Maxtor's
+  web-site for "JUMPON.EXE".  IBM has a similar tool at:
+  <http://www.storage.ibm.com/hdd/support/download.htm>.
+
+  If you are unsure, say N here.
+
+CONFIG_IDE_TASK_IOCTL
+  This is a direct raw access to the media.  It is a complex but
+  elegant solution to test and validate the domain of the hardware and
+  perform below the driver data recovery if needed.  This is the most
+  basic form of media-forensics.
+
+  If you are unsure, say N here.
+
+CONFIG_BLK_DEV_IDEDMA_FORCED
+  This is an old piece of lost code from Linux 2.0 Kernels.
+
+  Generally say N here.
+
+CONFIG_IDEDMA_ONLYDISK
+  This is used if you know your ATAPI Devices are going to fail DMA
+  Transfers.
+
+  Generally say N here.
+
+CONFIG_BLK_DEV_IT8172
+  Say Y here to support the on-board IDE controller on the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
+CONFIG_IT8172_TUNING
+  Say Y here to support tuning the ITE8172's IDE interface.  This makes
+  it possible to set DMA channel or PIO opration and the transfer rate.
+
+CONFIG_IT8172_REVC
+  Say Y here to support the older, Revision C version of the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
+CONFIG_IT8172_SCR0
+  Say Y here to support smart-card reader 0 (SCR0) on the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
+CONFIG_IT8172_SCR1
+  Say Y here to support smart-card reader 1 (SCR1) on the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
diff --git a/drivers/media/video/Config.in b/drivers/media/video/Config.in
index 4a4ed77..d6a2f9e 100644
--- a/drivers/media/video/Config.in
+++ b/drivers/media/video/Config.in
@@ -22,10 +22,8 @@
    fi
 fi
 if [ "$CONFIG_PARPORT" != "n" ]; then
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      if [ "$CONFIG_PARPORT_1284" != "n" ]; then
-         dep_tristate '  Winbond W9966CF Webcam Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT
-      fi
+   if [ "$CONFIG_PARPORT_1284" != "n" ]; then
+      dep_tristate '  W9966CF Webcam (FlyCam Supra and others) Video For Linux' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT
    fi
 fi
 dep_tristate '  CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV
diff --git a/drivers/net/Config.help b/drivers/net/Config.help
index d34d5ca..fe7ba7e 100644
--- a/drivers/net/Config.help
+++ b/drivers/net/Config.help
@@ -1154,6 +1154,17 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/natsemi.html>.
 
+CONFIG_NATSEMI_CABLE_MAGIC
+  Some systems see lots of errors with NatSemi ethernet controllers
+  on certain cables.  If you are seeing lots of errors, try turning
+  this option on.  Some boards have incorrect values for supporting
+  resistors that can cause this change to break.  If you turn this
+  option on and your network suddenly stops working, turn this
+  option off.
+
+  Say N unless you are certain you need this option.
+  Vendors should not enable this option by default.
+
 CONFIG_SK_G16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available from
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index eee781f..9fe05fb 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -171,6 +171,9 @@
       dep_tristate '    Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
       dep_tristate '    Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
       dep_tristate '    National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
+      if [ "$CONFIG_NATSEMI" = "y" -o "$CONFIG_NATSEMI" = "m" ]; then
+        bool       '      NatSemi workaround for high errors' CONFIG_NATSEMI_CABLE_MAGIC
+      fi
       dep_tristate '    PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
       dep_tristate '    Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
       dep_tristate '    Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index f9d6cb7..c670ba0 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -833,6 +833,10 @@
 	sp->phy[0] = eeprom[6];
 	sp->phy[1] = eeprom[7];
 	sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;
+	if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) 
+	    || (pdev->device == 0x2449)) {
+	    	sp->chip_id = 1;
+	}
 
 	if (sp->rx_bug)
 		printk(KERN_INFO "  Receiver lock-up workaround activated.\n");
@@ -987,6 +991,11 @@
 	if ((sp->phy[0] & 0x8000) == 0)
 		sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4);
 
+	if (mdio_read(ioaddr, sp->phy[0] & 0x1f, MII_BMSR) & BMSR_LSTATUS)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
+
 	if (speedo_debug > 2) {
 		printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
 			   dev->name, inw(ioaddr + SCBStatus));
@@ -1098,10 +1107,10 @@
 			/* Clear sticky bit. */
 			mdio_read(ioaddr, phy_num, 1);
 			/* If link beat has returned... */
-			if (mdio_read(ioaddr, phy_num, 1) & 0x0004)
-				dev->flags |= IFF_RUNNING;
+			if (mdio_read(ioaddr, phy_num, MII_BMSR) & BMSR_LSTATUS)
+				netif_carrier_on(dev);
 			else
-				dev->flags &= ~IFF_RUNNING;
+				netif_carrier_off(dev);
 		}
 	}
 	if (speedo_debug > 3) {
@@ -1375,7 +1384,7 @@
 
 	/* workaround for hardware bug on 10 mbit half duplex */
 
-	if ((sp->partner==0) && (sp->chip_id==1)) {
+	if ((sp->partner == 0) || (sp->chip_id == 1)) {
 		wait_for_cmd_done(ioaddr + SCBCmd);
 		outb(0 , ioaddr + SCBCmd);
 	}
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a94d694..d3d5782 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -394,7 +394,11 @@
 	SDCFG			= 0xF8
 };
 /* the values for the 'magic' registers above (PGSEL=1) */
+#ifdef CONFIG_NATSEMI_CABLE_MAGIC
+#define PMDCSR_VAL	0x1898
+#else
 #define PMDCSR_VAL	0x189C
+#endif
 #define TSTDAT_VAL	0x0
 #define DSPCFG_VAL	0x5040
 #define SDCFG_VAL	0x008c
@@ -1511,7 +1515,7 @@
 		if (intr_status == 0)
 			break;
 
-		if (intr_status & (IntrRxDone | IntrRxIntr))
+		if (intr_status & (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | IntrRxErr | IntrRxOverrun ))
 			netdev_rx(dev);
 
 		if (intr_status & (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr) ) {
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 25b86ec..8dd2af6 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -65,15 +65,15 @@
 static const int max_interrupt_work = 80;
 static const int rx_copybreak = 200;
 
-#define PORT_AUI      0x00
-#define PORT_10BT     0x01
-#define PORT_GPSI     0x02
-#define PORT_MII      0x03
+#define PCNET32_PORT_AUI      0x00
+#define PCNET32_PORT_10BT     0x01
+#define PCNET32_PORT_GPSI     0x02
+#define PCNET32_PORT_MII      0x03
 
-#define PORT_PORTSEL  0x03
-#define PORT_ASEL     0x04
-#define PORT_100      0x40
-#define PORT_FD	      0x80
+#define PCNET32_PORT_PORTSEL  0x03
+#define PCNET32_PORT_ASEL     0x04
+#define PCNET32_PORT_100      0x40
+#define PCNET32_PORT_FD	      0x80
 
 #define PCNET32_DMA_MASK 0xffffffff
 
@@ -82,22 +82,22 @@
  * to internal options
  */
 static unsigned char options_mapping[] = {
-    PORT_ASEL,			   /*  0 Auto-select	  */
-    PORT_AUI,			   /*  1 BNC/AUI	  */
-    PORT_AUI,			   /*  2 AUI/BNC	  */ 
-    PORT_ASEL,			   /*  3 not supported	  */
-    PORT_10BT | PORT_FD,	   /*  4 10baseT-FD	  */
-    PORT_ASEL,			   /*  5 not supported	  */
-    PORT_ASEL,			   /*  6 not supported	  */
-    PORT_ASEL,			   /*  7 not supported	  */
-    PORT_ASEL,			   /*  8 not supported	  */
-    PORT_MII,			   /*  9 MII 10baseT	  */
-    PORT_MII | PORT_FD,		   /* 10 MII 10baseT-FD	  */
-    PORT_MII,			   /* 11 MII (autosel)	  */
-    PORT_10BT,			   /* 12 10BaseT	  */
-    PORT_MII | PORT_100,	   /* 13 MII 100BaseTx	  */
-    PORT_MII | PORT_100 | PORT_FD, /* 14 MII 100BaseTx-FD */
-    PORT_ASEL			   /* 15 not supported	  */
+    PCNET32_PORT_ASEL,			   /*  0 Auto-select	  */
+    PCNET32_PORT_AUI,			   /*  1 BNC/AUI	  */
+    PCNET32_PORT_AUI,			   /*  2 AUI/BNC	  */ 
+    PCNET32_PORT_ASEL,			   /*  3 not supported	  */
+    PCNET32_PORT_10BT | PCNET32_PORT_FD,	   /*  4 10baseT-FD	  */
+    PCNET32_PORT_ASEL,			   /*  5 not supported	  */
+    PCNET32_PORT_ASEL,			   /*  6 not supported	  */
+    PCNET32_PORT_ASEL,			   /*  7 not supported	  */
+    PCNET32_PORT_ASEL,			   /*  8 not supported	  */
+    PCNET32_PORT_MII,			   /*  9 MII 10baseT	  */
+    PCNET32_PORT_MII | PCNET32_PORT_FD,		   /* 10 MII 10baseT-FD	  */
+    PCNET32_PORT_MII,			   /* 11 MII (autosel)	  */
+    PCNET32_PORT_10BT,			   /* 12 10BaseT	  */
+    PCNET32_PORT_MII | PCNET32_PORT_100,	   /* 13 MII 100BaseTx	  */
+    PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */
+    PCNET32_PORT_ASEL			   /* 15 not supported	  */
 };
 
 #define MAX_UNITS 8
@@ -709,12 +709,12 @@
     lp->ltint = ltint;
     lp->mii = mii;
     if (options[card_idx] > sizeof (options_mapping))
-	lp->options = PORT_ASEL;
+	lp->options = PCNET32_PORT_ASEL;
     else
 	lp->options = options_mapping[options[card_idx]];
     
-    if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx])
-	lp->options |= PORT_FD;
+    if (fdx && !(lp->options & PCNET32_PORT_ASEL) && full_duplex[card_idx])
+	lp->options |= PCNET32_PORT_FD;
     
     if (a == NULL) {
       printk(KERN_ERR "pcnet32: No access methods\n");
@@ -726,7 +726,7 @@
     
     /* detect special T1/E1 WAN card by checking for MAC address */
     if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75)
-	lp->options = PORT_FD | PORT_GPSI;
+	lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
 
     lp->init_block.mode = le16_to_cpu(0x0003);	/* Disable Rx and Tx. */
     lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); 
@@ -829,16 +829,16 @@
     
     /* set/reset autoselect bit */
     val = lp->a.read_bcr (ioaddr, 2) & ~2;
-    if (lp->options & PORT_ASEL)
+    if (lp->options & PCNET32_PORT_ASEL)
 	val |= 2;
     lp->a.write_bcr (ioaddr, 2, val);
     
     /* handle full duplex setting */
     if (lp->full_duplex) {
 	val = lp->a.read_bcr (ioaddr, 9) & ~3;
-	if (lp->options & PORT_FD) {
+	if (lp->options & PCNET32_PORT_FD) {
 	    val |= 1;
-	    if (lp->options == (PORT_FD | PORT_AUI))
+	    if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
 		val |= 2;
 	}
 	lp->a.write_bcr (ioaddr, 9, val);
@@ -846,19 +846,19 @@
     
     /* set/reset GPSI bit in test register */
     val = lp->a.read_csr (ioaddr, 124) & ~0x10;
-    if ((lp->options & PORT_PORTSEL) == PORT_GPSI)
+    if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
 	val |= 0x10;
     lp->a.write_csr (ioaddr, 124, val);
     
-    if (lp->mii && !(lp->options & PORT_ASEL)) {
+    if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
 	val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
-	if (lp->options & PORT_FD)
+	if (lp->options & PCNET32_PORT_FD)
 	    val |= 0x10;
-	if (lp->options & PORT_100)
+	if (lp->options & PCNET32_PORT_100)
 	    val |= 0x08;
 	lp->a.write_bcr (ioaddr, 32, val);
     } else {
-	if (lp->options & PORT_ASEL) {  /* enable auto negotiate, setup, disable fd */
+	if (lp->options & PCNET32_PORT_ASEL) {  /* enable auto negotiate, setup, disable fd */
 		val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
 		val |= 0x20;
 		lp->a.write_bcr(ioaddr, 32, val);
@@ -878,7 +878,7 @@
 	lp->a.write_csr (ioaddr, 5, val);
     }
    
-    lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+    lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
     lp->init_block.filter[0] = 0x00000000;
     lp->init_block.filter[1] = 0x00000000;
     if (pcnet32_init_ring(dev))
@@ -1465,9 +1465,9 @@
     if (dev->flags&IFF_PROMISC) {
 	/* Log any net taps. */
 	printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
-	lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7);
+	lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << 7);
     } else {
-	lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+	lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
 	pcnet32_load_multicast (dev);
     }
     
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 3a88c44..7e66f90 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -39,8 +39,13 @@
 		printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
 			   dev->name, csr12, medianame[dev->if_port]);
 	if (tulip_media_cap[dev->if_port] & MediaIsMII) {
-		tulip_check_duplex(dev);
-		next_tick = 60*HZ;
+		if (tulip_check_duplex(dev) < 0) {
+			netif_carrier_off(dev);
+			next_tick = 3*HZ;
+		} else {
+			netif_carrier_on(dev);
+			next_tick = 60*HZ;
+		}
 	} else if (tp->nwayset) {
 		/* Don't screw up a negotiated session! */
 		if (tulip_debug > 1)
diff --git a/drivers/net/tulip/ChangeLog b/drivers/net/tulip/ChangeLog
index 8a1caaa..3111685 100644
--- a/drivers/net/tulip/ChangeLog
+++ b/drivers/net/tulip/ChangeLog
@@ -1,3 +1,30 @@
+2002-01-28  Stefan Rompf  <srompf@isg.de>,
+            Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+        * 21142.c (t21142_timer):  Use return value of
+        tulip_check_duplex() to indicate to system whether or not
+        carrier is present.  Use carrier presence/absence to determine
+        when next the 21142 media timer should check for link beat.
+
+        * timer (tulip_timer):  Un-comment-out calls to
+        netif_carrier_{on,off}, as there is now value in
+        reporting link beta information to userspace.
+
+2002-01-28  Pavel Roskin  <proski@gnu.org>
+
+	* tulip_core.c (tulip_init_one): Use tp->eeprom instead of
+	allocating a buffer for EEPROM copy on the stack.
+
+	* tulip_core.c: Add support for Conexant RS7112 (a.k.a. CN7112)
+	chip.
+	* tulip.h: Likewise.  Increase EEPROM_SIZE to 512 bytes to
+	accomodate EEPROM on Conexant RS7112.
+
+2002-02-07  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>
+
+        * tulip_core (tulip_pci_tbl[]):
+        Add PCI id for comet tulip clone.
+
 2001-12-11  Jeff Garzik  <jgarzik@mandrakesoft.com>
 
 	* eeprom.c, timer.c, media.c, tulip_core.c:
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index 53c4391..c67dd85 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -83,10 +83,10 @@
 					       medianame[mleaf->media & MEDIA_MASK]);
 				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
 					goto actually_mii;
-				/* netif_carrier_on(dev); */
+				netif_carrier_on(dev);
 				break;
 			}
-			/* netif_carrier_off(dev); */
+			netif_carrier_off(dev);
 			if (tp->medialock)
 				break;
 	  select_next_media:
@@ -110,11 +110,13 @@
 		}
 		case 1:  case 3:		/* 21140, 21142 MII */
 		actually_mii:
-			if (tulip_check_duplex(dev) < 0)
-				{ /* netif_carrier_off(dev); */ }
-			else
-				{ /* netif_carrier_on(dev); */ }
-			next_tick = 60*HZ;
+			if (tulip_check_duplex(dev) < 0) {
+				netif_carrier_off(dev);
+				next_tick = 3*HZ;
+			} else {
+				netif_carrier_on(dev);
+				next_tick = 60*HZ;
+			}
 			break;
 		case 2:					/* 21142 serial block has no link beat. */
 		default:
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 2171eb9..c39cb3c 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -84,6 +84,7 @@
 	COMPEX9881,
 	I21145,
 	DM910X,
+	CONEXANT,
 };
 
 
@@ -290,7 +291,7 @@
 #define DESC_RING_WRAP 0x02000000
 
 
-#define EEPROM_SIZE 128 	/* 2 << EEPROM_ADDRLEN */
+#define EEPROM_SIZE 512 	/* 2 << EEPROM_ADDRLEN */
 
 
 #define RUN_AT(x) (jiffies + (x))
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index b396f5b..9143deb 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -15,8 +15,8 @@
 */
 
 #define DRV_NAME	"tulip"
-#define DRV_VERSION	"1.1.0"
-#define DRV_RELDATE	"Dec 11, 2001"
+#define DRV_VERSION	"1.1.11"
+#define DRV_RELDATE	"Feb 08, 2002"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -185,6 +185,10 @@
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
 	tulip_timer },
+
+  /* RS7112 */
+  { "Conexant LANfinity", 256, 0x0001ebef,
+	HAS_MII | HAS_ACPI, tulip_timer },
 };
 
 
@@ -202,6 +206,7 @@
 	{ 0x1317, 0x1985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x13D1, 0xAB02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x13D1, 0xAB03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
@@ -211,6 +216,7 @@
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
 	{ } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -417,7 +423,7 @@
 		tp->csr6 = 0x01a80200;
 		outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
 		outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
-	} else if (tp->chip_id == COMET) {
+	} else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
 		/* Enable automatic Tx underrun recovery. */
 		outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
 		dev->if_port = tp->mii_cnt ? 11 : 0;
@@ -1253,7 +1259,7 @@
 	u8 chip_rev;
 	int i, irq;
 	unsigned short sum;
-	u8 ee_data[EEPROM_SIZE];
+	unsigned char *ee_data;
 	struct net_device *dev;
 	long ioaddr;
 	static int board_idx = -1;
@@ -1430,6 +1436,7 @@
 	   be polled, waiting for the value to be read bit serially from the
 	   EEPROM.
 	   */
+	ee_data = tp->eeprom;
 	sum = 0;
 	if (chip_idx == LC82C168) {
 		for (i = 0; i < 3; i++) {
@@ -1452,17 +1459,22 @@
 		int sa_offset = 0;
 		int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
 
-		for (i = 0; i < sizeof(ee_data)/2; i++)
+		for (i = 0; i < sizeof(tp->eeprom)/2; i++)
 			((u16 *)ee_data)[i] =
 				le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size));
 
 		/* DEC now has a specification (see Notes) but early board makers
 		   just put the address in the first EEPROM locations. */
-		/* This does  memcmp(eedata, eedata+16, 8) */
+		/* This does  memcmp(ee_data, ee_data+16, 8) */
 		for (i = 0; i < 8; i ++)
 			if (ee_data[i] != ee_data[16+i])
 				sa_offset = 20;
-		if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
+		if (chip_idx == CONEXANT) {
+			/* Check that the tuple type and length is correct. */
+			if (ee_data[0x198] == 0x04  &&  ee_data[0x199] == 6)
+				sa_offset = 0x19A;
+		} else if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&
+				   ee_data[2] == 0) {
 			sa_offset = 2;		/* Grrr, damn Matrox boards. */
 			multiport_cnt = 4;
 		}
@@ -1555,8 +1567,6 @@
 	}
 
 	if (tp->flags & HAS_MEDIA_TABLE) {
-		memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
-
 		sprintf(dev->name, "tulip%d", board_idx);	/* hack */
 		tulip_parse_eeprom(dev);
 		strcpy(dev->name, "eth%d");			/* un-hack */
diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c
index 514b57d..90055d1 100644
--- a/drivers/net/winbond-840.c
+++ b/drivers/net/winbond-840.c
@@ -347,7 +347,7 @@
 	struct w840_rx_desc *rx_ring;
 	dma_addr_t	rx_addr[RX_RING_SIZE];
 	struct w840_tx_desc *tx_ring;
-	dma_addr_t	tx_addr[RX_RING_SIZE];
+	dma_addr_t	tx_addr[TX_RING_SIZE];
 	dma_addr_t ring_dma_addr;
 	/* The addresses of receive-in-place skbuffs. */
 	struct sk_buff* rx_skbuff[RX_RING_SIZE];
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 875160b..7001c37 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -279,6 +279,11 @@
 		pci_readw(dev, PCI_DEVICE_ID, &dev->device);
 		dev->hdr_type = hdr & 0x7f;
 
+		dev->dev.parent = bus->dev;
+		strcpy(dev->dev.name, dev->name);
+		strcpy(dev->dev.bus_id, dev->slot_name);
+		device_register(&dev->dev);
+
 		pci_setup_device(dev);
 
 		/* FIXME: Do we need to enable the expansion ROM? */
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 1590354..f18bc7a 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -130,6 +130,7 @@
 static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
 {
 	int count;
+	char *buf;
 
 	while (bcount) {
 		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
@@ -138,7 +139,8 @@
 			return;
 		}
 		count = IDE_MIN (pc->sg->length - pc->b_count, bcount);
-		atapi_input_bytes (drive, pc->sg->address + pc->b_count, count);
+		buf = page_address(pc->sg->page) + pc->sg->offset;
+		atapi_input_bytes (drive, buf + pc->b_count, count);
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
 			pc->sg++;
@@ -150,6 +152,7 @@
 static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
 {
 	int count;
+	char *buf;
 
 	while (bcount) {
 		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
@@ -158,7 +161,8 @@
 			return;
 		}
 		count = IDE_MIN (pc->sg->length - pc->b_count, bcount);
-		atapi_output_bytes (drive, pc->sg->address + pc->b_count, count);
+		buf = page_address(pc->sg->page) + pc->sg->offset;
+		atapi_output_bytes (drive, buf + pc->b_count, count);
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
 			pc->sg++;
@@ -750,25 +754,11 @@
 		printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10);
 #endif /* IDESCSI_DEBUG_LOG */
 		while (segments--) {
-			struct page *page = sg->page;
-			int offset = sg->offset;
-
-			if (!page) {
-				BUG_ON(!sg->address);
-				page = virt_to_page(sg->address);
-				offset = (unsigned long) sg->address & ~PAGE_MASK;
-			}
-				
-			bh->bi_io_vec[0].bv_page = page;
+			bh->bi_io_vec[0].bv_page = sg->page;
 			bh->bi_io_vec[0].bv_len = sg->length;
-			bh->bi_io_vec[0].bv_offset = offset;
+			bh->bi_io_vec[0].bv_offset = sg->offset;
 			bh->bi_size = sg->length;
 			bh = bh->bi_next;
-			/*
-			 * just until scsi_merge is fixed up...
-			 */
-			BUG_ON(PageHighMem(page));
-			sg->address = page_address(page) + offset;
 			sg++;
 		}
 	} else {
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 62263c5..e590742 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -76,8 +76,6 @@
 #include <linux/version.h>
 #endif /* LINUX_VERSION_CODE */
 
-#define SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST
-
 #define SG_ALLOW_DIO_DEF 0
 #define SG_ALLOW_DIO_CODE	/* compile out be commenting this define */
 #ifdef SG_ALLOW_DIO_CODE
@@ -1714,9 +1712,6 @@
 						rem_sz;
 	sclp->page = kp->maplist[k];
 	sclp->offset = offset;
-#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST
-	sclp->address = page_address(kp->maplist[k]) + offset;
-#endif
 	sclp->length = num;
 	mem_src_arr[k] = SG_USER_MEM;
 	rem_sz -= num;
@@ -1804,9 +1799,6 @@
             }
             sclp->page = virt_to_page(p);
             sclp->offset = (unsigned long)p & ~PAGE_MASK;
-#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST
-            sclp->address = p;
-#endif
             sclp->length = ret_sz;
 	    mem_src_arr[k] = mem_src;
 
@@ -1967,9 +1959,6 @@
             sg_free(sg_scatg2virt(sclp), sclp->length, mem_src);
 	    sclp->page = NULL;
             sclp->offset = 0;
-#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST
-	    sclp->address = 0;
-#endif
             sclp->length = 0;
         }
 	sg_free(schp->buffer, schp->sglist_len, schp->buffer_mem_src);
diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c
index 9791d7a..d8b25ed 100644
--- a/drivers/sound/opl3sa2.c
+++ b/drivers/sound/opl3sa2.c
@@ -55,6 +55,7 @@
  *                         sb_card.c and awe_wave.c. (Dec 12, 2000)
  * Scott Murray            Some small cleanups to the init code output.
  *                         (Jan 7, 2001)
+ * Zwane Mwaikambo	   Added PM support. (Dec 4 2001)
  *
  */
 
@@ -62,13 +63,14 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/isapnp.h>
-
+#include <linux/pm.h>
 #include "sound_config.h"
 
 #include "ad1848.h"
 #include "mpu401.h"
 
 /* Useful control port indexes: */
+#define OPL3SA2_PM	     0x01
 #define OPL3SA2_SYS_CTRL     0x02
 #define OPL3SA2_IRQ_CONFIG   0x03
 #define OPL3SA2_DMA_CONFIG   0x06
@@ -86,6 +88,11 @@
 #define DEFAULT_MIC    50
 #define DEFAULT_TIMBRE 0
 
+/* Power saving modes */
+#define OPL3SA2_PM_MODE1	0x05
+#define OPL3SA2_PM_MODE2	0x04
+#define OPL3SA2_PM_MODE3	0x03
+
 /* For checking against what the card returns: */
 #define VERSION_UNKNOWN 0
 #define VERSION_YMF711  1
@@ -121,6 +128,10 @@
 typedef struct opl3sa2_mixerdata_tag {
 	unsigned short cfg_port;
 	unsigned short padding;
+	unsigned char  reg;
+	unsigned int   in_suspend;
+	struct pm_dev  *pmdev;
+	unsigned int   card;
 	unsigned int   volume_l;
 	unsigned int   volume_r;
 	unsigned int   mic;
@@ -328,6 +339,20 @@
 }
 
 
+static void opl3sa2_mixer_restore(opl3sa2_mixerdata* devc, int card)
+{
+	if (devc) {
+		opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
+		opl3sa2_set_mic(devc, devc->mic);
+
+		if (chipset[card] == CHIPSET_OPL3SA3) {
+			opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
+			opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
+		}
+	}
+}
+
+
 static inline void arg_to_vol_mono(unsigned int vol, int* value)
 {
 	int left;
@@ -892,6 +917,77 @@
 
 /* End of component functions */
 
+/* Power Management support functions */
+static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode)
+{
+	unsigned long flags;
+	opl3sa2_mixerdata *p;
+
+	if (!pdev)
+		return -EINVAL;
+
+	save_flags(flags);
+	cli();
+
+	p = (opl3sa2_mixerdata *) pdev->data;
+	p->in_suspend = 1;
+	switch (pm_mode) {
+	case 1:
+		pm_mode = OPL3SA2_PM_MODE1;
+		break;
+	case 2:
+		pm_mode = OPL3SA2_PM_MODE2;
+		break;
+	case 3:
+		pm_mode = OPL3SA2_PM_MODE3;
+		break;
+	default:
+		pm_mode = OPL3SA2_PM_MODE3;
+		break;
+	}
+
+	/* its supposed to automute before suspending, so we wont bother */
+	opl3sa2_read(p->cfg_port, OPL3SA2_PM, &p->reg);
+	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->reg | pm_mode);
+
+	restore_flags(flags);
+	return 0;
+}
+
+static int opl3sa2_resume(struct pm_dev *pdev)
+{
+	unsigned long flags;
+	opl3sa2_mixerdata *p;
+
+	if (!pdev)
+		return -EINVAL;
+
+	p = (opl3sa2_mixerdata *) pdev->data;
+	save_flags(flags);
+	cli();
+
+	/* I don't think this is necessary */
+	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->reg);
+	opl3sa2_mixer_restore(p, p->card);
+	p->in_suspend = 0;
+
+	restore_flags(flags);
+	return 0;
+}
+
+static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
+{
+	unsigned char mode = (unsigned  char)data;
+
+	switch (rqst) {
+		case PM_SUSPEND:
+			return opl3sa2_suspend(pdev, mode);
+
+		case PM_RESUME:
+			return opl3sa2_resume(pdev);
+	}
+	return 0;
+}
 
 /*
  * Install OPL3-SA2 based card(s).
@@ -989,6 +1085,12 @@
 		attach_opl3sa2_mss(&cfg_mss[card]);
 		attach_opl3sa2_mixer(&cfg[card], card);
 
+		opl3sa2_data[card].card = card;
+		/* register our power management capabilities */
+		opl3sa2_data[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
+		if (opl3sa2_data[card].pmdev)
+			opl3sa2_data[card].pmdev->data = &opl3sa2_data[card];
+
 		/*
 		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
 		 * it's supported.
@@ -1033,6 +1135,9 @@
 	int card;
 
 	for(card = 0; card < opl3sa2_cards_num; card++) {
+		if (opl3sa2_data[card].pmdev)
+			pm_unregister(opl3sa2_data[card].pmdev);
+
 	        if(cfg_mpu[card].slots[1] != -1) {
 			unload_opl3sa2_mpu(&cfg_mpu[card]);
 		}
diff --git a/drivers/usb/ibmcam.h b/drivers/usb/ibmcam.h
deleted file mode 100644
index 6a5e1cd..0000000
--- a/drivers/usb/ibmcam.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Header file for USB IBM C-It Video Camera driver.
- *
- * Supports IBM C-It Video Camera.
- *
- * This driver is based on earlier work of:
- *
- * (C) Copyright 1999 Johannes Erdfelt
- * (C) Copyright 1999 Randy Dunlap
- */
-
-#ifndef __LINUX_IBMCAM_H
-#define __LINUX_IBMCAM_H
-
-#include <linux/list.h>
-
-#define USES_IBMCAM_PUTPIXEL    0       /* 0=Fast/oops 1=Slow/secure */
-
-/* Video Size 384 x 288 x 3 bytes for RGB */
-/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
-#define V4L_FRAME_WIDTH         384
-#define V4L_FRAME_WIDTH_USED	352
-#define V4L_FRAME_HEIGHT        288
-#define V4L_BYTES_PER_PIXEL     3
-#define MAX_FRAME_SIZE          (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL)
-
-/* Camera capabilities (maximum) */
-#define CAMERA_IMAGE_WIDTH      352
-#define CAMERA_IMAGE_HEIGHT     288
-#define CAMERA_IMAGE_LINE_SZ    ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */
-#define CAMERA_URB_FRAMES       32
-#define CAMERA_MAX_ISO_PACKET   1023 /* 1022 actually sent by camera */
-
-#define IBMCAM_NUMFRAMES	2
-#define IBMCAM_NUMSBUF		2
-
-#define FRAMES_PER_DESC		(CAMERA_URB_FRAMES)
-#define FRAME_SIZE_PER_DESC	(CAMERA_MAX_ISO_PACKET)
-
-/* This macro restricts an int variable to an inclusive range */
-#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
-
-/*
- * This macro performs bounds checking - use it when working with
- * new formats, or else you may get oopses all over the place.
- * If pixel falls out of bounds then it gets shoved back (as close
- * to place of offence as possible) and is painted bright red.
- */
-#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \
-	register unsigned char *pf; \
-	int limiter = 0, mx, my; \
-	mx = ix; \
-	my = iy; \
-	if (mx < 0) { \
-		mx=0; \
-		limiter++; \
-	} else if (mx >= 352) { \
-		mx=351; \
-		limiter++; \
-	} \
-	if (my < 0) { \
-		my = 0; \
-		limiter++; \
-	} else if (my >= V4L_FRAME_HEIGHT) { \
-		my = V4L_FRAME_HEIGHT - 1; \
-		limiter++; \
-	} \
-	pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \
-	if (limiter) { \
-		*pf++ = 0; \
-		*pf++ = 0; \
-		*pf++ = 0xFF; \
-	} else { \
-		*pf++ = (vb); \
-		*pf++ = (vg); \
-		*pf++ = (vr); \
-	} \
-}
-
-/*
- * We use macros to do YUV -> RGB conversion because this is
- * very important for speed and totally unimportant for size.
- *
- * YUV -> RGB Conversion
- * ---------------------
- *
- * B = 1.164*(Y-16)		    + 2.018*(V-128)
- * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
- * R = 1.164*(Y-16) + 1.596*(U-128)
- *
- * If you fancy integer arithmetics (as you should), hear this:
- *
- * 65536*B = 76284*(Y-16)		  + 132252*(V-128)
- * 65536*G = 76284*(Y-16) -  53281*(U-128) -  25625*(V-128)
- * 65536*R = 76284*(Y-16) + 104595*(U-128)
- *
- * Make sure the output values are within [0..255] range.
- */
-#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
-#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
-    int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
-    mm_y = (my) - 16;  \
-    mm_u = (mu) - 128; \
-    mm_v = (mv) - 128; \
-    mm_yc= mm_y * 76284; \
-    mm_b = (mm_yc		+ 132252*mm_v	) >> 16; \
-    mm_g = (mm_yc -  53281*mm_u -  25625*mm_v	) >> 16; \
-    mm_r = (mm_yc + 104595*mm_u			) >> 16; \
-    mb = LIMIT_RGB(mm_b); \
-    mg = LIMIT_RGB(mm_g); \
-    mr = LIMIT_RGB(mm_r); \
-}
-
-/* Debugging aid */
-#define IBMCAM_SAY_AND_WAIT(what) { \
-	wait_queue_head_t wq; \
-	init_waitqueue_head(&wq); \
-	printk(KERN_INFO "Say: %s\n", what); \
-	interruptible_sleep_on_timeout (&wq, HZ*3); \
-}
-
-/*
- * This macro checks if ibmcam is still operational. The 'ibmcam'
- * pointer must be valid, ibmcam->dev must be valid, we are not
- * removing the device and the device has not erred on us.
- */
-#define IBMCAM_IS_OPERATIONAL(ibm_cam) (\
-	(ibm_cam != NULL) && \
-	((ibm_cam)->dev != NULL) && \
-	((ibm_cam)->last_error == 0) && \
-	(!(ibm_cam)->remove_pending))
-
-enum {
-	STATE_SCANNING,		/* Scanning for header */
-	STATE_LINES,		/* Parsing lines */
-};
-
-enum {
-	FRAME_UNUSED,		/* Unused (no MCAPTURE) */
-	FRAME_READY,		/* Ready to start grabbing */
-	FRAME_GRABBING,		/* In the process of being grabbed into */
-	FRAME_DONE,		/* Finished grabbing, but not been synced yet */
-	FRAME_ERROR,		/* Something bad happened while processing */
-};
-
-struct usb_device;
-
-struct ibmcam_sbuf {
-	char *data;
-	struct urb *urb;
-};
-
-struct ibmcam_frame {
-	char *data;		/* Frame buffer */
-	int order_uv;		/* True=UV False=VU */
-	int order_yc;		/* True=Yc False=cY ('c'=either U or V) */
-	unsigned char hdr_sig;	/* "00 FF 00 ??" where 'hdr_sig' is '??' */
-
-	int width;		/* Width application is expecting */
-	int height;		/* Height */
-
-	int frmwidth;		/* Width the frame actually is */
-	int frmheight;		/* Height */
-
-	volatile int grabstate;	/* State of grabbing */
-	int scanstate;		/* State of scanning */
-
-	int curline;		/* Line of frame we're working on */
-
-	long scanlength;	/* uncompressed, raw data length of frame */
-	long bytes_read;	/* amount of scanlength that has been read from *data */
-
-	wait_queue_head_t wq;	/* Processes waiting */
-};
-
-#define	IBMCAM_MODEL_1	1	/* XVP-501, 3 interfaces, rev. 0.02 */
-#define IBMCAM_MODEL_2	2	/* KSX-X9903, 2 interfaces, rev. 3.0a */
-
-struct usb_ibmcam {
-	struct video_device vdev;
-
-	/* Device structure */
-	struct usb_device *dev;
-
-	unsigned char iface;                            /* Video interface number */
-	unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
-
-	struct semaphore lock;
-	int user;		/* user count for exclusive use */
-
-	int ibmcam_used;        /* Is this structure in use? */
-	int initialized;	/* Had we already sent init sequence? */
-	int camera_model;	/* What type of IBM camera we got? */
-	int streaming;		/* Are we streaming Isochronous? */
-	int grabbing;		/* Are we grabbing? */
-	int last_error;		/* What calamity struck us? */
-
-	int compress;		/* Should the next frame be compressed? */
-
-	char *fbuf;		/* Videodev buffer area */
-	int fbuf_size;		/* Videodev buffer size */
-
-	int curframe;
-	struct ibmcam_frame frame[IBMCAM_NUMFRAMES];	/* Double buffering */
-
-	int cursbuf;		/* Current receiving sbuf */
-	struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF];	/* Double buffering */
-	volatile int remove_pending;	/* If set then about to exit */
-
-        /*
-	 * Scratch space from the Isochronous pipe.
-	 * Scratch buffer should contain at least one pair of lines
-	 * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here.
-	 * This will be approximately 2 KB. HOWEVER in reality this
-	 * buffer must be as large as hundred of KB because otherwise
-	 * you'll get lots of overflows because V4L client may request
-	 * frames not as uniformly as USB sources them.
-	 */
-	unsigned char *scratch;
-	int scratchlen;
-
-	struct video_picture vpic, vpic_old;	/* Picture settings */
-	struct video_capability vcap;		/* Video capabilities */
-	struct video_channel vchan;	/* May be used for tuner support */
-	unsigned char video_endp;	/* 0x82 for IBM camera */
-        int has_hdr;
-        int frame_num;
-	int iso_packet_len;		/* Videomode-dependent, saves bus bandwidth */
-
-	/* Statistics that can be overlayed on screen */
-        unsigned long urb_count;        /* How many URBs we received so far */
-        unsigned long urb_length;       /* Length of last URB */
-        unsigned long data_count;       /* How many bytes we received */
-        unsigned long header_count;     /* How many frame headers we found */
-	unsigned long scratch_ovf_count;/* How many times we overflowed scratch */
-	unsigned long iso_skip_count;	/* How many empty ISO packets received */
-	unsigned long iso_err_count;	/* How many bad ISO packets received */
-};
-
-#endif /* __LINUX_IBMCAM_H */
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index 1d92c99..513ab3f 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -121,14 +121,14 @@
 	 if [ "$CONFIG_FB_MATROX" != "n" ]; then
 	    bool '    Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM
 	    bool '    Mystique support' CONFIG_FB_MATROX_MYSTIQUE
-	    bool '    G100/G200/G400/G450 support' CONFIG_FB_MATROX_G100
+	    bool '    G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G100
             if [ "$CONFIG_I2C" != "n" ]; then
 	       dep_tristate '      Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT
 	       if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then
 	          dep_tristate '      G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C
 	       fi
             fi
-            dep_tristate '      G450 second head support' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
+            dep_tristate '      G450/G550 second head support' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
 	    bool '    Multihead support' CONFIG_FB_MATROX_MULTIHEAD
 	 fi
 	 tristate '  ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
diff --git a/fs/Config.in b/fs/Config.in
index 23796ba..ff38501 100644
--- a/fs/Config.in
+++ b/fs/Config.in
@@ -8,9 +8,9 @@
 tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
 tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS
 
-dep_tristate 'Reiserfs support' CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL
-dep_mbool '  Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL
-dep_mbool '  Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL
+tristate 'Reiserfs support' CONFIG_REISERFS_FS
+dep_mbool '  Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS
+dep_mbool '  Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS
 
 dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
 dep_mbool '  ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index adce085..8a0ce05 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -346,7 +346,7 @@
 	return discsize;
 }
 
-struct super_block *adfs_read_super(struct super_block *sb, void *data, int silent)
+static int adfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct adfs_discrecord *dr;
 	struct buffer_head *bh;
@@ -467,15 +467,26 @@
 		goto error;
 	} else
 		sb->s_root->d_op = &adfs_dentry_operations;
-	return sb;
+	return 0;
 
 error_free_bh:
 	brelse(bh);
 error:
-	return NULL;
+	return -EINVAL;
 }
 
-static DECLARE_FSTYPE_DEV(adfs_fs_type, "adfs", adfs_read_super);
+static struct super_block *adfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
+}
+
+static struct file_system_type adfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"adfs",
+	get_sb:		adfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_adfs_fs(void)
 {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index e824a71..ecf11f3 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -265,8 +265,7 @@
  * hopefully have the guts to do so. Until then: sorry for the mess.
  */
 
-static struct super_block *
-affs_read_super(struct super_block *sb, void *data, int silent)
+static int affs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct buffer_head	*root_bh = NULL;
 	struct buffer_head	*boot_bh;
@@ -294,7 +293,7 @@
 				&blocksize,&AFFS_SB->s_prefix,
 				AFFS_SB->s_volume, &mount_flags)) {
 		printk(KERN_ERR "AFFS: Error parsing options\n");
-		return NULL;
+		return -EINVAL;
 	}
 	/* N.B. after this point s_prefix must be released */
 
@@ -462,7 +461,7 @@
 	sb->s_root->d_op = &affs_dentry_operations;
 
 	pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
-	return sb;
+	return 0;
 
 	/*
 	 * Begin the cascaded cleanup ...
@@ -475,7 +474,7 @@
 	affs_brelse(root_bh);
 	if (AFFS_SB->s_prefix)
 		kfree(AFFS_SB->s_prefix);
-	return NULL;
+	return -EINVAL;
 }
 
 static int
@@ -533,7 +532,18 @@
 	return 0;
 }
 
-static DECLARE_FSTYPE_DEV(affs_fs_type, "affs", affs_read_super);
+static struct super_block *affs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super);
+}
+
+static struct file_system_type affs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"affs",
+	get_sb:		affs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_affs_fs(void)
 {
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index ee3a64b..7c3f0d5 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -279,8 +279,7 @@
 #endif
 }
 
-static struct super_block * bfs_read_super(struct super_block * s, 
-	void * data, int silent)
+static int bfs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct buffer_head * bh;
 	struct bfs_super_block * bfs_sb;
@@ -355,14 +354,25 @@
 		s->s_dirt = 1;
 	} 
 	dump_imap("read_super", s);
-	return s;
+	return 0;
 
 out:
 	brelse(bh);
-	return NULL;
+	return -EINVAL;
 }
 
-static DECLARE_FSTYPE_DEV(bfs_fs_type, "bfs", bfs_read_super);
+static struct super_block *bfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super);
+}
+
+static struct file_system_type bfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"bfs",
+	get_sb:		bfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_bfs_fs(void)
 {
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 2132104..66dcaa6 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -188,12 +188,11 @@
 }
 			
 
-static struct super_block * cramfs_read_super(struct super_block *sb, void *data, int silent)
+static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	int i;
 	struct cramfs_super super;
 	unsigned long root_offset;
-	struct super_block * retval = NULL;
 
 	sb_set_blocksize(sb, PAGE_CACHE_SIZE);
 
@@ -252,9 +251,9 @@
 	/* Set it all up.. */
 	sb->s_op = &cramfs_ops;
 	sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
-	retval = sb;
+	return 0;
 out:
-	return retval;
+	return -EINVAL;
 }
 
 static int cramfs_statfs(struct super_block *sb, struct statfs *buf)
@@ -442,7 +441,18 @@
 	statfs:		cramfs_statfs,
 };
 
-static DECLARE_FSTYPE_DEV(cramfs_fs_type, "cramfs", cramfs_read_super);
+static struct super_block *cramfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super);
+}
+
+static struct file_system_type cramfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"cramfs",
+	get_sb:		cramfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_cramfs_fs(void)
 {
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
index 54e35bc..9502dc7 100644
--- a/fs/driverfs/inode.c
+++ b/fs/driverfs/inode.c
@@ -245,6 +245,9 @@
 	if (!entry->show)
 		return 0;
 
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+
 	dev = list_entry(entry->parent,struct device, dir);
 
 	page = (unsigned char*)__get_free_page(GFP_KERNEL);
@@ -260,7 +263,8 @@
 			if (len < 0)
 				retval = len;
 			break;
-		}
+		} else if (len > count)
+			len = count;
 
 		if (copy_to_user(buf,page,len)) {
 			retval = -EFAULT;
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 541d86f..7605c75 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -14,7 +14,18 @@
 #include <linux/efs_fs_sb.h>
 #include <linux/slab.h>
 
-static DECLARE_FSTYPE_DEV(efs_fs_type, "efs", efs_read_super);
+static struct super_block *efs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super);
+}
+
+static struct file_system_type efs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"efs",
+	get_sb:		efs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static kmem_cache_t * efs_inode_cachep;
 
@@ -188,7 +199,8 @@
 	return 0;    
 }
 
-struct super_block *efs_read_super(struct super_block *s, void *d, int silent) {
+int efs_fill_super(struct super_block *s, void *d, int silent)
+{
 	struct efs_sb_info *sb;
 	struct buffer_head *bh;
 
@@ -246,11 +258,11 @@
 		goto out_no_fs;
 	}
 
-	return(s);
+	return 0;
 
 out_no_fs_ul:
 out_no_fs:
-	return(NULL);
+	return -EINVAL;
 }
 
 int efs_statfs(struct super_block *s, struct statfs *buf) {
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 013bb13..24ddd1d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -934,8 +934,7 @@
 	return res;
 }
 
-struct super_block * ext3_read_super (struct super_block * sb, void * data,
-				      int silent)
+static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 {
 	struct buffer_head * bh;
 	struct ext3_super_block *es = 0;
@@ -1054,7 +1053,7 @@
 		if (!bh) {
 			printk(KERN_ERR 
 			       "EXT3-fs: Can't read superblock on 2nd try.\n");
-			return NULL;
+			return -EINVAL;
 		}
 		es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);
 		sbi->s_es = es;
@@ -1252,7 +1251,7 @@
 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
 		"writeback");
 
-	return sb;
+	return 0;
 
 failed_mount3:
 	journal_destroy(sbi->s_journal);
@@ -1264,7 +1263,7 @@
 	ext3_blkdev_remove(sbi);
 	brelse(bh);
 out_fail:
-	return NULL;
+	return -EINVAL;
 }
 
 static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
@@ -1769,7 +1768,18 @@
 	return 0;
 }
 
-static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super);
+static struct super_block *ext3_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super);
+}
+
+static struct file_system_type ext3_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"ext3",
+	get_sb:		ext3_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_ext3_fs(void)
 {
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 768e91b..8658b3c 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -135,8 +135,7 @@
  * Locking:
  *   We are under the bkl and @sbp->s_lock.
  */
-static struct super_block *
-vxfs_read_super(struct super_block *sbp, void *dp, int silent)
+static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 {
 	struct vxfs_sb_info	*infp;
 	struct vxfs_sb		*rsbp;
@@ -146,7 +145,7 @@
 	infp = kmalloc(sizeof(*infp), GFP_KERNEL);
 	if (!infp) {
 		printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(infp, 0, sizeof(*infp));
 
@@ -213,7 +212,7 @@
 		goto out_free_ilist;
 	}
 
-	return (sbp);
+	return 0;
 	
 out_free_ilist:
 	vxfs_put_fake_inode(infp->vsi_fship);
@@ -222,13 +221,24 @@
 out:
 	brelse(bp);
 	kfree(infp);
-	return NULL;
+	return -EINVAL;
 }
 
 /*
  * The usual module blurb.
  */
-static DECLARE_FSTYPE_DEV(vxfs_fs_type, "vxfs", vxfs_read_super);
+static struct super_block *vxfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
+}
+
+static struct file_system_type vxfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"vxfs",
+	get_sb:		vxfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init
 vxfs_init(void)
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 9ac627b..2d27494 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -95,7 +95,18 @@
 
 /*================ File-local variables ================*/
 
-static DECLARE_FSTYPE_DEV(hfs_fs, "hfs", hfs_read_super);
+static struct super_block *hfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super);
+}
+
+static struct file_system_type hfs_fs = {
+	owner:		THIS_MODULE,
+	name:		"hfs",
+	get_sb:		hfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 /*================ File-local functions ================*/
 
@@ -429,8 +440,7 @@
  * hfs_btree_init() to get the necessary data about the extents and
  * catalog B-trees and, finally, reading the root inode into memory.
  */
-struct super_block *hfs_read_super(struct super_block *s, void *data,
-				   int silent)
+int hfs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct hfs_mdb *mdb;
 	struct hfs_cat_key key;
@@ -501,7 +511,7 @@
 	s->s_root->d_op = &hfs_dentry_operations;
 
 	/* everything's okay */
-	return s;
+	return 0;
 
 bail_no_root: 
 	hfs_warn("hfs_fs: get root inode failed.\n");
@@ -511,7 +521,7 @@
 bail2:
 	set_blocksize(dev, BLOCK_SIZE);
 bail3:
-	return NULL;	
+	return -EINVAL;	
 }
 
 static int __init init_hfs_fs(void)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 3d59f27..4cc04ff 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -405,8 +405,7 @@
 	return 0;
 }
 
-struct super_block *hpfs_read_super(struct super_block *s, void *options,
-				    int silent)
+static int hpfs_fill_super(struct super_block *s, void *options, int silent)
 {
 	struct buffer_head *bh0, *bh1, *bh2;
 	struct hpfs_boot_block *bootblock;
@@ -598,7 +597,7 @@
 	}
 	if (de) hpfs_brelse4(&qbh);
 
-	return s;
+	return 0;
 
 bail4:	brelse(bh2);
 bail3:	brelse(bh1);
@@ -607,10 +606,21 @@
 bail0:
 	if (s->s_hpfs_bmp_dir) kfree(s->s_hpfs_bmp_dir);
 	if (s->s_hpfs_cp_table) kfree(s->s_hpfs_cp_table);
-	return NULL;
+	return -EINVAL;
 }
 
-DECLARE_FSTYPE_DEV(hpfs_fs_type, "hpfs", hpfs_read_super);
+static struct super_block *hpfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super);
+}
+
+static struct file_system_type hpfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"hpfs",
+	get_sb:		hpfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_hpfs_fs(void)
 {
diff --git a/fs/inflate_fs/infutil.h b/fs/inflate_fs/infutil.h
index cc219ac..5c90a27 100644
--- a/fs/inflate_fs/infutil.h
+++ b/fs/inflate_fs/infutil.h
@@ -11,7 +11,7 @@
 #ifndef _INFUTIL_H
 #define _INFUTIL_H
 
-#include "zconf.h"
+#include <linux/zconf.h>
 #include "inftrees.h"
 #include "infcodes.h"
 
diff --git a/fs/inflate_fs/zconf.h b/fs/inflate_fs/zconf.h
deleted file mode 100644
index 0b5ec88..0000000
--- a/fs/inflate_fs/zconf.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* @(#) $Id$ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-#if defined(__GNUC__) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
-#  endif
-#endif
-
-#if defined(__STDC__) || defined(__cplusplus)
-#  ifndef STDC
-#    define STDC
-#  endif
-#endif
-
-/* The memory requirements for deflate are (in bytes):
-            (1 << (windowBits+2)) +  (1 << (memLevel+9))
- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
-   The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-#  define MAX_MEM_LEVEL 9
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-#  define MAX_WBITS   15 /* 32K LZ77 window */
-#endif
-
-                        /* Type declarations */
-
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-#ifndef ZEXPORT
-#  define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-#  define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-#  define ZEXTERN extern
-#endif
-#ifndef FAR
-#   define FAR
-#endif
-
-typedef unsigned char  Byte;  /* 8 bits */
-typedef unsigned int   uInt;  /* 16 bits or more */
-typedef unsigned long  uLong; /* 32 bits or more */
-
-typedef Byte  FAR Bytef;
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-typedef void FAR *voidpf;
-typedef void     *voidp;
-
-#include <linux/types.h> /* for off_t */
-#include <linux/unistd.h>    /* for SEEK_* and off_t */
-#define z_off_t  off_t
-
-#endif /* _ZCONF_H */
diff --git a/fs/intermezzo/super.c b/fs/intermezzo/super.c
index a60d869..2b011f1 100644
--- a/fs/intermezzo/super.c
+++ b/fs/intermezzo/super.c
@@ -452,12 +452,13 @@
 
 struct file_system_type presto_fs_type = {
 #ifdef PRESTO_DEVEL
-	name: "izofs",
+        "izofs",
 #else 
-	name: "intermezzo",
+        "intermezzo",
 #endif
-	fs_flags: FS_REQUIRES_DEV, /* can use Ibaskets when ext2 does */
-	read_super: presto_read_super
+        FS_REQUIRES_DEV, /* can use Ibaskets when ext2 does */
+        presto_read_super,
+        NULL
 };
 
 
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 939748c..66ea867 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -510,8 +510,7 @@
  * Note: a check_disk_change() has been done immediately prior
  * to this call, so we don't need to check again.
  */
-static struct super_block *isofs_read_super(struct super_block *s, void *data,
-					    int silent)
+static int isofs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct buffer_head	      * bh = NULL, *pri_bh = NULL;
 	struct hs_primary_descriptor  * h_pri = NULL;
@@ -843,16 +842,16 @@
 	if (opt.check == 'r') table++;
 	s->s_root->d_op = &isofs_dentry_ops[table];
 
-	return s;
+	return 0;
 
 	/*
 	 * Display error messages and free resources.
 	 */
 out_bad_root:
-	printk(KERN_WARNING "isofs_read_super: root inode not initialized\n");
+	printk(KERN_WARNING "isofs_fill_super: root inode not initialized\n");
 	goto out_iput;
 out_no_root:
-	printk(KERN_WARNING "isofs_read_super: get root inode failed\n");
+	printk(KERN_WARNING "isofs_fill_super: get root inode failed\n");
 out_iput:
 	iput(inode);
 #ifdef CONFIG_JOLIET
@@ -861,7 +860,7 @@
 #endif
 	goto out_unlock;
 out_no_read:
-	printk(KERN_WARNING "isofs_read_super: "
+	printk(KERN_WARNING "isofs_fill_super: "
 		"bread failed, dev=%s, iso_blknum=%d, block=%d\n",
 		s->s_id, iso_blknum, block);
 	goto out_unlock;
@@ -885,7 +884,7 @@
 out_freebh:
 	brelse(bh);
 out_unlock:
-	return NULL;
+	return -EINVAL;
 }
 
 static int isofs_statfs (struct super_block *sb, struct statfs *buf)
@@ -1395,7 +1394,18 @@
 
 #endif
 
-static DECLARE_FSTYPE_DEV(iso9660_fs_type, "iso9660", isofs_read_super);
+static struct super_block *isofs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
+}
+
+static struct file_system_type iso9660_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"iso9660",
+	get_sb:		isofs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_iso9660_fs(void)
 {
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index db71f74..2bc47cf 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -71,8 +71,7 @@
 kmem_cache_t     *fm_cache = NULL;
 
 /* Called by the VFS at mount time to initialize the whole file system.  */
-static struct super_block *
-jffs_read_super(struct super_block *sb, void *data, int silent)
+static int jffs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	kdev_t dev = sb->s_dev;
 	struct inode *root_inode;
@@ -84,7 +83,7 @@
 	if (major(dev) != MTD_BLOCK_MAJOR) {
 		printk(KERN_WARNING "JFFS: Trying to mount a "
 		       "non-mtd device.\n");
-		return 0;
+		return -EINVAL;
 	}
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -145,7 +144,7 @@
 
 	D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n",
 	       sb->s_id));
-	return sb;
+	return 0;
 
 jffs_sb_err3:
 	iput(root_inode);
@@ -154,7 +153,7 @@
 jffs_sb_err1:
 	printk(KERN_WARNING "JFFS: Failed to mount device %s.\n",
 	       sb->s_id);
-	return 0;
+	return -EINVAL;
 }
 
 
@@ -1730,8 +1729,18 @@
 	statfs:       jffs_statfs,
 };
 
+static struct super_block *jffs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super);
+}
 
-static DECLARE_FSTYPE_DEV(jffs_fs_type, "jffs", jffs_read_super);
+static struct file_system_type jffs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"jffs",
+	get_sb:		jffs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init
 init_jffs_fs(void)
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 884bc8a..05f1185 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -195,7 +195,7 @@
 	return 0;
 }
 
-static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
+static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct jffs2_sb_info *c;
 	struct inode *root_i;
@@ -206,7 +206,7 @@
 	if (major(sb->s_dev) != MTD_BLOCK_MAJOR) {
 		if (!silent)
 			printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
-		return NULL;
+		return -EINVAL;
 	}
 
 	c = JFFS2_SB_INFO(sb);
@@ -215,7 +215,7 @@
 	c->mtd = get_mtd_device(NULL, minor(sb->s_dev));
 	if (!c->mtd) {
 		D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)));
-		return NULL;
+		return -EINVAL;
 	}
 	c->sector_size = c->mtd->erasesize;
 	c->free_size = c->flash_size = c->mtd->size;
@@ -275,7 +275,7 @@
 	sb->s_magic = JFFS2_SUPER_MAGIC;
 	if (!(sb->s_flags & MS_RDONLY))
 		jffs2_start_garbage_collect_thread(c);
-	return sb;
+	return 0;
 
  out_root_i:
 	iput(root_i);
@@ -285,7 +285,7 @@
 	kfree(c->blocks);
  out_mtd:
 	put_mtd_device(c->mtd);
-	return NULL;
+	return -EINVAL;
 }
 
 void jffs2_put_super (struct super_block *sb)
@@ -340,8 +340,18 @@
 	jffs2_mark_erased_blocks(c);
 }
 
+static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, jffs2_fill_super);
+}
 
-static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
+static struct file_system_type jffs2_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"jffs2",
+	get_sb:		jffs2_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_jffs2_fs(void)
 {
diff --git a/fs/msdos/msdosfs_syms.c b/fs/msdos/msdosfs_syms.c
index 4dc34bf..a37c99f 100644
--- a/fs/msdos/msdosfs_syms.c
+++ b/fs/msdos/msdosfs_syms.c
@@ -25,7 +25,18 @@
 EXPORT_SYMBOL(msdos_unlink);
 EXPORT_SYMBOL(msdos_put_super);
 
-static DECLARE_FSTYPE_DEV(msdos_fs_type, "msdos", msdos_read_super);
+static struct super_block *msdos_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super);
+}
+
+static struct file_system_type msdos_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"msdos",
+	get_sb:		msdos_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_msdos_fs(void)
 {
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 28d0caa..6b136aa 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -579,21 +579,21 @@
 	setattr:	fat_notify_change,
 };
 
-struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent)
+int msdos_fill_super(struct super_block *sb,void *data, int silent)
 {
 	struct super_block *res;
 
 	MSDOS_SB(sb)->options.isvfat = 0;
 	res = fat_read_super(sb, data, silent, &msdos_dir_inode_operations);
 	if (IS_ERR(res))
-		return NULL;
+		return PTR_ERR(res);
 	if (res == NULL) {
 		if (!silent)
 			printk(KERN_INFO "VFS: Can't find a valid"
 			       " MSDOS filesystem on dev %s.\n", sb->s_id);
-		return NULL;
+		return -EINVAL;
 	}
 
 	sb->s_root->d_op = &msdos_dentry_operations;
-	return res;
+	return 0;
 }
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 617f182..51fbb9b 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -453,7 +453,7 @@
 
 /*
  *  Get the NFS port numbers and file handle, and return the prepared 'data'
- *  argument for ->read_super() if everything went OK. Return NULL otherwise.
+ *  argument for mount() if everything went OK. Return NULL otherwise.
  */
 void * __init nfs_root_data(void)
 {
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a4a6d4c..03c7735 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/stat.h>
 #include <linux/in.h>
+#include <linux/seq_file.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -32,10 +33,9 @@
 typedef struct svc_client	svc_client;
 typedef struct svc_export	svc_export;
 
-static svc_export *	exp_find(svc_client *clp, kdev_t dev);
-static svc_export *	exp_parent(svc_client *clp, kdev_t dev,
+static svc_export *	exp_parent(svc_client *clp, struct super_block *sb,
 					struct dentry *dentry);
-static svc_export *	exp_child(svc_client *clp, kdev_t dev,
+static svc_export *	exp_child(svc_client *clp, struct super_block *sb,
 					struct dentry *dentry);
 static void		exp_unexport_all(svc_client *clp);
 static void		exp_do_unexport(svc_export *unexp);
@@ -66,40 +66,43 @@
 static int			hash_count;
 static DECLARE_WAIT_QUEUE_HEAD(	hash_wait );
 
-
-/*
- * Find a client's export for a device.
- */
-static inline svc_export *
-exp_find(svc_client *clp, kdev_t dev)
-{
-	svc_export *	exp;
-
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	while (exp && !kdev_same(exp->ex_dev, dev))
-		exp = exp->ex_next;
-	return exp;
-}
-
 /*
  * Find the client's export entry matching xdev/xino.
  */
 svc_export *
 exp_get(svc_client *clp, kdev_t dev, ino_t ino)
 {
-	svc_export *	exp;
+	struct list_head *head, *p;
+	svc_export *exp = NULL;
 
 	if (!clp)
 		return NULL;
 
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	if (exp)
-		do {
-			if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
-				goto out;
-		} while (NULL != (exp = exp->ex_next));
-	exp = NULL;
-out:
+	head = &clp->cl_export[EXPORT_HASH(dev)];
+	list_for_each(p, head) {
+		exp = list_entry(p, svc_export, ex_hash);
+		if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
+			break;
+	}
+	return exp;
+}
+
+svc_export *
+exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry)
+{
+	struct list_head *head, *p;
+	int hash = EXPORT_HASH(mnt->mnt_sb->s_dev);
+	svc_export *exp = NULL;
+
+	if (!clp)
+		return NULL;
+
+	head = &clp->cl_export[hash];
+	list_for_each(p, head) {
+		exp = list_entry(p, svc_export, ex_hash);
+		if (exp->ex_dentry == dentry && exp->ex_mnt == mnt)
+			break;
+	}
 	return exp;
 }
 
@@ -107,16 +110,17 @@
  * Find the export entry for a given dentry.  <gam3@acm.org>
  */
 static svc_export *
-exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
+exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)];
+	struct list_head *p;
+	svc_export *exp = NULL;
 
-	if (clp == NULL)
-		return NULL;
-
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next)
+	list_for_each(p, head) {
+		exp = list_entry(p, svc_export, ex_hash);
 		if (is_subdir(dentry, exp->ex_dentry))
 			break;
+	}
 	return exp;
 }
 
@@ -126,21 +130,35 @@
  * <gam3@acm.org>
  */
 static svc_export *
-exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry)
+exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)];
+	struct list_head *p;
+	svc_export *exp = NULL;
+	struct dentry *ndentry;
 
-	if (clp == NULL)
-		return NULL;
-
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) {
-		struct dentry	*ndentry = exp->ex_dentry;
+	list_for_each(p, head) {
+		exp = list_entry(p, svc_export, ex_hash);
+		ndentry = exp->ex_dentry;
 		if (ndentry && is_subdir(ndentry->d_parent, dentry))
 			break;
 	}
 	return exp;
 }
 
+/* Update parent pointers of all exports */
+static void exp_change_parents(svc_client *clp, svc_export *old, svc_export *new)
+{
+	struct list_head *head = &clp->cl_list;
+	struct list_head *p;
+
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_list);
+		if (exp->ex_parent == old)
+			exp->ex_parent = new;
+	}
+}
+
 /*
  * Export a file system.
  */
@@ -149,10 +167,9 @@
 {
 	svc_client	*clp;
 	svc_export	*exp, *parent;
-	svc_export	**head;
 	struct nameidata nd;
 	struct inode	*inode = NULL;
-	int		i, err;
+	int		err;
 	kdev_t		dev;
 	ino_t		ino;
 
@@ -221,12 +238,12 @@
 		goto finish;
 	}
 
-	if ((parent = exp_child(clp, dev, nd.dentry)) != NULL) {
+	if ((parent = exp_child(clp, inode->i_sb, nd.dentry)) != NULL) {
 		dprintk("exp_export: export not valid (Rule 3).\n");
 		goto finish;
 	}
 	/* Is this is a sub-export, must be a proper subset of FS */
-	if ((parent = exp_parent(clp, dev, nd.dentry)) != NULL) {
+	if ((parent = exp_parent(clp, inode->i_sb, nd.dentry)) != NULL) {
 		dprintk("exp_export: sub-export not valid (Rule 2).\n");
 		goto finish;
 	}
@@ -248,21 +265,11 @@
 	exp->ex_anon_gid = nxp->ex_anon_gid;
 
 	/* Update parent pointers of all exports */
-	if (parent) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			svc_export *temp = clp->cl_export[i];
+	if (parent)
+		exp_change_parents(clp, parent, exp);
 
-			while (temp) {
-				if (temp->ex_parent == parent)
-					temp->ex_parent = exp;
-				temp = temp->ex_next;
-			}
-		}
-	}
-
-	head = clp->cl_export + EXPORT_HASH(dev);
-	exp->ex_next = *head;
-	*head = exp;
+	list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev));
+	list_add_tail(&exp->ex_list, &clp->cl_list);
 
 	err = 0;
 
@@ -285,21 +292,12 @@
 static void
 exp_do_unexport(svc_export *unexp)
 {
-	svc_export	*exp;
-	svc_client	*clp;
 	struct dentry	*dentry;
 	struct vfsmount *mnt;
 	struct inode	*inode;
-	int		i;
 
 	/* Update parent pointers. */
-	clp = unexp->ex_client;
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		for (exp = clp->cl_export[i]; exp; exp = exp->ex_next)
-			if (exp->ex_parent == unexp)
-				exp->ex_parent = unexp->ex_parent;
-	}
-
+	exp_change_parents(unexp->ex_client, unexp, unexp->ex_parent);
 	dentry = unexp->ex_dentry;
 	mnt = unexp->ex_mnt;
 	inode = dentry->d_inode;
@@ -319,18 +317,15 @@
 static void
 exp_unexport_all(svc_client *clp)
 {
-	svc_export	*exp;
-	int		i;
+	struct list_head *p = &clp->cl_list;
 
 	dprintk("unexporting all fs's for clnt %p\n", clp);
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		exp = clp->cl_export[i];
-		clp->cl_export[i] = NULL;
-		while (exp) {
-			svc_export *next = exp->ex_next;
-			exp_do_unexport(exp);
-			exp = next;
-		}
+
+	while (!list_empty(p)) {
+		svc_export *exp = list_entry(p->next, svc_export, ex_list);
+		list_del(&exp->ex_list);
+		list_del(&exp->ex_hash);
+		exp_do_unexport(exp);
 	}
 }
 
@@ -341,7 +336,6 @@
 exp_unexport(struct nfsctl_export *nxp)
 {
 	svc_client	*clp;
-	svc_export	**expp, *exp = NULL;
 	int		err;
 
 	/* Consistency check */
@@ -355,17 +349,12 @@
 	clp = exp_getclientbyname(nxp->ex_client);
 	if (clp) {
 		kdev_t ex_dev = to_kdev_t(nxp->ex_dev);
-		expp = clp->cl_export + EXPORT_HASH(ex_dev);
-		while ((exp = *expp) != NULL) {
-			if (kdev_same(exp->ex_dev, ex_dev)) {
-				if (exp->ex_ino == nxp->ex_ino) {
-					*expp = exp->ex_next;
-					exp_do_unexport(exp);
-					err = 0;
-					break;
-				}
-			}
-			expp = &(exp->ex_next);
+		svc_export *exp = exp_get(clp, ex_dev, nxp->ex_ino);
+		if (exp) {
+			list_del(&exp->ex_hash);
+			list_del(&exp->ex_list);
+			exp_do_unexport(exp);
+			err = 0;
 		}
 	}
 
@@ -380,55 +369,34 @@
  * since its harder to fool a kernel module than a user space program.
  */
 int
-exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino,
-	   char *path, struct knfsd_fh *f, int maxsize)
+exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
 {
 	struct svc_export	*exp;
 	struct nameidata	nd;
 	struct inode		*inode;
 	struct svc_fh		fh;
+	kdev_t			dev;
 	int			err;
 
 	err = -EPERM;
-	if (path) {
-		if (path_init(path, LOOKUP_POSITIVE, &nd) &&
-		    path_walk(path, &nd)) {
-			printk("nfsd: exp_rootfh path not found %s", path);
-			return err;
-		}
-		dev = nd.dentry->d_inode->i_dev;
-		ino = nd.dentry->d_inode->i_ino;
-	
-		dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n",
-		         path, nd.dentry, clp->cl_ident,
-		         major(dev), minor(dev), (long) ino);
-		exp = exp_parent(clp, dev, nd.dentry);
-	} else {
-		dprintk("nfsd: exp_rootfh(%s:%02x:%02x/%ld)\n",
-		         clp->cl_ident, major(dev), minor(dev), (long) ino);
-		if ((exp = exp_get(clp, dev, ino))) {
-			nd.mnt = mntget(exp->ex_mnt);
-			nd.dentry = dget(exp->ex_dentry);
-		}
+	/* NB: we probably ought to check that it's NUL-terminated */
+	if (path_init(path, LOOKUP_POSITIVE, &nd) &&
+	    path_walk(path, &nd)) {
+		printk("nfsd: exp_rootfh path not found %s", path);
+		return err;
 	}
+	inode = nd.dentry->d_inode;
+	dev = inode->i_dev;
+
+	dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n",
+		 path, nd.dentry, clp->cl_ident,
+		 major(dev), minor(dev), (long) inode->i_ino);
+	exp = exp_parent(clp, inode->i_sb, nd.dentry);
 	if (!exp) {
 		dprintk("nfsd: exp_rootfh export not found.\n");
 		goto out;
 	}
 
-	inode = nd.dentry->d_inode;
-	if (!inode) {
-		printk("exp_rootfh: Aieee, NULL d_inode\n");
-		goto out;
-	}
-	if (!kdev_same(inode->i_dev, dev) || inode->i_ino != ino) {
-		printk("exp_rootfh: Aieee, ino/dev mismatch\n");
-		printk("exp_rootfh: arg[dev(%02x:%02x):ino(%ld)]"
-		       " inode[dev(%02x:%02x):ino(%ld)]\n",
-		       major(dev), minor(dev), (long) ino,
-		       major(inode->i_dev), minor(inode->i_dev), (long) inode->i_ino);
-	}
-
 	/*
 	 * fh must be initialized before calling fh_compose
 	 */
@@ -547,6 +515,67 @@
 	return NULL;
 }
 
+/* Iterator */
+
+static void *e_start(struct seq_file *m, loff_t *pos)
+{
+	loff_t n = *pos;
+	unsigned client, export;
+	svc_client *clp;
+	struct list_head *p;
+	
+	exp_readlock();
+	if (!n--)
+		return (void *)1;
+	client = n >> 32;
+	export = n & ((1LL<<32) - 1);
+	for (clp = clients; client && clp; clp = clp->cl_next, client--)
+		;
+	if (!clp)
+		return NULL;
+	list_for_each(p, &clp->cl_list)
+		if (!export--)
+			return list_entry(p, svc_export, ex_list);
+	n &= ~((1LL<<32) - 1);
+	do {
+		clp = clp->cl_next;
+		n += 1LL<<32;
+	} while(clp && list_empty(&clp->cl_list));
+	if (!clp)
+		return NULL;
+	*pos = n+1;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void *e_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	svc_export *exp = p;
+	svc_client *clp;
+
+	if (p == (void *)1)
+		clp = clients;
+	else if (exp->ex_list.next == &exp->ex_client->cl_list)
+		clp = exp->ex_client->cl_next;
+	else {
+		++*pos;
+		return list_entry(exp->ex_list.next, svc_export, ex_list);
+	}
+	*pos &= ~((1LL<<32) - 1);
+	while (clp && list_empty(&clp->cl_list)) {
+		clp = clp->cl_next;
+		*pos += 1LL<<32;
+	}
+	if (!clp)
+		return NULL;
+	++*pos;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void e_stop(struct seq_file *m, void *p)
+{
+	exp_unlock();
+}
+
 struct flags {
 	int flag;
 	char *name[2];
@@ -569,128 +598,77 @@
 	{ 0, {"", ""}}
 };
 
-static int
-exp_flags(char *buffer, int flag)
+static void exp_flags(struct seq_file *m, int flag)
 {
-    int len = 0, first = 0;
-    struct flags *flg = expflags;
+	int first = 0;
+	struct flags *flg;
 
-    for (;flg->flag;flg++) {
-        int state = (flg->flag & flag)?0:1;
-        if (!flg->flag)
-		break;
-        if (*flg->name[state]) {
-		len += sprintf(buffer + len, "%s%s",
-                               first++?",":"", flg->name[state]);
-        }
-    }
-    return len;
+	for (flg = expflags; flg->flag; flg++) {
+		int state = (flg->flag & flag)?0:1;
+		if (*flg->name[state])
+			seq_printf(m, "%s%s", first++?",":"", flg->name[state]);
+	}
 }
 
-
-
-/* mangling borrowed from fs/super.c */
-/* Use octal escapes, like mount does, for embedded spaces etc. */
-static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
-
-static int
-mangle(const unsigned char *s, char *buf, int len) {
-        char *sp;
-        int n;
-
-        sp = buf;
-        while(*s && sp-buf < len-3) {
-                for (n = 0; n < sizeof(need_escaping); n++) {
-                        if (*s == need_escaping[n]) {
-                                *sp++ = '\\';
-                                *sp++ = '0' + ((*s & 0300) >> 6);
-                                *sp++ = '0' + ((*s & 070) >> 3);
-                                *sp++ = '0' + (*s & 07);
-                                goto next;
-                        }
-                }
-                *sp++ = *s;
-        next:
-                s++;
-        }
-        return sp - buf;	/* no trailing NUL */
+static inline void mangle(struct seq_file *m, const char *s)
+{
+	seq_escape(m, s, " \t\n\\");
 }
 
-#define FREEROOM	((int)PAGE_SIZE-200-len)
-#define MANGLE(s)	len += mangle((s), buffer+len, FREEROOM);
-
-int
-exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data)
+static int e_show(struct seq_file *m, void *p)
 {
-	struct svc_clnthash	**hp, **head, *tmp;
-	struct svc_client	*clp;
-	svc_export *exp;
-	off_t	pos = 0;
-        off_t	begin = 0;
-        int	len = 0;
-	int	i,j;
+	struct svc_export *exp = p;
+	struct svc_client *clp;
+	int j, first = 0;
 
-        len += sprintf(buffer, "# Version 1.1\n");
-        len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");
-
-	for (clp = clients; clp; clp = clp->cl_next) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			exp = clp->cl_export[i];
-			while (exp) {
-				int first = 0;
-				MANGLE(exp->ex_path);
-				buffer[len++]='\t';
-				MANGLE(clp->cl_ident);
-				buffer[len++]='(';
-
-				len += exp_flags(buffer+len, exp->ex_flags);
-				len += sprintf(buffer+len, ") # ");
-				for (j = 0; j < clp->cl_naddr; j++) {
-					struct in_addr	addr = clp->cl_addr[j]; 
-
-					head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
-					for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
-						if (tmp->h_addr.s_addr == addr.s_addr) {
-							if (first++) len += sprintf(buffer+len, "%s", " ");
-							if (tmp->h_client != clp)
-								len += sprintf(buffer+len, "(");
-							len += sprintf(buffer+len, "%d.%d.%d.%d",
-									htonl(addr.s_addr) >> 24 & 0xff,
-									htonl(addr.s_addr) >> 16 & 0xff,
-									htonl(addr.s_addr) >>  8 & 0xff,
-									htonl(addr.s_addr) >>  0 & 0xff);
-							if (tmp->h_client != clp)
-							  len += sprintf(buffer+len, ")");
-							break;
-						}
-					}
-				}
-				exp = exp->ex_next;
-
-				buffer[len++]='\n';
-
-				pos=begin+len;
-				if(pos<offset) {
-					len=0;
-					begin=pos;
-				}
-				if (pos > offset + length)
-					goto done;
-			}
-		}
+	if (p == (void *)1) {
+		seq_puts(m, "# Version 1.1\n");
+		seq_puts(m, "# Path Client(Flags) # IPs\n");
+		return 0;
 	}
 
-	*eof = 1;
+	clp = exp->ex_client;
 
-done:
-	*start = buffer + (offset - begin);
-	len -= (offset - begin);
-	if ( len > length )
-		len = length;
-	return len;
+	mangle(m, exp->ex_path);
+	seq_putc(m, '\t');
+	mangle(m, clp->cl_ident);
+	seq_putc(m, '(');
+	exp_flags(m, exp->ex_flags);
+	seq_puts(m, ") # ");
+	for (j = 0; j < clp->cl_naddr; j++) {
+		struct svc_clnthash **hp, **head, *tmp;
+		struct in_addr addr = clp->cl_addr[j]; 
+
+		head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
+		for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
+			if (tmp->h_addr.s_addr == addr.s_addr)
+				break;
+		}
+		if (tmp) {
+			if (first++)
+				seq_putc(m, ' ');
+			if (tmp->h_client != clp)
+				seq_putc(m, '(');
+			seq_printf(m, "%d.%d.%d.%d",
+				htonl(addr.s_addr) >> 24 & 0xff,
+				htonl(addr.s_addr) >> 16 & 0xff,
+				htonl(addr.s_addr) >>  8 & 0xff,
+				htonl(addr.s_addr) >>  0 & 0xff);
+			if (tmp->h_client != clp)
+				seq_putc(m, ')');
+		}
+	}
+	seq_putc(m, '\n');
+	return 0;
 }
 
+struct seq_operations nfs_exports_op = {
+	start:	e_start,
+	next:	e_next,
+	stop:	e_stop,
+	show:	e_show,
+};
+
 /*
  * Add or modify a client.
  * Change requests may involve the list of host addresses. The list of
@@ -726,6 +704,9 @@
 		if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL)))
 			goto out_unlock;
 		memset(clp, 0, sizeof(*clp));
+		for (i = 0; i < NFSCLNT_EXPMAX; i++)
+			INIT_LIST_HEAD(&clp->cl_export[i]);
+		INIT_LIST_HEAD(&clp->cl_list);
 
 		dprintk("created client %s (%p)\n", ncp->cl_ident, clp);
 
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 25c4288..aad14fb 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -20,6 +20,7 @@
 #include <linux/unistd.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <linux/nfs.h>
 #include <linux/sunrpc/svc.h>
@@ -37,7 +38,6 @@
 static int	nfsctl_delclient(struct nfsctl_client *data);
 static int	nfsctl_export(struct nfsctl_export *data);
 static int	nfsctl_unexport(struct nfsctl_export *data);
-static int	nfsctl_getfh(struct nfsctl_fhparm *, __u8 *);
 static int	nfsctl_getfd(struct nfsctl_fdparm *, __u8 *);
 static int	nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
 #ifdef notyet
@@ -46,17 +46,28 @@
 
 static int	initialized;
 
-int exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data);
+extern struct seq_operations nfs_exports_op;
+static int exports_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &nfs_exports_op);
+}
+static struct file_operations exports_operations = {
+	open:		exports_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
 
 void proc_export_init(void)
 {
+	struct proc_dir_entry *entry;
 	if (!proc_mkdir("fs/nfs", 0))
 		return;
-	create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL);
+	entry = create_proc_entry("fs/nfs/exports", 0, NULL);
+	if (entry)
+		entry->proc_fops =  &exports_operations;
 }
 
-
 /*
  * Initialize nfsd
  */
@@ -125,7 +136,7 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, NODEV, 0, data->gd_path, res, data->gd_maxlen);
+		err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
 	exp_unlock();
 	return err;
 }
@@ -148,40 +159,7 @@
 	if (!(clp = exp_getclient(sin)))
 		err = -EPERM;
 	else
-		err = exp_rootfh(clp, NODEV, 0, data->gd_path, &fh, NFS_FHSIZE);
-	exp_unlock();
-
-	if (err == 0) {
-		if (fh.fh_size > NFS_FHSIZE)
-			err = -EINVAL;
-		else {
-			memset(res,0, NFS_FHSIZE);
-			memcpy(res, &fh.fh_base, fh.fh_size);
-		}
-	}
-
-	return err;
-}
-
-static inline int
-nfsctl_getfh(struct nfsctl_fhparm *data, __u8 *res)
-{
-	struct sockaddr_in	*sin;
-	struct svc_client	*clp;
-	int			err = 0;
-	struct knfsd_fh		fh;
-
-	if (data->gf_addr.sa_family != AF_INET)
-		return -EPROTONOSUPPORT;
-	if (data->gf_version < 2 || data->gf_version > NFSSVC_MAXVERS)
-		return -EINVAL;
-	sin = (struct sockaddr_in *)&data->gf_addr;
-
-	exp_readlock();
-	if (!(clp = exp_getclient(sin)))
-		err = -EPERM;
-	else
-		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE);
+		err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
 	exp_unlock();
 
 	if (err == 0) {
@@ -277,9 +255,6 @@
 		err = nfsctl_ugidupdate(&arg->ca_umap);
 		break;
 #endif
-	case NFSCTL_GETFH:
-		err = nfsctl_getfh(&arg->ca_getfh, res->cr_getfh);
-		break;
 	case NFSCTL_GETFD:
 		err = nfsctl_getfd(&arg->ca_getfd, res->cr_getfh);
 		break;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index af9bd34..2455606 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -114,35 +114,30 @@
 	if (isdotent(name, len)) {
 		if (len==1)
 			dentry = dget(dparent);
-		else  { /* must be ".." */
+		else if (dparent != exp->ex_dentry)
+			dentry = dget(dparent->d_parent);
+		else  if (!EX_CROSSMNT(exp))
+			dentry = dget(dparent); /* .. == . just like at / */
+		else {
 			/* checking mountpoint crossing is very different when stepping up */
-			if (dparent == exp->ex_dentry) {
-				if (!EX_CROSSMNT(exp))
-					dentry = dget(dparent); /* .. == . just like at / */
-				else
-				{
-					struct svc_export *exp2 = NULL;
-					struct dentry *dp;
-					struct vfsmount *mnt = mntget(exp->ex_mnt);
-					dentry = dget(dparent);
-					while(follow_up(&mnt, &dentry))
-						;
-					dp = dget(dentry->d_parent);
-					dput(dentry);
-					dentry = dp;
-					for ( ; exp2 == NULL && dp->d_parent != dp;
-					      dp=dp->d_parent)
-						exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
-					if (exp2==NULL) {
-						dput(dentry);
-						dentry = dget(dparent);
-					} else {
-						exp = exp2;
-					}
-					mntput(mnt);
-				}
-			} else
-				dentry = dget(dparent->d_parent);
+			struct svc_export *exp2 = NULL;
+			struct dentry *dp;
+			struct vfsmount *mnt = mntget(exp->ex_mnt);
+			dentry = dget(dparent);
+			while(follow_up(&mnt, &dentry))
+				;
+			dp = dget(dentry->d_parent);
+			dput(dentry);
+			dentry = dp;
+			for ( ; !exp2 && dp->d_parent != dp; dp=dp->d_parent)
+				exp2 = exp_get_by_name(exp->ex_client, mnt, dp);
+			if (!exp2) {
+				dput(dentry);
+				dentry = dget(dparent);
+			} else {
+				exp = exp2;
+			}
+			mntput(mnt);
 		}
 	} else {
 		fh_lock(fhp);
@@ -159,9 +154,7 @@
 			struct dentry *mounts = dget(dentry);
 			while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
 				;
-			exp2 = exp_get(rqstp->rq_client,
-				       mounts->d_inode->i_dev,
-				       mounts->d_inode->i_ino);
+			exp2 = exp_get_by_name(rqstp->rq_client, mnt, mounts);
 			if (exp2 && EX_CROSSMNT(exp2)) {
 				/* successfully crossed mount point */
 				exp = exp2;
@@ -591,6 +584,7 @@
 	mm_segment_t	oldfs;
 	int		err;
 	struct file	file;
+	struct inode	*inode;
 
 	err = nfsd_open(rqstp, fhp, S_IFREG, MAY_READ, &file);
 	if (err)
@@ -598,14 +592,15 @@
 	err = nfserr_perm;
 	if (!file.f_op->read)
 		goto out_close;
+	inode = file.f_dentry->d_inode;
 #ifdef MSNFS
 	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
-		(!lock_may_read(file.f_dentry->d_inode, offset, *count)))
+		(!lock_may_read(inode, offset, *count)))
 		goto out_close;
 #endif
 
 	/* Get readahead parameters */
-	ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino);
+	ra = nfsd_get_raparms(inode->i_dev, inode->i_ino);
 	if (ra) {
 		file.f_reada = ra->p_reada;
 		file.f_ramax = ra->p_ramax;
diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c
index d28ea94..56b85e1 100644
--- a/fs/ntfs/fs.c
+++ b/fs/ntfs/fs.c
@@ -1050,8 +1050,7 @@
  *
  * NOTE : A context switch can happen in kernel code only if the code blocks
  * (= calls schedule() in kernel/sched.c). */
-struct super_block *ntfs_read_super(struct super_block *sb, void *options,
-		int silent)
+static int ntfs_fill_super(struct super_block *sb, void *options, int silent)
 {
 	ntfs_volume *vol;
 	struct buffer_head *bh;
@@ -1142,19 +1141,28 @@
 		ntfs_error("Could not get root dir inode\n");
 		goto ntfs_read_super_mft;
 	}
-ntfs_read_super_ret:
-	ntfs_debug(DEBUG_OTHER, "read_super: done\n");
-	return sb;
+	return 0;
 ntfs_read_super_mft:
 	ntfs_free(vol->mft);
 ntfs_read_super_unl:
 ntfs_read_super_vol:
-	sb = NULL;
-	goto ntfs_read_super_ret;
+	ntfs_debug(DEBUG_OTHER, "read_super: done\n");
+	return -EINVAL;
 }
 
 /* Define the filesystem */
-static DECLARE_FSTYPE_DEV(ntfs_fs_type, "ntfs", ntfs_read_super);
+static struct super_block *ntfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super);
+}
+
+static struct file_system_type ntfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"ntfs",
+	get_sb:		ntfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_ntfs_fs(void)
 {
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 972fa8e..cd07c66 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -119,7 +119,6 @@
 
 #endif
 
-static struct super_block *qnx4_read_super(struct super_block *, void *, int);
 static void qnx4_put_super(struct super_block *sb);
 static struct inode *qnx4_alloc_inode(struct super_block *sb);
 static void qnx4_destroy_inode(struct inode *inode);
@@ -337,8 +336,7 @@
 	return NULL;
 }
 
-static struct super_block *qnx4_read_super(struct super_block *s,
-					   void *data, int silent)
+static int qnx4_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct buffer_head *bh;
 	struct inode *root;
@@ -396,7 +394,7 @@
 
 	brelse(bh);
 
-	return s;
+	return 0;
 
       outi:
 	iput(root);
@@ -404,7 +402,7 @@
 	brelse(bh);
       outnobh:
 
-	return NULL;
+	return -EINVAL;
 }
 
 static void qnx4_put_super(struct super_block *sb)
@@ -541,7 +539,18 @@
 		       "qnx4_inode_cache: not all structures were freed\n");
 }
 
-static DECLARE_FSTYPE_DEV(qnx4_fs_type, "qnx4", qnx4_read_super);
+static struct super_block *qnx4_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super);
+}
+
+static struct file_system_type qnx4_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"qnx4",
+	get_sb:		qnx4_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_qnx4_fs(void)
 {
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index e1ac705..a9ae97d 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -965,7 +965,7 @@
 // at the ext2 code and comparing. It's subfunctions contain no code
 // used as a template unless they are so labeled.
 //
-static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent)
+static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
 {
     int size;
     struct inode *root_inode;
@@ -981,12 +981,12 @@
     memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info));
     jdev_name = NULL;
     if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks, &jdev_name) == 0) {
-	return NULL;
+	return -EINVAL;
     }
 
     if (blocks) {
   	printk("reserfs: resize option for remount only\n");
-	return NULL;
+	return -EINVAL;
     }	
 
     size = block_size(s->s_dev);
@@ -997,14 +997,14 @@
       old_format = 1;
     /* try new format (64-th 1k block), which can contain reiserfs super block */
     else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) {
-      printk("sh-2021: reiserfs_read_super: can not find reiserfs on %s\n", s->s_id);
+      printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", s->s_id);
       goto error;    
     }
     s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s);
     s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;
 
     if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 
-	printk ("reiserfs_read_super: unable to read bitmap\n");
+	printk ("reiserfs_fill_super: unable to read bitmap\n");
 	goto error;
     }
 #ifdef CONFIG_REISERFS_CHECK
@@ -1014,7 +1014,7 @@
 
     // set_device_ro(s->s_dev, 1) ;
     if( journal_init(s, jdev_name, old_format) ) {
-	printk("sh-2022: reiserfs_read_super: unable to initialize journal space\n") ;
+	printk("sh-2022: reiserfs_fill_super: unable to initialize journal space\n") ;
 	goto error ;
     } else {
 	jinit_done = 1 ; /* once this is set, journal_release must be called
@@ -1022,7 +1022,7 @@
 			 */
     }
     if (reread_meta_blocks(s)) {
-	printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ;
+	printk("reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
 	goto error ;
     }
 
@@ -1036,7 +1036,7 @@
     args.objectid = REISERFS_ROOT_PARENT_OBJECTID ;
     root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args));
     if (!root_inode) {
-	printk ("reiserfs_read_super: get root inode failed\n");
+	printk ("reiserfs_fill_super: get root inode failed\n");
 	goto error;
     }
 
@@ -1115,7 +1115,7 @@
     reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
     init_waitqueue_head (&(s->u.reiserfs_sb.s_wait));
 
-    return s;
+    return 0;
 
  error:
     if (jinit_done) { /* kill the commit thread, free journal ram */
@@ -1132,7 +1132,7 @@
     if (SB_BUFFER_WITH_SB (s))
 	brelse(SB_BUFFER_WITH_SB (s));
 
-    return NULL;
+    return -EINVAL;
 }
 
 
@@ -1159,7 +1159,18 @@
   return 0;
 }
 
-static DECLARE_FSTYPE_DEV(reiserfs_fs_type,"reiserfs",reiserfs_read_super);
+static struct super_block *reiserfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
+}
+
+static struct file_system_type reiserfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"reiserfs",
+	get_sb:		reiserfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 //
 // this is exactly what 2.3.99-pre9's init_ext2_fs is
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 0aa6ca8..2f758e8 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -92,8 +92,7 @@
 
 static struct super_operations romfs_ops;
 
-static struct super_block *
-romfs_read_super(struct super_block *s, void *data, int silent)
+static int romfs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct buffer_head *bh;
 	struct romfs_super_block *rsb;
@@ -150,10 +149,10 @@
 out:
 		brelse(bh);
 outnobh:
-		s = NULL;
+		return -EINVAL;
 	}
 
-	return s;
+	return 0;
 }
 
 /* That's simple too. */
@@ -529,7 +528,18 @@
 	statfs:		romfs_statfs,
 };
 
-static DECLARE_FSTYPE_DEV(romfs_fs_type, "romfs", romfs_read_super);
+static struct super_block *romfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super);
+}
+
+static struct file_system_type romfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"romfs",
+	get_sb:		romfs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_romfs_fs(void)
 {
diff --git a/fs/super.c b/fs/super.c
index 2a4cb32..2b4162e 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -597,11 +597,8 @@
  *
  *	Rather than duplicating all that logics every time when
  *	we want something that doesn't fit "nodev" and "single" we pull
- *	the relevant code into common helper and let get_sb_...() call
+ *	the relevant code into common helper and let ->get_sb() call
  *	it.
- *
- *	NB: get_sb_...() is going to become an fs type method, with
- *	current ->read_super() becoming a callback used by common instances.
  */
 struct super_block *get_anon_super(struct file_system_type *type,
 	int (*compare)(struct super_block *,void *), void *data)
@@ -787,17 +784,6 @@
 	return s;
 }
 
-/* Will go away */
-static int fill_super(struct super_block *sb, void *data, int verbose)
-{
-	return sb->s_type->read_super(sb, data, verbose) ? 0 : -EINVAL;
-}
-static struct super_block *__get_sb_bdev(struct file_system_type *fs_type,
-	int flags, char *dev_name, void * data)
-{
-	return get_sb_bdev(fs_type, flags, dev_name, data, fill_super);
-}
-
 struct vfsmount *
 do_kern_mount(const char *fstype, int flags, char *name, void *data)
 {
@@ -811,10 +797,7 @@
 	mnt = alloc_vfsmnt(name);
 	if (!mnt)
 		goto out;
-	if (type->get_sb)
-		sb = type->get_sb(type, flags, name, data);
-	else if (type->fs_flags & FS_REQUIRES_DEV)
-		sb = __get_sb_bdev(type, flags, name, data);
+	sb = type->get_sb(type, flags, name, data);
 	if (IS_ERR(sb))
 		goto out_mnt;
 	if (type->fs_flags & FS_NOMOUNT)
diff --git a/fs/udf/super.c b/fs/udf/super.c
index cf78cf5..b9952e7 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -76,7 +76,7 @@
 static char error_buf[1024];
 
 /* These are the "meat" - everything else is stuffing */
-static struct super_block *udf_read_super(struct super_block *, void *, int);
+static int udf_fill_super(struct super_block *, void *, int);
 static void udf_put_super(struct super_block *);
 static void udf_write_super(struct super_block *);
 static int udf_remount_fs(struct super_block *, int *, char *);
@@ -96,7 +96,18 @@
 static int udf_statfs(struct super_block *, struct statfs *);
 
 /* UDF filesystem type */
-static DECLARE_FSTYPE_DEV(udf_fstype, "udf", udf_read_super);
+static struct super_block *udf_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super);
+}
+
+static struct file_system_type udf_fstype = {
+	owner:		THIS_MODULE,
+	name:		"udf",
+	get_sb:		udf_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static kmem_cache_t * udf_inode_cachep;
 
@@ -1387,8 +1398,7 @@
  *	July 1, 1997 - Andrew E. Mileski
  *	Written, tested, and released.
  */
-static struct super_block *
-udf_read_super(struct super_block *sb, void *options, int silent)
+static int udf_fill_super(struct super_block *sb, void *options, int silent)
 {
 	int i;
 	struct inode *inode=NULL;
@@ -1545,7 +1555,7 @@
 		goto error_out;
 	}
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
-	return sb;
+	return 0;
 
 error_out:
 	if (UDF_SB_VAT(sb))
@@ -1588,7 +1598,7 @@
 		udf_close_lvid(sb);
 	udf_release_data(UDF_SB_LVIDBH(sb));
 	UDF_SB_FREE(sb);
-	return NULL;
+	return -EINVAL;
 }
 
 void udf_error(struct super_block *sb, const char *function,
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index f62f971..ef84557 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -434,8 +434,7 @@
 	UFSD(("EXIT\n"))
 }
 
-struct super_block * ufs_read_super (struct super_block * sb, void * data,
-	int silent)
+static int ufs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
@@ -807,7 +806,7 @@
 			goto failed;
 
 	UFSD(("EXIT\n"))
-	return(sb);
+	return 0;
 
 dalloc_failed:
 	iput(inode);
@@ -815,7 +814,7 @@
 	if (ubh) ubh_brelse_uspi (uspi);
 	if (uspi) kfree (uspi);
 	UFSD(("EXIT (FAILED)\n"))
-	return(NULL);
+	return -EINVAL;
 }
 
 void ufs_write_super (struct super_block * sb) {
@@ -1009,7 +1008,18 @@
 	remount_fs:	ufs_remount,
 };
 
-static DECLARE_FSTYPE_DEV(ufs_fs_type, "ufs", ufs_read_super);
+static struct super_block *ufs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super);
+}
+
+static struct file_system_type ufs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"ufs",
+	get_sb:		ufs_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_ufs_fs(void)
 {
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index 8651639..a761c31 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -1254,20 +1254,19 @@
 	setattr:	fat_notify_change,
 };
 
-struct super_block *vfat_read_super(struct super_block *sb,void *data,
-				    int silent)
+int vfat_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct super_block *res;
   
 	MSDOS_SB(sb)->options.isvfat = 1;
 	res = fat_read_super(sb, data, silent, &vfat_dir_inode_operations);
 	if (IS_ERR(res))
-		return NULL;
+		return PTR_ERR(res);
 	if (res == NULL) {
 		if (!silent)
 			printk(KERN_INFO "VFS: Can't find a valid"
 			       " VFAT filesystem on dev %s.\n", sb->s_id);
-		return NULL;
+		return -EINVAL;
 	}
 
 	if (parse_options((char *) data, &(MSDOS_SB(sb)->options))) {
@@ -1281,6 +1280,5 @@
 			sb->s_root->d_op = &vfat_dentry_ops[2];
 		}
 	}
-
-	return res;
+	return 0;
 }
diff --git a/fs/vfat/vfatfs_syms.c b/fs/vfat/vfatfs_syms.c
index 2feb122..f52faa7 100644
--- a/fs/vfat/vfatfs_syms.c
+++ b/fs/vfat/vfatfs_syms.c
@@ -11,14 +11,24 @@
 #include <linux/mm.h>
 #include <linux/msdos_fs.h>
 
-DECLARE_FSTYPE_DEV(vfat_fs_type, "vfat", vfat_read_super);
+static struct super_block *vfat_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
+}
+
+static struct file_system_type vfat_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"vfat",
+	get_sb:		vfat_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 EXPORT_SYMBOL(vfat_create);
 EXPORT_SYMBOL(vfat_unlink);
 EXPORT_SYMBOL(vfat_mkdir);
 EXPORT_SYMBOL(vfat_rmdir);
 EXPORT_SYMBOL(vfat_rename);
-EXPORT_SYMBOL(vfat_read_super);
 EXPORT_SYMBOL(vfat_lookup);
 
 static int __init init_vfat_fs(void)
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index 0cf51b7..3104bc3 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -47,6 +47,7 @@
 /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
 /* Don't duplicate feature flags which are redundant with Intel! */
 #define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP		(1*32+19) /* MP Capable. */
 #define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
 #define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
 #define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 3463340..462ec5a 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -28,17 +28,17 @@
 
 
 #define unlazy_fpu( tsk ) do { \
-	if (test_thread_flag(TIF_USEDFPU)) \
+	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) \
 		save_init_fpu( tsk ); \
 } while (0)
 
-#define clear_fpu( tsk )			\
-do {						\
-	if (test_thread_flag(TIF_USEDFPU)) {	\
-		asm volatile("fwait");		\
-		clear_thread_flag(TIF_USEDFPU);	\
-		stts();				\
-	}					\
+#define clear_fpu( tsk )					\
+do {								\
+	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {		\
+		asm volatile("fwait");				\
+		clear_tsk_thread_flag(tsk, TIF_USEDFPU);	\
+		stts();						\
+	}							\
 } while (0)
 
 /*
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 5ea17fb..9fdc376 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -90,6 +90,7 @@
 #define cpu_has_xmm	(test_bit(X86_FEATURE_XMM,  boot_cpu_data.x86_capability))
 #define cpu_has_fpu	(test_bit(X86_FEATURE_FPU,  boot_cpu_data.x86_capability))
 #define cpu_has_apic	(test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
+#define cpu_has_mp (test_bit(X86_FEATURE_MP, boot_cpu_data.x86_capability))
 
 extern char ignore_irq13;
 
diff --git a/include/asm-i386/rwlock.h b/include/asm-i386/rwlock.h
index 9475419..5c2f470 100644
--- a/include/asm-i386/rwlock.h
+++ b/include/asm-i386/rwlock.h
@@ -24,23 +24,23 @@
 	asm volatile(LOCK "subl $1,(%0)\n\t" \
 		     "js 2f\n" \
 		     "1:\n" \
-		     ".section .text.lock,\"ax\"\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tcall " helper "\n\t" \
 		     "jmp 1b\n" \
-		     ".previous" \
+		     LOCK_SECTION_END \
 		     ::"a" (rw) : "memory")
 
 #define __build_read_lock_const(rw, helper)   \
 	asm volatile(LOCK "subl $1,%0\n\t" \
 		     "js 2f\n" \
 		     "1:\n" \
-		     ".section .text.lock,\"ax\"\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tpushl %%eax\n\t" \
 		     "leal %0,%%eax\n\t" \
 		     "call " helper "\n\t" \
 		     "popl %%eax\n\t" \
 		     "jmp 1b\n" \
-		     ".previous" \
+		     LOCK_SECTION_END \
 		     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_read_lock(rw, helper)	do { \
@@ -54,23 +54,23 @@
 	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
 		     "jnz 2f\n" \
 		     "1:\n" \
-		     ".section .text.lock,\"ax\"\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tcall " helper "\n\t" \
 		     "jmp 1b\n" \
-		     ".previous" \
+		     LOCK_SECTION_END \
 		     ::"a" (rw) : "memory")
 
 #define __build_write_lock_const(rw, helper) \
 	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
 		     "jnz 2f\n" \
 		     "1:\n" \
-		     ".section .text.lock,\"ax\"\n" \
+		     LOCK_SECTION_START("") \
 		     "2:\tpushl %%eax\n\t" \
 		     "leal %0,%%eax\n\t" \
 		     "call " helper "\n\t" \
 		     "popl %%eax\n\t" \
 		     "jmp 1b\n" \
-		     ".previous" \
+		     LOCK_SECTION_END \
 		     :"=m" (*(volatile int *)rw) : : "memory")
 
 #define __build_write_lock(rw, helper)	do { \
diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
index 0d416f7..3cac142 100644
--- a/include/asm-i386/rwsem.h
+++ b/include/asm-i386/rwsem.h
@@ -101,7 +101,7 @@
 LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
 		"  js        2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  pushl     %%ecx\n\t"
 		"  pushl     %%edx\n\t"
@@ -109,7 +109,7 @@
 		"  popl      %%edx\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".previous"
+		LOCK_SECTION_END
 		"# ending down_read\n\t"
 		: "+m"(sem->count)
 		: "a"(sem)
@@ -130,13 +130,13 @@
 		"  testl     %0,%0\n\t" /* was the count 0 before? */
 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
 		"1:\n\t"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  pushl     %%ecx\n\t"
 		"  call      rwsem_down_write_failed\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".previous\n"
+		LOCK_SECTION_END
 		"# ending down_write"
 		: "+d"(tmp), "+m"(sem->count)
 		: "a"(sem)
@@ -154,7 +154,7 @@
 LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
 		"  js        2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  decw      %%dx\n\t" /* do nothing if still outstanding active readers */
 		"  jnz       1b\n\t"
@@ -162,7 +162,7 @@
 		"  call      rwsem_wake\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".previous\n"
+		LOCK_SECTION_END
 		"# ending __up_read\n"
 		: "+m"(sem->count), "+d"(tmp)
 		: "a"(sem)
@@ -180,7 +180,7 @@
 LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
 		"1:\n\t"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\n\t"
 		"  decw      %%dx\n\t" /* did the active count reduce to 0? */
 		"  jnz       1b\n\t" /* jump back if not */
@@ -188,7 +188,7 @@
 		"  call      rwsem_wake\n\t"
 		"  popl      %%ecx\n\t"
 		"  jmp       1b\n"
-		".previous\n"
+		LOCK_SECTION_END
 		"# ending __up_write\n"
 		: "+m"(sem->count)
 		: "a"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS)
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
index 76c738e..a0ce1b8 100644
--- a/include/asm-i386/semaphore.h
+++ b/include/asm-i386/semaphore.h
@@ -122,10 +122,10 @@
 		LOCK "decl %0\n\t"     /* --sem->count */
 		"js 2f\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed\n\t"
 		"jmp 1b\n"
-		".previous"
+		LOCK_SECTION_END
 		:"=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -149,10 +149,10 @@
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed_interruptible\n\t"
 		"jmp 1b\n"
-		".previous"
+		LOCK_SECTION_END
 		:"=a" (result), "=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -177,10 +177,10 @@
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __down_failed_trylock\n\t"
 		"jmp 1b\n"
-		".previous"
+		LOCK_SECTION_END
 		:"=a" (result), "=m" (sem->count)
 		:"c" (sem)
 		:"memory");
@@ -203,10 +203,11 @@
 		LOCK "incl %0\n\t"     /* ++sem->count */
 		"jle 2f\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
+		LOCK_SECTION_START("")
 		"2:\tcall __up_wakeup\n\t"
 		"jmp 1b\n"
-		".previous"
+		LOCK_SECTION_END
+		".subsection 0\n"
 		:"=m" (sem->count)
 		:"c" (sem)
 		:"memory");
diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h
index 2542244..b9f7796 100644
--- a/include/asm-i386/softirq.h
+++ b/include/asm-i386/softirq.h
@@ -33,12 +33,12 @@
 			"jnz 2f;"					\
 			"1:;"						\
 									\
-			".section .text.lock,\"ax\";"			\
+			LOCK_SECTION_START("")				\
 			"2: pushl %%eax; pushl %%ecx; pushl %%edx;"	\
 			"call %c1;"					\
 			"popl %%edx; popl %%ecx; popl %%eax;"		\
 			"jmp 1b;"					\
-			".previous;"					\
+			LOCK_SECTION_END				\
 									\
 		: /* no output */					\
 		: "r" (ptr), "i" (do_softirq)				\
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index dbdd68b..89118fc 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -56,13 +56,13 @@
 	"\n1:\t" \
 	"lock ; decb %0\n\t" \
 	"js 2f\n" \
-	".section .text.lock,\"ax\"\n" \
+	LOCK_SECTION_START("") \
 	"2:\t" \
 	"cmpb $0,%0\n\t" \
 	"rep;nop\n\t" \
 	"jle 2b\n\t" \
 	"jmp 1b\n" \
-	".previous"
+	LOCK_SECTION_END
 
 /*
  * This works. Despite all the confusion.
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index e8515e0..61c7b42 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -73,8 +73,8 @@
 #define THREAD_SIZE (2*PAGE_SIZE)
 #define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
 #define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
-#define get_thread_info(ti) get_task_struct((ti)->l_task)
-#define put_thread_info(ti) put_task_struct((ti)->l_task)
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
 
 #else /* !__ASSEMBLY__ */
 
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index 4acf48c..8581f36 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -9,6 +9,7 @@
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
+#include <linux/stringify.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -94,11 +95,10 @@
 		"subql #1,%0@\n\t"
 		"jmi 2f\n\t"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
-		".even\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed\n"
-		".previous"
+		LOCK_SECTION_END
 		: /* no outputs */
 		: "a" (sem1)
 		: "memory");
@@ -119,11 +119,10 @@
 		"jmi 2f\n\t"
 		"clrl %0\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
-		".even\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed_interruptible\n"
-		".previous"
+		LOCK_SECTION_END
 		: "=d" (result)
 		: "a" (sem1)
 		: "memory");
@@ -145,11 +144,10 @@
 		"jmi 2f\n\t"
 		"clrl %0\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
-		".even\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\tpea 1b\n\t"
 		"jbra __down_failed_trylock\n"
-		".previous"
+		LOCK_SECTION_END
 		: "=d" (result)
 		: "a" (sem1)
 		: "memory");
@@ -175,12 +173,11 @@
 		"addql #1,%0@\n\t"
 		"jle 2f\n"
 		"1:\n"
-		".section .text.lock,\"ax\"\n"
-		".even\n"
+		LOCK_SECTION_START(".even\n\t")
 		"2:\t"
 		"pea 1b\n\t"
 		"jbra __up_wakeup\n"
-		".previous"
+		LOCK_SECTION_END
 		: /* no outputs */
 		: "a" (sem1)
 		: "memory");
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index 54a8d54..1434908 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -12,10 +12,6 @@
  *
  */
 
-/* if you're going to use out-of-line slowpaths, use .section .lock.text,
- * not .text.lock or the -ffunction-sections monster will eat you alive
- */
-
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 7a59ed6..15c6d00 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -3,10 +3,6 @@
 
 #include <asm/system.h>
 
-/* if you're going to use out-of-line slowpaths, use .section .lock.text,
- * not .text.lock or the -ffunction-sections monster will eat you alive
- */
-
 /* we seem to be the only architecture that uses 0 to mean locked - but we
  * have to.  prumpf */
 
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
index 99d4689..c5cbc10 100644
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -47,7 +47,7 @@
 extern struct file_operations efs_dir_operations;
 extern struct address_space_operations efs_symlink_aops;
 
-extern struct super_block *efs_read_super(struct super_block *, void *, int);
+extern int efs_fill_super(struct super_block *, void *, int);
 extern int efs_statfs(struct super_block *, struct statfs *);
 
 extern void efs_read_inode(struct inode *);
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index c7fed24..14a44ec 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -671,7 +671,6 @@
 extern void ext3_write_super_lockfs (struct super_block *);
 extern void ext3_unlockfs (struct super_block *);
 extern int ext3_remount (struct super_block *, int *, char *);
-extern struct super_block * ext3_read_super (struct super_block *,void *,int);
 extern int ext3_statfs (struct super_block *, struct statfs *);
 
 #define ext3_std_error(sb, errno)				\
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 68902b1..28027aa 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -934,21 +934,10 @@
 	int (*transfer) (struct inode *, struct iattr *);
 };
 
-/*
- *		NOTE NOTE NOTE
- *
- *	->read_super() is going to die.  New method (->get_sb) should replace
- * it.  The only reason why ->read_super() is left for _SHORT_ transition
- * period is to avoid a single patch touching every fs.  They will be
- * converted one-by-one and ONCE THAT IS DONE OR TWO WEEKS HAD PASSED
- * (whatever sooner) ->read_super() WILL DISAPPEAR.  
- */
-
 struct file_system_type {
 	const char *name;
 	int fs_flags;
 	struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *);
-	struct super_block *(*read_super) (struct super_block *, void *, int);
 	struct module *owner;
 	struct file_system_type * next;
 	struct list_head fs_supers;
@@ -964,14 +953,6 @@
 	int flags, void *data,
 	int (*fill_super)(struct super_block *, void *, int));
 
-#define DECLARE_FSTYPE_DEV(var,type,read) \
-struct file_system_type var = { \
-	name:		type, \
-	read_super:	read, \
-	fs_flags:	FS_REQUIRES_DEV, \
-	owner:		THIS_MODULE, \
-}
-
 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */
 #define fops_get(fops) \
 	(((fops) && (fops)->owner)	\
diff --git a/include/linux/hfs_fs.h b/include/linux/hfs_fs.h
index bd64f19..d8549ae 100644
--- a/include/linux/hfs_fs.h
+++ b/include/linux/hfs_fs.h
@@ -301,7 +301,7 @@
 extern void hfs_sngl_ifill(struct inode *, ino_t, const int);
 
 /* super.c */
-extern struct super_block *hfs_read_super(struct super_block *,void *,int);
+extern int hfs_fill_super(struct super_block *,void *,int);
 
 /* trans.c */
 extern void hfs_colon2mac(struct hfs_name *, const char *, int);
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 8749f6f..2204760 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -91,6 +91,9 @@
 
 extern int tainted;
 extern const char *print_tainted(void);
+#define TAINT_PROPRIETORY_MODULE	(1<<0)
+#define TAINT_FORCED_MODULE		(1<<1)
+#define TAINT_UNSAFE_SMP		(1<<2)
 
 #if DEBUG
 #define pr_debug(fmt,arg...) \
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index eff3797..4851d84 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -330,8 +330,7 @@
 extern int msdos_unlink(struct inode *dir, struct dentry *dentry);
 extern int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
 			struct inode *new_dir, struct dentry *new_dentry);
-extern struct super_block *msdos_read_super(struct super_block *sb,
-					    void *data, int silent);
+extern int msdos_fill_super(struct super_block *sb, void *data, int silent);
 
 /* vfat/namei.c - these are for dmsdos */
 extern struct dentry *vfat_lookup(struct inode *dir, struct dentry *);
@@ -341,8 +340,7 @@
 extern int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode);
 extern int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 		       struct inode *new_dir, struct dentry *new_dentry);
-extern struct super_block *vfat_read_super(struct super_block *sb, void *data,
-					   int silent);
+extern int vfat_fill_super(struct super_block *sb, void *data, int silent);
 
 /* vfat/vfatfs_syms.c */
 extern struct file_system_type vfat_fs_type;
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index db948a7..6f3e970 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -54,11 +54,13 @@
 	int			cl_naddr;
 	struct in_addr		cl_addr[NFSCLNT_ADDRMAX];
 	struct svc_uidmap *	cl_umap;
-	struct svc_export *	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_list;
 };
 
 struct svc_export {
-	struct svc_export *	ex_next;
+	struct list_head	ex_hash;
+	struct list_head	ex_list;
 	char			ex_path[NFS_MAXPATHLEN+1];
 	struct svc_export *	ex_parent;
 	struct svc_client *	ex_client;
@@ -90,7 +92,10 @@
 struct svc_client *	exp_getclient(struct sockaddr_in *sin);
 void			exp_putclient(struct svc_client *clp);
 struct svc_export *	exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
-int			exp_rootfh(struct svc_client *, kdev_t, ino_t,
+struct svc_export *	exp_get_by_name(struct svc_client *clp,
+					struct vfsmount *mnt,
+					struct dentry *dentry);
+int			exp_rootfh(struct svc_client *, 
 					char *path, struct knfsd_fh *, int maxsize);
 int			nfserrno(int errno);
 void			exp_nlmdetach(void);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 904d4a4..e3d3e68 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1486,6 +1486,9 @@
 #define PCI_DEVICE_ID_PANACOM_QUADMODEM	0x0400
 #define PCI_DEVICE_ID_PANACOM_DUALMODEM	0x0402
 
+#define PCI_VENDOR_ID_AFAVLAB		0x14db
+#define PCI_DEVICE_ID_AFAVLAB_P028	0x2180
+
 #define PCI_VENDOR_ID_BROADCOM		0x14e4
 #define PCI_DEVICE_ID_TIGON3_5700	0x1644
 #define PCI_DEVICE_ID_TIGON3_5701	0x1645
diff --git a/include/linux/proc_fs_i.h b/include/linux/proc_fs_i.h
deleted file mode 100644
index d4bde09..0000000
--- a/include/linux/proc_fs_i.h
+++ /dev/null
@@ -1,9 +0,0 @@
-struct proc_inode_info {
-	struct task_struct *task;
-	int type;
-	union {
-		int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
-		int (*proc_read)(struct task_struct *task, char *page);
-	} op;
-	struct file *file;
-};
diff --git a/include/linux/serialP.h b/include/linux/serialP.h
index 9fff64f..40c5b93 100644
--- a/include/linux/serialP.h
+++ b/include/linux/serialP.h
@@ -70,7 +70,7 @@
 	int			x_char;	/* xon/xoff character */
 	int			close_delay;
 	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
+	unsigned short		closing_wait2; /* obsolete */
 	int			IER; 	/* Interrupt Enable Register */
 	int			MCR; 	/* Modem control register */
 	int			LCR; 	/* Line control register */
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 440ba7d..dc27910 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -35,6 +35,23 @@
 						if (!__r) local_bh_enable();   \
 						__r; })
 
+/* Must define these before including other files, inline functions need them */
+
+#include <linux/stringify.h>
+
+#define LOCK_SECTION_NAME			\
+	".text.lock." __stringify(KBUILD_BASENAME)
+
+#define LOCK_SECTION_START(extra)		\
+	".subsection 1\n\t"			\
+	extra					\
+	".ifndef " LOCK_SECTION_NAME "\n\t"	\
+	LOCK_SECTION_NAME ":\n\t"		\
+	".endif\n\t"
+
+#define LOCK_SECTION_END			\
+	".previous\n\t"
+
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
 
diff --git a/include/linux/stringify.h b/include/linux/stringify.h
new file mode 100644
index 0000000..0b43883
--- /dev/null
+++ b/include/linux/stringify.h
@@ -0,0 +1,12 @@
+#ifndef __LINUX_STRINGIFY_H
+#define __LINUX_STRINGIFY_H
+
+/* Indirect stringification.  Doing two levels allows the parameter to be a
+ * macro itself.  For example, compile with -DFOO=bar, __stringify(FOO)
+ * converts to "bar".
+ */
+
+#define __stringify_1(x)	#x
+#define __stringify(x)		__stringify_1(x)
+
+#endif	/* !__LINUX_STRINGIFY_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index b0ac239..3535d0d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -50,8 +50,12 @@
 
 #include <asm/atomic.h>
 
-#define SWP_USED	1
-#define SWP_WRITEOK	3
+enum {
+	SWP_USED	= (1 << 0),	/* is slot in swap_info[] used? */
+	SWP_WRITEOK	= (1 << 1),	/* ok to write to this swap?	*/
+	SWP_BLOCKDEV	= (1 << 2),	/* is this swap a block device? */
+	SWP_ACTIVE	= (SWP_USED | SWP_WRITEOK),
+};
 
 #define SWAP_CLUSTER_MAX 32
 
@@ -63,7 +67,6 @@
  */
 struct swap_info_struct {
 	unsigned int flags;
-	kdev_t swap_device;
 	spinlock_t sdev_lock;
 	struct file *swap_file;
 	unsigned short * swap_map;
diff --git a/init/Config.in b/init/Config.in
index 64c2643..5e225a7 100644
--- a/init/Config.in
+++ b/init/Config.in
@@ -1,16 +1,14 @@
 mainmenu_option next_comment
-comment 'General setup'
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
 
+mainmenu_option next_comment
+comment 'General setup'
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
-
-endmenu
-
-mainmenu_option next_comment
-comment 'Code maturity level options'
-bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
 mainmenu_option next_comment
diff --git a/kernel/panic.c b/kernel/panic.c
index 1eccb0e..84adabf 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -103,6 +103,10 @@
 /**
  *	print_tainted - return a string to represent the kernel taint state.
  *
+ *  'P' - Proprietory module has been loaded.
+ *  'F' - Module has been forcibly loaded.
+ *  'S' - SMP with CPUs not designed for SMP.
+ *
  *	The string is overwritten by the next call to print_taint().
  */
  
@@ -110,9 +114,10 @@
 {
 	static char buf[20];
 	if (tainted) {
-		snprintf(buf, sizeof(buf), "Tainted: %c%c",
-			tainted & 1 ? 'P' : 'G',
-			tainted & 2 ? 'F' : ' ');
+		snprintf(buf, sizeof(buf), "Tainted: %c%c%c",
+			tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
+			tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
+			tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
 	}
 	else
 		snprintf(buf, sizeof(buf), "Not tainted");
diff --git a/lib/zlib_inflate/infutil.h b/lib/zlib_inflate/infutil.h
index 7d1a8d3..f3f883e 100644
--- a/lib/zlib_inflate/infutil.h
+++ b/lib/zlib_inflate/infutil.h
@@ -11,7 +11,7 @@
 #ifndef _INFUTIL_H
 #define _INFUTIL_H
 
-#include "zconf.h"
+#include <linux/zconf.h>
 #include "inftrees.h"
 #include "infcodes.h"
 
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 925286b..fbe3898 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -114,7 +114,7 @@
 
 	while (1) {
 		p = &swap_info[type];
-		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+		if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) {
 			swap_device_lock(p);
 			offset = scan_swap_map(p);
 			swap_device_unlock(p);
@@ -729,7 +729,7 @@
 	swap_list_lock();
 	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
 		p = swap_info + type;
-		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+		if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) {
 			if (p->swap_file->f_dentry == nd.dentry)
 				break;
 		}
@@ -752,7 +752,7 @@
 	}
 	nr_swap_pages -= p->pages;
 	total_swap_pages -= p->pages;
-	p->flags = SWP_USED;
+	p->flags &= ~SWP_WRITEOK;
 	swap_list_unlock();
 	unlock_kernel();
 	err = try_to_unuse(type);
@@ -770,7 +770,7 @@
 			swap_info[prev].next = p - swap_info;
 		nr_swap_pages += p->pages;
 		total_swap_pages += p->pages;
-		p->flags = SWP_WRITEOK;
+		p->flags |= SWP_WRITEOK;
 		swap_list_unlock();
 		goto out_dput;
 	}
@@ -778,7 +778,6 @@
 	swap_device_lock(p);
 	swap_file = p->swap_file;
 	p->swap_file = NULL;
-	p->swap_device = NODEV;
 	p->max = 0;
 	swap_map = p->swap_map;
 	p->swap_map = NULL;
@@ -822,7 +821,8 @@
 				}
 			len += sprintf(buf + len, "%-39s %s\t%d\t%d\t%d\n",
 				       path,
-				       !kdev_none(ptr->swap_device) ? "partition" : "file\t",
+				       (ptr->flags & SWP_BLOCKDEV) ?
+				       		"partition" : "file\t",
 				       ptr->pages << (PAGE_SHIFT - 10),
 				       usedswap << (PAGE_SHIFT - 10),
 				       ptr->prio);
@@ -837,9 +837,10 @@
 	int i;
 
 	for (i = 0 ; i < nr_swapfiles ; i++, ptr++) {
-		if (ptr->flags & SWP_USED)
-			if (kdev_same(ptr->swap_device, dev))
-				return 1;
+		if ((ptr->flags & SWP_USED) &&
+		    (ptr->flags & SWP_BLOCKDEV) &&
+		    (kdev_same(ptr->swap_file->f_dentry->d_inode->i_rdev, dev)))
+			return 1;
 	}
 	return 0;
 }
@@ -883,7 +884,6 @@
 		nr_swapfiles = type+1;
 	p->flags = SWP_USED;
 	p->swap_file = NULL;
-	p->swap_device = NODEV;
 	p->swap_map = NULL;
 	p->lowest_bit = 0;
 	p->highest_bit = 0;
@@ -911,8 +911,10 @@
 
 	error = -EINVAL;
 	if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode)) {
-		p->swap_device = swap_file->f_dentry->d_inode->i_rdev;
-		set_blocksize(p->swap_device, PAGE_SIZE);
+		error = set_blocksize(swap_file->f_dentry->d_inode->i_rdev,
+				      PAGE_SIZE);
+		if (error < 0)
+			goto bad_swap;
 	} else if (!S_ISREG(swap_file->f_dentry->d_inode->i_mode))
 		goto bad_swap;
 
@@ -1035,7 +1037,9 @@
 	swap_list_lock();
 	swap_device_lock(p);
 	p->max = maxpages;
-	p->flags = SWP_WRITEOK;
+	p->flags = SWP_ACTIVE;
+	if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode))
+		p->flags |= SWP_BLOCKDEV;
 	p->pages = nr_good_pages;
 	nr_swap_pages += nr_good_pages;
 	total_swap_pages += nr_good_pages;
@@ -1064,7 +1068,6 @@
 bad_swap_2:
 	swap_list_lock();
 	swap_map = p->swap_map;
-	p->swap_device = NODEV;
 	p->swap_file = NULL;
 	p->swap_map = NULL;
 	p->flags = 0;
@@ -1090,7 +1093,7 @@
 	swap_list_lock();
 	for (i = 0; i < nr_swapfiles; i++) {
 		unsigned int j;
-		if (swap_info[i].flags != SWP_USED)
+		if (!(swap_info[i].flags & SWP_USED))
 			continue;
 		for (j = 0; j < swap_info[i].max; ++j) {
 			switch (swap_info[i].swap_map[j]) {